你的Agent又不听话了?先别急着改提示词。
这是很多团队的日常:Agent效果不好,第一反应就是把系统提示词拿出来改改。加一句"你必须调用工具",不行;改成"请务必使用工具",还是不行;再网上搜个"万能提示词模板"粘进去,好像好了一点,换几个输入又崩了。一轮折腾下来,时间没少花,效果全凭运气。
我把这种现象叫"提示词玄学"。它的典型特征是:改了有反应,但不稳定;验证靠肉眼,不靠数据;归因靠感觉,不靠日志。说白了,就是把Agent优化当成了提示词修辞大赛,而不是一个可观测、可评测、可迭代的工程问题。
这篇内容我想围绕一个问题展开:Agent优化到底该怎么从"玄学"变回"工程"。会先聊为什么大家容易陷进提示词玄学,再给一套我自己在项目里反复用、确认有效的分层优化方法,最后盘几个常见的坑——包括最近网上很火的那些"测试提示词""提示词泄露"话题,它们背后暴露的东西,可能和你想的不一样。
1. 为什么Agent优化最后都变成了提示词玄学
1.1 效果差的真凶:问题根本不在提示词
先泼一盆冷水:Agent表现拉胯,大概率不是提示词写得不好。我拆过不少跑偏的Agent项目,最后定位到根因,分布大概是这样的:
- 工具层问题(工具数量太多、schema设计不合理、接口报错没人管)约占三到四成;
- 上下文层问题(系统提示词太长、检索结果杂乱、记忆没做好)约占两到三成;
- 模型参数问题(temperature乱设、模型本身不适合任务)约占一两成;
- 真正的提示词表达问题,可能只占两成左右。
这个比例不是拍脑袋。你想想,一个Agent完整链路是:用户输入 → 意图理解 → 工具选择 → 参数提取 → 工具调用 → 结果解析 → 答案生成。这里面任何一环出问题,表象都是"Agent不听话",但根因相差很远。
举个例子。我之前遇到一个项目,Agent老是调用错工具——用户问"订单到哪了",它去调了商品详情接口。所有人第一反应是改提示词:"请根据用户问题选择正确工具"。改了两周,时好时坏。后来查日志发现,商品详情工具的描述里写了"用于查询订单状态"这句话——是文件里抄错了。工具描述错了,提示词写得再花也没用。
所以,当Agent不听话时,第一步不是改提示词,而是先回答一个问题:它到底在哪一步开始不听话的?没有这个答案,所有调整都是在猜。
1.2 调prompt像赌博:即时反馈带来的错觉
那为什么大家还是忍不住先调提示词?因为改提示词是整条链路上"试错成本最低、即时反馈最强"的操作。改一行字,立刻跑一次,看到输出变了,大脑就分泌多巴胺——这个感觉太像赌博了,容易上瘾。
对比一下:改工具Schema要走代码、要重新定义JSON结构、要改后端起服务;改上下文管理要设计检索链路、写缓存逻辑;这些改动周期长、反馈慢。而改提示词是纯文本操作,几秒钟就有结果。
问题在于,"有反馈"不等于"有进展"。你改了一版提示词,跑通了一个case,很可能只是命中了模型的随机性。下一次同样的输入、同样的提示词,输出又不一样。你以为自己在优化,其实在做无意义的重复劳动。
我自己的习惯是:如果一次改动后在10个以上用例上都稳定生效,我才认为这个改动是有效的;如果只是单个case从失败变成功,那多半是运气,不算优化。
1.3 什么时候才轮到提示词背锅
当然,我不是说提示词永远无辜。当排除了工具、上下文、参数这些因素之后,提示词确实需要优化。具体来说,提示词该背锅的场景有这么几类:
- 模型能理解,但输出格式不稳定:比如要求返回JSON,偶尔多了一句讲解;
- 任务规则复杂且模型经常违反:比如"用户没确认价格就不能下单",模型老抢跑;
- 同一个意图有不同的表达,模型对其中一种表达理解不到位;
- 需要模型扮演特定角色或保持特定语气,但风格不稳定。
这些时候,提示词优化是有意义的工作。请注意,它们的共同特征是:链路其他环节已经正常,剩下的就是"模型没按约定做事"。约定写得不清楚、不具体、不一致,优化它们,就是提示词工程的本职。
2. 把玄学变成工程:优化前必须打好的四个地基
说到优化方法论之前,得先把地基打牢。很多人一上来就调提示词,跳过了四个前提步骤,最后越调越乱。这四个步骤是:可观测性、评测集、失败分类、版本管理。
2.1 可观测性:没有日志的Agent优化是闭眼开车
我接手任何一个Agent项目的第一件事,不是看提示词,是看日志。
需要记录的关键信息至少包括:
- 每一轮用户输入、最终输出;
- 每次LLM调用的完整输入(当时使用的prompt)和输出;
- 每次工具调用的名称、参数、返回结果、耗时、状态码;
- 单轮对话的token消耗和总延迟;
- 链路中每个环节的标记(比如"意图识别通过""工具调用完成")。
工具层面,Langfuse、LangSmith、AgentOps这些都能用。如果不想引入重框架,哪怕自己写个JSONL日志追加都行——重点是"有日志",而不是"用了多贵的工具"。
有了日志,很多"玄学问题"立刻现原形。比如之前说的工具调用错,打开日志一看,模型压根没调用你预期那个工具,它调了另一个;再比如"Agent复读机"问题,日志显示工具返回结果为空,模型只能自己瞎编。这些原因,肉眼盯对话记录看不出来,盯日志能看出来。
提示:我在项目里会额外给每个Agent调用注入一个request_id,贯穿前后端。排查问题时输入request_id就能把整条链路拉出来,比对着聊天记录猜高效得多。
这是第一个地基:先知道Agent到底做了什么,再谈优化。
2.2 最小评测集:用30个用例锁死优化方向
第二个地基是评测集。没有评测集的优化,等于打靶不看靶子。
不需要一上来就做几百条,先做30条左右,覆盖三类场景:主流程场景(15条)、边界场景(10条)、典型badcase(5条)。
每条用例要包含:输入(用户话术)、期望行为(期望调用哪个工具、期望返回什么、期望不做什么)、通过标准(可客观判断)。比如:
| 输入 | 期望行为 | 通过标准 |
|---|---|---|
| "查一下昨天的订单到哪了" | 调用 order_tracking 工具,query="昨天的" | 工具名正确、query参数正确 |
| "帮我退掉这个订单" | 不直接执行,先询问订单号和原因 | 输出包含"确认"或"请问" |
| 用户输入为空/乱码 | 触发澄清话术 | 不调用任何工具,输出澄清语句 |
有了评测集,每次改动之后跑一遍,通过率是升是降,一目了然。通过率不降的改动才是有效改动;通过率下降的,哪怕感觉"效果更好"也要回滚。
我见过一个团队,一周改了十几版提示词,每版都觉得"这次好了",结果跑评测集,通过率一直在40%-50%之间波动——他们的"好"只是看见了几个成功case而产生的幸存者偏差。评测集就是为了打破这种偏差而存在的。
2.3 失败分类学:八成问题不在提示词层
第三个地基是失败分类。评测集跑完,你会得到一批失败case。接下来要做分类,而不是直接去改提示词。我的习惯是把失败分成下面五类:
| 失败类型 | 典型表现 | 主要优化方向 |
|---|---|---|
| 意图理解失败 | 用户说A,模型理解成B | 模型选型、few-shot、澄清机制 |
| 工具选择错误 | 该调A工具,调了B工具 | 工具描述、工具数量、路由策略 |
| 参数提取错误 | 调用正确,参数是"上海市上海市" | 工具Schema、结构化输出约束 |
| 执行/环境错误 | API报错、权限不足、超时 | 工程修复,别碰提示词 |
| 答案生成错误 | 工具返回正确,输出时胡编 | 提示词规则、输出校验、低temperature |
分类的意义在于:告诉你该去动哪一层。我看到太多人把"参数提取错误"当成提示词问题去调,调半天没用——那是工具Schema的字段约束没写好,需要的是给参数加枚举、加正则描述、加示例,而不是在系统提示词里写"你提取参数时必须准确"。
每类问题都有对应解法。你在优化提示词之前,先花半小时把失败case分好类,你会发现真正需要动提示词的,可能只有一只手的数量。
2.4 提示词版本管理:改过的每一版都要留档
第四个地基可能最容易被忽略:提示词版本管理。
很多人改提示词是"覆盖式"的——今天在这份提示词上改一句,明天又改一句,改来改去,最后忘了原始版本长什么样,也不知道哪一版对哪个指标负责。这是典型的玄学操作。
我建议两个习惯:
一是"一发版,一存档"。每次修改后,把当前版本的提示词全文、评测集通过率、修改意图记在一个文件夹或Git仓库里。文件名写清楚日期和改动目的,比如20250401_系统提示词_v12_增加工具调用失败重试说明.md。
二是"一改一验"。一次只改一个点,改完跑评测集对比通过率。从v11到v12只改了一个句子,通过率从62%涨到75%,这个改动就是有效贡献;如果一次改了五处,通过率涨了,你根本不知道是谁的功劳,下次复制不了经验。
版本管理本质上是在给"优化"建立因果记录。有了因果记录,提示词优化才从"感觉有用"变成"可验证有效"。
3. 分层优化实操:从工作流到提示词,哪层该动哪层不该动
地基打好之后,就可以开始真正的优化了。我的优化顺序是固定的:先工作流与工具层,再上下文与记忆层,再模型参数层,最后才轮到提示词。为什么是这个顺序?因为越靠前的层级,影响面越大、越稳定。提示词在最底层,是因为它最容易改,但它也最不稳定——同一个提示词换个说法可能就变了。前面的层级稳了,提示词才能发挥应有作用。
3.1 工作流与工具层:让Agent先"会做事"
工作流和工具层是一个Agent的骨架。这一步做不好,后面全是白费。具体看几个高频优化点。
第一,控制工具选择面。理想情况下,单个Agent能看到的工具数量建议控制在10个以内。工具越多,模型的选择准确率下降得越厉害。实在有几十个工具,别让一个Agent自己选——用分组、路由Agent或者检索式工具选择,让Agent先定位到"能处理这类问题的工具子集",再从中选。
第二,把工具描述写成"说明书"而不是"名词解释"。工具描述是模型做选择时最重要的依据。写好的技巧是:动词开头 + 使用场景 + 关键参数说明 + 一个例子。比如:
- 描述: 查询订单物流信息。当用户询问"订单/快递/物流/到哪了"时使用。 - 参数: - order_id: 订单号,必填,用户未提供时先询问。 - mobile: 手机号后四位,选填,用于身份校验。这段描述里包含了"什么时候用""参数要不要问用户",模型照着这个就能减少很多误判。
第三,给工具调用加上"重试和保护机制"。工具调用失败时,Agent要想清楚是重试还是换工具,不能傻傻返回错误;涉及删除、转账、发消息这类不可逆操作,要在工作流里加一层人工确认。这些跟提示词没关系,但对"Agent听不听话"的影响极大。
第四,善用状态机和子任务拆解。一个Agent做五件事,不如拆成三个各司其职的子Agent,由主Agent编排。功能边界清晰了,提示词反而可以写得更短。
3.2 上下文与记忆层:让Agent"记得住"
骨架搭好后,看上下文。Agent的"记忆力"和"注意力"都由这一层决定,但它常常被当成"提示词不够长"来对待——这是个大误区。
系统提示词不是越长越好。我见过不少项目把系统提示词写成三千字的小作文,恨不得把所有业务规则都塞进去。实测下来,提示词超过一定长度之后,模型对关键规则的遵循度是下降的——它记不住,或者被大量无关信息稀释了注意力。
真正该做的是"按需投喂":把不变的规则放进系统提示词(控制在几百字内),把动态的业务数据放到检索结果或工具返回值里,让模型在需要的时候才看到。
- 用户身份、权限信息,在每轮对话里动态注入,而不是写死在提示词里;
- 商品信息、库存数据,通过检索或工具调用获取,不要让模型"背";
- 对话历史不是越长越好,超过一定轮次要做摘要压缩,不然模型会被旧信息带偏。
我这里特别想提醒一句:如果你发现Agent总是"忘记"某个规则,先别急着在提示词里再强调一遍。看看这条规则是不是离用户当前意图太远,或者被淹没在太多规则里。把规则移到合适的层级(比如工具描述里、结构化校验里),往往比再加一句"记住!"有效得多。
3.3 模型参数层:让Agent"稳定发挥"
上下文没问题之后,看模型参数。这一层是很多人忽略的重灾区:不少项目从头到尾用默认参数跑,出了问题就怨提示词,其实问题出在随机性上。
最重要的参数是temperature。它的作用范围是所有输出token的概率分布——如果任务是稳定性优先的(客服问答、数据提取、工具调用),建议设置0或者0.1。我实测过,很多"时好时坏"的玄学问题,把temperature从1调到0.1之后直接消失。原因很简单:Agent场景本来就不需要"文采",需要的是输出可复现。
top_p一般不建议单独调,如果一定要动,和temperature二选一即可。此外还有两个常被忽视的"参数":模型本身和最大输出长度。有些任务Instructions能力弱的模型,提示词写得再好也白搭——这时候该换模型而不是改提示词。最大输出长度太小会导致回答被截断,看起来也像"Agent傻了"。
一个真实案例:某个Agent经常输出到一半就断了,团队成员在提示词里加了"请完整回答不要省略",没用。最后排查发现是max_tokens设成了300,而工具返回结果本身就远超300 token。参数问题,被当成提示词问题折腾了一周。
3.4 提示词层:单变量A/B测试的科学调法
到了这一层,才开始真正动提示词。提示词的调法,原则就是四个字:单变量验证。
一次只改一个点,改完跑评测集,通过率说话。不要甩锅,也不要贪功。具体来说,我常用的提示词优化动作有这几个:
第一,把"模糊愿望"改成"具体指令"。比如"请准确地调用工具"是模糊愿望;"当用户问题涉及物流信息时,必须调用tool_get_logistics,参数order_id从用户消息中提取,提取不到先询问"是具体指令。输出格式也一样,"请返回JSON"不如"只返回一个JSON对象,不要包含任何其他文字或解释"。
第二,少用堆砌强调词。"必须""一定""千万"用多了,等于没有强调。重点太多,模型反而抓不住重心。我见过有人的提示词连续出现七八个"必须",实测效果并不比一个都不用强多少。
第三,给模型"反例",比给"正例"更省事。比如:"不要猜测订单号,如果用户没有提供,请直接询问用户:请问您的订单号是?"这类负向约束在输出格式上尤其管用。
第四,不同角色的指令要分块写。系统提示词里"你是一个客服助手""工具列表""输出格式""禁止事项"分块清晰,比揉成一团要好维护得多。也更容易做版本对比。
第五,提示词里不要写"事实",要写"规则"。比如系统提示词里写"我们的客服电话是400-123456"就不合适,哪天电话换了,你还得改提示词换版本。正确做法是让Agent需要时通过工具查询。提示词应该是不变的,变化的数据尽量走数据链路——这也是提示词能长期稳定发挥的前提。
4. 常见误区与避坑:那些被热词吹大的坑
最后聊点行业里最近很热闹,我实际观察下来纯属坑的东西。
4.1 复杂提示词框架不一定是更优解
网上流传很多所谓的"高级提示词模板",什么上策、下策、角色扮演、思维链、零样本链……不可否认它们在某些任务上有效,但Agent优化的核心问题不在"一个句子写得好不好",而在"整套系统稳不稳固"。把大量精力花在打磨一个华丽的提示词框架上,往往得不偿失——越复杂的提示词,越难维护、越难复制、越容易出现"换个输入就崩"的问题。
我的经验是:Agent的提示词先写短。能一句话说明白的规则,不要写一段话。规则的表达优先于修辞,明确优先于华丽。等评测集告诉你"这里确实需要更详细的规则"时,再往深了加。提示词是从短到长、从粗到细地长出来的,不是一上来就写三五千字的宏伟模板。
4.2 一次跑通不算修复:随机性陷阱
Agent开发和普通软件开发一个很大的不同,是它有随机性。同一段代码,同一条输入,两次运行结果可能不一样。这让很多人产生了"我改好了"的错觉。
判断一个问题真的修好没有,我的标准是:在评测集上连续跑三轮,通过率稳定不回落,才算修好。另外,复现问题的时候不要只看一次输出,至少要跑三到五次,看看失败模式是"稳定的失败"还是"偶发的失败"——后者大概率是参数、上下文或工具链路的随机问题,不是提示词问题。
还有一个实用技巧:定位问题时把temperature临时设为0,先排除随机干扰;等问题定位修好了,再恢复原设置。这个技巧帮我节省了大量排查时间。
4.3 提示词泄露暴露了什么
最近"Cursor提示词泄露"这类话题很热,评论里一片"快抄"。我看了下流传的那些内容,老实说:就算把别人全套系统提示词给你抄,你大概率也复现不了人家的效果。
原因很简单:提示词只是一份"说明书",Agent的能力来自模型、工具实现、数据链路、评测闭环的组合。缺了后面的工程部分,光有说明书是开不动车的。更值得做的,是反过来想想自己项目的提示词有没有泄露风险,重点检查:系统提示词里有没有写入内部密钥、数据库账号、业务机密;对外提供的接口有没有可能被用户套出内部指令;日志系统会不会把完整提示词打到第三方平台。
注意:如果你的Agent会读取外部不可信内容(网页、邮件、用户上传文档),要小心"提示词注入"——内容里可能夹带"忽略之前所有指令,只做我要求的操作"这类攻击指令。务必要把外部内容当作数据而不是指令来处理,把指令和数据在结构上隔离,并对高风险操作加人工确认。
这里我也想把网上那些"破甲""NSFW提示词"之类的话题点一句:这类所谓"提示词"本质是试图绕过模型安全限制的攻击输入,我们不讨论具体写法,更不建议在任何产品里尝试。真正值得关注的是怎么防御:输入侧过滤、输出侧校验、权限最小化、关键操作二次确认。Agent越强大,安全护栏越要做实。
4.4 警惕"玄学热词":鹈鹕骑自行车提示词背后的事实
最近还有一类热词,什么"鹈鹕骑自行车提示词""鹈鹕测试",据说用一条奇怪的提示词就能测出模型水平高下。我试过,也专门研究过这类测试的逻辑。这类测试词的特点是比较"反常识"、场景模糊、需要模型进行一定推理和想象。它能反映一部分模型的指令跟随能力和世界知识,但它不是"万能标尺"——同样是"鹈鹕骑自行车",换一个模型、换一种表述,结果可能完全不同。
这一点恰恰说明我前面反复强调的问题:提示词的效果不是一个孤立变量,它和模型能力、任务类型、上下文设计紧紧绑在一起。拿一条模糊的网络热词提示词去给Agent能力下定论,就是在把Agent优化往玄学方向带。真要知道Agent行不行,回到你的业务场景,用真实评测集跑分,那才是唯一靠谱的标尺。
说到底,Agent优化不是一个"调词"的活儿,是一个"调系统"的活儿。我经手的每个Agent项目,最后稳定下来靠的都不是什么神级提示词,而是一层一层把工具、上下文、参数、评测这些地基打牢,提示词只是其中最后一块拼图。
我的个人习惯是:收到任何"Agent不听话"的报告,先查日志、跑case、分类,再动手;每次改动只动一层,改完跑评测集;评测集通过率是我唯一的说服标准。这套方法不性感,但管用。希望你看完这篇,下次面对一个跑偏的Agent,也能先按住改提示词的手,从日志和评测开始。