MCP Sampling 机制:服务器请求补全、人工审批与授权边界

系统讲解 MCP Sampling(采样)机制:服务器如何向客户端请求 LLM 补全、Sampling 的 request/response 流程、与 tools 调用方向的关系(反向的工具调用)、人工审批与共识策略、采样频率与内容大小控制、以及 Sampling 的安全边界与授权模型。

1. Sampling 解决什么问题

通常的调用方向是客户端 → 服务器:Agent 调用服务器提供的工具。但很多场景需要反向:服务器在运行中需要「聪明的补充」。

场景:代码评审服务器
  服务器扫描到一段可疑代码
  → 它想让 LLM 判断「这段代码有什么问题」
  → 于是向客户端请求一次「补全」(Sampling)
  → 客户端(Agent)调用自己的 LLM → 返回结果给服务器

一句话:Sampling 是「服务器反向向 Agent 借 LLM 一用」——它让服务器从纯工具提供者,升级为能自主思考的组件。

1.1 与 Tools 的方向对比

能力调用方向语义
ToolsAgent → 服务器Agent 执行服务器的操作
Sampling服务器 → Agent服务器请求 Agent 的 LLM

2. Sampling 的请求与响应

2.1 协议流程

服务器发 sampling/createMessage 请求
  → 客户端(Agent)调用 LLM 生成补全
  → 返回 response(含内容、停止原因、模型信息)
  → 服务器用该内容继续自己的逻辑

2.2 请求结构

// sampling/createMessage 请求
{
  "messages": [
    { "role": "user", "content": { "type": "text", "text": "评审以下代码..." } }
  ],
  "systemPrompt": "你是一个严谨的代码评审专家",
  "includeContext": "thisServer",   // 注入哪些上下文
  "maxTokens": 2000,
  "stopSequences": ["END"],
  "metadata": { "purpose": "code-review" },
  "modelPreferences": { "hints": [{ "name": "claude" }] }
}

2.3 响应结构

{
  "role": "assistant",
  "content": { "type": "text", "text": "该代码存在重入攻击风险..." },
  "stopReason": "end_turn",
  "model": "claude-sonnet-5"
}

2.4 服务器端实现

import { SamplingMessageSchema } from "@modelcontextprotocol/sdk/types.js";

// 服务器请求一次补全
const res = await client.request({
  method: "sampling/createMessage",
  params: {
    messages: [{ role: "user", content: { type: "text", text: prompt } }],
    maxTokens: 2000,
  },
}, SamplingMessageSchema);

const advice = res.content.text;

一句话:Sampling 是标准的 JSON-RPC 请求——服务器发 sampling/createMessage,Agent 用自己的 LLM 应答,请求/响应结构与普通工具调用对称。

3. 客户端如何应答 Sampling

客户端收到 sampling 请求后,决定「是否调用 LLM、调哪个模型、是否需要人工介入」。

3.1 客户端默认应答

// 客户端:处理 sampling 请求
client.setRequestHandler(SamplingCreateMessageSchema, async (req) => {
  // 1. 校验请求(来源服务器、内容安全)
  // 2. 是否需人工审批?
  if (requiresApproval(req)) {
    const ok = await askUser(req.messages, req.metadata);
    if (!ok) throw new Error("user rejected");
  }
  // 3. 调用 LLM
  const result = await llm.chat(req.messages, {
    system: req.systemPrompt,
    maxTokens: req.maxTokens,
    stop: req.stopSequences,
  });
  return {
    role: "assistant",
    content: { type: "text", text: result.text },
    stopReason: "end_turn",
    model: result.model,
  };
});

3.2 人工审批策略

策略行为适用
自动放行低风险补全直接执行分析、格式化
审批提示展示内容,用户确认有副作用的建议
拒绝高风险直接拒绝敏感操作

3.3 审批条件示例

- metadata.purpose 是否高风险(如「准备执行删除」)
- 请求 maxTokens 过大 / 内容异常
- 服务器来源是否可信
- 涉及敏感数据时 → 必须审批

一句话:Sampling 的应答权在客户端——Agent 是「LLM 的管家」,它决定调不调、要不要人看、给不给内容,这是 Sampling 的安全闸门。

4. 模型选择与偏好

4.1 modelPreferences

