LangChain工具描述怎么写才能让智能体不跑偏

话题来源: LangChain重构工作流:智能体如何自动化你的日常任务?

即使你给了智能体最先进的推理引擎,如果工具描述写得含糊不清,它照样会在关键时刻做出匪夷所思的调用——该重启服务时它去检查天气,该发警报时它偏要执行 Shell 脚本。这种事见得太多了。

工具描述就是智能体理解“这是什么、何时用、怎么用”的唯一说明书。它不像人类程序员能读你的注释然后心领神会,它真的会逐字逐句抠字眼。描述里写“检查服务器”,它就可能在任何需要获取信息的地方都去调用这个工具,哪怕需求其实是“查一下 CPU 温度”。

先定义“做什么”,再定义“不做什么”

最容易被忽略的是负面用例。很多开发者在 docstring 里只描述功能,不描述边界。例如:

"""检查服务器状态。"""

换成这样,效果完全不同:

"""检查指定 URL 的 HTTP 状态码和响应时间(毫秒)。
输入必须是完整的 https:// URL。仅用于 HTTP 健康检查,不要用于 WebSocket 或 TCP 端口探测。"""

智能体拿到后者的描述,就会明白――这不是一个万能检查工具,它不能拿去做端口扫描。少了后半句,它就敢在需要连通性检测时,直接用这个工具去 curl 一个 WebSocket 端点,然后给你返回一个莫名其妙的 400 错误,你还得花半小时去翻日志。

用“输入示例”锚定参数格式

很多跑偏问题出在参数格式上。工具定义了个 command: str,描述里却只写“执行命令”,智能体可能会传入一整段自然语言,比如“请重启 nginx 服务”,而不是 systemctl restart nginx

描述中一定要给出具体的输入例子,越接近真实调用形式越好。比如:

"""在本地 Shell 执行命令。输入示例:'systemctl restart nginx'。
仅允许 systemctl、docker、grep 等白名单命令。"""

这样它就学会了:参数必须是一个原生的 Shell 命令,而不是一段说明文字。我在自己的运维智能体里加了这个示例后,“行动输入”从模糊的自由文本瞬间变成了可执行的指令串,误调用率下降了至少七成。

给工具命名时讲点“人话”

工具名称也是描述的一部分。别图省事起个 tool_afunc1 之类的名字。智能体会用名称去匹配任务意图。把工具叫 check_api_health,它就知道是健康检查;叫 send_slack_alert,它就知道跟报警有关。名称本身就是一种提示。如果名称里带有动词“check”“send”“restart”,智能体的推理链路会明显更稳定。

踩坑得来的一个小原则

描述写好后,不妨亲自测试一种对抗场景:故意给一个不匹配的任务,看智能体会不会误用工具。比如给它一个“查看日志文件”的指令,看它会不会跑去调用“重启服务”的工具。如果会,说明描述缺少约束,需要加上“仅用于……”“不要用于……”。

说到底,工具描述不是在写技术文档给同事看,而是在给一个极度缺乏常识但非常听话的推理系统写操作手册。你遗漏的任何细节,它都会用你意想不到的方式“弥补”回来,而那种弥补通常就是跑偏的开始。下次写工具时,多花的那两分钟,可能会省掉之后两个小时的排错。就这么直接。

评论