自进化 (Self-evolution) 是 Agent Harness 的核心模块,拥有自进化能力后 Agent 才能在长期的任务交互中不断成长,总结和改进自己的技能、记录用户的反馈和偏好,从被动应答升级为能够主动复盘和自我成长的 Agent。本文以 CowAgent 开源项目为例,介绍 Agent 框架中五层自进化机制的架构设计和工程实现。

整体设计

要实现 Agent 的自我进化,不只是让它记住信息,更要能通过持续的反馈改进和修复自己。自进化机制根据深度不同可以划分为:记录信息、保留信息、主动行动、整理沉淀、自我重构,不同深度需要改进的对象、触发的时机和影响范围都不同。

在具体实现上,有两个关键点要考虑: "什么时候触发进化""要改进的是什么"。在 CowAgent 中,完整的自进化机制由五个层级共同构成,分别对应不同的进化深度,包括:基础的记忆和知识维护、上下文智能总结、会话后主动复盘、梦境记忆整理、源码自更新。整体架构如下:

五层自进化机制总览

层级改进内容触发时机进化深度
基础记忆和知识维护记忆 / 知识 / 提示词每次对话中记录
上下文智能总结记忆上下文超限时保留
会话后主动复盘技能 / 记忆 / 提示词 / 任务会话空闲后行动
梦境记忆整理长期记忆每天定时沉淀
源代码自更新代码被动/主动触发自我重构

一、基础记忆和知识维护

最基础的一层自进化其实发生在每一次的对话过程中,Agent 通过大模型的工具决策能力以及系统提示词的引导,判断对话中是否包含有价值的信息,并通过内置工具把偏好、决策、事实、经验教训等写进长期记忆,把可复用的知识写进知识库,把涉及到 Agent 设定及运行规则等内容写入提示词文件。

这三类信息维护的对象和时机各不相同:

  • 记忆:持久化在工作空间的文件中,又分核心记忆和天级记忆。核心记忆(MEMORY.md)存放用户偏好、关键决策这类长期有效的事实,会被注入到每次对话的系统提示词里,所以必须保持精炼;天级记忆(memory/YYYY-MM-DD.md)按天记录关键事件和对话摘要,只在 Agent 用记忆检索工具时才加载。
  • 知识库:以 Markdown 源文件存于工作空间、向量化数据存于数据库,按主题组织、页面间交叉引用成知识图谱。当对话中发生搜索学习、深度研究等任务时,Agent 会主动把整理后的知识沉淀进来。
  • 提示词:人格设定(AGENT.md)、规则(RULE.md)、用户信息(USER.md)等也支持在对话中被实时修改,它们都会加载进系统提示词,让 Agent 根据反馈持续调整自身设定,贴合用户习惯。

对话中自动写入记忆与知识库的示例

上图示例:用户在一次提问中表达了偏好并让 Agent 研究一个新概念,Agent 在回答的同时主动把偏好写进记忆、把整理后的资料沉淀进知识库

二、上下文智能总结

上一节关于长期记忆的维护解决的是如何记住关键信息,而这一节主要解决的是 Agent 在进化中如何不丢失信息。上下文是短期记忆,项目中提供了可配置的轮次和 Token 长度限制,当超限时不能简单裁剪掉旧消息,而是要把其中的重要信息提炼总结后写入天级记忆中。整个智能压缩分四步处理:

  1. 截断超长工具结果:第一道也是最廉价的一道。历史轮次里单个工具结果(如一次返回上万行的检索)超过阈值时,只保留首尾两段加一句省略说明,正在进行的当前轮次不动。这一步纯字符串处理、不调模型,往往就能挡住大部分增长。
  2. 按完整轮次裁剪:轮次超限时,以"一轮完整对话"为最小单位裁掉最早的一半,而不是逐条删消息——这样能保证一次工具调用的入参和执行结果始终成对保留,不会给模型留下"调用了工具却没有结果"的残缺上下文。被裁的内容并不是丢弃,而是由 LLM 进行整理、提炼、总结,一方面写入当天的天级记忆持久化,另一方面注入回保留消息的开头,让模型在丢掉原始细节后仍能接住前文的来龙去脉。
  3. 按 Token 压缩:当裁完轮次仍超出 Token 限制时,再做进一步更精细化的裁剪,当轮次本就不多时会对每一轮做文本压缩(只留用户的首条提问和 Agent 的末条回复,剥掉中间的工具调用链);当轮次较多时则继续裁剪并总结更早的前一半对话。
  4. 溢出兜底:当模型 API 直接抛出上下文溢出,同样会先把当前对话总结进记忆,再做一次更激进的截断,这是最后一道保险。

