Claude Code 执行业务流程


一、五层架构总览

┌─────────────────────────────────────────┐
  Layer 1: Model (LLM)                   
  决策层:理解意图、推理、决定调用什么       
└──────────┬──────────────┬───────────────┘
            text + tool_use blocks
           
┌─────────────────────────────────────────┐
  Layer 2: Claude Code Harness (CLI)     
  编排层:收发API、权限控制、执行调度、状态管理│
└──────────┬──────────────┬───────────────┘
            执行工具调用
           
┌─────────────────────────────────────────┐
  Layer 3: Built-in Tools (25个)         
  原生能力:文件操作、搜索、Shell、子代理等  
   Skill 工具在这里 —— 它是一个特殊工具   
└──────────┬──────────────────────────────┘
            Skill 工具触发
           
┌─────────────────────────────────────────┐
  Layer 4: Skills (8个)                  
  本质是"动态注入的提示词包"               
  加载专业指令、上下文,可能注册额外工具     
└──────────┬──────────────────────────────┘
            MCP 协议
           
┌─────────────────────────────────────────┐
  Layer 5: MCP Servers (外部进程)         
  提供额外工具,通过 stdio/HTTP 通信       
  Harness  MCP 工具也注册给 Model       
└─────────────────────────────────────────┘

二、核心概念: Model 眼中只有 "Tools"

无论是 Bash、Skill、还是 MCP 工具,对 Model 来说都是扁平的 function call。 Model 不知道也不关心这些工具是谁提供的——它只看到一个工具列表(JSON Schema),它选择调用哪个,然后 Harness 负责路由到正确的实现。

Model 视角:
  tools: [
    Bash, Read, Write, Edit, Glob, Grep,
    WebFetch, WebSearch, Agent, Skill,
    TaskCreate, TaskUpdate, TaskList, TaskGet, TaskStop,
    EnterPlanMode, ExitPlanMode, CronCreate, CronDelete, CronList,
    EnterWorktree, ExitWorktree, ScheduleWakeup,
    AskUserQuestion, NotebookEdit,
    mcp__playwright__navigate,  ← 来自 MCP Server
    mcp__playwright__click,     ← 来自 MCP Server
    ...
  ]

三、完整执行链路示例: "测试登录页面"

3.1 总览

用户输入
  → Harness 构造请求发给 Model
    → Model 推理, 返回 tool_use
      → Harness 路由执行工具
        → 结果返回给 Model
          → Model 继续推理 → 返回下一个 tool_use 或 文本

3.2 逐步分析

Step 1: 用户输入 → Harness → Model
用户: "帮我测试 https://example.com/login 这个H5页面"

Harness 构造 API 请求发送给 Model,System Prompt 里包含所有可用的工具定义。下面是 Harness 发送给 Model 的完整 JSON Schema 定义:


