乐于分享
好东西不私藏

AI 编程 Agent 不需要更聪明,它们需要一张地图

AI 编程 Agent 不需要更聪明,它们需要一张地图

AI 编程 Agent 不需要更聪明

它们需要一张地图

形式化架构声明作为 AI Coding Agent 的导航原语

arXiv:2604.13108 — 一个看不懂代码的人,如何让 AI Agent 的导航步数降低 33–44%。

作者:靳若琦 (Independent Researcher)


我为什么要做这件事

我看不懂代码。

这不是谦虚。我是一个视频剪辑师,靠着 AI Agent(Claude Code)写 Rust 来搭建整套软件系统。我审 diff、批 PR、部署上线。这套模式一直运转良好——直到项目超过一万五千行。

到了这个规模,崩溃的不是代码,而是 Agent 的导航能力。Claude Code 开始反复 grep 三轮前已经找到的函数、重复读同一个文件、猜模块边界而不是确定它们。我眼睁睁看着它烧掉 10 次工具调用去定位一个函数——而那个函数我 5 秒钟就能指出来,如果我看得懂 Rust 的话。

我管理 20 个项目。最小的两万行,最大的四十七万行。如果 Agent 一半时间都在迷路,那我一半时间都在等它。

我需要的不是一个更聪明的 Agent。我需要一张地图。


intent.lisp:架构声明文件

我开始用 S 表达式(Lisp 的括号语法)编写架构描述文件。不是因为觉得 Lisp 有什么魔法,而是因为括号能强制结构化。你没法在 S 表达式里含糊其辞——而 Markdown 可以。

(intent jarvis  (design-constraints    (three-pillars (memory control tools))    (communication (must-use EventBus))    (db-access (only memory/storage)))  (pillar memory    (purpose "数据采集、存储、分析")    (component storage      (role "唯一的数据库网关")      (invariants "此模块外禁止裸 SQL")      (data-flow "Event → Storage → PostgreSQL"))))

组件包含在支柱(pillar)内部,符号包含在组件内部。这不是格式偏好——这是语法强制。两个人(或两个 LLM)描述同一个项目,产出的文件在结构上是收敛的。Markdown 做不到这一点。

我为所有项目都写了 intent.lisp。一个 11 万行的 Rust 守护进程被压缩到 1,587 行。一个 47 万行的 monorepo 被压缩到 7,877 行(32 个文件)。跨 64.6 万行生产代码的加权平均压缩比是 34:1

我不手写它们。我用自然语言描述我想要的架构,Claude Code 翻译成 S 表达式。另一个 Claude Code 会话在后续工作中读取它。


让我意外的实验结果

我原本想证明 S 表达式比 Markdown 更适合 AI Agent。所以做了对照实验:24 个代码定位任务,四种条件(无上下文、S 表达式、JSON、Markdown),Claude Sonnet 4.6,温度 = 0。

我期望的结果:有架构上下文显著减少导航步数。验证了——步数减少 33–44%(Wilcoxon p = 0.009,Cohen’s d = 0.92)。

我没有预料到的结果:格式完全不重要。

S 表达式、JSON、YAML、Markdown——LLM 在四种格式上达到了一模一样的 95% 准确率。没有显著差异。Agent 根本不在乎你用括号还是用 bullet point 还是用花括号写架构。它读什么都一样。

这彻底推翻了我的论文假设。如果格式无所谓,那为什么还要用 S 表达式?


真正重要的三件事

1. 形式化重要。格式不重要。

有架构文件就能减少 33–44% 的导航步数。没有就意味着 Agent 在盲走。内容是信号,括号是噪音。

但更深层的发现来自田野研究(7,012 个 Claude Code 会话):读了 intent.lisp 的会话和没读的会话,效率完全一样(explore/edit 比 1.65 vs 1.65)。改善是系统性的,而非逐会话的。

变的不是 Agent 消费了文件。变的是我写了它。形式化架构的过程迫使我想清楚自己的系统——哪个模块负责数据库、事件怎么流转、约束在哪里。这种清晰度渗透到了更好的提示词、更清晰的代码边界、更显式的 CLAUDE.md 引用。我称之为开发者自明效应(developer self-clarification effect)

2. 文件本身有直接价值——即使自动生成。

为了排除"是写文件帮了忙还是文件本身帮了忙",我在一个从未重构过代码的项目上做了第二个实验。工具自动扫描代码库,生成了一份 170 行的架构摘要——零人工编辑、零代码重构。

自动生成:100% 任务完成率。无上下文:80%。(p = 0.002,d = 1.04)

文件本身就能帮忙。你不需要亲自写它来受益。机器生成、机器消费。开发者自明效应是附加值,不是全部。

