LLMs + Tool Calls: 똑똑하지만 저주받은

발행: (2025년 12월 12일 오전 12:51 GMT+9)
4 min read
원문: Dev.to

Source: Dev.to

소개

LLM이 도구를 창의적으로 사용하는 실제 예시 — 그리고 샌드박스 안전성이 대부분의 사람들이 생각하는 것보다 왜 더 중요한지 보여줍니다.

LLM은 코드를 생성하는 데 뛰어나지만, 때때로 너무 창의적으로 나아갈 수도 있습니다. 오늘은 LLM + 도구 호출 시스템을 구축하는 사람이라면 꼭 알아야 할, 너무 흥미로워 공유하지 않을 수 없는 “똑똑하지만 저주받은” AI 순간을 경험했습니다.

설정

Genkit 앱에 간단한 LuaExecutor 도구를 추가했습니다. 목표는 아주 직관적이었습니다:

  • 하나의 Genkit Flow
  • 하나의 도구 (LuaExecutor)
  • Go 애플리케이션 내에서 Lua 코드를 실행하기 위한 Lua VM (gopher-lua 사용)

의도된 목적: LLM에게 “무언가를 수행하는 Lua 스크립트를 생성하고 실행해라”와 같은 요청을 하는 것.

프롬프트

모델에게 가볍게 물었습니다:

Go 프로그램을 생성해서 컨텍스트 취소를 시연하고, 실행해 주세요.

참고: 저는 Go 프로그램을 요청했으며, Lua 코드는 요청하지 않았습니다.

일어난 일

모델은 “Go를 실행할 수 없습니다”라고 답하지 않고 즉석에서 다음을 수행했습니다:

  1. Go 코드를 생성함.
  2. 이를 다중행 Lua 문자열 안에 삽입함.
  3. os.execute("go run main.go") 로 Lua에서 실행함.
  4. Go 프로그램의 출력을 마치 전혀 이상하지 않은 일처럼 캡처해 반환함.
-- Example of the generated Lua wrapper (syntax highlighted for Lua)
local go_code = [[
package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    go func() {
        time.Sleep(2 * time.Second)
        cancel()
    }()

    select {
    -- (rest of the generated Go code)
]]

똑똑함. 안전하고 회복력 있는 LLM 앱/도구를 구축하려면 모델의 “지능”에만 의존하는 것이 아니라, 체계적인 엔지니어링 관행이 필요합니다.

결론

이번 사건은 버그가 아니라 모델이 너무 똑똑했기 때문입니다. 샌드박싱, 명확한 도구 경계, 그리고 견고한 시스템 프롬프트가 왜 필수적인지를 완벽히 보여줍니다. 힘이 커질수록 책임도 커집니다.

Back to Blog

관련 글

더 보기 »