1. Read — 文件读取
{
  "name": "Read",
  "description": "Reads a file from the local filesystem. Supports text, images (PNG/JPG/GIF/WebP), PDF, and Jupyter notebooks (.ipynb).",
  "input_schema": {
    "type": "object",
    "properties": {
      "file_path": {
        "type": "string",
        "description": "Absolute path to the file (required)"
      },
      "offset": {
        "type": "integer",
        "description": "Line number to start reading from"
      },
      "limit": {
        "type": "integer",
        "description": "Number of lines to read"
      },
      "pages": {
        "type": "string",
        "description": "Page range for PDFs, e.g. \"1-5\""
      }
    },
    "required": ["file_path"]
  }
}
2. Write — 文件写入
{
  "name": "Write",
  "description": "Writes a file to the local filesystem. Overwrites existing files. Use Edit for modifications.",
  "input_schema": {
    "type": "object",
    "properties": {
      "file_path": {
        "type": "string",
        "description": "Absolute path to the file (required, must be absolute)"
      },
      "content": {
        "type": "string",
        "description": "Content to write to the file (required)"
      }
    },
    "required": ["file_path", "content"]
  }
}
3. Edit — 精确字符串替换编辑
{
  "name": "Edit",
  "description": "Performs exact string replacements in existing files. Uses old_string matching to find and replace.",
  "input_schema": {
    "type": "object",
    "properties": {
      "file_path": {
        "type": "string",
        "description": "Absolute path to the file (required)"
      },
      "old_string": {
        "type": "string",
        "description": "Text to replace — must be unique in the file (required)"
      },
      "new_string": {
        "type": "string",
        "description": "Replacement text, must differ from old_string (required)"
      },
      "replace_all": {
        "type": "boolean",
        "description": "If true, replace all occurrences of old_string. Default: false"
      }
    },
    "required": ["file_path", "old_string", "new_string"]
  }
}
4. Glob — 文件名模式匹配
{
  "name": "Glob",
  "description": "Fast file pattern matching. Supports glob patterns like '**/*.js' or 'src/**/*.ts'.",
  "input_schema": {
    "type": "object",
    "properties": {
      "pattern": {
        "type": "string",
        "description": "The glob pattern to match files against (required)"
      },
      "path": {
        "type": "string",
        "description": "Directory to search in. If omitted, uses current working directory"
      }
    },
    "required": ["pattern"]
  }
}
5. Grep — 正则内容搜索 (基于 ripgrep)
{
  "name": "Grep",
  "description": "Powerful content search using ripgrep. Full regex support, file type filtering, and multiline matching.",
  "input_schema": {
    "type": "object",
    "properties": {
      "pattern": {
        "type": "string",
        "description": "Regular expression to search for (required)"
      },
      "path": {
        "type": "string",
        "description": "File or directory to search in. Defaults to current working directory"
      },
      "glob": {
        "type": "string",
        "description": "Glob filter for files, e.g. '*.js', '*.{ts,tsx}'"
      },
      "output_mode": {
        "type": "string",
        "enum": ["content", "files_with_matches", "count"],
        "description": "'content' shows matching lines; 'files_with_matches' shows file paths (default); 'count' shows match counts"
      },
      "-B": { "type": "number", "description": "Lines to show before each match (rg -B)" },
      "-A": { "type": "number", "description": "Lines to show after each match (rg -A)" },
      "-C": { "type": "number", "description": "Alias for context" },
      "context": { "type": "number", "description": "Lines to show before and after each match (rg -C)" },
      "-n": { "type": "boolean", "description": "Show line numbers. Default: true" },
      "-i": { "type": "boolean", "description": "Case insensitive search (rg -i)" },
      "-o": { "type": "boolean", "description": "Only matching parts (rg -o). Default: false" },
      "type": { "type": "string", "description": "File type filter: js, py, rust, go, java, etc." },
      "head_limit": { "type": "number", "description": "Limit output to first N lines. Default: 250" },
      "offset": { "type": "number", "description": "Skip first N entries before head_limit" },
      "multiline": { "type": "boolean", "description": "Enable multiline mode where . matches newlines. Default: false" }
    },
    "required": ["pattern"]
  }
}
6. Bash — Shell 命令执行
{
  "name": "Bash",
  "description": "Executes a bash command. Uses Unix shell syntax. Working directory persists between commands but shell state does not.",
  "input_schema": {
    "type": "object",
    "properties": {
      "command": {
        "type": "string",
        "description": "The command to execute (required)"
      },
      "timeout": {
        "type": "number",
        "description": "Optional timeout in milliseconds (max 600000 = 10 minutes)"
      },
      "description": {
        "type": "string",
        "description": "Clear, concise description of what this command does in active voice"
      },
      "run_in_background": {
        "type": "boolean",
        "description": "Run command in background, return immediately"
      },
      "dangerouslyDisableSandbox": {
        "type": "boolean",
        "description": "Dangerously override sandbox mode"
      }
    },
    "required": ["command"]
  }
}
7. Agent — 子代理
{
  "name": "Agent",
  "description": "Launch a new agent to handle complex, multi-step tasks. Available types: explore (read-only search), claude-code-guide (CLI/SDK/API help), general-purpose, plan (software architect), and more.",
  "input_schema": {
    "type": "object",
    "properties": {
      "description": {
        "type": "string",
        "description": "A short (3-5 word) description of the task (required)"
      },
      "prompt": {
        "type": "string",
        "description": "The task for the agent to perform (required)"
      },
      "subagent_type": {
        "type": "string",
        "description": "Type of specialized agent to use. Available: explore, claude-code-guide, general-purpose, plan, statusline-setup"
      },
      "model": {
        "type": "string",
        "enum": ["sonnet", "opus", "haiku"],
        "description": "Model override for this agent. Takes precedence over agent definition's model"
      },
      "run_in_background": {
        "type": "boolean",
        "description": "Run agent in background, notify on completion"
      },
      "isolation": {
        "type": "string",
        "enum": ["worktree"],
        "description": "Isolate agent in a temporary git worktree"
      }
    },
    "required": ["description", "prompt"]
  }
}
8. WebFetch — 网页抓取
{
  "name": "WebFetch",
  "description": "Fetches a URL, converts HTML to markdown, and processes it with an AI model. 15-minute cache.",
  "input_schema": {
    "type": "object",
    "properties": {
      "url": {
        "type": "string",
        "format": "uri",
        "description": "The URL to fetch (required). HTTP upgraded to HTTPS. Authenticated/private URLs WILL FAIL."
      },
      "prompt": {
        "type": "string",
        "description": "The prompt describing what information to extract from the page (required)"
      }
    },
    "required": ["url", "prompt"]
  }
}
9. WebSearch — 网络搜索
{
  "name": "WebSearch",
  "description": "Performs web searches and returns results as markdown links. Use for accessing information beyond Claude's knowledge cutoff.",
  "input_schema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "minLength": 2,
        "description": "The search query (required)"
      },
      "allowed_domains": {
        "type": "array",
        "items": { "type": "string" },
        "description": "Only include results from these domains"
      },
      "blocked_domains": {
        "type": "array",
        "items": { "type": "string" },
        "description": "Exclude results from these domains"
      }
    },
    "required": ["query"]
  }
}
10. AskUserQuestion — 向用户提问
{
  "name": "AskUserQuestion",
  "description": "Ask the user questions during execution. Supports single-select (2-4 options with optional previews) and multi-select.",
  "input_schema": {
    "type": "object",
    "properties": {
      "questions": {
        "type": "array",
        "minItems": 1,
        "maxItems": 4,
        "description": "Questions to ask the user (1-4)",
        "items": {
          "type": "object",
          "properties": {
            "question": { "type": "string", "description": "The complete question to ask. End with a question mark." },
            "header": { "type": "string", "description": "Short label displayed as chip/tag, max 12 chars. e.g. 'Auth method', 'Library'" },
            "options": {
              "type": "array",
              "minItems": 2,
              "maxItems": 4,
              "items": {
                "type": "object",
                "properties": {
                  "label": { "type": "string", "description": "Display text, 1-5 words" },
                  "description": { "type": "string", "description": "What choosing this option means" },
                  "preview": { "type": "string", "description": "Optional markdown preview for side-by-side comparison" }
                },
                "required": ["label", "description"]
              }
            },
            "multiSelect": { "type": "boolean", "description": "Allow multiple selections. Default: false" }
          },
          "required": ["question", "header", "options", "multiSelect"]
        }
      }
    },
    "required": ["questions"]
  }
}
11. EnterPlanMode — 进入计划模式
{
  "name": "EnterPlanMode",
  "description": "Transitions into plan mode for designing implementation approaches before writing code. Use for non-trivial implementation tasks.",
  "input_schema": {
    "type": "object",
    "properties": {},
    "required": []
  }
}
12. ExitPlanMode — 退出计划模式
{
  "name": "ExitPlanMode",
  "description": "Signals that the plan is complete and ready for user review/approval. Reads the plan from the plan file.",
  "input_schema": {
    "type": "object",
    "properties": {
      "allowedPrompts": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "tool": { "type": "string", "enum": ["Bash"] },
            "prompt": { "type": "string", "description": "Semantic description, e.g. 'run tests'" }
          },
          "required": ["tool", "prompt"]
        }
      }
    },
    "required": []
  }
}
13. TaskCreate — 创建任务
{
  "name": "TaskCreate",
  "description": "Creates a structured task in the task list for tracking complex multi-step work.",
  "input_schema": {
    "type": "object",
    "properties": {
      "subject": {
        "type": "string",
        "description": "A brief, actionable title in imperative form, e.g. 'Fix authentication bug' (required)"
      },
      "description": {
        "type": "string",
        "description": "What needs to be done (required)"
      },
      "activeForm": {
        "type": "string",
        "description": "Present continuous form shown in spinner, e.g. 'Running tests'"
      },
      "metadata": {
        "type": "object",
        "description": "Arbitrary metadata to attach to the task"
      }
    },
    "required": ["subject", "description"]
  }
}
14. TaskGet — 获取任务详情
{
  "name": "TaskGet",
  "description": "Retrieves a task by ID, including description, status, and dependencies.",
  "input_schema": {
    "type": "object",
    "properties": {
      "taskId": {
        "type": "string",
        "description": "The ID of the task to retrieve (required)"
      }
    },
    "required": ["taskId"]
  }
}
15. TaskUpdate — 更新任务状态
{
  "name": "TaskUpdate",
  "description": "Updates a task's status, subject, description, dependencies, or owner.",
  "input_schema": {
    "type": "object",
    "properties": {
      "taskId": { "type": "string", "description": "The ID of the task to update (required)" },
      "subject": { "type": "string", "description": "New subject" },
      "description": { "type": "string", "description": "New description" },
      "activeForm": { "type": "string", "description": "Present continuous form for spinner" },
      "status": {
        "type": "string",
        "enum": ["pending", "in_progress", "completed", "deleted"],
        "description": "New status. 'deleted' permanently removes the task"
      },
      "addBlocks": {
        "type": "array",
        "items": { "type": "string" },
        "description": "Task IDs that this task blocks"
      },
      "addBlockedBy": {
        "type": "array",
        "items": { "type": "string" },
        "description": "Task IDs that block this task"
      },
      "owner": { "type": "string", "description": "New owner for the task" },
      "metadata": { "type": "object", "description": "Metadata keys to merge; set a key to null to delete it" }
    },
    "required": ["taskId"]
  }
}
16. TaskList — 列出所有任务
{
  "name": "TaskList",
  "description": "Lists all tasks with id, subject, status, owner, and blockedBy. Use to see progress and find available work.",
  "input_schema": {
    "type": "object",
    "properties": {},
    "required": []
  }
}
17. TaskStop — 停止后台任务
{
  "name": "TaskStop",
  "description": "Stops a running background task (shell, agent, or remote session) by its ID.",
  "input_schema": {
    "type": "object",
    "properties": {
      "task_id": {
        "type": "string",
        "description": "The ID of the background task to stop"
      }
    },
    "required": ["task_id"]
  }
}
18. TaskOutput — 获取后台任务输出
{
  "name": "TaskOutput",
  "description": "Retrieves output from a running or completed background task. Supports blocking wait with timeout.",
  "input_schema": {
    "type": "object",
    "properties": {
      "task_id": { "type": "string", "description": "The task ID to get output from (required)" },
      "block": { "type": "boolean", "description": "Whether to wait for completion. Default: true" },
      "timeout": { "type": "number", "description": "Max wait time in ms. Default: 30000", "maximum": 600000 }
    },
    "required": ["task_id"]
  }
}
19. CronCreate — 创建定时任务
{
  "name": "CronCreate",
  "description": "Schedule a prompt to be enqueued at future times. Uses standard 5-field cron in local timezone. Supports one-shot and recurring.",
  "input_schema": {
    "type": "object",
    "properties": {
      "cron": {
        "type": "string",
        "description": "Standard 5-field cron expression: M H DoM Mon DoW. e.g. '*/5 * * * *' for every 5 minutes (required)"
      },
      "prompt": {
        "type": "string",
        "description": "The prompt to enqueue at each fire time (required)"
      },
      "recurring": {
        "type": "boolean",
        "description": "true = fire on every match (recurring, expires after 7 days). false = fire once then auto-delete. Default: true"
      },
      "durable": {
        "type": "boolean",
        "description": "true = persist to .claude/scheduled_tasks.json, survive restarts. false = in-memory only. Default: false"
      }
    },
    "required": ["cron", "prompt"]
  }
}
20. CronDelete — 删除定时任务
{
  "name": "CronDelete",
  "description": "Cancel a cron job previously scheduled with CronCreate. Removes from persistence store.",
  "input_schema": {
    "type": "object",
    "properties": {
      "id": {
        "type": "string",
        "description": "Job ID returned by CronCreate (required)"
      }
    },
    "required": ["id"]
  }
}
21. CronList — 列出定时任务
{
  "name": "CronList",
  "description": "List all cron jobs scheduled via CronCreate, both durable (.claude/scheduled_tasks.json) and session-only.",
  "input_schema": {
    "type": "object",
    "properties": {},
    "required": []
  }
}
22. ScheduleWakeup — 动态循环调度
{
  "name": "ScheduleWakeup",
  "description": "Schedule next wake-up for /loop dynamic mode. Works with autonomous-loop-dynamic sentinel.",
  "input_schema": {
    "type": "object",
    "properties": {
      "delaySeconds": {
        "type": "number",
        "description": "Seconds from now to wake up. Clamped to [60, 3600] (required)"
      },
      "reason": {
        "type": "string",
        "description": "One short sentence explaining the chosen delay (required)"
      },
      "prompt": {
        "type": "string",
        "description": "The /loop input to fire on wake-up. Use '<<autonomous-loop-dynamic>>' for autonomous loops (required)"
      }
    },
    "required": ["delaySeconds", "reason", "prompt"]
  }
}
23. EnterWorktree — 进入 Git Worktree
{
  "name": "EnterWorktree",
  "description": "Creates an isolated git worktree on a new branch and switches the session into it. Base ref configurable via worktree.baseRef setting.",
  "input_schema": {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "description": "Optional name for new worktree. Segments: letters, digits, dots, underscores, dashes; max 64 chars"
      },
      "path": {
        "type": "string",
        "description": "Path to existing worktree to enter (must appear in 'git worktree list'). Mutually exclusive with name."
      }
    },
    "required": []
  }
}
24. ExitWorktree — 退出 Git Worktree
{
  "name": "ExitWorktree",
  "description": "Exit a worktree session created by EnterWorktree. Restores session to original working directory.",
  "input_schema": {
    "type": "object",
    "properties": {
      "action": {
        "type": "string",
        "enum": ["keep", "remove"],
        "description": "'keep' leaves worktree on disk; 'remove' deletes both worktree and branch (required)"
      },
      "discard_changes": {
        "type": "boolean",
        "description": "Required true when action='remove' and worktree has uncommitted changes. Default: false"
      }
    },
    "required": ["action"]
  }
}
25. NotebookEdit — Jupyter Notebook 编辑
{
  "name": "NotebookEdit",
  "description": "Replaces the contents of a specific cell in a Jupyter notebook (.ipynb). Supports replace, insert, and delete edit modes.",
  "input_schema": {
    "type": "object",
    "properties": {
      "notebook_path": {
        "type": "string",
        "description": "Absolute path to the .ipynb file (required)"
      },
      "cell_id": {
        "type": "string",
        "description": "ID of the cell to edit. For insert: inserted after this cell; omitted = beginning"
      },
      "new_source": {
        "type": "string",
        "description": "New source for the cell (required)"
      },
      "cell_type": {
        "type": "string",
        "enum": ["code", "markdown"],
        "description": "Cell type. Required for insert mode"
      },
      "edit_mode": {
        "type": "string",
        "enum": ["replace", "insert", "delete"],
        "description": "The type of edit. Default: replace"
      }
    },
    "required": ["notebook_path", "new_source"]
  }
}
26. Skill — 技能调用 (原生内置)
{
  "name": "Skill",
  "description": "Execute a skill within the main conversation. Skills provide specialized capabilities and domain knowledge.",
  "input_schema": {
    "type": "object",
    "properties": {
      "skill": {
        "type": "string",
        "description": "The exact name of an available skill (no leading slash). Available: playwright-cli, update-config, keybindings-help, simplify, fewer-permission-prompts, loop, claude-api, init, review, security-review (required)"
      },
      "args": {
        "type": "string",
        "description": "Optional arguments for the skill"
      }
    },
    "required": ["skill"]
  }
}
MCP — 动态 MCP 工具 (示例)

