Claude Code 执行业务流程(附上:skills、mcp、tool、funsion_call本质是什么)
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? offset是number还是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),但它独特在:
- Model 调用
Skill(skill="playwright-cli") - Harness 不执行实际动作,而是把 Playwright 的完整使用说明注入下一次的 System Prompt
- 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-api | Claude API / Anthropic SDK 开发调试 |
init | 初始化 CLAUDE.md |
review | PR 审查 |
security-review | 安全审查 |
八、一句话总结
Model 永远是说"我要做什么"的角色;Claude Code Harness 是"怎么做"的执行者;Tools/Skills/MCP 是实现能力的三层提供方。Skill 本质是动态提示词注入,MCP 本质是外部工具扩展。对 Model 而言,它们都是扁平的 function call 列表。