上下文智能压缩的四步流程

三、会话后主动复盘

会话后复盘 是自进化中主动性最强、也是最核心的部分,当一段对话告一段落、进入空闲时,Agent 会主动回顾整个会话内容,把对话中暴露的问题修复、将可复用流程固化为技能、把没做完的任务接着完成等。

3.1 进化内容

首先来看在复盘中主要做哪些改进:

  • 优化和创建技能:当某个 Skill 在用的时候暴露了问题(例如配置错误、缺少步骤、内容过时等),会直接修改技能文件让问题不再复发;如果在对话中跑出了一套可复用的流程,则会主动固化成一个新技能,在下次类似任务时可以更稳定地执行。这一步让 Agent 从「技能的使用者」变成「技能的维护者」。
  • 收尾未完成任务:把承诺了用户但没做完、或因临时性故障 (例如网络波动、环境问题等) 中断的任务,进行 review 并再次尝试完成。
  • 补齐记忆 / 知识 / 提示词:作为查缺补漏,主对话本身就会主动写入记忆和知识库,所以这里只作为兜底。

会话后主动复盘的对话效果示例

上图示例:Agent 在会话后复盘中发现可复用的工作流程,创建为一个新技能,并主动通知用户

在改进中有两个关键的设计取舍:

  1. 技能和未完成任务是主要价值,记忆、知识、提示词只作为查缺补漏,因为这部分已有其他多层机制覆盖,无需太多重复关注。
  2. 修复源头而不是只记录问题:如果问题根因在技能本身,正确的动作是改技能,而不只是在记忆里记一句「技能 X 有个错」,这是目前很多 Agent 项目都存在的问题。记录症状不能阻止复发,只有优化源头才能根除问题。

3.2 触发时机

主动复盘会在会话结束、空闲一段时间后触发,且需要积累一定对话轮次才值得复盘,简单说就是「用户不再继续聊了,且这段对话有足够的信息量」,两个条件都满足才触发一次。

在项目中,可以通过 Web 控制台的开关一键开启和关闭自进化开关,另外触发空闲时间 (默认10分钟) 和 会话轮次阈值 (默认6轮会话) 也可以通过配置文件进行进一步调整。

Web 控制台中的自进化开关与配置

3.3 安全可控

让 Agent 动手改自己,一个最重要的问题就是 "会不会改坏、会不会打扰用户"。一个支持自主修改的系统,最容易出现的几个问题包括:1. 把错误的信息写进记忆或技能等;2. 执行命令时越权改到系统内置的模块;3. 修改完无法追溯和回退。

所以这一层的设计就是围绕 可追溯、可回滚、隔离执行 的安全可控目标来实现:

  • 隔离执行:每次的复盘是一个独立的异步临时任务,使用同一个主模型,但可用工具集大幅收紧(只能读上下文、改记忆与技能),不污染、也不会拖慢主对话,同时项目自带的内置技能会在代码层面进行保护。
  • 变更可回滚:在 Agent 改动前会自动备份相关文件,用户如果不认同某次改动,直接在对话发送消息 (例如 "把刚才的改动撤销") 即可还原工作空间。
  • 变更可追溯:Agent 会将每一次变更记录持久化存储于空间中,在「Web 控制台-记忆-自主进化」页面中可以追踪具体信息。
  • 未变更则不打扰:复盘后会核对是否有实际的改动,如果有变更则会主动将内容推送给用户,否则全程静默、用户无感知。