MCP 工具不由 Claude Code 硬编码定义,而是由外部 MCP Server 在运行时注册。以下展示一个典型的 Playwright MCP Server 注册的工具:

{
  "name": "mcp__playwright__navigate",
  "description": "Navigate to a URL",
  "input_schema": {
    "type": "object",
    "properties": {
      "url": { "type": "string", "description": "The URL to navigate to" }
    },
    "required": ["url"]
  }
}
{
  "name": "mcp__playwright__screenshot",
  "description": "Take a screenshot of the current page or an element",
  "input_schema": {
    "type": "object",
    "properties": {
      "name": { "type": "string", "description": "Name of the screenshot file" },
      "fullPage": { "type": "boolean", "description": "Capture full scrollable page" },
      "element": { "type": "string", "description": "Human-readable element description used to obtain permission to interact with the element" },
      "ref": { "type": "string", "description": "Exact target element reference from the page snapshot" }
    },
    "required": ["name"]
  }
}
{
  "name": "mcp__playwright__click",
  "description": "Perform click on a web page element",
  "input_schema": {
    "type": "object",
    "properties": {
      "element": { "type": "string", "description": "Human-readable element description" },
      "ref": { "type": "string", "description": "Exact target element reference" }
    },
    "required": ["element", "ref"]
  }
}
{
  "name": "mcp__playwright__fill",
  "description": "Fill a form field with text",
  "input_schema": {
    "type": "object",
    "properties": {
      "element": { "type": "string", "description": "Human-readable form field description" },
      "ref": { "type": "string", "description": "Exact target element reference" },
      "text": { "type": "string", "description": "Text to fill into the field" }
    },
    "required": ["element", "ref", "text"]
  }
}

