- Remove all reverse-engineered Claude Code source code - Replace with 100% original educational content from mini-claude-code - Add clear disclaimer: independent project, not affiliated with Anthropic - 5 progressive agent implementations (v0-v4, ~1100 lines total) - Include agent-builder skill for teaching agent construction - Bilingual documentation (EN + ZH) This repository now focuses purely on teaching how modern AI agents work through original, from-scratch implementations. Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
7.4 KiB
mini Claude Code v3:用 150 行代码揭开 Subagent 的神秘面纱
v2 版本让模型学会了"做计划"——通过 Todo 工具把任务显式拆解、逐项推进。但当任务规模再大一些,比如"探索整个代码库然后重构认证模块",单一代理就会陷入上下文膨胀的泥潭:探索时的大量文件内容、重构时的代码细节,全部堆在一个对话里,模型的注意力被稀释,效果急剧下降。
Claude Code 的解法是 Task 工具——让主代理像项目经理一样,把子任务派发给专门的"子代理"(Subagent),各自独立完成后再汇报结果。这套机制在 Kode Agent CLI里也有完整实现,而 v3 版 mini Claude Code 则用最精简的方式复现了它的核心:约 150 行新增代码,还原核心机制。
本次完整教学代码地址:https://github.com/shareAI-lab/Mini_Claude_Code
1. 具体做了什么?
1.1 Agent 类型注册表
AGENT_TYPES = {
"explore": {
"description": "Fast read-only agent for exploring codebases...",
"tools": ["bash", "read_file"], # 只读工具
"system_prompt": "You are an exploration agent..."
},
"code": {
"tools": "*", # 全部工具
"system_prompt": "You are a coding agent..."
},
"plan": {
"tools": ["bash", "read_file"],
"system_prompt": "You are a planning agent..."
},
}
每种代理类型定义三件事:
- 什么时候用(description):写进 Task 工具描述,让主代理知道何时派发
- 能用什么工具(tools):白名单机制,explore 只能读不能写
- 怎么工作(system_prompt):代理专属指令,聚焦单一职责
1.2 Task 工具
{
"name": "Task",
"input_schema": {
"description": "短描述(3-5 词)",
"prompt": "详细指令",
"subagent_type": "explore | code | plan"
}
}
主代理调用 Task 时,只需指定代理类型和任务描述,剩下的全部由框架处理。
1.3 子代理执行核心(run_task)
这是整个机制的核新,核心逻辑只有 5 步:
def run_task(inp, depth=0):
# 1. 构造专属 system prompt
sub_system = f"You are a {agent_type} subagent...\n{agent_config['system_prompt']}"
# 2. 过滤可用工具
sub_tools = get_tools_for_agent(agent_type) # explore 只拿 bash + read_file
# 3. 创建隔离的消息历史(关键!)
sub_messages = [{"role": "user", "content": prompt}]
# 4. 递归调用同一个 query 循环
result_messages = query(sub_messages, sub_system, sub_tools, silent=True)
# 5. 提取最终文本返回给主代理
return extract_final_text(result_messages)
隔离消息历史是灵魂:子代理看不到主对话的任何内容,也不会污染主对话。它执行完毕后,只有最终总结文本被返回——就像员工提交的工作报告,而不是把所有草稿都堆到老板桌上。
1.4 Kode 风格的进度显示
子代理执行时,内部的工具调用不会打印到主聊天区,而是用单行进度实时更新:
@ Task(explore: 探索代码库)...
| Read(README.md) (+3 tool uses, 2.1s) <- 实时刷新
| completed: 8 tool calls in 15.2s <- 最终摘要
这在v3代码中通过 silent 参数 + SubagentProgress 类实现:子代理的 query 循环不打印任何内容,而是把工具调用信息发送给进度追踪器,由它负责覆盖更新同一行。
2. 背后的思想
分而治之 + 最小知识原则
-
上下文隔离解决注意力稀释
探索代码库可能需要读 20 个文件,但重构模块只需要知道"哪些文件和认证相关"。如果所有内容都堆在一个对话里,模型很快就会"忘记"前面的内容。子代理机制让每个子任务拥有干净的上下文窗口,专注做好一件事。
-
工具白名单实现职责分离
explore 代理只能读不能写,code 代理才有写权限。这不是为了"安全"(虽然也有帮助),而是为了引导模型行为:当模型知道自己只有只读工具时,它就不会尝试"顺手改一下",而是专注于信息收集。
-
递归复用而非重复实现
子代理用的是同一个
query()函数,只是参数不同。这意味着:- 工具执行逻辑共享
- 错误处理一致
- 未来扩展(如添加新工具)自动生效
Claude Code、Kode 的设计也是如此:agent loop 被主代理和子代理共用(但隔离用各自的Context、tools)
-
结果抽象而非细节透传
子代理可能调用了 105 次工具、读了 35 个文件,但返回给主代理的只是一段详细总结文本。主代理不需要知道这些细节,它只关心"探索的结论是什么"。这就像公司里的汇报机制:CTO 不需要看每个工程师的代码提交记录,只需要看项目进度报告。
3. 与 Claude Code 、 Kode CLI的对比
| 机制 | Claude Code 、 Kode CLI | mini Claude Code v3 |
|---|---|---|
| Agent Registry | AgentConfig (type, tools, prompt, model, forkContext) | AGENT_TYPES dict |
| Task Schema | description, prompt, subagent_type, model, resume, run_in_background | description, prompt, subagent_type |
| Tool Filtering | 白名单 + 黑名单 | 白名单 |
| 消息隔离 | 独立 messages[] | 独立 sub_messages[] |
| 进度显示 | 折叠式进度面板 | 单行实时刷新 |
| 后台执行 | run_in_background + TaskOutput | 省略(同步执行) |
| Resume | transcript 存储恢复 | 省略 |
| forkContext | 可传递父对话上下文 | 省略 |
省略的功能(后台执行、Resume、forkContext)都是高级特性,不影响理解子代理的核心原理。v3 的目标是用最少代码展示最关键机制。
4. 典型使用场景
场景一:大型代码库探索
用户:帮我理解这个项目的架构
主代理:我来派一个探索子代理...
@ Task(explore: 分析项目架构)...
| completed: 12 tool calls in 18.3s
根据探索结果,这个项目是一个...
场景二:规划后执行
用户:重构用户认证模块
主代理:
1. 先派 plan 代理分析现有代码
@ Task(plan: 分析认证模块)...
2. 根据计划,派 code 代理逐步实现
@ Task(code: 重构 auth.py)...
@ Task(code: 更新测试用例)...
场景三:并行探索(概念)
主代理同时派出多个 explore 子代理,分别探索不同目录
(当前 v3 是同步执行,但机制上完全支持并行)
5. 三部曲回顾
| 版本 | 核心主题 | 新增代码 | 关键洞察 |
|---|---|---|---|
| v1 | Model as Agent | ~400 行 | 模型是 80%,代码只是工具循环的载体 |
| v2 | 结构化规划 | ~170 行 | 用 Todo 工具把模型"拴"在工作流里 |
| v3 | 分而治之 | ~150 行 | 子代理隔离上下文,专注单一职责 |
三个版本加起来不到 900 行 Python,却覆盖了 Claude Code 最核心的设计思想:
- 工具循环:模型持续调用工具直到任务完成
- 结构化约束:用数据结构(Todo)引导模型行为
- 层级委派:复杂任务拆解为子代理独立执行
这就是"Model as Agent"的全部奥秘——没有魔法,只有清晰的工程设计。
完整代码见仓库 v3_subagent.py。如果你想要生产级实现,欢迎使用 Kode。