Bỏ qua tới nội dung
Bài 9/11 · MCP cho người mới bắt đầu (Microsoft)

Sampling: uỷ thác việc cho client

Sampling cho phép MCP server nhờ LLM do client quản lý; cấu trúc request và response, cấu hình phía client, ví dụ tạo tóm tắt bài blog và thử trong Visual Studio Code.

Trung cấp@shine19048 phút đọc

Trong các phần cài đặt cũ, sampling cho phép một MCP server nhờ một LLM do client quản lý giúp đỡ. Với phần cài đặt mới, hãy gọi trực tiếp API của nhà cung cấp LLM đã chọn. Bài này đi qua các tình huống sử dụng và cách xây một giải pháp có sampling.

Tổng quan

Bài này tập trung giải thích khi nào, ở đâu dùng sampling và cách cấu hình nó.

Mục tiêu học tập

Trong bài này, chúng ta sẽ:

  • Giải thích sampling là gì và khi nào dùng.
  • Cách cấu hình sampling trong MCP.
  • Ví dụ sampling hoạt động thực tế.

Sampling là gì và vì sao dùng?

Sampling là một tính năng nâng cao, hoạt động như sau:

mermaid
sequenceDiagram
    participant User
    participant MCP Client
    participant LLM
    participant MCP Server

    User->>MCP Client: Author blog post
    MCP Client->>MCP Server: Tool call (blog post draft)
    MCP Server->>MCP Client: Sampling request (create summary)
    MCP Client->>LLM: Generate blog post summary
    LLM->>MCP Client: Summary result
    MCP Client->>MCP Server: Sampling response (summary)
    MCP Server->>MCP Client: Complete blog post (draft + summary)
    MCP Client->>User: Blog post ready

Tóm lại luồng trên: người dùng nhờ client viết bài blog; client gọi tool trên server với bản nháp; server gửi ngược một yêu cầu sampling (tạo tóm tắt) cho client; client nhờ LLM tạo tóm tắt rồi gửi kết quả lại cho server; server trả về bài blog hoàn chỉnh (bản nháp kèm tóm tắt).

Yêu cầu sampling

Giờ đã có cái nhìn tổng quan về một tình huống hợp lý, hãy xem yêu cầu (request) sampling mà server gửi lại cho client. Ở định dạng JSON-RPC, nó có thể trông như sau:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "sampling/createMessage",
  "params": {
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "Create a blog post summary of the following blog post: <BLOG POST>"
        }
      }
    ],
    "modelPreferences": {
      "hints": [
        {
          "name": "gpt-5.1"
        }
      ],
      "intelligencePriority": 0.8,
      "speedPriority": 0.5
    },
    "systemPrompt": "You are a helpful assistant.",
    "maxTokens": 100
  }
}

Một số điểm đáng chú ý:

  • Prompt, nằm ở content -> text, là chỉ dẫn cho LLM tóm tắt nội dung bài blog.
  • modelPreferences: đúng như tên gọi, đây chỉ là ưu tiên, một khuyến nghị về cấu hình dùng với LLM. Người dùng có thể theo hoặc đổi. Ở đây có khuyến nghị về model và mức ưu tiên tốc độ, trí tuệ.
  • systemPrompt: system prompt thông thường, tạo tính cách cho LLM và chứa chỉ dẫn định hướng.
  • maxTokens: số token được khuyến nghị dùng cho tác vụ này.

Phản hồi sampling

Đây là phản hồi (response) mà MCP client gửi lại cho MCP server: client gọi LLM, chờ kết quả rồi dựng thông điệp này. Ở JSON-RPC, nó có thể trông như sau:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "role": "assistant",
    "content": {
      "type": "text",
      "text": "Here's your abstract <ABSTRACT>"
    },
    "model": "gpt-5.1",
    "stopReason": "endTurn"
  }
}

Phản hồi là bản tóm tắt bài blog đúng như yêu cầu. Client chọn deployment gpt-5.1 đang hoạt động theo ưu tiên model của server; vì ưu tiên model chỉ là khuyến nghị, client có thể chọn deployment khác khi cần.

Đã hiểu luồng chính và một tác vụ hữu ích để dùng nó ("tạo bài blog + tóm tắt"), hãy xem cần làm gì để chạy được.

Các loại thông điệp

Thông điệp sampling không chỉ giới hạn ở văn bản, mà còn có thể gửi ảnh và âm thanh. JSON-RPC khác nhau như sau:

Văn bản

json
{
  "type": "text",
  "text": "The message content"
}

Nội dung ảnh

json
{
  "type": "image",
  "data": "base64-encoded-image-data",
  "mimeType": "image/jpeg"
}

Nội dung âm thanh

json
{
  "type": "audio",
  "data": "base64-encoded-audio-data",
  "mimeType": "audio/wav"
}

Về trạng thái hiện tại và hướng dẫn chuyển đổi, xem tài liệu Sampling (đã ngừng khuyến nghị).

Cấu hình sampling ở client

Nếu bạn chỉ xây server, ở đây bạn không cần làm gì nhiều.

