Prompt 是 Agent 的灵魂:ReAct 提示词设计
作者:程序员马丁
Ragent AI —— 从 0 到 1 纯手工打造企业级 Agentic RAG,拒绝 Demo 玩具!AI 时代,助你拿个offer。
上一篇咱们用 JSON Schema 升级了工具的参数定义,大脑传参的准确率从“大部分时候对”提升到了“绝大部分时候对”。工具的入参问题基本解决了,但如果你多跑几轮不同的场景,会发现另一类问题开始冒头——大脑偶尔跳过思考直接出手、输出格式时不时跑偏、最终回复里冒出工具名和 JSON 这种用户根本不该看到的东西。
这些问题的根源不在工具,而在提示词。
从第 05 篇到现在,buildSystemPrompt() 里的系统提示词只做过一处小改动(Action Input 的格式说明加了 JSON 要求),整体还是最初那个“够用但不完美的最小版”。这一篇,咱们把它升级成一个结构化的、带 Few-shot 示例的、有负面约束的完整版——让大脑不只是“能跑”,而是“稳定地跑”。
本项目中具体代码已上传 GitHub TinyAgent,大家 Clone 项目后,将代码分支切换到 1.2.x,默认主分支是最新代码。运行前复制
.env.example为.env,把自己的 API Key 填进去,默认阿里云百炼平台;.env已加入.gitignore,切分支时不会丢。
先看翻车现场
提示词太简陋,大脑会怎么跑偏?咱们用比特严选的场景看三个真实案例。
1. 跳过 Thought 直接出手
用户说“帮我查一下订单 88231”,大脑的理想输出应该是先想再干:
Thought: 用户想查询订单 88231 的详情,我需要调用 queryOrder 工具。
Action: queryOrder
Action Input: {"orderId":"88231"}
但有些模型(特别是参数量较小或指令跟随能力偏弱的)会直接蹦出:
Action: queryOrder
Action Input: {"orderId":"88231"}
没有 Thought,直接出手。对于“查订单”这种简单场景,跳过思考好像也没什么问题——反正结果是对的。但到了退款这种需要多步判断的场景,问题就来了。大脑不写 Thought,就跳过了“先查订单、再看签收时间、再判断是否在退货期内”这些推理步骤,可能一上来就直接调 applyRefund,连订单状态都没确认就退款。
更重要的是,Thought 是你调试 Agent 的唯一窗 口。大脑为什么调了这个工具而不是那个?为什么在第三圈突然决定给最终答复?没有 Thought,你只能看到一连串工具调用,根本不知道它在想什么,出了问题也无从下手。
2. 格式漂移
提示词里写了 Thought: / Action: / Action Input: 这三个标签,但有些模型会自作主张改格式:
思考:用户要查订单,我先看看订单信息。
操作:queryOrder
输入:{"orderId":"88231"}
中文标签、不同的冒号格式,甚至有时候大小写也不一致(action: 而不是 Action:)。咱们的 parseAction() 是按 Action: 和 Action Input: 这两个精确前缀来匹配的,换了标签就解析不出来。解析不出工具名,兜底逻辑把整段文字当最终答复返回——用户看到的是一段莫名其妙的内部推理过程。