Claude Code只会用不会讲?→ 三层架构拆解+工具调用循环7步轨迹+40行代码手写MCP Server
Claude Code 深度拆解:Agent 循环与 MCP 扩展
问题场景:Claude Code 用了半年,效率确实高——但面试被问"它和 Copilot 有什么区别?Agent 循环怎么实现的?“你只能说"它是个命令行 AI 工具”。你需要的不只是"会用"——是从架构层面理解 Agent Loop 的工作机制、MCP 协议的扩展原理、以及它和 Copilot/Cursor 的本质差异。
30秒速览:Claude Code 三层架构——Agent Loop 核心层:system prompt 驱动,Thought(分析意图)→ Action(选择工具+参数)→ Observation(读取结果)→ Reflection(判断是否完成)→ 循环,完整 7 步轨迹可追踪。内置工具层:31 个工具分五大类——文件操作(Read/Write/Edit)、搜索(Grep/Glob)、执行(Bash)、Web(WebSearch/WebFetch)、代码智能(SmartEdit/LSP)。扩展层:MCP Server 通过 JSON-RPC 接入外部服务(40 行代码写一个图片生成 Server),Skills 打包领域知识,Hooks 拦截生命周期事件。CC vs Copilot vs Cursor——CC 是 Agent 级 CLI(项目级理解+多文件自动编辑),Copilot 行级补全最强,Cursor AI-native IDE+Agent 模式。
跟其他 CC 介绍文章不同:这篇不列功能清单——从 system prompt 源码出发,拆解 Agent Loop 的 7 步工具调用轨迹(tool_use→tool_result 的完整 JSON 交互),讲清楚每一步在做什么、为什么这样设计。再手把手带你写一个 MCP Server,40 行代码让 CC 接入图片生成能力。
本文是《AI 应用开发完全指南》系列第 8 篇(共 14 篇)。
⚠️ 时效性提示:本文基于 2026 年 7 月的技术状态撰写。大模型版本迭代迅速(通常 3-6 个月一次大版本更新),文中涉及的模型名称、API 端点及性能基准数据请以各厂商最新公告为准。建议重点关注文章中的架构原理与设计决策——这些内容具有更长的时效性。
一、模型运行时、Agent 与模型的关系
这是初学者最容易混淆的三层概念。
三层架构
┌─────────────────────────────────────────────────────────┐
│ Agent(智能体) │
│ Claude Code / Cursor / Copilot / 自建 Agent │
│ "大脑的额叶"——决策层 │
│ 职责:接收任务 → 拆解步骤 → 决定调什么工具 → 分析结果 │
├─────────────────────────────────────────────────────────┤
│ 模型运行时(Model Runtime) │
│ Ollama / vLLM / llama.cpp / PyTorch / diffusers │
│ "大脑的神经元"——执行层 │
│ 职责:接收文本请求 → 运行模型推理 → 返回推理结果 │
├─────────────────────────────────────────────────────────┤
│ 模型(Model) │
│ Qwen / DeepSeek / FLUX / SD 3.5 ... │
│ "大脑存储的知识"——知识层 │
│ 职责:权重文件(.gguf / .safetensors),网络结构定义 │
└─────────────────────────────────────────────────────────┘
关键认知:
Ollama 不是 Agent。
Ollama 是模型运行时——它只负责"收文本 → 模型计算 → 返回文本"。
Claude Code 是 Agent。
它调用的模型运行时可以是 DeepSeek 远程 API、可以是 Ollama 本地服务、
可以是 OpenAI API——Agent 不关心运行时是谁,只关心它能收到文本回复。
模型是纯粹的数据 + 结构定义,不包含任何执行逻辑。
没有运行时加载,模型文件只是一堆字节。
常见 Agent 形态
| Agent | 底层模型(可换) | 工具调用 | 适用场景 |
|---|---|---|---|
| Claude Code | Claude / DeepSeek(可换) | Bash, Read, Edit, MCP | 命令行编程助手 |
| Cursor | GPT / Claude / 自定义 | 代码编辑、终端、LSP | IDE 内编程助手 |
| GitHub Copilot | GPT / Claude | 代码补全、Chat、Agent | IDE 内编程助手 |
| 自建 Agent | 任意(OpenAI 兼容即可) | 自定义工具集 | 特定业务场景 |
二、Claude Code 深度拆解
2.1 启动时做了什么
用户执行 claude
│
▼
┌─────────────────────────────────────────┐
│ 1. 读取配置 │
│ - settings.json(用户权限、MCP 服务器) │
│ - CLAUDE.md(项目指令) │
│ - .claude/ 目录(Memory、Corrections) │
│ - 环境变量(API key、代理配置等) │
├─────────────────────────────────────────┤
│ 2. 建立与模型的连接 │
│ - 根据配置 base_url + api_key │
│ - 验证连接可用性 │
├─────────────────────────────────────────┤
│ 3. 加载 MCP 服务器 │
│ - 启动配置中列出的 MCP 子进程 │
│ - 获取各 MCP 提供的工具列表 │
│ - 将工具定义注册到 Agent 的工具集 │
├─────────────────────────────────────────┤
│ 4. 构建系统提示词(System Prompt) │
│ - 注入项目指令(CLAUDE.md 内容) │
│ - 注入 Memory(当前项目的记忆文件) │
│ - 注入可用工具列表及使用说明 │
│ - 注入行为约束规则 │
├─────────────────────────────────────────┤
│ 5. 等待用户输入 │
└─────────────────────────────────────────┘
2.2 每次对话做了什么
用户输入消息
│
▼
┌─────────────────────────────────────────┐
│ 1. 组装请求体 │
│ system: 系统提示词(含工具定义) │
│ messages: 对话历史(经过上下文管理) │
│ tools: 可用工具列表(JSON Schema) │
├─────────────────────────────────────────┤
│ 2. 发送 POST 请求至模型 API │
│ POST /v1/chat/completions │
│ Body: { model, messages, tools, ... } │
├─────────────────────────────────────────┤
│ 3. 接收模型响应 │
│ 情况 A:返回纯文本 → 展示给用户,结束 │
│ 情况 B:返回工具调用 → 进入工具循环 │
└─────────────────────────────────────────┘
2.3 工具调用循环(Agent 的核心机制)
模型回复:"我需要执行 read_file 来查看代码"
│
▼
┌──────────────────────────────────────────────┐
│ 模型返回结构化工具调用: │
│ { │
│ "tool_calls": [{ │
│ "function": { │
│ "name": "read_file", │
│ "arguments": {"file_path": "/a/b.py"} │
│ } │
│ }] │
│ } │
├──────────────────────────────────────────────┤
│ 1. Claude Code 收到这个 JSON │
│ 2. 检查权限:该工具是否需要用户批准? │
│ 3. 执行工具(如:读取文件) │
│ 4. 将工具执行结果作为新消息追加到对话历史: │
│ {"role": "tool", "content": "文件内容..."} │
│ 5. 再次调用模型(带上工具结果) │
│ 6. 模型基于结果继续推理 → 可能再调工具或回复文字 │
│ 7. 循环直到模型回复纯文本(不再调工具) │
└──────────────────────────────────────────────┘
一个典型的对话轨迹:
[user] "帮我修复 test.py 中的 bug"
↓
[model] "我先看看 test.py 的内容" → tool_call: Read("test.py")
↓
[tool] "文件内容是:def foo():\n return 1/0"
↓
[model] "找到了,是除零错误" → tool_call: Edit("test.py", ...)
↓
[tool] "文件已修改"
↓
[model] "已修复。将 `1/0` 改为 `1/1`,现在运行测试验证一下?"
↓
[model] → tool_call: Bash("python -m pytest test.py")
↓
[tool] "测试通过"
↓
[model] "测试全部通过,修复完成。"
2.4 上下文管理
每次调用模型都需要携带对话历史。当对话历史超出模型的上下文窗口时:
| 机制 | 作用 |
|---|---|
| 上下文压缩(Compaction) | 将早前的内容压缩为摘要,释放上下文空间 |
| Memory 系统 | 将关键事实持久化到磁盘,跨会话保留 |
| CLAUDE.md 注入 | 项目指令始终在 System Prompt 中,不随对话增长而丢失 |
| 子 Agent 隔离 | 子 Agent 有独立上下文,完成后只返回结果 |
三、MCP 协议 — 扩展能力的标准接口
3.1 MCP 的工作原理
┌──────────────────┐ MCP 协议 ┌──────────────────┐
│ Claude Code │ ←─────────────→ │ MCP Server │
│ (MCP Client) │ JSON-RPC │ (独立进程) │
│ │ over stdio/SSE │ │
│ │ │ │
│ "帮我搜索数据库" │ ① 列出可用工具 │ PostgreSQL MCP │
│ │ ② 调用工具 │ → 执行 SQL 查询 │
│ │ ③ 返回结果 │ │
└──────────────────┘ └──────────────────┘
MCP 的两种通信模式:
stdio 模式(标准输入输出): SSE 模式(Server-Sent Events):
Claude Code ──启动子进程──→ MCP Server Claude Code ──HTTP 长连接──→ MCP Server
└── JSON 通过 stdin/stdout ──┘ └── JSON 通过 HTTP ────────┘
适合:本地工具、单用户 适合:远程工具、多用户共享
3.2 MCP 配置示例
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-server-chrome-devtools"]
},
"context7": {
"command": "npx",
"args": ["-y", "@context7/mcp-server"]
},
"custom-image-gen": {
"command": "python",
"args": ["D:/tools/image_mcp_server.py"]
}
}
}
四、如何扩展 Claude Code 的能力
4.1 更换对话模型
Claude Code 通过 base_url + api_key 连接对话模型。只要目标模型支持 OpenAI 兼容的 /v1/chat/completions 端点且支持 Tool Calling,即可替换:
export ANTHROPIC_BASE_URL="https://api.deepseek.com"
export ANTHROPIC_API_KEY="sk-xxxxxxxx"
注意:不是所有模型都支持 Tool Calling。如果模型不支持工具调用,Agent 的核心循环就无法运作——模型只能回复文字,不会触发工具执行。
4.2 通过 MCP 接入图片生成能力
Claude Code 本身是文本 Agent,不能直接生成图片。但通过 MCP,可以接入图片生成能力:
# image_gen_mcp_server.py — 一个最简单的图片生成 MCP Server
import json, sys
from openai import OpenAI
client = OpenAI(base_url="https://api.siliconflow.cn/v1", api_key="sk-xxx")
def handle_request(request):
# 本示例使用同步 IO 简化演示,生产环境建议使用 asyncio 处理并发请求
req = json.loads(request)
method = req.get("method")
if method == "tools/list":
return json.dumps({
"tools": [{
"name": "generate_image",
"description": "根据文字描述生成图片,返回图片URL",
"inputSchema": {
"type": "object",
"properties": {
"prompt": {"type": "string", "description": "图片描述"}
},
"required": ["prompt"]
}
}]
})
elif method == "tools/call":
args = req["params"]["arguments"]
resp = client.images.generate(
model="black-forest-labs/FLUX.1-dev",
prompt=args["prompt"], size="1024x1024"
)
return json.dumps({
"content": [{"type": "text", "text": f"图片已生成:{resp.data[0].url}"}]
})
for line in sys.stdin:
response = handle_request(line)
sys.stdout.write(response + "\n")
sys.stdout.flush()
配置后,在 Claude Code 中说出"帮我生成一张猫的图片",Agent 会:
- 判断需要调用
generate_image工具 - 提取 Prompt = “猫的图片”
- 执行 MCP 工具 → 调 SiliconFlow API → 返回图片 URL
- 将 URL 展示给你
4.3 通过 MCP 接入的能力类型
| MCP Server 类型 | 赋予的能力 |
|---|---|
| 文件系统 | 浏览/编辑本地文件 |
| 数据库 (PostgreSQL/MySQL/SQLite) | 执行 SQL 查询、查看表结构 |
| 浏览器 (Playwright/Puppeteer) | 打开网页、截图、点击、填表 |
| 搜索引擎 (Brave/Google) | 网络搜索 |
| 代码仓库 (GitHub/GitLab) | 创建 Issue、提交 PR、搜索代码 |
| 知识库 (Context7) | 查询最新框架文档 |
| 图片生成 | 远程调图片 API |
| 自定义业务 | 任何能封装成 API 的企业内部系统 |
核心要点回顾
- **三层架构(模型→运行时→Agent)**是理解"谁负责什么"的基础框架——Ollama 是运行时不是 Agent
- Agent 的核心 = 工具调用循环——模型返回 JSON 工具调用 → 执行 → 结果回传 → 再次推理 → 循环直到返回纯文本
- MCP 是 Agent 能力的标准扩展接口——stdio 适合本地工具,SSE 适合远程服务
- 只要模型支持 Tool Calling + OpenAI 兼容端点,就可以替换 Claude Code 的底层模型
- 通过 MCP,文本 Agent 可以接入图片生成、数据库查询、浏览器操作等任意能力——突破了"文本模型只能聊天"的限制
系列回顾
本文是《AI 应用开发完全指南》系列的最后一篇。8 篇系列覆盖:
第 1 篇:AI 应用开发全景 — LLM 原理 + 模型选型 + MCP/Skills/Hooks
第 2 篇:RAG 从入门到工程落地 — 切分/Embedding/评估/CRAG/代码走读
第 3 篇:Agent 的本质 — ReAct 循环 + FC vs MCP + 代码走读
第 4 篇:AI 工程化实践 — 安全/成本/可观测性/部署/PrismAI 全景
第 5 篇:AI 图片生成完全指南 — 扩散模型 + DiT 架构
第 6 篇:精确控制与视频生成 — LoRA/ControlNet/IP-Adapter + 视频
第 7 篇:大模型部署实战 — 远程 API + 本地部署 + KV Cache
第 8 篇:Claude Code 深度拆解(本文)— Agent 循环 + MCP 扩展
深度 1:RAG 核心组件深度剖析 — 嵌入模型与向量数据库
深度 2:Agent 工具体系与选型指南
上一篇:《大模型部署实战》 | 下一篇:《AI图片视频处理工具手册》(附录)
系列专栏:AI专栏
💬 聊聊你的经历:Claude Code 用了多久?你最喜欢的 feature 是哪个——workflow 模式一个 prompt 编排多个子 Agent,还是 MCP Server 扩展让你接入自己的工具?有没有自己写过 MCP Server?评论区聊聊你的 CC 使用心得和"最惊艳的一次体验"。
如果这篇文章让你从"会用 Claude Code"升级到"能画出它的架构图、讲清 Agent Loop 的 7 步轨迹",欢迎收藏+点赞 🙏
更多推荐

所有评论(0)