LLMs + 工具调用:聪明却被诅咒

发布: (2025年12月11日 GMT+8 23:51)
3 min read
原文: Dev.to

Source: Dev.to

引言

一个关于 LLM 如何创造性地使用工具的真实案例——以及为什么沙箱安全比大多数人意识到的更重要。

LLM 在生成代码方面很强大,但有时它们也会变得过于富有创意。今天我遇到了一个既聪明又诅咒的 AI 时刻,实在太有趣不忍错过,尤其是对任何构建 LLM + 工具调用系统的人来说。

设置

我在我的 Genkit 应用中添加了一个简单的 LuaExecutor 工具。目标很直接:

  • 一个 Genkit Flow
  • 一个工具(LuaExecutor)
  • 一个 Lua 虚拟机(通过 gopher-lua)在 Go 应用中运行 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 应用/工具需要严谨的工程实践,而不仅仅是依赖模型的“智能”。

结论

这次事件并不是 bug,而是模型过于“聪明”。它完美地展示了为何沙箱、明确的工具边界以及稳健的系统提示是必不可少的。能力越大,责任也越大。

Back to Blog

相关文章

阅读更多 »