Skip to content

Commit 4fa2d23

Browse files
committed
Rewrite Zhihu article: more human, highlight fork/learn value, no raw GitHub URLs
1 parent ef5805f commit 4fa2d23

2 files changed

Lines changed: 315 additions & 0 deletions

File tree

article/zhihu-guide-series.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# 知乎文章草稿 2:导读系列引流
2+
3+
**标题方案**
4+
- A: Claude Code 源码里最值得学的 7 个设计模式
5+
- B: 读完 Claude Code 51 万行源码,我写了 7 篇技术导读
6+
- C: AI 编程 Agent 是怎么工作的?Claude Code 源码里的答案
7+
8+
---
9+
10+
上个月 Claude Code 源码泄露之后,我写了一篇分析文章,反响挺大(17万阅读)。很多朋友的反馈是:分析文看了,但 51 万行源码自己根本看不动,能不能出个导读?
11+
12+
于是我花了两周写了一套导读。不是把每个文件都过一遍那种——那个版本也有,16 篇 16 万字,放在 GitHub 上了——这套导读只挑了我认为最值得开发者了解的 7 个设计模式,每篇围绕一个核心问题展开。
13+
14+
如果你在做 AI Agent 相关的工作,或者单纯对"一个 51 万行的生产级 AI 产品内部长什么样"好奇,这个系列应该能给你一些启发。
15+
16+
全部文章在 GitHub 上,欢迎来点个Star:https://github.com/he-yufeng/NanoCoder/tree/main/article
17+
18+
下面是每篇的内容概要和核心发现。
19+
20+
---
21+
22+
## 第一篇:从 51 万行说起
23+
24+
为什么一个 CLI 工具需要 51 万行?
25+
26+
答案是它不只是一个 CLI 工具。它同时是:一个 LLM 交互引擎、一个终端 UI 应用(用 React 渲染)、一个文件系统操作器、一个代码搜索引擎、一个多 Agent 协调器、一个插件系统、一个权限管理系统、一个 MCP 协议客户端。51 万行不是膨胀,是真的有那么多事要做。
27+
28+
技术栈选型里最意外的是 **Bun + React**。Bun 的选择比较好理解(启动速度是 Node.js 的四分之一),React 写终端就让人意外了。但看完代码之后理解了——多 Agent 并行输出、实时进度条、权限弹窗、代码 diff 高亮,这些 UI 状态管理用 React 的声明式模型处理比手搓 ANSI 转义码合理得多。
29+
30+
这篇还总结了读完全部代码后的十大设计哲学。其中我觉得最值得借鉴的是"上下文经济学"——token 就是钱,每个工具的输出都有截断策略,上下文有四层压缩,工具定义里有专门的 `getToolUseSummary()` 方法定义压缩时的摘要策略。
31+
32+
---
33+
34+
## 第二篇:1729 行的 while(true)
35+
36+
`src/query.ts`,整个 Claude Code 最核心的文件。一个 `while(true)` 循环驱动所有行为。
37+
38+
这篇深入了循环的五个关键细节:
39+
40+
**系统提示词是动态拼的。** 不是一个写死的字符串——`prompts.ts` 有 914 行,根据工作目录、Git 状态、可用工具、甚至具体模型版本动态组装。里面还有一堆 `@[MODEL LAUNCH]` 注释,是给未发布的 Capybara 模型准备的行为修正。
41+
42+
**StreamingToolExecutor。** 模型还在流式输出的时候,前面的工具已经在跑了。530 行的事件驱动状态机,监听 SSE 流事件,每个 tool_use 块的参数收集完毕就立即提交执行。只读工具并行,写工具独占。
43+
44+
**错误恢复。** 429 限流指数退避重试、400/413 上下文过长自动压缩重试、529 服务过载切 fallback 模型、输出触顶悄悄重试最多 3 次(上面还有段中世纪巫师口吻的注释,维护者显然被这段代码坑过很多次)。
45+
46+
**工具异常喂回 LLM。** 大多数 Agent 框架遇到工具异常就报错给用户。Claude Code 把异常包装成 tool_result 喂回 LLM,让 LLM 自己决定怎么处理。这才是"agentic"的核心含义——Agent 遇到问题自己想办法。
47+
48+
---
49+
50+
## 第三篇:让 AI 安全地改你的代码
51+
52+
Claude Code 不用行号补丁,不整文件重写,不生成 diff 格式。它用**搜索替换**
53+
54+
LLM 指定一段精确的文本和替换内容,文本必须在文件中唯一出现。0 次 = 记错了文件内容,2+ 次 = 上下文不够无法定位。只有 1 次才执行。这把"编辑文件"从一个模糊操作变成了确定性操作。
55+
56+
这篇还分析了工具系统的整体设计——40 多个工具零继承,全是 `buildTool()` 工厂函数生成的纯对象。两阶段门控(先检查输入合法性,再检查权限)减少了不必要的弹窗。BashTool 1143 行的安全堡垒——命令分类器、沙箱(macOS sandbox-exec / Linux seccomp)、交互式命令拦截、大输出管理、sed 检测。
57+
58+
---
59+
60+
## 第四篇:有限窗口,无限任务
61+
62+
128K token 听起来很多,十几轮工具调用就快满了。Claude Code 用四层策略分级处理:
63+
64+
1. **HISTORY_SNIP**:删纯噪声(grep 返回 500 行,模型只用了 3 行,剩下 497 行直接删)
65+
2. **CACHED_MICROCOMPACT**:调一次 LLM 做摘要,结果缓存复用
66+
3. **CONTEXT_COLLAPSE**:结构化归档,保留每轮的决策要点
67+
4. **Autocompact**:后台自动触发,用户无感知
68+
69+
按顺序执行,前面能搞定就不动后面。核心洞察:不同信息的"保质期"不一样——工具中间输出几轮后就没用了,但用户的需求描述整个会话都要保留。按保质期分级处理,比一刀切好得多。
70+
71+
---
72+
73+
## 第五篇:边想边做
74+
75+
`StreamingToolExecutor` 的深度分析。530 行,事件驱动状态机。
76+
77+
核心价值:把工具执行时间从用户可感知的延迟中移除。LLM 生成 2 秒的回复,其中包含三个 read_file 调用——如果串行等生成完再执行,用户等 2.45 秒。如果流式解析并行执行,用户等 2 秒(工具执行被完全吸收在 LLM 生成时间里)。
78+
79+
这篇分析了并发安全调度逻辑(`isConcurrencySafe` 标记)、结果排序保证(按接收顺序缓冲)、以及为什么完整实现需要 530 行——部分 JSON 拼接、错误传播、UI 更新竞争、AbortController 取消,这些 edge case 组合起来产生了大量状态管理代码。
80+
81+
---
82+
83+
## 第六篇:当一个 Claude 不够用
84+
85+
AgentTool 6700 行代码解析。三种执行模式:普通模式(共享文件系统)、Worktree 模式(Git 隔离)、后台模式(异步执行)。
86+
87+
子 Agent 不能再创建子 Agent——不是做不到,是工程上不值得。递归 Agent 的费用爆炸风险和调试难度远超两层的收益。
88+
89+
六种内置 Agent 类型:通用、规划(只做计划不执行)、探索(只读,没有写工具)、验证(跑测试)、帮助、配置。`exploreAgent` 的设计特别好——只给 read/grep/glob,保证它不会误改代码。
90+
91+
团队系统(`TeamCreateTool`)已经在源码里实现了,但还在 Feature Flag 后面。支持角色分配、Agent 间消息通信、tmux pane / in-process / remote 三种后端。
92+
93+
---
94+
95+
## 第七篇:Feature Flag 背后的秘密
96+
97+
44 个 Feature Flag。两层系统:编译时 DCE(Dead Code Elimination,代码物理消失)和运行时 GrowthBook A/B 测试。
98+
99+
最有趣的发现:
100+
101+
**KAIROS 永驻模式。** Claude Code 变成守护进程,定期醒来检查是否有事要做,自主决定是否行动。包含 autoDream(后台记忆整理)和 PROACTIVE(主动执行模式)。从工具变成同事。
102+
103+
**Buddy 宠物系统。** 18 个物种,5 级稀有度,1% 传说概率,帽子系统,闪光变体。
104+
105+
**Undercover Mode。** Anthropic 员工给外部开源项目提代码时自动去除 AI 归因。说明他们内部已经大规模使用 Claude Code 做日常开发了。
106+
107+
**消融实验。** `ABLATION_BASELINE` 一键关闭 thinking/compact/memory/background,跑对照实验量化每个功能的价值。在工业代码里用 ML 研究的方法论做产品。
108+
109+
---
110+
111+
## Python 参考实现
112+
113+
1300 行,上面讨论的所有设计模式都有可运行的代码:
114+
115+
👉 https://github.com/he-yufeng/NanoCoder
116+
117+
觉得有用给个 Star。有技术问题可以在评论区讨论或到 GitHub 开 issue。
118+
119+
---
120+
121+
*作者:何宇峰 | Agentic AI Researcher @ Moonshot AI (Kimi) | 港大 CS 硕士*

