درس ۱۴ از ۳۳

Sampling

عنوان اصلی: Sampling

هدف یادگیری: درک sampling: چطور یک server می‌تواند از LLM hostای که به آن وصل است، یک completion درخواست کند، بدون اینکه SDK مدل خودش را بیاورد.

مفاهیم کلیدی: sampling/createMessage، modelPreferences (hints، costPriority، speedPriority، intelligencePriority)، systemPrompt، includeContext، maxTokens، stopReason، human-in-the-loop.

Sampling جهت معمول را معکوس می‌کند: server یک request به client می‌فرستد و از host می‌خواهد یک LLM completion به نیابت آن اجرا کند. این به نویسنده‌های server اجازه می‌دهد رفتار agentic بسازند (مثلاً summarize-this، classify-this) بدون اینکه API key شیپ کنند، بدون اینکه vendor مدل را انتخاب کنند، و بدون اینکه برای inference پول بدهند — host پرداخت می‌کند. Client باید capability sampling را در init اعلام کند، و بهتر است برای هر sampling request یک human-in-the-loop review پیاده کند.

modelPreferences انتزاعی است که انتخاب مدل cross-vendor را handle می‌کند: server priorityها را بیان می‌کند (cost، speed، intelligence به‌صورت float صفر تا یک) و hintها را (substringهایی مثل "claude-3-sonnet" یا "claude" که client به مدل‌های موجودش map می‌کند). hintها advisory هستند؛ host تصمیم می‌گیرد.

مثال عملی — JSON-RPC خام (request که server می‌فرستد)

{ "jsonrpc": "2.0", "id": 1, "method": "sampling/createMessage",
  "params": {
    "messages": [{ "role": "user",
                   "content": { "type": "text", "text": "What is the capital of France?" } }],
    "modelPreferences": {
      "hints": [{ "name": "claude-3-sonnet" }],
      "intelligencePriority": 0.8,
      "speedPriority": 0.5
    },
    "systemPrompt": "You are a helpful assistant.",
    "maxTokens": 100
  } }

مثال عملی — Python (server درخواست sampling از داخل یک tool)

from mcp.types import SamplingMessage, TextContent

@mcp.tool()
async def generate_poem(topic: str, ctx) -> str:
    """Generate a poem using LLM sampling via the host."""
    result = await ctx.session.create_message(
        messages=[
            SamplingMessage(
                role="user",
                content=TextContent(type="text", text=f"Write a poem about {topic}"),
            )
        ],
        max_tokens=100,
    )
    return result.content.text if result.content.type == "text" else str(result.content)

دیاگرام معماری (متنی): Server → Client: sampling/createMessage. Client → User (UI prompt برای approval). User → Client: approve. Client → LLM: forward. LLM → Client: completion. Client → User: review اختیاری خروجی. Client → Server: response.

اشتباهات رایج

  • طراحی serverای که نیازمند sampling است و وقتی client پشتیبانی نمی‌کند می‌شکند. همیشه capability negotiated را چک کنید.
  • hard-code کردن "claude-3-opus" به‌عنوان نام مدل — از hints استفاده کنید، نه نام دقیق.
  • رفتار با sampling مثل عمل رایگان. host می‌پردازد و کاربر review می‌کند؛ throttle کنید.