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...

相关推荐
shandianchengzi1 小时前
【记录】Claude Code|Windows11给Claude Code新增任务消息提示音
windows·ai·音频·claude·claude code
来让爷抱一个2 小时前
MonkeyCode vs Copilot vs Cursor:三大 AI 编程工具深度对比
人工智能·安全·开源·ai编程
协享科技2 小时前
前端 SSE 流式响应处理实践:从接收、解析到渲染
前端·人工智能·程序人生·go·ai编程·sse
人月神话Lee3 小时前
【图像处理】一文带你窥探近期火热图像App的主要实现原理:主色提取——从图像到调色板
ios·ai编程·图像识别
码途漫谈3 小时前
Harness:让 Claude Code 先组队,再开工
开源·ai编程
wuhen_n3 小时前
RAG 入门:检索增强生成核心原理
前端·人工智能·typescript·langchain·ai编程