
大部分 Agent 项目跑不过一周。不是模型不够聪明也不是工具链不好用而是 Agent 没有经验。它记不住上个任务踩过哪些坑复用不了已经验证过的路径同一个错可以一而再再而三地犯。这个问题的背后正是标题里的四个核心关键词——Agent 记忆、上下文、Skills、Harness。做 Agent 这么久我越来越觉得这才是决定一个 Agent 从能跑 Demo到能在生产环境活下来的分水岭。这篇文章是 Agent 系列总结的第三篇前面聊过 Agent 的基础范式和工具调用这次聚焦一个更值钱的问题经验是如何被保存、调用和更新的。我会把论文里那些比较抽象的设计思路和工业界真正跑过的做法放在一起讲尽量给你一套能照着搭建的参考。适合正在做 Agent 落地、被长任务必翻车多轮必失忆困扰的开发者也适合想搞懂纸上架构到底怎么落地的研究者。1. Agent为什么需要记忆从聊天记录到决策资产的认知升级1.1 上下文窗口只是一条流水线记忆才是有状态的工作台很多团队的第一版 Agent 非常简单粗暴把所有历史消息一股脑塞进 prompt然后祈祷上下文窗口够大。短期看起来没问题任务一长问题全暴露了——最早的信息被挤出窗口、关键决策依据被新消息稀释、用户三天前在某个角落提过的偏好再也想不起来。这里有个非常容易混淆的点聊天记录的堆积和记忆完全是两回事。聊天记录是对会话的录像记忆是能被检索、被更新、被遗忘的决策资产。录像只能回放资产可以复用。论文领域有个特别形象的类比把 LLM 当前的消息列表当成虚拟内存把记忆当成磁盘上的文件系统。虚拟内存一断电就没了文件系统可以跨会话持久化而且有目录结构、有缓存淘汰、有索引加速。Agent 如果只有虚拟内存那每次重启都是失忆有了文件系统它才有积累的可能。我做客服类 Agent 项目的时候第一版就是纯聊天记录流式塞入。任务短效果还不错一旦出现多轮转人工、再转回机器人的流程状态就乱了。后来我才意识到真正缺的不是更大的窗口而是一个记忆层。这个层不是用来存更多消息的而是用来回答几个核心问题当前这个任务做到哪一步了以前有没有做过类似的事上次的结果能不能直接复用。1.2 记忆在 Agent 决策闭环里的真实位置把 Agent 的一个完整动作周期拆开看应该是这样感知环境信息从记忆中读取当前状态与相关经验规划本次动作调用工具或技能执行收到观察结果最后更新记忆。大量 Demo 只做了中间的感知—规划—行动最后两步根本没做。这意味着 Agent 每次重新开始都是同一个失忆的实习生。它会一遍遍用同样的错误方案去处理类似工单也会在同一个用户偏好上反复犯错因为它根本不知道用户已经说过一遍了。工业直觉在这里非常重要给 Agent 加上记忆读写之后单个任务的耗时一定会变长因为每次动作前后都有额外的读写开销。但只要记忆层设计得当任务成功率和决策质量的提升会远远覆盖掉这部分损耗。说白了以前 5 轮搞砸一次的任务加记忆后 3 轮就完成了多出来的读写开销根本不值一提。2. 记忆的分层与存储选型工作记忆、情景记忆、语义记忆、程序记忆2.1 一张表分清四种记忆类型认知科学里对记忆有一个比较成熟的分法现在被学术界借过来描述 Agent 的记忆体系。我建议做系统设计的人先把这张表刻在脑子里记忆类型对应人类心智存储形态典型检索方式例子工作记忆手头正在处理的事token 窗口 / 临时缓存顺序阅读当前订单状态、正在填的表单情景记忆具体经历的事件向量库 元数据相似度检索昨天处理过的一笔退款工单语义记忆抽象出来的知识知识库 / 关系表结构化查询用户偏好、公司退款规则程序记忆学会的动作代码 / Skill 定义按触发条件精确匹配退款超时自动催办这个技能这四类记忆不是互相替代的关系而是互补的关系。工作记忆管当下情景记忆管历史上发生过什么语义记忆管总结出来的规律程序记忆管已经掌握的动作。2.2 论文怎么切工业界怎么落地很多研究把上下文之外的记忆按功能分层情景记忆存具体事件语义记忆存事实和偏好程序记忆存技能。有个关于长期记忆的工作专门提过让 Agent 长期工作的关键是分层记忆 显式索引不要在单一向量库里堆所有记忆而是让不同层级的记忆走不同的读写路径。工业界落地上我见过比较稳的组合是向量库 关系数据库 KV 缓存三层结构向量库存情景记忆负责模糊召回解决好像见过类似的事的问题关系数据库存语义记忆负责精确查询解决用户到底偏好什么渠道这类确定性需求KV 缓存存短期工作状态解决高频读写但不值得进长期存储的内容。我在一个多租户项目里踩过一个印象很深的坑只有向量库没有归属字段的过滤导致用户 A 的偏好被检索器捞出来喂给了用户 B。后来我给每条记忆强制加了一套元数据——所属会话、所属用户、创建时间、来源任务——召回的时候先按归属做硬过滤再按向量相似度排序问题立刻消失。这就是论文和工业界的典型差别。论文里把归属过滤一句话带过但真做产品的时候这往往是隐私和数据隔离的核心护栏。3. 上下文工程窗口有限经验无限3.1 记忆索引比塞入记忆内容更优先很多人拿到记忆系统之后第一反应是把相关记忆全部塞进上下文。这其实是个误区。上下文窗口再大也是有限的而召回出来的记忆内容多了之后模型真正依赖的核心信息反而会被淹没。更好的做法是在上下文里放记忆索引让模型知道自己有记忆能力、能按什么条件找到某类记忆而不是把记忆内容一次性全部展开。这个思路很像一本书的目录——你不需要把整本书都背下来你只需要知道哪一章讲什么需要的时候翻过去就行。具体到提示词设计上我在系统指令里会给 Agent 一段类似这样的逻辑约束请先确认当前任务是否与历史记忆相关如果相关请求检索某类记忆检索结果会以特定格式返回检索结果只在你的工作记忆中存在不应该当作外部事实无条件采信。这个索引 按需检索的模式比一次性大而全地塞入更省 token也更稳。检索到的记忆内容只放进当前动作周期动作结束就丢弃下一次需要再次检索。这样上下文里的工作记忆永远只保留当下最需要的量窗口就变得非常耐用。3.2 压缩不是事后的补救而是预算管理的一部分上下文压缩最忌讳的一点就是等窗口满了再压缩。到那个节点Agent 可能已经边写边丢弃早期的关键信息了压缩只是在给残局善后很多信息已经损失。我建议把 token 当作一项固定预算而不是无限资源提前划分好每个区块的上限系统指令固定不该被任何历史内容挤占实时状态当前任务的必要字段越小越好召回记忆按需检索用完即弃工具定义和 Skills 描述只放当前任务可能用得上的不要把所有工具都挂着会话历史做摘要和丢弃策略保留最近若干轮原文。在压缩策略上我见过最实用的组合是原文保留 分层摘要两层短期内保留最近几轮完整对话保证模型能看到最新的语气和措辞更早的历史则被压缩成结构化摘要只保留决策关键值和结果。对现金金额、日期、合同状态这类信息摘要会丢细节所以必须同时落到语义记忆里做结构化字段而不是只依赖摘要文本。3.3 缓存让记忆系统变快但也容易让遗忘失效为了减少检索开销不少工程团队会给记忆召回加缓存。这个方向没错但是有个容易忽略的问题缓存会让旧记忆一直处于热状态导致遗忘机制失效。我在某个系统里就吃过这个亏。记忆更新逻辑明明写了过期删除但因为缓存把旧版本一直保留着Agent 每次检索都命中旧记忆甚至引用已经被推翻的结论。后来给缓存项加了失效时间和强制穿透策略这个问题才被堵住。4. Skills的本质把经验固化成 Agent 可复用的程序性记忆4.1 Skill 定义与注册的一个最小可用方案Skills 在标题里和记忆并列很多人容易把它们当成两套独立的东西。但实际上技能就是程序性记忆的工业级载体。一次工具调用只是会用工具只有把稳定有效的调用路径固化下来才是 Agent 学会了某个技能。我在项目里用的 Skill 定义是这个思路一份自然语言描述给 LLM 看一份 JSON Schema 给系统校验用。自然语言描述负责让模型的推理链路理解什么时候用、怎么用、注意什么Schema 负责让 Harness 能程序化地检查参数合法性、版本号、依赖关系。{ skill_id: refund_escalation_v3, name: 退款超时自动催办, version: 3, description: 当退款工单超过24小时未处理时自动生成催办任务并通知相关审核角色, trigger_conditions: [ 工单状态退款中, 已等待时长24h ], input_schema: { ticket_id: string, wait_hours: number }, output_actions: [ create_todo, send_notification ], success_rate: 0.92, side_effects: [notify_human_reviewer], last_validated_at: 2025-01-10 }4.2 入库门槛一次成功不算技能稳定成功才算我在带项目的时候定过一条比较严格的规矩任何调用路径要沉淀成 Skill必须先满足三个条件——成功率连续若干次达到阈值、在不同场景下有泛化能力、副作用可控。一条链路只在某一个固定的测试用例里跑通不能算技能只能算是偶然的成功。这个门槛看起来很保守但能省掉大量维护成本。因为 Skill 一旦入库就会被 Harness 在其他会话里自动调取如果它本身不够稳就会把错误传播给一批新任务。4.3 已有技能与新工具冲突时怎么排优先级实操中一定会遇到一个问题已经沉淀的技能和刚接入的新工具都能完成同一个任务。我的策略是——默认优先选已沉淀技能因为它的成功率是被验证过的新工具要超越旧技能必须满足在当前任务场景下可测量地更好而且需要经过一段灰度期积累足够样本确认没有再切回去。不要因为新工具看起来更酷就贸然替换成熟技能这是从工程角度最容易踩的坑。5. Harness串起记忆、上下文与技能的 Agent 执行骨架5.1 Harness 不是什么神秘框架而是 Agent 的运行时骨架Harness 这个词翻译过来最接近执行容器或跑车底盘但它不是一个具体的框架名而是一类组件的统称。它干的事情是在 Agent 循环的每一层提供控制、调度、资源约束和可观测性。如果说 LLM 是 Agent 的大脑、记忆是文件系统、Skills 是肌肉记忆那 Harness 就是骨骼和神经系统——把所有组件连接起来让它们按正确的顺序被调用并且在场外人开发者和调试工具能看到内部发生了什么。很多团队区分不清楚 Harness 和 Orchestrator。我的理解是Orchestrator 协调的是多个 Agent 或任务之间的协作关系Harness 则更内层它决定了单个 Agent 一次动作周期怎么走完。作为 Agent 自身的运行骨架Harness 需要考虑循环控制、资源约束、错误恢复、可观测性这四件事。5.2 工业级 Harness 里四个值得认真处理的 Hook我在设计 Harness 的时候发现四个生命周期钩子直接决定了记忆系统能不能好用。第一个是循环开始前的 Hook每次 LLM 推理之前把可能进入上下文的记忆做一轮过滤。这个环节是数据隔离的最后一道防线。前面说的归属过滤我最后就是放在这个 Hook 里统一执行的。第二个是动作完成后的 Hook判断本次动作是否产生了值得写回的经验。这个 Hook 执行写入评估把临时状态、候选经验和正式记忆区分开避免什么东西都写库。第三个是异常时的 Hook任务报错或循环超时的时候Harness 要执行失败归因并把可能受污染的工作记忆回滚防止错误状态被当作成功经验写入记忆。这一步很多人不重视导致记忆库里存了一堆带病经验。第四个是会话结束时的 Hook把本次会话产生的工作记忆做一次归档高价值的部分转入情景记忆抽象的结论转入语义记忆稳定的路径尝试沉淀为 Skill。这个 Hook 是整个经验闭环的最后一道闸门。5.3 可观测性记忆污染是最大的隐形风险Harness 里最容易被人忽略的是可观测性。Agent 的记忆系统一旦开始工作调试难度就上来了一个行为异常可能是当下指令不对也可能是被一条错误的记忆引导了。我在 Harness 里强制保留了记忆操作日志每次写入、召回、更新、删除都记录触发者和内容摘要。出问题的时候第一件事就是翻记忆日志看 Agent 到底被哪条历史经验影响了。这个习惯救过我很多次——有一次 Agent 反复拒绝执行某个任务查下来就是一条嘲讽性历史记忆污染了它的判断。删掉之后行为立刻恢复正常。6. 经验闭环保存、调用、更新的完整链路设计6.1 保存什么值得写什么时候写写到哪里经验保存最怕两件事写太脏存了一堆没用的信息写太少真正有价值的经验丢了。我采用的方式是分级写入临时缓存每个任务跑完先把关键事件放到临时区候选池只有经过质量评估的临时信息才能进入候选池评估维度包括任务的异常程度、结果的确认程度、与现有记忆的差异度正式记忆候选池里被多次引用或确认为高价值的信息升级为正式记忆程序沉淀如果同一类型的正向处理路径连续多次成功就尝试生成或更新一个 Skill。这个链路最核心的思想就是写入不是一次到位的而是一条有多道闸门的流水线。每一道闸门都对信息做一次提纯。6.2 调用让经验在对的时间、对的任务里出现记忆调用不能只靠每次暴力检索一遍。我见过很多系统把所有记忆一次性捞出来塞进上下文效果很不稳定。经验被调用是需要条件的相关性、置信度、时效性三者缺一不可。相关性这个经验与当前任务在语义上有多接近置信度这条记忆被验证过多少次来源是成功经验还是失败教训时效性规则和偏好会变三年前的用户偏好不一定适用于今天。调用链路上我建议做触发式召回也就是根据当前任务状态主动决定是否需要记忆介入。比如任务早期只检索工作记忆和语义记忆只有在任务连续失败、或者需要判断以前有没有做过类似的事的时候才触发情景记忆的深度召回。这种按需召回的方式既省 token又能降低噪声。6.3 更新遗忘机制和冲突消解记忆不能只增不减否则系统最终会被大量过期内容淹没。我意识到遗忘不是缺陷而是一种反哺决策质量的机制。遗忘机制有两种有效形态一种是过期淘汰按时间戳和最近引用频率给记忆降权长期不被引用的记忆自然沉底一种是冲突淘汰新经验与旧记忆结论冲突时进入待复核状态由更高置信度的来源决定最终版本。冲突消解是最容易被搞砸的一环。我的做法是不要把旧记忆直接删除而是把它降级为历史候选同时保留新记忆为当前推荐。这样即便新的经验本身有问题Agent 还有机会通过置信度对比回到旧记忆的版本不至于一下把成熟经验推翻。6.4 一个最小闭环实例退款超时工单用一个我在客服场景中的真实案例来串一遍闭环。第一天Agent 收到一张退款超时工单按通用流程处理先查状态发现等待超过 24 小时于是走催办流程。这里花了两轮循环用户等得不太满意。任务结束Harness 的会话结束 Hook把这次处理过程写入候选池标记为超时工单类任务通用流程不够高效。接下来三天同样类型工单又出现了几次Agent 每次都尝试不同的催办路径其中一种路径连续三次在单轮循环内解决了问题。于是候选池里的经验升级为正式情景记忆同时触发 Skill退款超时自动催办的生成流程。这个 Skill 经过成功率验证后入库。第四天新的超时工单出现了。Harness 在循环开始时检索到相关 SkillAgent 直接自动创建催办任务并通知审核角色整个动作在一步内完成。后面某一天Agent 通过催办发现某个支付渠道的响应时间总体变慢了这个观察结果反馈到了语义记忆同时把 Skill 里24 小时阈值这个预期参数更新为32 小时。整个经验闭环——保存、调用、更新——到这里就形成了完整的一圈。结尾的一点经验如果让我给正在做 Agent 的朋友一个实用建议我会说先搭好 Harness 骨架再跑通记忆闭环最后沉淀 Skills。顺序一旦搞反你会陷入技能写错但找不到是哪个环节引入的这种深坑。另外记忆污染这件事远比你想的更容易发生一定要在 Harness 里保留记忆操作日志出事的时候日志会告诉你 Agent 到底是被哪条历史经验带偏的。