1. Sampling 解决什么问题
通常的调用方向是客户端 → 服务器:Agent 调用服务器提供的工具。但很多场景需要反向:服务器在运行中需要「聪明的补充」。
场景:代码评审服务器
服务器扫描到一段可疑代码
→ 它想让 LLM 判断「这段代码有什么问题」
→ 于是向客户端请求一次「补全」(Sampling)
→ 客户端(Agent)调用自己的 LLM → 返回结果给服务器
一句话:Sampling 是「服务器反向向 Agent 借 LLM 一用」——它让服务器从纯工具提供者,升级为能自主思考的组件。
1.1 与 Tools 的方向对比
| 能力 | 调用方向 | 语义 |
|---|---|---|
| Tools | Agent → 服务器 | 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 生态的增益,而非漏洞。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。