本文是「Agent 开发实践与思考」系列第 17 篇。系列目录:
- 2024
- 2025
- 01-28 长任务不失忆:上下文压缩、交接文档与子任务隔离
- 02-25 MCP 用了三个月:工具标准化之后 Agent 设计变了什么
- 03-25 拆解 Coding Agent:为什么”写代码 + 文件系统”是通用 Agent 的内核
- 05-13 Agent 如何用代码完成推理、校验、适配与展示
- 06-03 能看会说的 Agent:语音交互与 Computer Use 这半年
- 06-24 从同步问答到事件驱动:异步 Agent 的架构改造笔记
- 07-08 没有评估就没有迭代:我的 Agent 评估落地记
- 09-09 后训练扫盲:SFT 记知识、RL 学长处,和 Agent 有什么关系
- 10-01 AI Coding 的上下文摘要:几家产品到底在压缩什么
- 10-14 让 Agent 从经验里长本事:失败复盘、经验库与提示词自动优化(本篇)
三种学习发生的位置
先把”学习”这个词拆开。一个 Agent 系统里有三个位置可以发生变化。
第一个位置是模型权重,也就是后训练。SFT 和 RL 怎么做事,我在后训练扫盲里写过。这条路对应用层基本关闭:训练成本高,需要成规模的数据,而且我们的失败 case 是按周产生的,等不起按季度的训练周期。更实际的问题是,业务规则下个月可能就变,写进权重的东西改不动。
第二个位置是上下文。每次任务开始时,把相关经验塞进提示词,模型当场就能用上。这是大家默认在做的方式。它的缺陷是不积累:上下文是会话级的,会话结束就清空,下一次任务从零开始。模型在同一个坑里摔一百次,只要没人把坑写进上下文,第一百零一次照样摔。
第三个位置是外部资产:经验库、记忆条目、流程文档、提示词本身。这些东西存在模型之外,持久、可版本管理、可审查、可以按需注入上下文。应用层能做的”学习”,发生在这里。机制上它不神秘:把经验从日志里提炼出来,存成结构化资产,在合适的时机放回上下文。真正的工程问题是怎么提炼、存成什么形状、什么时候取。
下面按我们落地的顺序说。
失败复盘:教训要带场景标签
失败复盘的做法参考 Reflexion(2023):任务失败后,让模型生成一段反思文本,放入后续重试的上下文。Reflexion 的原始机制主要服务于单个任务的多次尝试,反思文本不会自动改变模型权重。我们在此基础上把反思内容扩展为跨任务的持久存储。
具体流程:评估判负或者用户差评的 case,会触发一个复盘调用。输入是任务描述、执行轨迹、失败判据,输出是一条固定格式的教训,三个字段:适用场景、触发条件、建议动作。比如:
{
"scenario": "billing.refund",
"trigger": "用户要求退还已使用部分的费用",
"action": "先查订阅周期和使用量,按剩余天数折算,不要直接全额退款"
}这里有两个工程点,都是用教训换来的。
第一,教训必须绑定场景标签,注入时按标签检索,而不是全文注入。早期版本我们把所有教训一股脑塞进系统提示词,结果一条”调用退款接口前必须二次确认金额”的教训在纯查询任务里生效,模型开始拒绝执行正常的查询,非要用户再确认一次。教训注入错场景,从资产变成负债。现在我们按任务类型加上向量相似度双重过滤,只取最相关的三五条。数量上限也是算过账的:注入的教训占的是任务的上下文预算,十条教训就是上千 token;而且条目一多,教训之间会互相打架,模型面对两条部分冲突的指令时行为变得不可预测。宁可少而准。
第二,教训要定期清理。业务规则会变,三个月前”赠送额度上限是 500”的教训,在额度政策改成 1000 之后就是错误知识,而模型无法分辨一条教训是否仍然有效,只会照做。所以过时教训比没有教训更糟。我们给每条教训记录来源 case 和写入时间,每两周用最新的评估集回归一次,被新数据证伪的、长期没被命中的,都淘汰掉。教训库里的条目都有保鲜期。
经验库:把验证过的路径存成流程
失败复盘存的是”别做什么”,成功的做法同样值得存。这一路的思路参照 Voyager(2023):它在 Minecraft 里把学会的技能封装成代码存进技能库,后续任务检索复用,技能库越滚越大,全程不改模型权重。
我们的对应物不是代码库,是流程文档。一个任务类型在评估集上稳定通过之后,把它的执行路径提炼成结构化文档:步骤、分支条件、每步的验收点。比如退订类任务,验证过的标准路径是:先查订阅状态,判断是否在合约期内,在合约期内先算违约金并告知,确认后执行退订,最后检查关联服务是否需要一并处理。这份文档由成功轨迹自动提炼初稿,人工修改确认后入库,遇到同类任务注入上下文。载体就是 Markdown 文件,存在 Git 仓库里,改动走正常的 review 流程。这样做的好处是经验资产和代码使用同一套基础设施:版本历史、diff、回滚、评审记录,不用另造一套管理系统。Voyager 的重点是把可执行技能封装成代码并在后续任务中检索调用,不是把自然语言流程文档直接当成技能库。
流程文档和提示词里的规则是两样东西。规则是约束,告诉模型不许做什么;流程文档是程序性知识,告诉模型先做什么后做什么、每个岔口怎么判断。规则写在系统提示词里常驻,流程文档按需取用。这和记忆篇里的结论一致:写入比读取难,存错的代价大于存漏,所以入库要过人审,验证要先于沉淀,这个顺序不能反。
经验库运转起来之后有个附带收益:它成了新人了解业务的材料。机器能读的流程文档,人也能读,而且因为是从事故和成功案例里长出来的,比入职培训的 PPT 更接近真实业务。
记忆的离线整理
记忆那篇讲了记忆的写入、检索和遗忘,当时留了一个问题没解决:记忆条目会腐化。用户偏好会变,同一个事实可能被记成两条,模型推断出来的条目带着不准的置信度。运行半年之后,记忆库里这种”半死”的条目越积越多,检索质量被拖垮。
解法是起一个离线任务定期整理,做的事有三件:合并语义重复的条目,把过期或被新事实覆盖的条目标记失效,把频繁被命中且验证有效的条目提升优先级。整理过程本身也是 LLM 做的,但所有改动落库留痕,可以逐条审计,发现整理错了能回滚。
有人说这像大脑在睡眠时整理记忆。这个比喻我只在”离线、批量、不占用在线任务的上下文和延迟预算”这一层意思上承认它成立,机制上完全两回事。工程上的要点反而朴素:在线写入保持简单快速,复杂的清洗合并挪到离线做,因为离线任务错了能重跑,在线写入错了直接污染下一次检索。
提示词自动优化:前提是先有评估集
前面三样都在积累内容,还有一个手工环节没动:提示词本身。手写提示词的调参方式是手工作坊式的,改一句话,凭感觉测几个 case,觉得变好了就上线。我在评估那篇里写过这种方式被打脸的经历。
DSPy(2023 年起)代表另一类做法:把提示词里的指令和 few-shot 例子作为可优化的参数,把评估集上的指标作为目标,用优化器搜索更好的组合。TextGrad 则把 LLM 生成的自然语言反馈当作类似梯度的信号,沿着计算图回传到提示词或其他文本参数,再据此改写。两者都依赖一个信得过的目标函数。
我小规模试了一次。在 200 条 case 的评估集上,让优化器自动改写工单 Agent 的指令并重选 few-shot 示例,跑了十几轮。结果指令的评估分数比我手调的版本高了几个点,更重要的是省掉了我反复改提示词的时间。但有两个限制要说清楚。一是过拟合:优化器会找到针对这批 case 讨巧的写法,所以我留了一部分 case 不参与优化、只做最终验证,holdout 上不涨就当作没发生。二是搜索成本:十几轮优化跑掉的 token 费用不低,只有评估集可以自动判分、不用人盯的时候,这笔账才划算。
所以结论绕回原地:提示词自动优化的前提是评估集。没有评估集,自动优化就是自动瞎蒙,而且蒙得比人快。
自动产物进生产前过人
到这里,教训、流程文档、记忆整理、提示词改写,四个环节都能自动跑了。必须说清楚边界:所有自动产出的东西,进生产前过一道人审。这里讨论的是应用层资产的更新,不是从头训练或完整后训练模型。应用层可以更新提示词、外部记忆和流程文档,但不会因此改变模型权重。
原因在评估篇和后训练篇里都出现过:你给的反馈信号就是 Agent 的优化目标,目标歪了,它会一本正经地优化错误的东西。实际遇到过一次:评估判据里有一条”回答覆盖所有要点”,优化器学到的对策是把回答写长、把可能相关的信息全堆上去,评估分确实涨了,用户体验明显变差。判据的漏洞会被自动优化以十倍速放大,这是它和手调的本质区别。
人审的成本比想象中低。这些产物全是文本,以 diff 形式提交 review,审一条教训或一段提示词改写比审代码快得多。提示词的自动改写另外走灰度:先小流量跑,评估集回归通过再全量。自动化的作用是把人从重复劳动里撤出来,不是把判断权交出去。
飞轮
把整篇收拢一下。让 Agent 从经验里学习,落地的不是一个功能,而是一个循环:评估(没有评估就没有迭代)指出哪里失败,复盘把失败变成教训、把成功变成流程,沉淀物进入经验库和提示词改变 Agent 的行为,再评估验证这个改变是不是正向的。飞轮转一圈,资产厚一层。
我的判断是,模型权重大家用的是同一批,应用层之间的差异会越来越体现为经验资产滚动的速度。同一个坑,你的系统摔一次就记住了,对手的系统每周摔一次,半年后的差距不是模型能弥补的。
最后照例泼一点冷水:这个飞轮有两个地基,评估集和全链路 trace。没有它们,复盘没有输入,沉淀没有验证,优化没有目标。如果这两样还没搭,先回去补评估的课,那篇比这篇优先。

