LLMs + Tool Calls: 똑똑하지만 저주받은
Source: Dev.to
소개
LLM이 도구를 창의적으로 사용하는 실제 예시 — 그리고 샌드박스 안전성이 대부분의 사람들이 생각하는 것보다 왜 더 중요한지 보여줍니다.
LLM은 코드를 생성하는 데 뛰어나지만, 때때로 너무 창의적으로 나아갈 수도 있습니다. 오늘은 LLM + 도구 호출 시스템을 구축하는 사람이라면 꼭 알아야 할, 너무 흥미로워 공유하지 않을 수 없는 “똑똑하지만 저주받은” AI 순간을 경험했습니다.
설정
Genkit 앱에 간단한 LuaExecutor 도구를 추가했습니다. 목표는 아주 직관적이었습니다:
- 하나의 Genkit Flow
- 하나의 도구 (LuaExecutor)
- Go 애플리케이션 내에서 Lua 코드를 실행하기 위한 Lua VM (
gopher-lua사용)
의도된 목적: LLM에게 “무언가를 수행하는 Lua 스크립트를 생성하고 실행해라”와 같은 요청을 하는 것.
프롬프트
모델에게 가볍게 물었습니다:
Go 프로그램을 생성해서 컨텍스트 취소를 시연하고, 실행해 주세요.
참고: 저는 Go 프로그램을 요청했으며, Lua 코드는 요청하지 않았습니다.
일어난 일
모델은 “Go를 실행할 수 없습니다”라고 답하지 않고 즉석에서 다음을 수행했습니다:
- Go 코드를 생성함.
- 이를 다중행 Lua 문자열 안에 삽입함.
os.execute("go run main.go")로 Lua에서 실행함.- 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 앱/도구를 구축하려면 모델의 “지능”에만 의존하는 것이 아니라, 체계적인 엔지니어링 관행이 필요합니다.
결론
이번 사건은 버그가 아니라 모델이 너무 똑똑했기 때문입니다. 샌드박싱, 명확한 도구 경계, 그리고 견고한 시스템 프롬프트가 왜 필수적인지를 완벽히 보여줍니다. 힘이 커질수록 책임도 커집니다.