Ở client, bạn khai báo khả năng (capability) sau:

json
{
  "capabilities": {
    "sampling": {}
  }
}

Khai báo này sẽ được nhận khi client khởi tạo kết nối với server.

Ví dụ sampling thực tế: tạo bài blog

Hãy cùng viết một server có sampling. Ta cần:

  1. Tạo một tool trên server.
  2. Tool đó tạo một yêu cầu sampling.
  3. Tool chờ yêu cầu sampling được client trả lời.
  4. Sau đó tạo ra kết quả của tool.

Xem code từng bước.

Bước 1: tạo tool

python
@mcp.tool()
async def create_blog(title: str, content: str, ctx: Context[ServerSession, None]) -> str:
    """Create a blog post and generate a summary"""

Bước 2: tạo yêu cầu sampling

Mở rộng tool bằng code sau:

python
post = BlogPost(
        id=len(posts) + 1,
        title=title,
        content=content,
        abstract=""
    )

prompt = f"Create an abstract of the following blog post: title: {title} and draft: {content} "

result = await ctx.session.create_message(
        messages=[
            SamplingMessage(
                role="user",
                content=TextContent(type="text", text=prompt),
            )
        ],
        max_tokens=100,
)

Bước 3: chờ phản hồi và trả kết quả

python
post.abstract = result.content.text

posts.append(post)

# return the complete product
return json.dumps({
    "id": post.title,
    "abstract": post.abstract
})

Bước 4: code đầy đủ

python
from starlette.applications import Starlette
from starlette.routing import Mount, Host

from mcp.server.fastmcp import Context, FastMCP

from mcp.server.session import ServerSession
from mcp.types import SamplingMessage, TextContent

import json


from uuid import uuid4
from typing import List
from pydantic import BaseModel


mcp = FastMCP("Blog post generator")

# app = FastAPI()

posts = []

class BlogPost(BaseModel):
    id: int
    title: str
    content: str
    abstract: str

posts: List[BlogPost] = []

@mcp.tool()
async def create_blog(title: str, content: str, ctx: Context[ServerSession, None]) -> str:
    """Create a blog post and generate a summary"""

    post = BlogPost(
        id=len(posts) + 1,
        title=title,
        content=content,
        abstract=""
    )

    prompt = f"Create an abstract of the following blog post: title: {title} and draft: {content} "

    result = await ctx.session.create_message(
        messages=[
            SamplingMessage(
                role="user",
                content=TextContent(type="text", text=prompt),
            )
        ],
        max_tokens=100,
    )

    post.abstract = result.content.text

    posts.append(post)

    # return the complete blog post
    return json.dumps({
        "id": post.title,
        "abstract": post.abstract
    })

if __name__ == "__main__":
    print("Starting server...")
    # mcp.run()
    mcp.run(transport="streamable-http")

# run app with: python server.py

Bước 5: thử trong Visual Studio Code

Để thử trong Visual Studio Code:

  1. Khởi động server trong terminal.

  2. Thêm server vào mcp.json (và đảm bảo nó đã chạy), ví dụ:

    json
    "servers": {
       "blog-server": {
         "type": "http",
         "url": "http://localhost:8000/mcp"
       }
    }
    
  3. Gõ một prompt:

    text
    create a blog post named "Where Python comes from", the content is "Python is actually named after Monty Python Flying Circus"
    
  4. Cho phép sampling diễn ra. Lần đầu thử, bạn sẽ thấy thêm một hộp thoại cần chấp nhận, sau đó là hộp thoại thông thường hỏi có chạy tool không.

  5. Xem kết quả. Kết quả hiển thị đẹp trong GitHub Copilot Chat, và bạn cũng xem được phản hồi JSON thô.

Thêm: công cụ của Visual Studio Code hỗ trợ sampling rất tốt. Bạn cấu hình quyền sampling cho server đã cài như sau:

  1. Vào mục extension.
  2. Chọn biểu tượng bánh răng của server đã cài trong mục "MCP SERVERS - INSTALLED".
  3. Chọn "Configure Model Access": tại đây bạn chọn các model GitHub Copilot được phép dùng khi thực hiện sampling. Bạn cũng xem được mọi yêu cầu sampling gần đây bằng "Show Sampling requests".

Bài tập

Bạn sẽ xây một tích hợp sampling hơi khác: tạo mô tả sản phẩm. Tình huống:

Tình huống: nhân viên hậu cần của một trang thương mại điện tử cần giúp đỡ vì viết mô tả sản phẩm mất quá nhiều thời gian. Bạn cần xây một giải pháp có tool "create_product" nhận đối số "title" và "keywords", tạo ra một sản phẩm hoàn chỉnh gồm trường "description" do LLM của client điền.

Gợi ý: dùng những gì đã học để dựng server và tool với một yêu cầu sampling.

Lời giải: solution.

Điểm chính

Sampling là tính năng mạnh cho phép server uỷ thác tác vụ cho client khi cần LLM giúp đỡ.

Bài tiếp theo: Xác thực đơn giản.

Nguồn