路线图

04 Tool Calling 与 MCP

星辉 2026-07-02 阅读 6 min 1,175 字 路线图
04 Tool Calling 与 MCP 封面

学习目标:能把数据库、文件、搜索、浏览器、企业 API 封装成 Agent 可调用工具;能说清楚 MCP 与 A2A 的边界;能让 Agent 安全地操作浏览器/GUI。 重点度:必会(12 分) 前置要求:Ch2 LLM 应用基础(Function Calling)、Ch3 Context 工程


概述#

Agent 不能只回答,还要能调用工具、查询系统、写入数据、触发流程,甚至直接操作浏览器和桌面 GUI。

这一章把 Agent 从"会聊天"变成"能动手"。但能动手 = 能闯祸——所以工具权限、错误处理、安全边界与工具能力本身同等重要。


Part 1:Tool Calling 基础#

Tool Schema 与 Tool Selection#

Tool Schema 三要素#

python
{
    "name": "search_jira",                    # 1. 名字 - 动词+对象, 避免歧义
    "description": "搜索 Jira 工单。仅搜工单标题和描述,不搜评论。",  # 2. 描述 - 边界要说清
    "parameters": {                           # 3. 参数 schema
        "type": "object",
        "properties": {
            "query": {"type": "string", "description": "搜索关键词"},
            "status": {"type": "string", "enum": ["open", "closed", "all"]}
        },
        "required": ["query"]
    }
}

实战要点

  • description 是给模型看的:必须明确"做什么"和"不做什么",模糊的 description 是 Agent 选错工具的根因
  • 用 enum 约束取值:不要让模型自由发挥 status 字段
  • required 字段必须明确:可选参数要标注清楚
  • 工具数量上限:单次请求 20-30 个工具是模型决策准确率的上限,超过要 router 分流

Tool Selection(工具选择)#

模型如何在 N 个工具里选对?靠的就是 description 的语义匹配。但工具一多,重叠就多:

text
Bad:
  search_jira: "搜索 Jira"
  search_confluence: "搜索 Confluence"
  search_wiki: "搜索 Wiki"
→ 模型分不清 "搜项目文档" 该用哪个

Good:
  search_jira: "搜索 Jira 工单,用于查找任务/bug/需求追踪"
  search_confluence: "搜索 Confluence 文档,用于查找团队协作文档"
  search_wiki: "搜索 Wiki,用于查找技术规范/产品文档"

工具多了之后,要做 Router

text
用户请求
Router Agent (轻量模型): 判断属于哪个工具域 → 选 5 个候选工具
Main Agent: 在 5 个候选里决策调用

参数校验与错误处理#

参数校验#

模型填的参数不能信任,必须 preflight 校验:

python
def call_tool(tool_name, args):
    # 1. Schema 校验
    validate(args, tool_schemas[tool_name])
    
    # 2. 业务校验
    if tool_name == "delete_user":
        if args["user_id"] == current_user.id:
            raise ToolError("不能删除自己")
        if not user_has_permission("delete_user"):
            raise PermissionError("无权限")
    
    # 3. 范围/枚举校验
    if "limit" in args and args["limit"] > 1000:
        raise ToolError("limit 不能超过 1000")

工具错误处理#

工具执行失败时,错误信息怎么回灌给模型很关键:

text
Bad:
  Tool returns: "Error"
  → 模型不知道为什么错, 可能反复重试同一调用

Good:
  Tool returns: "Error: 数据库连接超时 (timeout=5s), 请稍后重试或换用 search_web 工具"
  → 模型知道是临时错误, 会改策略

错误回灌原则

  1. 可读:错误信息要让模型能理解
  2. 可恢复:告诉模型"该怎么办"(重试/换工具/问用户)
  3. 不带堆栈:技术堆栈给模型没用,反而占 token
  4. 区分错误类型:临时错误(网络)→ 重试;业务错误(无权限)→ 不要重试

工具权限#

工具调用必须做权限控制,不能"模型想调就调":

  • 白名单:每个 Agent 会话只能用预设的工具集
  • 审批门禁:高风险工具(删除/转账/部署)必须人工审批(见 Ch5 Permission Mode、Ch10 安全护栏)
  • 凭证最小化:工具拿到的凭证权限要 ≤ 任务所需权限(防 Confused Deputy,见 Ch10)