更出乎意料的是:自动生成的 170 行版本在准确率上跑赢了我手工精修的 698 行版本(100% vs 87%)。Less is more——至少在导航这件事上,更短的描述消耗的 token 更少,留给 Agent 更多的工具调用预算。

3. 失败模式才是格式真正分野的地方。

如果 LLM 读所有格式都一样好,那为什么要选其中一个?因为 LLM 也会写描述文件,写的时候会犯错。犯错的方式才是关键:

格式
解析有效率
静默损坏率
致命缺陷
S 表达式
96%
50%
JSON
100%
21%
原子失败(一个错毁全文件)
YAML
92%
50%
静默语义损坏
Markdown
N/A
N/A
零错误检测(0%)
  • JSON
     原子性失败——少一个花括号,整个文件不可解析,内容全损。
  • YAML
     静默损坏——缩进错误会把组件悄悄挂到错误的父节点下,没有任何警告。
  • Markdown
     无法检测——没有解析器,100% 的错误不可见。
  • S 表达式
     优雅降级——所有结构错误都能被检测到,错误之前的内容完好无损。

我选择 S 表达式,不是因为 LLM 读它更好。而是因为它坏得更好。


实验数据总览

全部实验使用 Claude Sonnet 4.6,温度 = 0。总计 317 次 API 调用,花费约 $27。

实验
发现
关键数据
A: 代码定位 (24×4)
上下文有效,格式无关
d = 0.92, p = 0.009
B: 理解测试 (20×4)
四种格式完全一致
95% 全线持平
C: 生成测试 (96 次)
可解析格式均 >91%
S 表达式最紧凑
D: 错误注入 (96 次)
每种格式失败方式不同
YAML 50% 静默
E: 工件 vs 过程 (15×3)
自动生成的描述有效
100% vs 80%, d = 1.04
田野研究 (7,012 会话)
行为方差减半
IQR −52%

forge survey:60 秒生成架构地图

基于上述研究,我构建了一个开源工具——Forge。它的核心命令只有一个:

cargo install forge-cliforge survey /path/to/your/project

它用 tree-sitter 扫描代码库的 AST,组装结构化提示词,调用 Claude 生成 S 表达式架构描述,然后通过内置的 S 表达式解析器验证输出。整个过程约 60 秒。生成的 intent.lisp 文件随代码一起进入版本控制。

对我来说,这就是管理 20 个项目和被 20 个项目淹没之间的区别。Agent 拿到一张地图,我拿到可预测性。


坦诚的局限性

  • N=1 开发者 ——
     所有田野观察来自一个人的项目,生态效度有限。
  • 效果量对模型敏感 ——
     Sonnet 4 时 d=1.70,Sonnet 4.6 时 d=0.92。模型越强,盲走效率越高,地图的边际收益越小。但在 47 万行项目上,强模型也会迷路。
  • 格式比较的统计功效不足 ——
     仅 3–6 个有效配对差异,不足以证明格式真正等价,只能说我没检测到差异。
  • 只测了代码定位 ——
     多文件修改和架构决策场景未验证。

对 Context Engineering 争论的回应

整个 Context Engineering 社区都在争论 CLAUDE.md / AGENTS.md / Cursor Rules 里应该用什么格式。YAML frontmatter?Markdown 标题?JSON Schema?

至少对于架构上下文来说,答案似乎是:格式无所谓。重要的是你形式化了你的架构。用你工具链支持的任何格式写。如果你需要下游的自动验证,选一个可解析的格式。如果不需要,Markdown 就够了。

更有生产力的问题不是「LLM 偏好什么格式」,而是「什么格式在 LLM 读写时都能避免灾难性失败」。我们的实验没有检测到显著的格式偏好。d = 0.92 是在一个 2.2 万行项目上测出的,而 Sonnet 4.6 在这个规模上已经能高效盲走。在 10 万行以上的项目中,盲走本质上更难——34:1 的压缩比意味着恒定成本的架构可达性,不受代码库规模影响。


关于作者

我是一个 33 岁的中国视频剪辑师,高中毕业,没有 CS 学位。我从 2012 年开始做影视后期,交付了 100 多个项目。2024 年,我开始自学 Rust、编译器和分布式系统——因为我管理的 AI Agent 编程系统越来越大,我需要一种方式来掌控我自己看不懂的代码库。

intent.lisp 就是这种方式。它最初是为了解决我个人的痛点——后来发现,对所有使用 AI 编程 Agent 的开发者都有效。

论文: arxiv.org/abs/2604.13108

代码: github.com/RuoqiJin/forge

DOI: doi.org/10.5281/zenodo.19500105

网站: ruoqijin.com

微信: Jinstudio626

如果你也在用 Claude Code / Cursor / Copilot 管理大型项目,欢迎交流。这张地图也许能帮你少走一些弯路。