MCP Quickstart 源码解析:processQuery 如何完成 Claude Tool Calling

理解 Anthropic Tool Use 消息流

本文结合源码,分析 processQuery() 的完整执行流程,并解释 Anthropic Tool Use API 的消息模型。

核心职责

processQuery() 的职责可以概括为:

  1. 接收用户问题
  2. 发送给 Claude
  3. 处理 Claude 发起的 Tool Use
  4. 调用 MCP Tool
  5. 将工具结果返回给 Claude
  6. 获取最终答案

整个流程本质上是一个标准的 Tool Calling 循环。


第一步:用户发起请求

用户输入:

复制代码
北京天气怎么样?

客户端构造消息:

ini 复制代码
const messages = [
  {
    role: "user",
    content: "北京天气怎么样?"
  }
];

当前消息历史:

sql 复制代码
user
└─ 北京天气怎么样?

第二步:Claude 请求调用工具

客户端调用:

csharp 复制代码
const response = await anthropic.messages.create(...)

Claude 判断需要查询天气,因此返回:

json 复制代码
{
  "type": "tool_use",
  "id": "toolu_001",
  "name": "weather",
  "input": {
    "city": "北京"
  }
}

此时源码执行:

php 复制代码
messages.push({
  role: "assistant",
  content: response.content as ContentBlockParam[]
});

消息历史变为:

scss 复制代码
user
└─ 北京天气怎么样?

assistant
└─ tool_use(weather)

这里保存的是 Claude 的完整响应内容,而不仅仅是工具名称。


第三步:调用 MCP Tool

客户端根据 Tool Use 信息调用 MCP Server:

php 复制代码
const result = await this.mcp.callTool({
  name: "weather",
  arguments: {
    city: "北京"
  }
});

工具返回:

json 复制代码
{
  "temperature": 28,
  "condition": "Sunny"
}

第四步:构造 Tool Result

这是很多人最容易疑惑的地方。

源码会把工具执行结果作为新的消息加入:

php 复制代码
messages.push({
  role: "user",
  content: [
    {
      type: "tool_result",
      tool_use_id: content.id,
      content: result.content
    }
  ]
});

注意:

vbnet 复制代码
role: "user"

而不是:

vbnet 复制代码
role: "tool"

这是 Anthropic Tool Use API 的设计要求。

消息历史变为:

scss 复制代码
user
└─ 北京天气怎么样?

assistant
└─ tool_use(weather)

user
└─ tool_result(28°C Sunny)

第五步:获取最终答案

再次调用 Claude:

csharp 复制代码
const finalResponse =
  await anthropic.messages.create(...)

Claude 收到工具结果后生成最终回复:

复制代码
北京当前温度为 28°C,天气晴朗。

消息流最终变成:

scss 复制代码
user
assistant(tool_use)
user(tool_result)
assistant(final answer)

为什么 Tool Result 的 Role 是 User?

很多开发者接触 OpenAI API 后会习惯这种模式:

scss 复制代码
user
assistant(tool_call)
tool
assistant

而 Anthropic 的设计不同:

scss 复制代码
user
assistant(tool_use)
user(tool_result)
assistant

原因是 Anthropic 将工具结果视为"外部环境返回的信息",统一由 user 角色提交给模型。

因此 Tool Result 必须放在:

vbnet 复制代码
role: "user"

中,并使用:

bash 复制代码
type: "tool_result"

进行标识。


processQuery 的本质

从架构角度看,processQuery() 实现的是一个最基础的 Agent Loop:

sql 复制代码
User Query
    ↓
Claude
    ↓
Tool Use
    ↓
MCP Tool
    ↓
Tool Result
    ↓
Claude
    ↓
Final Answer

其中最关键的两步是:

php 复制代码
messages.push({
  role: "assistant",
  content: response.content
});

保存 Claude 的 Tool Use 请求。

以及:

php 复制代码
messages.push({
  role: "user",
  content: [{
    type: "tool_result",
    ...
  }]
});

将工具执行结果返回给 Claude。

理解这两个消息的作用后,整个 MCP Client 的执行流程就非常清晰了。

总结

processQuery() 遵循的是 Anthropic Tool Use 标准协议,其完整角色流为:

scss 复制代码
user
assistant(tool_use)
user(tool_result)
assistant(final answer)

与 OpenAI 的 tool 角色不同,Anthropic 将工具执行结果包装为 user + tool_result 消息重新提交给模型。理解这一点,是理解 MCP Client、Claude Tool Calling 以及后续 Agent 框架实现的关键基础。

源码:github.com/modelcontex...

相关推荐
Lei活在当下21 小时前
如何在Windows环境选择适合自己的 AI Agent
chatgpt·agent·ai编程
ajassi20001 天前
AI语音智能体开发日记(十一)为智能设备“声”临其境——详解音频资源自动化生成流程
人工智能·ai·ai编程
viva51721 天前
Vibe/各规则定义的顺序和内容
ai编程
gptAI_plus1 天前
把报错日志发给 AI 前,先用 Python 做一次本地脱敏
openai·ai编程
码哥字节1 天前
我把 Karpathy 的 AI 编码准则,改造成了一套全栈开发的"工作流宪法",开源了
claude
moMo1 天前
考卷上有几道题?Temperature 和 Top-K 调参指南
ai编程
云原生melo荣1 天前
Multi-Agent 系统(一):问题域与架构选型——为什么这次"固定流程"编排不动
agent·ai编程
码农胖大海1 天前
AI 响应慢自查清单
agent·ai编程
梓䈑1 天前
【用 Vibe Coding 实现的 C++17 在线判题系统】前端开发 + Web 自动化测试
前端·c++·ai编程
机建狂魔1 天前
Codex 接入第三方模型 API 实战:以 Mimo 为例
java·服务器·数据库·ai·ai编程·codex