CrazyBoyM 85f44c358a Complete rewrite: original educational content only
- 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>
2025-12-31 07:01:42 +08:00

7.4 KiB
Raw Blame History

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. 背后的思想

分而治之 + 最小知识原则

  1. 上下文隔离解决注意力稀释

    探索代码库可能需要读 20 个文件,但重构模块只需要知道"哪些文件和认证相关"。如果所有内容都堆在一个对话里,模型很快就会"忘记"前面的内容。子代理机制让每个子任务拥有干净的上下文窗口,专注做好一件事。

  2. 工具白名单实现职责分离

    explore 代理只能读不能写code 代理才有写权限。这不是为了"安全"(虽然也有帮助),而是为了引导模型行为:当模型知道自己只有只读工具时,它就不会尝试"顺手改一下",而是专注于信息收集。

  3. 递归复用而非重复实现

    子代理用的是同一个 query() 函数,只是参数不同。这意味着:

    • 工具执行逻辑共享
    • 错误处理一致
    • 未来扩展(如添加新工具)自动生效

    Claude Code、Kode 的设计也是如此agent loop 被主代理和子代理共用但隔离用各自的Context、tools

  4. 结果抽象而非细节透传

    子代理可能调用了 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 最核心的设计思想:

  1. 工具循环:模型持续调用工具直到任务完成
  2. 结构化约束用数据结构Todo引导模型行为
  3. 层级委派:复杂任务拆解为子代理独立执行

这就是"Model as Agent"的全部奥秘——没有魔法,只有清晰的工程设计


完整代码见仓库 v3_subagent.py。如果你想要生产级实现,欢迎使用 Kode