Skip to content

用 Agent 开发 Agent,为什么修了很多 Bug,真实研究还是没完成? ​

内容主线:AI 工程研发实践;兼线:系统架构与工程观点。本文讨论复杂任务的研发与验收收敛,不重复介绍评测评分或单个 Runtime 模块。

开发 ETF Agent 有一段时间后,我们遇到了一个很不舒服的现实:架构越来越完整,局部测试越来越绿,但用户真正交给它的一份投资研究,还是没能正常完成。

2026 年 10 月 14 日的一次真实任务留下了 26 次物理模型请求、24 个持久模型回合、4 个发布块,最终 History 却是 partial / research_interrupted,正常 HTML 报告没有交付。六次子 Agent 请求都返回输入不可用;十三次脚本请求里,多数只是完成了方法描述,并没有真正运行计算、渲染和导出脚本。

如果只看工具调用次数,会觉得系统工作得很努力。如果只看局部测试,会觉得很多能力已经具备。可用户要的结果仍然不存在。

那之后,我们逐渐不再把“修复了多少故障”与“离用户任务完成还有多远”看成同一条进度线。

一、为什么只靠修最后一个报错,会陷入循环? ​

早期 Agent 项目里,一个直觉式的工作流程是:让模型跑真题,找到最后一个错误码,补一段适配逻辑或提示词,跑回归,再测一次。

这在局部软件缺陷上很有效,却容易遗漏复杂研究里的跨阶段交接。

比如一次结果已经存储,下一轮模型却没有看到。我们可以责怪模型忘记上下文,也可以加大 token 容量,但真正缺的可能是工具结果在请求投影里的来源证明。

又比如模型提交了完整修订,历史还是旧版。继续改善收尾提示没有意义,因为错误出在已接受提案到持久版本的交接。

所以我们把问题从“最后发生了什么错误”改成:用户目标需要哪些实际效果?本次失败究竟缺失哪一个效果,谁拥有那项事实?

这一转换让每一次修改有了更窄的目标,不必总是朝 Runtime 里新增一个保险判断。

二、一次 93 比 21 的对账,怎样改变了修复方向? ​

在前述真实研究中,工具结果已经留在存储里。我们对来源投影做独立只读检查,发现 93 组存储结果只有 21 组能进入可见投影,后续九个数值结果和三个可用目录结果被排除。

这让我们不能再笼统说“模型没利用查到的数据”。对部分结果而言,它甚至没有取得继续使用的当前证明。

进一步定位到一个很具体的生产者错误:Run 累计来源证明错误复用单次 Publication 的较窄依赖合并器。Publication 八条依赖的范围被用到应有 64 条依赖 / 24 KiB 上限的 Run 证明,合法的第九条及后续关系会丢失。

修复放回来源证明生产者,不去放松下游正确的越权拒绝。原代码路径和测试覆盖了 9、32、64 条合法依赖,65 条溢出拒绝,以及缺失、篡改和跨 Run 的负例;当时记录为 79 个聚焦、10 个独立和 173 个调用方检查通过。

这次工程问题有了明确结论:一条合法来源为什么在后续请求里失去资格,已经定位并做了限定回归。

但原来那次自然投资研究没有因此自动交出 HTML。我们不再拿这个修复关闭用户任务。

这就是第一条进度线与第二条进度线分开的意义。

三、另一次正例:Python 真正把错误修了,报告也真正送到了 ​

10 月 16 日,Python 专项终于留下了一条更完整的正向证据。

真实子 Agent 首次执行代码时因为字段读取出现 KeyError,随后修改为实际数据中的 nav 字段,重新完成规定计算;第一次 HTML 生成又遭遇 NameError,后续修正了字符串拼接。生成的结果没有停在“脚本返回成功”或“模型说报告已写好”。

子 Agent 经正常分析工作区导出 11,384 字节 HTML;Host 保留内容类型、大小和摘要。HTTP 实际下载返回 200,字节核对吻合。Main 实际消费了子任务交回的下载路径,新的 History 读取仍能拿到相同文件身份。

这次真实执行有 17 个物理模型请求,Root 在约 251.5 秒结束。独立计算也核对了合成用例的收益率和回撤。

这是值得记录的工程进步。但我们没有把它记成“ETF Agent 已经能自主完成全部指数组合研究”。因为它是一个 Python 失败修正及正式交接专项,不等于原问题、独立变体、PDF 视觉、取消控制和投资研究质量全部通过。