article/zhihu-nanocoder.md

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
# 分析完 Claude Code 51 万行源码后,我用 1300 行 Python 重写了它的核心
2+
3+
上一篇文章发出来之后(17 万阅读,感谢大家),评论区问得最多的两类问题:
4+
5+
一类是"所以 Claude Code 的核心到底怎么实现的?有没有 Python 版的参考实现,我想自己动手理解一下?"
6+
7+
另一类是"国内用不了 Anthropic 的 API,DeepSeek/Qwen/Kimi 能不能跑类似的东西?"
8+
9+
这篇算是交作业了。
10+
11+
---
12+
13+
## 先看效果
14+
15+
```
16+
$ nanocoder -m kimi-k2.5
17+
18+
You > 读一下 main.py,修掉拼错的 import
19+
20+
> read_file(file_path='main.py')
21+
> edit_file(file_path='main.py', old_string='from utils import halper',
22+
new_string='from utils import helper')
23+
24+
--- a/main.py
25+
+++ b/main.py
26+
@@ -1,4 +1,4 @@
27+
-from utils import halper
28+
+from utils import helper
29+
30+
修好了,halper → helper。
31+
```
32+
33+
它会自己读代码、做精准编辑(每次改动输出 unified diff 让你看清改了什么)、跑命令验证、搜索代码库。跟 Claude Code 一样的工作流,但模型你自己选。
34+
35+
项目叫 **NanoCoder**,MIT 协议开源,搜 GitHub 就能找到。
36+
37+
---
38+
39+
## 这不是又一个 Claude Code 克隆
40+
41+
得先把定位说清楚。
42+
43+
市面上已经有 Claw-Code(12 万+ star 的完整 Python/Rust 重写)、Aider、Cline 这些成熟工具。如果你只是想要一个能用的 AI 编程助手,直接用它们就好,NanoCoder 不跟它们抢这个位置。
44+
45+
NanoCoder 做的事情不太一样。
46+
47+
打个比方:想学 GPT 的训练过程,你大概不会上来就读 Megatron-LM 的几十万行代码。你会先看 Andrej Karpathy 的 nanoGPT——用三百来行代码把核心训练循环讲清楚。看完之后你就知道 GPT 是怎么回事了,然后你 fork 一份,加自己的数据集跑实验,或者在上面改出自己的架构。
48+
49+
**NanoCoder 对 AI 编程 Agent 的意义,就是 nanoGPT 对 Transformer 训练的意义。**
50+
51+
51 万行的 Claude Code,核心逻辑我提炼成了 1300 行 Python。每个文件一屏能看完。你 fork 下来,花一个下午读完,就能理解一个生产级 AI 编程 Agent 的全部核心设计。然后在这 1300 行的基础上加你自己的东西:接入你公司的内部 API、加一个代码审查工具、改成支持你们的私有模型,或者单纯拿来做 AI Agent 课程的教学素材。
52+
53+
1300 行代码,全部是从 Claude Code 源码里验证过的设计模式。不是我自己拍脑袋想的架构,是 Anthropic 在 51 万行的生产系统里跑过、用数据验证过的东西。
54+
55+
---
56+
57+
## 51 万行里哪些是"承重墙"
58+
59+
读完 Claude Code 全部源码,我觉得真正"承重"的设计模式就 7 个。剩下几十万行是 UI 渲染(React + Ink)、MCP 协议适配、OAuth 认证、Skill 插件系统、那个让人意外的宠物系统之类的。有意思,但不是一个编程 Agent 的核心。
60+
61+
以下是我提炼出来的 7 个模式,以及为什么它们重要。
62+
63+
### 1. 搜索替换式编辑
64+
65+
这可能是 Claude Code 对 AI 编程工具领域最大的单点贡献。
66+
67+
让 LLM 编辑代码,行业里试过很多方案。行号补丁?LLM 记不住行号,上下文压缩之后更对不上。整文件重写?500 行文件改 2 行也得全部重新生成,token 费用爆炸而且 LLM 复制长文本时经常悄悄丢行。输出 unified diff 格式?`@@` 行号经常算错,需要很复杂的容错解析。
68+
69+
Claude Code 的做法出奇地简单:LLM 给出一段精确的文本片段(old_string)和替换内容(new_string)。约束只有一条——old_string 必须在文件中**恰好出现一次**
70+
71+
0 次 = LLM 记错了文件内容,让它重新读文件。多于 1 次 = 给的上下文不够,让它多包含几行来消除歧义。只有恰好 1 次的情况才执行替换。
72+
73+
一个约束,干掉了一整类的编辑 bug。NanoCoder 完整实现了这个模式,每次编辑后还会输出 unified diff,你能清楚看到改了什么。
74+
75+
### 2. Agent 工具循环 + 并行执行
76+
77+
核心循环本身很简单:用户说话 → 调 LLM → LLM 说要用工具就执行 → 结果喂回 LLM → 重复,直到 LLM 只返回文本。每个 AI Agent 底层都是这个。
78+
79+
但 Claude Code 有个精妙的优化:`StreamingToolExecutor`(530 行),在模型**还没说完**的时候就开始执行前面的工具。模型流式吐出第一个工具调用的参数,那个工具立刻开始跑,不等后面的内容。多个只读工具(读文件、grep)并行执行,有副作用的(写文件、bash)独占。
80+
81+
用过 Claude Code 的人应该有体感——它"想"完之后开始干活的速度特别快。这是原因之一。
82+
83+
NanoCoder 用了简化版:等全部 tool_calls 返回后,用 ThreadPoolExecutor 并行跑。没有流式解析那么极致,但多工具并行的收益保住了。
84+
85+
### 3. 三层上下文压缩
86+
87+
128K token 听起来很多,十几轮工具调用就快满了。一个 `npm test` 的输出可能就好几千 token。
88+
89+
Claude Code 不是简单截断旧消息,而是用四层渐进策略:
90+
91+
1. **裁噪声**:grep 返回 500 行结果但模型只用了 3 行?剩下 497 行保留头尾、删中间
92+
2. **LLM 摘要**:调一次模型把旧对话压成一段话,结果缓存起来下次复用
93+
3. **硬压缩**:只留最近几轮 + 一段总结,其他全删
94+
4. **后台自动触发**:用户无感
95+
96+
不同信息有不同的"保质期"——工具输出几轮后就没用了,但用户的需求描述整个会话都要保留。按保质期分级处理。NanoCoder 实现了前三层。
97+
98+
### 4. 子代理生成
99+
100+
复杂任务拆给独立 Agent 处理,各有自己的上下文窗口。一个有意思的设计决策:子 Agent 不能再创建子 Agent,防递归爆炸。
101+
102+
Claude Code 的 AgentTool 有 1397 行。NanoCoder 实现了核心逻辑,50 行。
103+
104+
### 5. 危险命令拦截
105+
106+
`rm -rf /`、fork bomb、`curl | bash` 这些在执行前就被拦下来。
107+
108+
### 6. 会话持久化
109+
110+
`/save` 存盘,`nanocoder -r session_id` 恢复。长任务可以随时中断、改天继续。
111+
112+
### 7. 系统提示词动态组装
113+
114+
不是写死的字符串。根据工作目录、OS、可用工具列表实时拼接。在不同项目里 Agent 的行为是不一样的。
115+
116+
---
117+
118+
## 怎么用
119+
120+
安装一行:
121+
122+
```bash
123+
pip install nanocoderagent
124+
```
125+
126+
选你的模型,任何 OpenAI 兼容 API 都行:
127+
128+
```bash
129+
# Kimi K2.5
130+
export OPENAI_API_KEY=你的key OPENAI_BASE_URL=https://api.moonshot.ai/v1
131+
nanocoder -m kimi-k2.5
132+
133+
# Claude Opus 4.6(通过 OpenRouter)
134+
export OPENAI_API_KEY=你的key OPENAI_BASE_URL=https://openrouter.ai/api/v1
135+
nanocoder -m anthropic/claude-opus-4-6
136+
137+
# DeepSeek V3
138+
export OPENAI_API_KEY=你的key OPENAI_BASE_URL=https://api.deepseek.com
139+
nanocoder -m deepseek-chat
140+
141+
# GPT-5 / Qwen 3.5 / Ollama 本地模型... 都行
142+
```
143+
144+
也可以当 Python 库用:
145+
146+
```python
147+
from nanocoder import Agent, LLM
148+
149+
llm = LLM(model="kimi-k2.5", api_key="...", base_url="https://api.moonshot.ai/v1")
150+
agent = Agent(llm=llm)
151+
response = agent.chat("找出项目里所有 TODO 注释")
152+
```
153+
154+
想加自定义工具的话大概 20 行代码,继承一个 `Tool` 基类就行。
155+
156+
---
157+
158+
## 谁适合用
159+
160+
**想搞懂 AI 编程 Agent 原理的开发者。** 1300 行,每个文件一屏看完。比读 51 万行源码或者看第三方教程效率高。
161+
162+
**想自己造轮子的团队。** Fork 下来就是一个完整的起点。加 MCP 支持、加权限系统、换成你们公司的内部模型,比从零开始快一个量级。我见过的最小的、完整可运行的编程 Agent 实现。
163+
164+
**做 AI Agent 方向的研究者和学生。** 每个核心设计模式都有可运行的代码,带着代码理解论文和架构设计,比看流程图强。
165+
166+
**用国产大模型做编程 Agent 的开发者。** Kimi K2.5、DeepSeek、Qwen 的 coding 能力已经很强了,缺一个好用的 Agent 壳来驱动它们。NanoCoder 就是这个壳。
167+
168+
如果你只是想要一个开箱即用的 AI 编程助手日常用,Claude Code、Cursor 或者 Aider 更适合。NanoCoder 的价值在于**你能读懂它、改造它、在上面造出自己的东西**
169+
170+
---
171+
172+
## 配套导读
173+
174+
代码之外,我还写了一套 7 篇的 Claude Code 架构导读,每篇围绕一个核心设计模式展开:
175+
176+
1. 从 51 万行说起:技术栈、目录结构、十大设计哲学
177+
2. 1729 行的 while(true):Agent 核心循环的全部细节
178+
3. 让 AI 安全地改你的代码:工具系统和搜索替换编辑
179+
4. 有限窗口,无限任务:四层上下文压缩的工程权衡
180+
5. 边想边做:StreamingToolExecutor 如何让工具执行零延迟
181+
6. 当一个 Claude 不够用:多 Agent 协作系统的三种模式
182+
7. Feature Flag 背后的秘密:44 个未发布功能(KAIROS、Buddy 宠物系统、Voice Mode……)
183+
184+
导读也在 GitHub 仓库的 article/ 目录下。
185+
186+
---
187+
188+
## 最后
189+
190+
51 万行源码的核心设计,1300 行 Python 复刻。7 个工具,33 个测试全过。
191+
192+
代码全在 GitHub 上,MIT 协议,fork 了随便改。搜 NanoCoder 或者 he-yufeng 就能找到。
193+
194+
觉得有用的话给个 Star,有问题评论区聊。

0 commit comments

Comments
 (0)