Part 2:MCP(Model Context Protocol)#

MCP 解决什么问题#

前 MCP 时代#

每个 Agent 平台都自己定义工具接口:

text
OpenAI Function Calling:  自己的 schema 格式
Anthropic Tool Use:       自己的 schema 格式
LangChain Tools:          自己的 schema 格式
Dify Tools:               自己的 schema 格式

→ 同一个工具 (如查询天气) 要为每个平台写一遍适配
→ 工具生态被平台割裂

MCP 的目标#

MCP(Anthropic 2024 提出,2026 已成事实标准)解决的就是工具标准化

  • 工具开发者:写一次 MCP Server,所有支持 MCP 的 Agent 都能用
  • Agent 开发者:直接接入任何 MCP Server,不用为每个工具写适配
  • 协议层:统一了 Client / Server 通信、工具发现、调用、资源暴露

类比:MCP 之于 Agent 工具 = USB 之于硬件外设 = LSP 之于编辑器语言服务。


MCP 架构#

text
┌──────────────┐        ┌──────────────┐
│  MCP Client  │ ◄────► │  MCP Server  │
│ (Agent 侧)   │  JSON  │ (工具侧)     │
│              │  RPC   │              │
│ - 发起调用    │        │ - 实现 tools │
│ - 接收结果    │        │ - 暴露 resources │
│              │        │ - 暴露 prompts│
└──────────────┘        └──────────────┘
      │                       │
      │                       ├── 工具: search_web, query_db...
      │                       ├── 资源: file://doc.md, db://schema
      │                       └── 提示: code_review_template
      └── 可同时连多个 MCP Server

Transport(传输层)#

MCP 官方只定义两种标准 transport:stdio(本地)与 Streamable HTTP(远程)。早期的 HTTP+SSE 已在 2025-03 规范中被 Streamable HTTP 取代(仅保留向后兼容);WebSocket 至今不在官方规范内。

Transport适用场景特点
stdio本地工具、CLI Agent走 stdin/stdout 的进程间通信,最快
Streamable HTTP远程工具、Web Agent2025-03 起的标准远程传输:单 HTTP 端点 + 可选 SSE 流式,可跨网
HTTP+SSE(已废弃)旧版远程传输2024-11 老方案,2025-03 起被 Streamable HTTP 取代,仅向后兼容

MCP 三大组件:Resources / Prompts / Tools#

Resources(资源)#

MCP Server 暴露的只读数据源

text
Resources:
  file:///project/README.md   ← 文件内容
  db://schema/users           ← 数据库 schema
  git://repo/HEAD             ← 仓库当前状态

Agent 可以枚举、读取这些资源,但不能修改。

Prompts(提示模板)#

MCP Server 暴露的预定义提示模板

text
Prompts:
  code_review: 给定代码,生成 code review 报告
  sql_optimize: 给定 SQL,生成优化建议

让工具携带"使用建议",避免 Agent 用错。

Tools(工具)#

MCP Server 暴露的可执行函数

text
Tools:
  search_web(query: str, max_results: int)
  query_db(sql: str, db: str)
  send_email(to: str, subject: str, body: str)

工具是 MCP 最常用的部分。

补充(面试常考"MCP 原语有哪些"):Resources / Prompts / Tools 是 Server 端三大原语;MCP 还定义了 Client 端原语——Roots(客户端向 server 暴露可访问的文件根)、Sampling(server 反向请求客户端做 LLM 补全)、Elicitation(server 运行中向用户追加索取信息,2025-06 规范加入)。别只答 server 三件套。


MCP 实战:写一个 MCP Server#

python
# 用官方 Python SDK
from mcp.server import Server
from mcp.types import Tool, TextContent

server = Server("my-weather-server")