以上 26 个原生工具 + N 个动态 MCP 工具的 JSON Schema 就是 Harness 在 Step 1 发送给 Model 的 System Prompt 中的工具定义。


★ 关键疑问:为什么 Model 需要完整的 input_schema?只给 name + description 不够吗?

答案:不够。因为 Model 不仅要选工具,还要生成调用参数。

对比以下两种理解:

❌ 错误理解:
   Model 只输出 → "我想用 Read 工具"
   Harness 负责 → 自己去拼参数调用

✅ 正确理解(Anthropic API 真实行为):
   Model 输出完整的 tool_use 块 →
   {
     "type": "tool_use",
     "id": "toolu_abc123",
     "name": "Read",
     "input": {                          ← 这部分是 Model 生成的!
       "file_path": "/some/file.ts",
       "offset": 100,
       "limit": 50
     }
   }

如果 Model 不知道 input_schema,它就无法知道:

  • 参数名是 file_path 还是 path 还是 filename
  • offsetnumber 还是 string
  • 哪些参数必填(required),哪些可选?
  • output_mode 有哪些合法枚举值("content" / "files_with_matches" / "count")?

结论:三个字段各司其职:

字段模型用它做什么
name"我要调用哪个工具"
description"这个工具能做什么?何时应该用它?"
input_schema"该怎么传参?参数名、类型、必填项、枚举值——全部由 input_schema 告知"