服务器可在请求中声明「偏好模型」:
  - 按能力(工具调用、长上下文)
  - 按成本/速度
  - hints: [{ name: "claude" }, { type: "embedding" }]
客户端有最终决定权(可用别的模型应答)

4.2 多模型路由

客户端可做「模型路由器」:
  - 简单任务 → 快模型
  - 复杂推理 → 强模型
  - 图像分析 → 视觉模型
  - 依据 metadata.purpose 分流

4.3 includeContext

服务器可要求注入上下文:
  - thisServer:注入该服务器的资源/工具列表
  - allServers:全部服务器上下文
  - none:只给 messages
控制:防止采样请求把整个 Agent 上下文带走

一句话:模型选择是「服务器偏好 + 客户端决定权」的博弈——偏好是建议,路由是事实,includeContext 控制信息暴露范围。

5. 安全边界与授权

Sampling 是反向能力调用,天然有滥用风险:服务器可能用采样请求套取信息、消耗 LLM 配额、诱导不良输出。

5.1 安全威胁

- 信息套取:让 LLM 复述客户端上下文中的敏感内容
- 配额滥用:疯狂发采样请求耗尽 token 预算
- 输出污染:诱导 LLM 生成恶意建议
- 内容走私:把敏感数据塞进补全输出带走

5.2 防护清单

- 请求白名单:只允许可信服务器发起 sampling
- 频率限制:单服务器单位时间采样次数上限
- 内容审计:输入输出都过安全过滤
- includeContext 最小化:默认 thisServer 或 none
- 人工审批:高风险用途强制确认
- 预算控制:每会话 token 上限

5.3 权限最小化

服务器声明需要 sampling 能力 → 客户端按需授权
  不需要 sampling 的服务器 → 干脆不授权
  授权后仍可逐请求审批

一句话:Sampling 是把「LLM 能力」开放给服务器,等于开了后门——白名单、限频、审计、最小上下文、人工审批,五道闸门一个都不能少。

6. 实践模式

6.1 服务器内嵌思考

服务器处理工具请求时,需要「实时推理补充」:
  读文件 → 采样让 LLM 判断风险 → 决定是否继续
  场景:安全检查、数据清洗、日志归因

6.2 与工具调用的组合

场景:智能报表服务器
  服务器:收到「生成报表」工具调用
  采样:让 LLM 决定「按什么维度聚合」
  执行:用 SQL 工具真正聚合
  采样:让 LLM 撰写报表解读
  返回:报表 + 解读

6.3 成本控制

- 采样响应缓存(相同请求复用)
- 尽量用「小模型 + 小 maxTokens」
- 只在「无法用规则解决」时采样
- 采样前先尝试确定性方案

一句话:Sampling 不是「每次都问 LLM」,而是「规则处理不了的才问」——采样做决策、工具做执行、缓存降成本。

7. 常见陷阱

陷阱症状解决
客户端未实现 handler服务器请求失败注册 SamplingCreateMessage handler
无审批的敏感采样数据外泄按 purpose 强制审批
无限采样配额耗尽频率 + 预算限制
includeContext 全开上下文泄露最小化注入
忽略 modelPreferences响应质量差尊重偏好 + 路由
采样当执行副作用不可控采样只做决策,执行走 Tools

8. 总结

MCP Sampling 机制可以概括为「反向借脑、审批兜底、最小暴露」:

层面要点
方向服务器 → 客户端请求 LLM 补全
流程sampling/createMessage 请求-响应
决策权客户端决定调不调、审不审、用哪模型
审批高风险用途强制人工确认
安全白名单 + 限频 + 审计 + 最小上下文
实践采样决策、工具执行、缓存降本

Sampling 让 MCP 从「单向工具调用」进化成「双向智能协作」——服务器也能「思考」。但这份能力是双刃剑:给它套上审批、限流、最小上下文的笼头,Sampling 才能成为 Agent 生态的增益,而非漏洞。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「AI工程」更多文章

  1. MCP 资源模板与订阅:URI 模板、ListChanged 通知与上下文注入
  2. MCP 的 OAuth 鉴权与会话:动态注册、PKCE 与令牌轮换
  3. MCP 服务器测试框架:in-memory 传输、协议断言与端到端测试