采样
让您的服务器从 LLM 请求完成
采样是一项强大的 MCP 功能,它允许服务器通过客户端请求 LLM 完成,从而在维护安全性和隐私性的同时实现复杂的代理行为。
一、采样的工作原理
采样流程遵循以下步骤:
- 服务器向客户端发送
sampling/createMessage
请求 - 客户端查看请求,并可以对其进行修改
- 客户端调用 LLM 生成消息(sample,一次生成尝试)
- 客户端审核 LLM 生成的消息内容
- 客户端将最终结果返回给服务器
这种人机交互流程确保上层能够对 LLM 所接收的输入和最终输出保持完全控制。
特别注释
sampling是比较坑爹的命名啊,《模型上下文协议中文网》需要做特别附注。
概念
正常的人机交互流程,是LLM先推理决策,再通过客户端向MCP服务端发出请求。但是特殊的情况下,被访问的MCP服务端,在执行任务的过程中,反过来有需要LLM先帮助解决问题,最后才能交答案。
工作原理
简言之,它是一种“反向请求”机制,其中服务器通过向客户端发送请求,并让客户端从 LLM 中采样内容。
场景举例
- 服务器向客户端发送请求:比如,服务器可能请求客户端直接利用其他MCP服务,或让客户端调用 LLM 执行某种任务(例如,生成 Git 提交信息、删除某个文件)。
- 客户端审查并修改请求:客户端接收到请求后,查看并可以根据需要修改请求内容。
- 客户端从 LLM 进行采样:客户端将修改后的内容输入 LLM,得到一个响应。
- 客户端审查结果:客户端再次检查 LLM 返回的结果,并决定是否合适。
- 客户端将最终结果返回服务器:如果客户端对 LLM 的生成内容满意,最终结果将被发送回服务器。
设计原理
注意,我重点标注了修改。
sampling是一个核心交互流程的过程概念,定义的是一个标准的三角(
MCP客户端
、MCP服务端
、LLM
)交互步骤流程。但为什么要采用这么一个复杂流程?
人机回圈设计:这种设计确保客户端和 LLM 之间的交互是透明且可控的,代表用户的Agent产品(
MCP客户端
),始终掌握对话的控制权。提高控制度与准确度:通过这种方式,客户端可以避免自动生成的内容偏离预期,并且在用户需求不清晰的情况下,可以向 LLM 请求逐步精细的修正输出。
别的不说,如果不需要用户确认即删除本地文件,甚至无知情权反显,则无安全性可言。所以,本质上,这是
安全可控
的消息生成与审订流程
概念。精简命名成采样确实是有误导性的。特此长文注释。
二、消息格式
采样请求使用标准化的消息格式:
{
messages: [
{
role: "user" | "assistant",
// 消息的角色,"user" 表示用户输入,"assistant" 表示模型或 AI 回复。
content: {
type: "text" | "image", // 消息内容的类型
text?: string, // 仅在type为 "text" 时有效。
data?: string, // 图片的 base64 编码数据,仅在type为 "image" 时有效。
mimeType?: string // 图片的 MIME 类型(例如 "image/png" 或 "image/jpeg"),用于描述资源格式。
}
}
],
modelPreferences?: {
// 模型偏好设置,给模型调用方的建议配置(非强制)。
hints?: [
{
name?: string // 推荐的模型名称或模型家族名称(例如 "gpt-4", "claude" 等)
}
],
costPriority?: number, // 控制成本优先级,取值 0 到 1,数值越高越倾向于选择低成本模型。
speedPriority?: number, // 控制速度优先级,取值 0 到 1,数值越高越倾向于低延迟快速响应的模型。
intelligencePriority?: number // 控制智能优先级,取值 0 到 1,数值越高越倾向于选择能力更强的模型。
},
systemPrompt?: string,
// 给模型的系统级提示词,通常用于设定对话背景或指导模型行为。
includeContext?: "none" | "thisServer" | "allServers",
// 上下文包含范围设置:
// - "none": 不包含上下文;
// - "thisServer": 仅包含当前服务的上下文;
// - "allServers": 包含所有关联服务的上下文。
temperature?: number,
// 控制生成文本的随机性,通常取值范围 0-2。
// 数值越高越随机,越低越确定性强。
maxTokens: number,
// 生成回复的最大 token 数量上限,用于控制输出长度。
stopSequences?: string[],
// 停止序列,指定一个或多个字符串,如果模型生成的内容出现这些序列,则停止输出。
metadata?: Record<string, unknown>
// 附加元数据,可以包含任何结构的额外信息,便于日志、追踪或业务扩展。
}
三、请求参数
《模型上下文协议中文网》附注:标准的请求参数我已经在消息格式中做了直观的翻译。
下面的细节,你可以快速略过,主要掌握一级结构所代表的基础要素,都是围绕上下文和人机回圈设计这个核心。
1、Messages
该数组包含要发送到 LLM 的会话历史记录。每条消息都有:messages
role
: “user” 或 “assistant”content
:消息内容,可以是:- 带有字段的文本内容
text
- 具有 (base64) 和字段的图像内容
data``mimeType
- 带有字段的文本内容
2、模型偏好设置
该对象允许服务器指定其模型选择首选项:modelPreferences
hints
:客户端可用于选择适当模型的模型名称建议数组:name
:可以匹配完整或部分模型名称的字符串(例如“claude-3”、“sonnet”)- 客户端可以将 hint 映射到来自不同提供商的等效模型
- 按首选项顺序评估多个提示
- 优先级值(0-1 标准化):
costPriority
: 降低成本的重要性speedPriority
: 低延迟响应的重要性intelligencePriority
:高级模型功能的重要性
客户根据这些首选项及其可用模型进行最终模型选择。
3、系统提示符
可选字段允许服务器请求特定的系统提示符。客户端可以修改或忽略这一点。systemPrompt
4、上下文包含
该参数指定要包含的 MCP 上下文:includeContext
"none"
:无其他上下文"thisServer"
:包括来自请求服务器的上下文"allServers"
:包括来自所有连接的 MCP 服务器的上下文
客户端控制实际包含的上下文。
5、采样参数
使用以下方法微调 LLM 采样:
temperature
:控制随机性(0.0 到 1.0)maxTokens
:要生成的最大令牌数stopSequences
:停止生成的序列数组metadata
:其他特定于提供程序的参数
四、响应格式
客户端返回一个完成结果:
{
model: string, // 所使用的大语言模型(LLM)名称,例如 "gpt-4"、"llama-2" 等,方便标识消息由哪个模型生成
stopReason?: "endTurn" | "stopSequence" | "maxTokens" | string,
// (可选)消息生成停止的原因:
// - "endTurn": 表示对话轮次正常结束
// - "stopSequence": 碰到指定的停止符序列而终止
// - "maxTokens": 达到最大 token 限制
// - string: 其他自定义停止原因
role: "user" | "assistant",
// 消息的角色身份:
// - "user": 表示由用户发出的消息
// - "assistant": 表示由 LLM(助手)生成的消息
content: {
type: "text" | "image",
// 消息内容的类型:
// - "text": 文本消息
// - "image": 图片消息(例如 Base64 编码图片或 URL)
text?: string,
// (可选)文本消息内容,当 type 为 "text" 时有效
data?: string,
// (可选)二进制数据的字符串表示形式(如 Base64 编码),
// 一般用于存储图片等非文本内容,当 type 为 "image" 时使用
mimeType?: string
// (可选)数据的 MIME 类型,标识 data 字段的格式
// 例如:
// - "image/png": 表示 PNG 格式的图片
// - "image/jpeg": 表示 JPEG 格式的图片
// - "text/plain": 纯文本(一般用于 text 字段,不常用于 data)
}
}
五、示例请求
以下是向客户端请求采样的示例:
{
"method": "sampling/createMessage",
// 请求方法名称,表示调用 "sampling/createMessage",用于让客户端基于上下文与 LLM 进行采样生成回复。
"params": {
// 请求参数部分
"messages": [
{
"role": "user",
// 消息角色,"user" 表示用户发起的消息。
"content": {
"type": "text",
// 消息内容的类型,这里是纯文本。
"text": "当前目录中有哪些文件?"
// 用户实际输入的文本内容,询问目录下的文件列表。
}
}
],
"systemPrompt": "您是文件系统的得力助手.",
// 系统提示词,用于为 LLM 设定角色或行为约束,在本次对话中扮演文件系统助手的角色。
"includeContext": "当前服务",
// 上下文包含范围,指明是否包含当前服务的相关上下文信息,以便于生成更相关的回复。
// 示例值:"当前服务",表示只包含当前服务内的上下文。
"maxTokens": 100
// LLM 回复生成的最大 token 数量上限,用于限制输出长度,防止回复过长或超出资源限制。
}
}
其他
《模型上下文协议中文网》附注:下面部分新手可先不关注
1、最佳实践
实施采样时:
- 始终提供清晰、结构良好的提示
- 适当地处理文本和图像内容
- 设置合理的令牌限制
- 通过以下方式包含相关上下文
includeContext
- 在使用响应之前验证响应
- 优雅地处理错误
- 考虑对采样请求进行速率限制
- 记录预期的采样行为
- 使用各种模型参数进行测试
- 监控采样成本
2、人机交互控制
采样在设计时考虑了人工监督:
对于提示
- 客户端应向用户显示建议的提示
- 用户应该能够修改或拒绝提示
- 可以过滤或修改系统提示
- 上下文包含由客户端控制
对于完成
- 客户端应向用户显示完成情况
- 用户应该能够修改或拒绝完成
- 客户可以筛选或修改完成
- 用户控制使用哪个模型
3、安全注意事项
实施采样时:
- 验证所有消息内容
- 清理敏感信息
- 实施适当的速率限制
- 监控采样使用情况
- 加密传输中的数据
- 处理用户数据隐私
- 审计采样请求
- 控制成本风险
- 实施超时
- 优雅地处理模型错误
4、常见模式
代理工作流
采样支持代理模式,例如:
- 读取和分析资源
- 根据上下文做出决策
- 生成结构化数据
- 处理多步骤任务
- 提供交互式帮助
上下文管理
上下文的最佳实践:
- 请求最少的必要上下文
- 清晰地构建上下文
- 处理上下文大小限制
- 根据需要更新上下文
- 清理过时的上下文
错误处理
健壮的错误处理应该:
- 捕获采样失败
- 处理超时错误
- 管理速率限制
- 验证响应
- 提供回退行为
- 适当地记录错误
5、局限性
请注意以下限制:
- 采样取决于客户端功能
- 用户控制采样行为
- 上下文大小有限制
- 速率限制可能适用
- 应考虑成本
- 型号可用性不尽相同
- 响应时间各不相同
- 并非所有内容类型都受支持