★ 真实的 Anthropic API 请求格式

以下是 Claude Code Harness 实际发给 Model API 的 HTTP 请求结构(基于 Anthropic Messages API 规范):

POST https://api.deepseek.com/anthropic/v1/messages
{
  "model": "deepseek-v4-pro",
  "max_tokens": 16000,
  "system": [
    {
      "type": "text",
      "text": "你是 Claude Code,Anthropic 的官方 CLI 工具...(大量 System Prompt)..."
    }
  ],
  "tools": [
    {
      "name": "Read",
      "description": "Reads a file from the local filesystem...",
      "input_schema": {
        "type": "object",
        "properties": {
          "file_path": {
            "type": "string",
            "description": "Absolute path to the file to read"
          },
          "offset": {
            "type": "integer",
            "description": "Line number to start reading from"
          },
          "limit": {
            "type": "integer",
            "description": "Number of lines to read"
          }
        },
        "required": ["file_path"]
      }
    },
    {
      "name": "Bash",
      "description": "Executes a bash command...",
      "input_schema": { ... }
    },
    ... (26 个原生工具 + MCP 动态工具)
  ],
  "messages": [
    {
      "role": "user",
      "content": "帮我测试 https://example.com/login 这个H5页面"
    }
  ]
}

Model 返回的响应:

{
  "id": "msg_abc123...",
  "model": "deepseek-v4-pro",
  "stop_reason": "tool_use",
  "role": "assistant",
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_001",
      "name": "Skill",
      "input": {
        "skill": "playwright-cli"
      }
    }
  ]
}

Harness 执行完 Skill 后,把结果返回给 Model,Model 继续生成:

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_001",
      "content": "playwright-cli skill loaded. Available MCP tools: mcp__playwright__navigate, mcp__playwright__click, ..."
    }
  ]
}

Model 新一轮响应(现在有了 Playwright 知识):

{
  "stop_reason": "tool_use",
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_002",
      "name": "mcp__playwright__navigate",
      "input": {
        "url": "https://example.com/login"
      }
    }
  ]
}

这个循环持续进行:Model 生成 tool_use → Harness 执行 → 返回 tool_result → Model 推理 → 下一个 tool_use... 直到 Model 认为任务完成,返回纯文本:

{
  "stop_reason": "end_turn",
  "content": [
    {
      "type": "text",
      "text": "登录页面测试完成。页面加载正常,登录按钮可见,表单验证工作正常..."
    }
  ]
}

Step 2: Model 决策 → 返回 tool_use

Model 理解用户想要浏览器自动化测试,但它本身没有 Playwright 知识。它决定先加载 skill:

{
  "role": "assistant",
  "content": [
    {
      "type": "tool_use",
      "name": "Skill",
      "input": { "skill": "playwright-cli" }
    }
  ]
}
Step 3: Harness 收到 tool_use → 路由执行
Harness 分析:
"tool_use name=Skill → 这不是 Bash/Read/Write,这是 Skill 工具"
→ 加载 playwright-cli 的提示词包
→ 把 Playwright 使用说明注入到下一次请求的 System Prompt
Step 4: Model 现在有了 Playwright 知识 → 调用浏览器工具

Model 在新的 System Prompt 中看到:

你可以使用 @playwright/test 进行浏览器测试。
可用的 MCP 工具有:
- mcp__playwright__navigate: 导航到 URL
- mcp__playwright__click: 点击元素
- mcp__playwright__screenshot: 截图
...

Model 决定导航到目标页面:

{
  "type": "tool_use",
  "name": "mcp__playwright__navigate",
  "input": { "url": "https://example.com/login" }
}
Step 5: Harness → MCP Server
Harness 分析:
"tool_use name 以 mcp__playwright__ 开头
 → 这是 Playwright MCP Server 的工具"
→ 通过 stdio/HTTP 发送给 Playwright MCP Server
→ Playwright 进程执行浏览器操作
→ 返回结果: { "status": "ok", "page_title": "Login" }
Step 6: 结果回传 → Model 继续推理
Model 收到结果: "页面标题是 Login,已加载完成"
Model: "好的,现在需要截图看看页面状态"
      → { "type": "tool_use", "name": "mcp__playwright__screenshot", ... }
      → 分析截图
      → "登录按钮可见,开始填写表单"
      → { "type": "tool_use", "name": "mcp__playwright__fill", ... }
      → { "type": "tool_use", "name": "mcp__playwright__click", ... }
      → "登录成功,跳转到首页,任务完成"

这个循环持续进行,直到 Model 认为任务完成,返回纯文本总结。