后来新的自然问题尝试里,仍然出现过 Python 提议在执行前被拒、HTML 导出失败、实际 Python 成功后又失去来源关系的结果。它们应当继续留在各自的原始记录,不能被前面一个正例抹平。

真实正例与真实负例,可以同时成立。 研发工作需要回答的是它们各自证明了什么,而不是强迫形成一条漂亮的成功故事。

四、怎样用 AI 开发 AI,却不把验证做成无穷任务? ​

这些问题让我们重新组织 Coding Agent 的工作节奏。

首先,冻结真正要回答的用户问题。例如原题考察一个自主研究目标,独立变体只改变假设新增资金的一个条件。冻结的意义不是要求模型每次写出相同文字,而是保证后续修复仍然面向同一业务问题。

其次,为每一次改动写出最小命题。“第九条合法来源证明会被保存”可以用确定性回归检查;“用户拿到了一份有决策价值的投资报告”,则还需要完整实际输出和独立内容判断。

第三,不让每个局部修复都触发昂贵的真实全题重跑。改动只涉及稳定且可隔离的接口时,先验证该接口;真正触及主路径必经交接、具备当前授权与可比输入时,再安排对应真实验证。原来的已知失败、账单未知和未完成任务不因本次绿测被自动改写。

第四,保留合理的停止条件。不是所有未通过的想法都要继续发展成新的 Runtime 层、修订循环或 Spec。确定本轮问题不在这条接缝,就应停止继续加同类拦截;如果出现新的风险,要按原职责另开有界问题,而不是让一轮研究永远没有结束。

这与“只要质量还不好就继续调 Prompt”不同。我们希望 Coding Agent 能识别什么时候该修代码、什么时候该补观察,什么时候应该承认当前结果只是 partial。

五、Spec、History 和 Skill 各自做什么? ​

我们原本已经积累了大量研发文档。后来发现,把每次失败都写成一篇新 history、为每次修复都重复整理一份全套工件,同样会造成维护负担。

因此现在更强调作用范围:

  • Spec 规定目标行为和验收条件,不应替当前代码宣布实现已完成。
  • Evidence 保存实际执行时的版本、结果与未通过项,不在收尾时凭记忆补造。
  • History 只晋升真正改变了工程判断的事实,例如“原先以为模型没写答案,后来撤回了这个归因”。
  • Skill 保存下一次可复用的方法,而不缓存某个可能已经过时的 main 状态。

这些不是为了文档齐全。真正的目标是让下一位 Coding Agent 不必重新猜测上次发生了什么,也不必把已经否定的路线再走一遍。

这个方向在已有研发验收流程和按需加载工程知识两篇文章里已有专门展开,这里不重复写一篇 Spec 教程。

六、我们怎么判断研发真的在推进? ​

我现在更愿意把结果分成三类。

能力进展:以前不能做到的具体执行接缝,已经留下实际正例和明确负例,例如 Python 修错后的真实文件下载与重开。

归因进展:即使整题仍失败,也已证明问题发生在哪个事实归属方,不再笼统归咎于模型或供应商,例如 Run 证明混用了发布容量。

产品进展:用户原来的自然任务真正完成,研究结论可以核查,关键风险与替代方案有实际决策增益,正式产物能够交付和重读。

前三种事实不能互相代替,尤其不能把开发者手工补位的报告算作 ETF Agent 的自主交付。

截至 2026 年 10 月 17 日的相关证据窗口,完整自主研究、独立变体和内容质量仍有未完成项。我们没有能够比较的长期研发成本或整体成功率数据,不能声称这种方法已经节省了多少时间。

但我们至少获得了一种更稳的工作方法:

用 AI 开发 Agent 时,真正要追踪的不是修复数量,而是每次修改有没有改变用户任务所需的那个真实条件。 能说明这一点的测试值得做;不能说明的,就不应该靠更多模型调用把它包装成进展。

取材与验证边界 ​

  • 自主指数组合研究的任务状态与原始失败
  • 2026-10-14 真实 partial 与来源证明修复
  • 2026-10-16 Python R4 修复及 HTML 真实交付
  • 后续真实验收与未完成项

本篇只复述原样本与它们的实际边界,没有重新运行模型或把不同测试的通过数拼成“整个 Agent 已通过”。

公开版本说明: 原稿引用的私有项目测试、Spec 与工程日志未随文章公开;本文保留案例及其取材时间、局部验证范围,不将内部验收作为读者可直接访问的外部证据。

与个人博客并行:这里按问题连续阅读,博客保留时间线。