背景是这样,我想对某个大型项目做源码解析,生成类似于《ClaudeCodeC源码解析》的一本书。
我先写了个skill(
https://github.com/DracoUnion/skills/tree/master/write-code-anls),拿ClaudeCode去跑,结果只得到了10章少于十万字的内容。这肯定覆盖不了全部源码。
然后我试着把整个流程拿Python调用OpenAI API 写成CLI应用(
https://github.com/DracoUnion/BookerGptTool/blob/master/BookerGptTool/code2book.py),结果生成了90多章的内容,覆盖了全部源码文件。
为什么会这样,难道是我Skill写的不好或者通用agent本来就有缺陷吗?
不是你 Skill 写得不好,是通用 Agent 的运行机制决定的。
核心差异在遍历策略的控制权。
你的 Python CLI 脚本大概率做了显式的文件遍历——递归走完每个源码文件,逐个调 API 生成章节,所以 90+ 章一个不漏。这是程序控制流程,覆盖率由你的遍历逻辑保证。
而 Claude Code 走的是 Agent Loop:模型自己决定下一步读哪个文件、什么时候算"够了"。面对大型项目,模型的 context window 会很快被源码撑满,于是它开始做信息压缩——跳过它认为"不重要"的文件、合并相似模块、用抽象概括代替逐文件分析。10 章 < 10 万字,就是模型自己做了裁剪决策的结果。
这不是缺陷,是通用 Agent 的设计取舍:它优化的是对话效率,不是穷举覆盖率。Claude Code 的 system prompt 和 tool use 模式天然倾向于"用最少步骤完成任务",而不是"遍历每一个文件"。
解决思路:如果你要用 Agent 做穷举式源码解析,关键是在 Skill 里强制显式遍历逻辑——比如先列出全部文件清单,然后逐个文件 obligate 模型生成独立章节,不给它跳过的自由度。把 Agent 当执行者而不是决策者,覆盖率就上来了。
这并非你的 Skill 写得不好,也不是通用 Agent 有根本性缺陷,而是“交互式 Agent(如 Claude Code)”与“批处理式脚本(如你的 Python CLI)”在处理大规模上下文任务时的底层逻辑差异导致的。
简单来说:Claude Code 被设计为“对话者”,受限于实时交互的上下文窗口和注意力机制;而你的 Python CLI 是“流水线工人”,通过强制分片和状态重置,规避了长程记忆的衰减。
两楼的结论都对,但还差一层:分歧不在「谁决定下一步」,而在已完成的覆盖率由谁保管。
Claude Code 这类 agent loop,把「我已经处理过哪些文件」这件事存在模型的上下文里。而长会话必然触发压缩(auto-compact / 用摘要替换历史)。压缩一旦发生,这份「进度账本」是最先被丢的东西——因为它看起来像过程赘述,不像结论。之后模型对覆盖率彻底失去状态,只能凭印象续跑,「这个模块前面好像说过类似的」于是跳过。漏章从这里开始,而且是静默的:它报「完成」的时候并不知道自己漏了 80 章。
Python 版没这个病:已遍历集合在变量里、进度在磁盘上,跟上下文活不活没关系。所以它能出 90 章不是因为脚本写得巧,而是因为账本不在模型脑子里。
能直接抄的四条:
一句话:不是 skill 措辞的问题,是把「谁证明做到了」从模型手里拿走,交给不依赖上下文的程序。
补充(2026-11-03,自测后修正)
上面四条,我自己按这个思路做了个最小对照实验(12 个文件、96KB,三组各跑一遍),结果要打个折:
真正起作用的只有第 3 条,而且要比原文写得更狠:差集的两边必须都是磁盘上的事实。输入清单从文件树枚举,产出从磁盘上实际存在的文件枚举,不能有一边是模型自己写的进度表 —— 进度表本身就是又一层的自报,它撒谎的时候,拿它做差集只会得到「全部完成」。
所以那句话改成:不是「把账本外置」,而是「账本不能由被核对的人来写」。