别把机器人放进人类的办公室

Image: AI generated

一个问题

打开你项目中最长的文件,看看里面有多少个函数。

让 AI 代理修改那个文件中的某一个函数。代理会读取整个文件。它打开文件是因为需要一个函数,结果却带来了 19 个不必要的函数。

问题就从这里开始。

人类阅读的代码 vs 代理操作的代码

一直以来,代码是给人类阅读的。给变量取好名字、写注释、写文档——一切都是为了减轻人类的认知负担。

在代理时代,问题变了。人类容易阅读的代码和代理容易操作的代码是一样的吗?

不一样。

人类AI 代理
导航方式用眼睛浏览目录树用 grep 搜索
打开文件在 IDE 中滚动read file — 全部加载
上下文判断直觉 + 经验只知道上下文中有的内容
不必要的代码忽略消耗上下文预算
2,000 行文件只看需要的部分全部处理

人类滚动 2,000 行文件时,“这部分别碰"的直觉会自动启动。代理没有这种直觉。读了 2,000 行,其中 1,950 行都是上下文污染。

研究证实了这一点。混入不相关信息时,AI 性能下降 30~85%。即使不必要的 token 是空白字符,性能也会下降。上下文越短越好,这不是直觉,而是实验结果。

别把机器人放进人类的办公室。要建造机器人能工作的工厂。

代理需要的三样东西

代理要在代码库中稳定工作,需要具备三个条件。

1. 必须可读——没有噪音

一个文件一个概念。文件名就是概念名。

before: read utils.go → 20 个函数,19 个不必要
after:  read check_one_file_one_func.go → 1 个函数,正好是需要的

filefunc 解决了这个问题。它用 22 条结构规则将代码按语义单元分离。在 Hono 框架(star 23k+)上,把 186 个文件拆成了 626 个。4,419 个测试全部通过。文件增加了 3.4 倍,但逻辑一行都没变。

“文件不会太多吗?"——代理不会浏览目录,它搜索。不管是 500 个还是 1,000 个文件,一次 grep 就够了。比起挑出需要的 5 个文件,不打开不必要的 295 个更重要。

2. 必须可验证——机械地

修改没有测试的函数,没人知道会坏什么。代理也不知道。陷入 doom loop。

before: 0 个测试,修改后不知道会坏什么
after:  527 个函数有测试,行为变更立即检测

tsma 解决了这个问题。它索引项目中的每个函数,检测是否有测试,衡量覆盖率,并以行号反馈未覆盖的分支。

不给反馈让 LLM 写测试,覆盖率在 60~70% 就停了。告诉它"第 41、44、70 行未覆盖”,它就能达到 100%。同一个模型。差别只在反馈的分辨率。

在 527 个函数的项目上的实验结果:TODO 完成到 0。自主代理在 40 个时宣布"全部完成”。应用棘轮后:527 个全部完成。

3. 规范必须可交叉验证

API 模式、数据库模式、安全策略、状态转换是否彼此一致,必须能够机械地确认。改了一个地方,编译之前就必须知道是否和其他地方矛盾。

before: 200 个端点,人工检查规范一致性
after:  一个 operationId 链接所有层,机器检测漂移

yongol 解决了这个问题。它通过一个 operationId 链接 10 个 SSOT(OpenAPI、DDL、sqlc、SSaC、Rego、Hurl 等),用约 287 条规则进行交叉验证。OpenAPI 中 user_id 是 string,DDL 中却是 BIGINT——这类跨层矛盾,现有工具抓不到。

贯穿三个工具的同一结构

filefunc、tsma 和 yongol 是独立工具,但有共同的结构。

filefunc:  22 条结构规则 → validate → 修复 → 重复
tsma:      测量覆盖率 → 反馈未覆盖分支 → 修复 → 重复
yongol:    交叉验证 → 检测漂移 → 修复 → 重复

全是同一个循环。

LLM 生成 → 确定性工具判定 → 结果反馈给 LLM → 重复

Symbolic Feedback Loop。确定性工具校正 LLM 概率性生成的循环结构。不是 AI 验证 AI,而是机器验证 AI。

给它意见,它就奉承。给它事实,它就修改。问"代码没问题吧?“它回答"嗯,很好”。告诉它"第 41 行:字段名不匹配",它立即修复。没有奉承对象的反馈——因为数字和位置不是情感。

从遗留系统到 agent-operable

不需要一次性改变现有代码库。这不是打地基,而是抗震加固。在不关店的情况下加固建筑。

第 1 步——使之可读

从最长的文件开始拆分。运行 filefunc validate,把违规降到零。所有现有测试必须通过。

第 2 步——使之可验证

反复运行 tsma next。为没有测试的函数添加测试,填补未覆盖的分支。即使代理中途挂了,进度也会保留。新代理运行 tsma next 就能接着干。

第 3 步——交叉验证

引入 SSOT,运行 yongol validate。机器捕捉跨层矛盾。

每一步都是独立的。不做第 1 步也可以做第 2 步,不做第 2 步也可以做第 1 步。但三者结合起来,代理自主工作的范围会急剧扩大。

改变操作系统

agent-operable codebase 不仅仅是 lint 或工具层面的事。这是改变代码库的操作系统。

human-readableagent-operable
文件大小人类可滚动的范围一个概念
测试有最好,没有靠直觉每个函数必须有
规范文档、wiki、口头传达声明式、可交叉验证、机器可读
反馈PR 审查(小时级)验证器运行(秒级)
完成判断人类说"差不多了"机器说"还剩 487 个"

很多人在让火车跑得更快。更大的模型、更聪明的代理、更好的提示词。

火车越快,轨道越重要。铺轨道的人几乎还没出现。


相关文章


参考资料

  • Stanford, “Lost in the Middle: How Language Models Use Long Contexts” (2024) — 相关信息埋在上下文中间时性能下降 30%+
  • Amazon, “Context Length Alone Hurts LLM Performance” (2025) — 即使不必要 token 是空白字符,性能也下降 13.9~85%
  • Hono 框架实证 — 186 个文件 → 626 个文件,4,419 个测试全部通过
  • tsma 527 个函数实证 — PASS 246 个(46.7%)、DONE 281 个(53.3%)、TODO 0 个
  • Ratchet Pattern 实验 — 自主代理 40/527(7.6%) vs 棘轮 CLI 527/527(100%)