记忆管理中的自主进化记录列表

四、梦境记忆整理

梦境记忆整理 (Deep Dream) 由每天夜间的定时任务 (默认 23:55) 主动完成。首先会将当天各会话的上下文 (短期记忆) 整理写进天级记忆,随后执行一次记忆蒸馏,读取当前的核心记忆和当天的天级记忆,交由模型进行去重、合并相近条目、修剪、提炼新信息并替换旧信息,输出一份精炼后的核心记忆,同时会生成一篇叙事风格的梦境日记,记录这次整理发现了什么、合并和清理了什么。

梦境整理是每天运行的全局视角的自进化,对当天所有会话的一次通盘梳理,解决的正是随着时间推移,长期记忆最容易出的两个问题:不断膨胀自相矛盾。整个过程遵循几条核心规则:

  • 含义相近的多条合并成一条更高密度表述;
  • 从天级日记里萃取值得永久记住的新信息(偏好、决策、规则、经验、教训);新旧记忆冲突以新条目替换旧条目;
  • 临时记录、空条目、已被覆盖的冗余则直接清理,最终将核心记忆 (MEMORY.md) 控制在一定数量内 (约 50 条以内)。

梦境记忆整理生成的梦境日记示例

为了让记忆整理更安全可控,在实现上做了几层保护:

  • 当天没有新日记时直接跳过,绝不空覆写已有的核心记忆
  • 对日记内容和每条消息分别做哈希去重,同样的内容不会被重复写入天级记忆(即使对话跨天)
  • 在提示词层面强约束整理的真实性,避免凭空生成不存在的记忆

除了每天定时跑,也支持手动触发指定整理最近 N 天的记忆,所有的梦境整理内容会以日记的形式持久化保存在工作空间中。

五、源代码自更新

源码自更新指的是 Agent 在运行过程中能够实时修改自身代码并重启,以解决无法通过外置技能、工具等解决的问题,由于存在一定不可控性,这里更多做开放性讨论。

出于安全性考虑,目前 CowAgent 项目没有把源码自更新作为内置开放的功能,但用户可通过指定要求来实现该效果。项目默认就是源码安装方式,Agent 天然有访问源代码的权限,只需将项目代码路径告诉 Agent 并给出明确改动需求即可让其修改自身代码并重启,如果想要让 Agent 能够更主动地修改代码,还可以封装为 Skill 或 Prompt 作为内置能力。

修改代码是修改 Agent 能力本身,不像变更记忆、技能等数据,影响面更大。源码自更新存在两个难点:

  • 如何避免 Agent 把代码改坏,影响正常启动
  • 如何在当前进程中关闭自身并重启新的进程

为了解决这两个问题,项目中实现了一个 cow self-restart 的 CLI 命令,专门用于 Agent 的自重启。首先会对代码进行运行自检,出现任何依赖导入或解释器错误都会中止重启;自检通过后则会启动一个脱离于当前进程树的接力进程,在这个进程中对旧的进程进行关闭,并启动新的进程,实现优雅自重启。

而在开源项目场景中,Agent 修改自身代码其实还有另一个问题,就是版本冲突。当本地修改代码后,必然会相对主干分支形成分叉,后续官方版本更新后,代码拉取就有可能存在冲突,这个时候就需要依赖人工或者 Agent 协助进行解决了。

Agent 修改自身代码并重启的示例

上图示例:Agent 自行定位到自身代码问题并修改,再通过命令完成自检与重启

总结

总结一下,我们通过不断递进的五层设计让 Agent 学会主动调整自己的提示词、记忆、知识、技能、甚至是源码,回顾整体设计思路,难点其实不是实现修改自己的能力,而是让它能够改得克制、改得可控。目标其实很朴素:真正实现一个越用越懂你、越用越少犯错的 Agent,而不是每天重新认识你一遍的 Agent。

目前这套自进化机制在 CowAgent 里已经可用,完全开源、模型中立。

标签: ai, Agent, harness, cowagent

添加新评论