四、各层扭转关系图

                     ┌──────────┐
                     │  Model   │  ← 唯一的"大脑",只做推理和决策
                     └────┬─────┘
                          │ 说出它想做什么(tool_use)
                          ▼
               ┌────────────────────┐
               │  Claude Code       │  ← 翻译官 + 执行器
               │  Harness           │     路由 tool_use 到正确的实现
               └───┬───┬───┬───┬───┘
                   │   │   │   │
          ┌────────┘   │   │   └──────────┐
          ▼            ▼   ▼              ▼
    ┌─────────┐  ┌─────────┐  ┌──────────────┐
    │原生Tools│  │ Skill   │  │ MCP Server   │
    │Bash     │  │(提示词  │  │(外部进程)     │
    │Read     │  │ 注入器) │  │Playwright等   │
    │Write    │  │         │  │              │
    │...      │  │触发后给  │  │提供额外工具    │
    └─────────┘  │Model更多│  └──────────────┘
                 │知识     │
                 └─────────┘

五、Tool / Skill / MCP 的本质区别

层级本质实现方式Model 怎么看
Tool原生能力编译进 claude.exe就是普通 function call
Skill动态提示词注入Harness 加载专用提示词,注入到 System Prompt先调用 Skill 工具,然后"变聪明"了
MCP外部工具扩展独立进程,stdio/HTTP 通信前缀 mcp__ 的普通 function call

Skill 的特殊性

Skill 本身是一个 Tool(叫 Skill),但它独特在:

  1. Model 调用 Skill(skill="playwright-cli")
  2. Harness 不执行实际动作,而是把 Playwright 的完整使用说明注入下一次的 System Prompt
  3. Model 在下一轮中获得了 Playwright 知识,然后才开始调用 MCP 浏览器工具

Skill = 热补丁式的知识注入,不增加新 tool,但让 Model 更会用现有 tool。


六、原生 Tools 完整清单 (25个)

文件操作

工具用途
Read读取文件(文本/图片/PDF/Notebook)
Write写入/创建文件
Edit精确字符串替换编辑

搜索

工具用途
Glob文件名模式匹配搜索
Grep基于 ripgrep 的内容搜索

命令执行

工具用途
Bash执行 Shell 命令
TaskOutput获取后台任务输出
TaskStop停止后台任务

代理与协作

工具用途
Agent派生子代理执行复杂任务

任务管理

工具用途
TaskCreate创建任务
TaskGet获取任务详情
TaskUpdate更新任务状态
TaskList列出所有任务

计划模式

工具用途
EnterPlanMode进入计划模式
ExitPlanMode退出计划模式

用户交互

工具用途
AskUserQuestion向用户提问(单选/多选)

Web

工具用途
WebFetch抓取网页内容并处理
WebSearch网络搜索

定时任务

工具用途
CronCreate创建定时任务
CronDelete删除定时任务
CronList列出定时任务
ScheduleWakeup/loop 动态模式调度

隔离环境

工具用途
EnterWorktree进入 git worktree 隔离环境
ExitWorktree退出 git worktree

MCP 协议

工具用途
ListMcpResources列出 MCP 资源
ReadMcpResource读取 MCP 资源
McpInput (动态)MCP 工具调用(前缀 mcp__

Notebook

工具用途
NotebookEdit编辑 Jupyter Notebook

七、原生 Skills 完整清单 (8个)

Skill用途
playwright-cli浏览器自动化测试(H5 测试策略)
update-config修改 settings.json 配置
keybindings-help自定义键盘快捷键
simplify代码审查与优化
fewer-permission-prompts减少权限提示
loop循环执行任务
claude-apiClaude API / Anthropic SDK 开发调试
init初始化 CLAUDE.md
reviewPR 审查
security-review安全审查

八、一句话总结

Model 永远是说"我要做什么"的角色;Claude Code Harness 是"怎么做"的执行者;Tools/Skills/MCP 是实现能力的三层提供方。Skill 本质是动态提示词注入,MCP 本质是外部工具扩展。对 Model 而言,它们都是扁平的 function call 列表。