Sampling 是一个强大的 MCP 功能,它允许 servers 通过 client 请求 LLM 补全,从而实现复杂的 agentic 行为,同时保持安全性和隐私性。

Claude Desktop client 尚未支持此 MCP 功能。

Sampling 的工作原理

Sampling 流程遵循以下步骤:

  1. Server 向 client 发送 sampling/createMessage 请求
  2. Client 审查请求并可以修改它
  3. Client 从 LLM 中 sampling
  4. Client 审查补全结果
  5. Client 将结果返回给 server

这种人机交互设计确保用户可以控制 LLM 看到和生成的内容。

消息格式

Sampling 请求使用标准化的消息格式:

{
  messages: [
    {
      role: "user" | "assistant",
      content: {
        type: "text" | "image",

        // 对于文本:
        text?: string,

        // 对于图像:
        data?: string,             // base64 编码
        mimeType?: string
      }
    }
  ],
  modelPreferences?: {
    hints?: [{
      name?: string                // 建议的模型名称/系列
    }],
    costPriority?: number,         // 0-1,最小化成本的重要性
    speedPriority?: number,        // 0-1,低延迟的重要性
    intelligencePriority?: number  // 0-1,高级功能的重要性
  },
  systemPrompt?: string,
  includeContext?: "none" | "thisServer" | "allServers",
  temperature?: number,
  maxTokens: number,
  stopSequences?: string[],
  metadata?: Record<string, unknown>
}

请求参数

Messages

messages 数组包含要发送给 LLM 的对话历史。每条消息都有:

  • role:“user” 或 “assistant”
  • content:消息内容,可以是:
    • 带有 text 字段的文本内容
    • 带有 data (base64) 和 mimeType 字段的图像内容

模型偏好

modelPreferences 对象允许 servers 指定他们的模型选择偏好:

  • hints:模型名称建议的数组,clients 可以使用它来选择合适的模型:

    • name:可以匹配完整或部分模型名称的字符串(例如 “claude-3”, “sonnet”)
    • Clients 可能会将提示映射到来自不同提供商的等效模型
    • 多个提示按优先顺序评估
  • 优先级值(0-1 归一化):

    • costPriority:最小化成本的重要性
    • speedPriority:低延迟响应的重要性
    • intelligencePriority:高级模型功能的重要性

Clients 根据这些偏好及其可用模型进行最终的模型选择。

System prompt

可选的 systemPrompt 字段允许 servers 请求特定的 system prompt。Client 可能会修改或忽略它。

上下文包含

includeContext 参数指定要包含的 MCP 上下文:

  • "none":不包含任何额外的上下文
  • "thisServer":包含来自请求 server 的上下文
  • "allServers":包含来自所有已连接 MCP servers 的上下文

Client 控制实际包含的上下文。

Sampling 参数

使用以下参数微调 LLM sampling:

  • temperature:控制随机性(0.0 到 1.0)
  • maxTokens:要生成的最大 tokens 数
  • stopSequences:停止生成的序列数组
  • metadata:其他特定于提供商的参数

响应格式

Client 返回一个补全结果:

{
  model: string,  // 使用的模型的名称
  stopReason?: "endTurn" | "stopSequence" | "maxTokens" | string,
  role: "user" | "assistant",
  content: {
    type: "text" | "image",
    text?: string,
    data?: string,
    mimeType?: string
  }
}

示例请求

以下是从 client 请求 sampling 的示例:

{
  "method": "sampling/createMessage",
  "params": {
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "当前目录中有哪些文件?"
        }
      }
    ],
    "systemPrompt": "你是一个有用的文件系统助手。",
    "includeContext": "thisServer",
    "maxTokens": 100
  }
}

最佳实践

在实现 sampling 时:

  1. 始终提供清晰、结构良好的 prompts
  2. 适当地处理文本和图像内容
  3. 设置合理的 token 限制
  4. 通过 includeContext 包含相关上下文
  5. 在使用响应之前验证它们
  6. 优雅地处理错误
  7. 考虑限制 sampling 请求的速率
  8. 记录预期的 sampling 行为
  9. 使用各种模型参数进行测试
  10. 监控 sampling 成本

人工干预控制

Sampling 的设计考虑到了人工监督:

对于 prompts

  • Clients 应该向用户显示建议的 prompt
  • 用户应该能够修改或拒绝 prompts
  • System prompts 可以被过滤或修改
  • 上下文包含由 client 控制

对于补全结果

  • Clients 应该向用户显示补全结果
  • 用户应该能够修改或拒绝补全结果
  • Clients 可以过滤或修改补全结果
  • 用户控制使用哪个模型

安全考虑

在实现 sampling 时:

  • 验证所有消息内容
  • 清理敏感信息
  • 实现适当的速率限制
  • 监控 sampling 使用情况
  • 加密传输中的数据
  • 处理用户数据隐私
  • 审计 sampling 请求
  • 控制成本暴露
  • 实现超时
  • 优雅地处理模型错误

常见模式

Agentic 工作流

Sampling 实现了 agentic 模式,例如:

  • 读取和分析 resources
  • 根据上下文做出决策
  • 生成结构化数据
  • 处理多步任务
  • 提供交互式帮助

上下文管理

上下文的最佳实践:

  • 请求最少必要的上下文
  • 清楚地构建上下文
  • 处理上下文大小限制
  • 根据需要更新上下文
  • 清理过时的上下文

错误处理

强大的错误处理应:

  • 捕获 sampling 失败
  • 处理超时错误
  • 管理速率限制
  • 验证响应
  • 提供回退行为
  • 适当地记录错误

限制

请注意以下限制:

  • Sampling 依赖于 client 的功能
  • 用户控制 sampling 行为
  • 上下文大小有限制
  • 可能会应用速率限制
  • 应该考虑成本
  • 模型可用性各不相同
  • 响应时间各不相同
  • 并非所有内容类型都受支持