@server.list_tools()
async def list_tools() -> list[Tool]:
    return [
        Tool(
            name="get_weather",
            description="查询指定城市的天气",
            inputSchema={
                "type": "object",
                "properties": {
                    "city": {"type": "string"}
                },
                "required": ["city"]
            }
        )
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
    if name == "get_weather":
        weather = await fetch_weather(arguments["city"])
        return [TextContent(type="text", text=f"{arguments['city']}: {weather}")]

关键工程点

  • 错误处理:MCP Server 异常不能崩,要返回结构化错误
  • 限流:Server 侧自己做限流,不能让 Agent 一通乱调
  • 审计日志:每次调用记录 who/when/what/result
  • 凭证隔离:Server 持有的凭证不能泄露给 Agent(见 Ch10 Confused Deputy)

MCP 的 Confused Deputy 风险(★2026 头号威胁)#

什么是 Confused Deputy#

Confused Deputy(混淆代理人)攻击:MCP Server 持有高权限凭证,Agent 用低权限身份请求,但 Server 用自己的高权限执行了请求。

text
场景:
  MCP Server 持有: 公司全员数据库读权限 (server 凭证)
  Agent 用户: 实习生 A (低权限)
  Agent 请求: "查询员工薪资表"
  
错误做法:
  Server 用自己凭证执行 → 实习生看到全员薪资 ← 越权!
  
正确做法:
  Server 按"请求者身份"校验权限 → 实习生无权 → 拒绝

防护要点#

  1. 凭证最小化委托:不给 agent 超出任务所需的权限
  2. 按请求者身份校验:不是按 server 身份校验
  3. 审计每条调用:who/what/result 都要记
  4. 敏感操作二次确认:高风险操作人工审批

OWASP 2026 把 Confused Deputy 列为 MCP 头号威胁,详见 Ch10 安全护栏与权限治理。


Part 3:A2A(Agent ↔ Agent)#

A2A 与 MCP 的边界#

MCPA2A
通信方agent ↔ 工具/上下文agent ↔ agent
解决问题标准化工具调用标准化 agent 协作
类比人 ↔ 工具人 ↔ 人
提出方AnthropicGoogle
状态事实标准补齐多 Agent 协作

关键判断:你调用的是"工具"(无自主决策)用 MCP;你调用的是"另一个 Agent"(有自主决策、自己的上下文)用 A2A。

治理(2026 现状,易踩反):2025-12 Linux Foundation 成立 Agentic AI Foundation(AAIF),MCP 与 Block 的 goose、OpenAI 的 AGENTS.md 一并作为首批项目并入 AAIF;A2A 则是更早(2025-06)由 Google 单独捐给 Linux Foundation 的独立项目(Agent2Agent Protocol Project),不属于 AAIF。两者都归 Linux Foundation 做中立治理,但不是同一个 foundation——别把"A2A 属于 AAIF"答反。

何时需要 A2A#

  • 多 Agent 分工:coding agent + reviewer agent + deploy agent 协作完成 PR
  • 跨系统 Agent 协作:我的 Agent 调用你的 Agent 查询数据
  • Agent 经济:Agent 之间互相雇佣、协商、付费

A2A 协议核心概念#

text
Agent Card: 描述 Agent 能力
  {
    "name": "code-reviewer",
    "capabilities": ["code_review", "security_audit"],
    "endpoint": "https://...",
    "auth": "..."
  }

Task: 任务生命周期
  submitted → working → completed/failed

Message: Agent 间消息
  role: user/agent
  parts: text/file/data

Part 4:Browser / Computer Use Agent(★2026 新主线)#

为什么 Browser Use 提级#

2026 最重要的趋势:Agent 不再满足于"调 API",要直接操作浏览器/GUI——很多旧系统没有 API,很多 SaaS 不开放 API,但所有应用都有 GUI。

OpenClaw(28 万+ star)内置浏览器控制;百度红手指 Operator 把 Computer Use 从浏览器扩展到整个桌面;BrowserSkill 类技能市场爆发。


浏览器接入方式#

1. CDP(Chrome DevTools Protocol)#

通过 CDP 直接控制 Chrome,不需要 Selenium:

python
# Playwright 风格
async with async_playwright() as p:
    browser = await p.chromium.launch(headless=False)
    page = await browser.new_page()
    await page.goto("https://example.com")
    await page.click("#login-button")

优势:快、稳定、能拦截网络请求;OpenClaw 内置 CDP,支持"借用已有浏览器 tab"。

2. 借用用户已登录的浏览器 tab#

text
用户在 Chrome 已登录 github.com
Agent 通过 CDP 接管这个 tab → 复用登录态
→ 不需要重新登录, 不需要存密码

这是 OpenClaw 等个人 Agent 的关键设计——避免存用户密码、避免触发 SaaS 风控。

3. Browser Sandbox#

不让 Agent 用用户真实浏览器(风险大),用隔离的 sandbox 浏览器:

  • 隔离环境:独立 profile、独立 cookies
  • 网络隔离:限制可访问域名
  • 截图/录像:所有操作可回放
  • 资源限制:CPU/内存/时间上限

观察源:DOM / Screenshot / a11y tree#

Agent 操作浏览器前,必须先"看到"页面。三种观察方式各有取舍:

观察源优势劣势适用
DOM信息全、可精确选择噪声多、token 大已知结构页面
Screenshot视觉直观、能看布局需要 vision 模型、定位难复杂视觉页面
a11y tree结构化、token 小信息有损通用、推荐

a11y tree(无障碍树)#

浏览器为无障碍工具暴露的页面结构树:

text
button "登录"
input "用户名" (editable)
input "密码" (password, editable)
link "忘记密码"

token 小、结构化、能直接映射到交互元素。Anthropic 的 Computer Use、OpenClaw 都优先用 a11y tree。

实战策略:多源融合#

text
1. 先读 a11y tree → 找到目标元素
2. 元素定位失败 → 截图给 vision 模型识别
3. 视觉识别仍失败 → 读 DOM 排查

Action 执行#

常见的 Action:

  • click(element_id) — 点击
  • type(element_id, text) — 输入
  • scroll(direction) — 滚动
  • navigate(url) — 跳转
  • wait(seconds) — 等待
  • screenshot() — 截图

关键工程点

  • 元素定位:不要用 xpath/css selector(页面变化就失效),用 a11y tree 的 element_id
  • 异步加载:点击后页面可能要等几秒才加载完,需要 wait_for_selector 或轮询
  • 失败重试:selector 失效、元素被遮挡、网络抖动都要重试
  • 回放:每次 Action 录制 trace,失败时能 replay 复现

登录态边界#

风险#

  • 凭证泄露:Agent 持有用户密码 → 高风险
  • 触发风控:自动化登录被 SaaS 检测 → 账号被锁
  • 会话污染:Agent 操作污染用户当前 session

防护#

  • 优先借用 tab:复用用户已登录的浏览器,不存凭证
  • OAuth 授权:必须存凭证时用 OAuth,存 token 而非密码
  • 隔离 session:Agent 用独立 browser profile,不污染用户主 profile
  • 操作审计:所有 Browser Action 留 trace,让用户能查

Computer Use(从浏览器扩展到 GUI)#

2026 趋势:从"操作浏览器"扩展到"操作整个桌面"——打开任意应用、点击任意窗口、输入任意字符。

实现路径#

路径代表原理
操作系统级 APIAnthropic Computer Use截图 + 鼠标键盘模拟
GUI 自动化框架PyAutoGUI / pywinauto直接调 OS API
远程桌面VNC/RDP 控制控制远程机器 GUI

风险升级#

Browser Use 出错最多搞乱浏览器,Computer Use 出错能搞乱整个系统:

  • 误删文件
  • 误发邮件
  • 误转账
  • 误操作系统设置

→ 必须 Sandbox + 强审批 + 操作回滚,见 Ch5 Permission Mode 与 Ch10 安全护栏。


阶段产出#

完成本章后应该能:

  • 设计清晰的 Tool Schema(name/description/parameters + enum/required)
  • 实现 Tool Selection Router,处理多工具场景
  • 实现参数校验 + 错误回灌 + 工具权限白名单
  • 写一个 MCP Server(list_tools / call_tool / Resources / Prompts)
  • 理解 MCP Confused Deputy 风险,能设计防护方案
  • 说清楚 MCP vs A2A 的边界,知道何时用哪个
  • 实现 Browser Use Agent(CDP + a11y tree + Action 执行)
  • 处理登录态边界(tab 借用 / OAuth / session 隔离)
  • 理解 Computer Use 的扩展场景和风险升级

下一章 Ch5 进入 Agent Runtime / Harness Engineering——这是全路线护城河:模型之外的脚手架才是产品的核心竞争力。