通过捕获用户 /rant 命令的反馈日志,由定时任务去重分类后生成代码改进 PR,用测试套件作为 fitness function,构成了一个无人值守的 Agent 自我优化闭环。
如何让一个软件 Agent 真正在使用中进化——不是 Demo,而是定时无人值守,以测试为门槛?
大多数"自改进" Agent 项目的进化方式不外乎两种:要么在遥测数据上微调(贵,且黑盒);要么让模型在会话内反思(跨会话直接遗忘)。这篇文章讲的是我们从 2026 年初就在生产环境中跑的第三种形态:以用户反馈为变异来源,以测试套件为适应度函数,以 git + PR 为交付机制。它刻意朴素——没有 RL,没有向量化记忆,没有协同进化评估器。只有一条边界锐利的闭环。
Capture(捕获)。Agent 对外暴露一个 /rant 命令(以及 CLI:emrg rant <msg>)。任何让你不爽的东西都进入结构化反馈日志(~/.emrg/rants.jsonl):每条投诉一行 JSON,带时间戳和项目标签。捕获阶段不做任何过滤——噪音留在后面处理,不是拦在门口。
Triage(分诊)。一个定时进化的任务(后台作业,不走聊天循环)读取积累的反馈、去重、分类、决定哪些值得处理。原始投诉大多是重复、困惑和小需求;分诊这一步才是信噪比所在。
Change(变更)。这个任务只编辑自己的仓库(~/.emrg/evolution/emrg),绝不碰用户项目文件。范围边界是硬性的:Agent 改进的是 Agent,不是你的代码库。
Gate(门禁)。任何东西提交之前:完整跑一遍 pytest + 导入检查。如果变更破坏了测试,就丢弃。这是整个安全故事的全部,且刻意平淡——确定性、可复现,通过/失败决策不涉及任何模型判断。
Ship(发布)。创建一个 commit,提交信息里带上触发这次投诉的时间戳(这样每一行历史都能追溯到一条投诉),推送,并以 PR 形式打开。经人工(或维护者流程)审核后合并。
Record(记录)。写一条演进日志条目(时间、原因、变更了什么、结果)。历史就是记忆:你可以通过 git blame 追溯到引发它的投诉,来回答"这条规则为什么存在?"
这个循环按定时任务运行(根据配置,从十几分钟到一小时不等)。空转循环是合法结果——"没有东西需要进化"是 Discover 步骤的输出,不是跳过的轮次。
反馈是你能免费获得的最高带宽信号。遥测告诉你发生了什么;投诉告诉你一个人想要什么但没得到。诀窍在于投诉生产便宜,但处理昂贵——只有处理成本足够低,这个循环才能盈利。我们的方案通过把每次改进做成小型、可测试的 diff 而不是一次重训练来让它足够便宜。
测试门禁让自改改足够安全,可以无人值守运行。一个不自测的自改 Agent 就是有 root 权限的恶作剧者。门禁把"AI 改进了自己"从一个可怕的说法变成了可审查的流水线:任何通过测试套件的变更至少是回归安全的,任何没通过的都直接丢弃。这和人类代码的 CI 逻辑一样,只是应用到了代码的作者本身。
Git 给你一个免费的事件日志。每一次演进 commit 都是一条审计记录:改了什么、什么时候、为什么(投诉 ID)、谁改的(Agent)。"Agent 周二相信了什么?"一个 git checkout 就能回答,不是数据库导出。一次糟糕的变更是 revert,不是 restore-from-backup。对于一个自我修改的系统,只追加、内容寻址的历史不是锦上添花——它是"可审计"和"不可知"之间的区别。
哪些行不通(来自实际运行)
没有分诊 → 循环被自己的输入淹没。先去重再分类再行动,否则改进器会反复修复同一条投诉,把用户困惑当缺陷来"修"。
大 diff 会腐烂。循环必须产出小型、单一目的的变更。十条发现 → 十个 PR。一个 40 文件的"改进"会被审阅者忽略,侵蚀整个机制的信任。
没有自动回滚 → 一次糟糕的合并毒害一切。如果一个合并的变更破坏了门禁,自动回滚而不是等人发现。
自改需要硬边界。Agent 只能动自己的仓库。一旦"改进自己"变成了"改进你的代码库",它就不再是自我改进了,是一个无人监管的承包商。
权衡,诚实说
这只改进测试套件能覆盖到的部分。如果你的 Agent 行为没有被测试覆盖,门禁就是形式主义,循环就是演戏。演进机制和测试套件必须一起成长。
改进的面大多很小。实际产出:路由微调、prompt 边角案例、更清晰的报错、不稳定命令修复。大改写还是人来做。这没问题——小修复的复利才是让循环值得跑的原因。
它是反馈形态的,不是通用目的的。这个循环按照用户投诉的方向改进 Agent。它不会发明没人要的能力。对信任来说是特性,对野心来说是局限。
一个未经验证的定时循环就是一个垃圾机器人。先手动触发,等门禁被验证后再定时。我们让它手动跑了好几周才放手让它自己跑。
"自改进 Agent"这个领域有令人兴奋的研究(协同进化评估器、哥德尔机式自我引用、基于测试 harness 的 RL——都值得一读)。但这个想法有一个生产可用的版本,不需要其中任何一样:人类沮丧与经过测试、审查、可追溯变更之间的闭环。它平淡、它小型、它复利。如果你在构建一个应该随使用改进的 Agent,从这个平淡的循环开始——捕获反馈、分诊过滤、用测试做门禁、当 diff 发布、每一步都可审计。炫酷的东西可以等。
这篇文章是 EMRG 所用循环的设计文档——EMRG 是一个开源(MIT)的 Agent 测试框架,其演进周期将 /rant 反馈转化为经过测试的合并 PR,作用于自身代码库。当前发布版本:v0.2.58(2026-08-20),HEAD 1a645a15a5。上述循环不是愿景:v0.2.52→v0.2.58 两天内发出(PR #857–#885)——daemon 单实例绑定独占性修复、vibe-check 证据修复 + 一个自找的 LLM-400 修复(6 个新测试)、一个数据丢失的事后分析(在脏树上是只读的,第 #881)、自动升级重构(第 #882)、调度器重构、TUI 多行渲染、tool-intent 元数据——全部通过这条流水线完成。