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:
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:
{
"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:
{
"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
{
"type": "text",
"text": "The message content"
}
Nội dung ảnh
{
"type": "image",
"data": "base64-encoded-image-data",
"mimeType": "image/jpeg"
}
Nội dung âm thanh
{
"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:
{
"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:
- Tạo một tool trên server.
- Tool đó tạo một yêu cầu sampling.
- Tool chờ yêu cầu sampling được client trả lời.
- Sau đó tạo ra kết quả của tool.
Xem code từng bước.
Bước 1: tạo tool
@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:
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ả
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 đủ
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:
-
Khởi động server trong terminal.
-
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" } } -
Gõ một prompt:
textcreate a blog post named "Where Python comes from", the content is "Python is actually named after Monty Python Flying Circus" -
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.
-
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:
- Vào mục extension.
- Chọn biểu tượng bánh răng của server đã cài trong mục "MCP SERVERS - INSTALLED".
- 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
- Dịch và biên tập từ microsoft/mcp-for-beginners · 03-GettingStarted/14-sampling/README.md, giấy phép MIT.