ClaudeCode原理分析
AI
2026-01-15 4028字

claude-code是一个终端编程的工具,非常强大能独立的完成独立软件的开发,最近提出的skill的概念也很强,让模型熟练掌握一项技能之后再去做事,能打到事半功倍的效果

learn-claude-code是大佬通过反编译claude-code的源码,对claude-code的整体设计有一定见解后写的一个能让大家理解claude-code原理的项目。项目从一个循环调用工具的模型的观点出发,循序渐进,一个版本引入一个claude-code的核心设计,让你一步步深入,了解claude-code的全貌。

复杂能力能从简单规则中涌现

v0的版本,作者通过bash工具和模型的结合达到能分析整个项目的需求,核心代码如下:

while True:
    response = model(messages, tools)
    if response.stop_reason != "tool_use":
        return response.text
    results = execute(response.tool_calls)
    messages.append(results)

通过不断调用工具来响应模型的分析结果,直到模型得到全部的信息来回答用户的问题。真正调用工具的不是模型是模型输出对应的工具需要的参数,如需要使用工具就在参数中填加“tool_use”,然后在输出命令如“find -name *.py”,最后的执行是终端。终端检测到tool_use的参数后,终端来调用独立的bash来执行这个指令。这个是整个claude-code的主逻辑,后续的版本讲围绕该代码进行优化。

给模型工具,让它工作

v1版本新增了一些工具扩展了终端的能力,首先需要在prompt描述你的能力,如下这里新增了读取文件的能力:


TOOLS = [
    # Tool 1: Bash - The gateway to everything
    # Can run any command: git, npm, python, curl, etc.
    {
        "name": "bash",
        "description": "Run a shell command. Use for: ls, find, grep, git, npm, python, etc.",
        "input_schema": {
            "type": "object",
            "properties": {
                "command": {
                    "type": "string",
                    "description": "The shell command to execute"
                }
            },
            "required": ["command"],
        },
    },

    # Tool 2: Read File - For understanding existing code
    # Returns file content with optional line limit for large files
    {
        "name": "read_file",
        "description": "Read file contents. Returns UTF-8 text.",
        "input_schema": {
            "type": "object",
            "properties": {
                "path": {
                    "type": "string",
                    "description": "Relative path to the file"
                },
                "limit": {
                    "type": "integer",
                    "description": "Max lines to read (default: all)"
                },
            },
            "required": ["path"],
        },
    },
]

新增工具后需要实现该工具的代码,如下:

def run_read(path: str, limit: int = None) -> str:
    """
    Read file contents with optional line limit.

    For large files, use limit to read just the first N lines.
    Output truncated to 50KB to prevent context overflow.
    """
    try:
        text = safe_path(path).read_text()
        lines = text.splitlines()

        if limit and limit < len(lines):
            lines = lines[:limit]
            lines.append(f"... ({len(text.splitlines()) - limit} more lines)")

        return "\n".join(lines)[:50000]

    except Exception as e:
        return f"Error: {e}"

在这个版本中,由于模型来控制整个循环,当没有工具调用后结束整个流程,工具的使用记录和模型的回答都一次增加到history后面,工具使用的结果给模型反馈推动模型持续处理直到解决问题。

适当的约束是赋能

上面的流程可以工作,但是对于复杂的任务,模型会失去方向,如让它“总结代码,重构代码,补充测试”等,模型没有显式的规划,它会忘记步骤失去焦点。

所以在v2版本中,新增了“TODO工具”,来改变Agent的工作方式,以前要做什么在模型的脑子中,现在让它展示出来。

输入:
  [x] 重构认证(已完成)
  [>] 添加测试(进行中)
  [ ] 更新文档(待办)

返回:
  "[x] 重构认证
   [>] 添加测试
   [ ] 更新文档
   (1/3 已完成)"

模型看到自己的计划,更新它,带着上下文继续。对于列出步骤的约束也很重要,它就像工作列表的护栏,防止异常和崩溃

规则 原因
最多 20 条 防止无限列表
只能一个进行中 强制聚焦
必填字段 结构化输出

好的约束不是限制,而是脚手架。Todo 的约束(最大条目、只能一个进行中)赋能了(可见计划、追踪进度)。

Agent 设计中的模式:

分而治之,保持聚焦

v3 引入的子代理(subagent / Task)机制,是对 v0–v2 线性历史增长问题的直接回应:当探索、规划和实现需要各自独立的上下文时,单一 Agent 的连续对话会把无关内容堆积进历史,导致忘记、混淆或失焦。

把每个子任务交给一个“干净”的短期子代理处理,子代理有自己的系统提示、受限工具集合与独立的会话历史,完成后只把最终摘要或结果返回给主代理。代码如下

def run_task(description, prompt, agent_type):
    config = AGENT_TYPES[agent_type]
    sub_system = f"You are a {agent_type} subagent.\n{config['prompt']}"
    sub_tools = get_tools_for_agent(agent_type)
    sub_messages = [{"role": "user", "content": prompt}]

    while True:
        response = client.messages.create(model=MODEL, system=sub_system, messages=sub_messages, tools=sub_tools)
        if response.stop_reason != "tool_use":
            break
        # 执行工具调用并把结果追加到 sub_messages

    return extract_final_text(response)

在进行任务处理时,采用分而治之的策略,将探索、规划和实现等过程在子代理中独立进行,以避免污染主代理的历史记录,使主代理能够始终保持关注核心逻辑和目标;同时,子代理设计遵循最小权限原则以保障安全与审计的可控性,并通过输出抽象化的方式,仅返回关键结论或补丁摘要,而不是大量原始数据或文件内容,从而提升结果清晰性减少成本。

需要注意的是对子代理应设定运行预算,包括工具调用次数、执行时间和步骤上限,以防止资源过度消耗或无限循环;同时,禁止子代理创建新任务,避免引发任务递归膨胀;此外,子代理输出的结果需具备可验证性,即包含可复现的命令或文件路径,便于主代理或人类进行审查与确认。

把知识从参数搬到文件

v3 解决了「如何分工」,而 v4 关注模型「如何知道」:把专业知识从模型参数外化到文件系统是 Skills 机制的核心。将知识以可编辑、可版本化的 SKILL.md 存储,按需注入对话历史,既可维护也利于审计。

要点概览:

Skill 的结构与使用:

实现要点(精要):

实践建议: