原文地址:https://modelcontextprotocol.io/docs/concepts/prompts#python
提示 (Prompts)
創建可重用的提示模板和工作流
提示 (Prompts) 使服務器能夠定義可重用的提示模板和工作流,客戶端可以輕松地將其呈現給用戶和 LLM。它們提供了一種強大的方式來標準化和共享常見的 LLM 交互。
提示被設計為用戶控制 (user-controlled),這意味著它們從服務器暴露給客戶端,目的是讓用戶能夠顯式選擇它們來使用。
概述
MCP 中的提示是預定義的模板,可以:
- 接受動態參數 (arguments)
- 包含來自資源 (resources) 的上下文
- 鏈接多個交互
- 指導特定的工作流
- 作為 UI 元素呈現(例如斜杠命令)
提示結構
每個提示都通過以下結構定義:
{name: string; // 提示的唯一標識符description?: string; // 人類可讀的描述arguments?: [ // 可選的參數列表{name: string; // 參數標識符description?: string; // 參數描述required?: boolean; // 參數是否必需}]
}
發現提示
客戶端可以通過 prompts/list
端點發現可用的提示:
// 請求
{method: "prompts/list"
}// 響應
{prompts: [{name: "analyze-code",description: "分析代碼以尋找潛在改進", // Analyze code for potential improvementsarguments: [{name: "language",description: "編程語言", // Programming languagerequired: true}]}// ... 其他提示]
}
使用提示
要使用一個提示,客戶端發出 prompts/get
請求:
// 請求
{method: "prompts/get",params: {name: "analyze-code", // 要使用的提示名稱arguments: { // 提供的參數language: "python"}}
}// 響應
{description: "分析 Python 代碼以尋找潛在改進", // Analyze Python code for potential improvementsmessages: [ // 生成的、準備發送給 LLM 的消息列表{role: "user", // 角色通常是 "user" 或 "assistant"content: {type: "text", // 內容類型,可以是 "text" 或 "resource"text: "請分析以下 Python 代碼以尋找潛在改進:\n\n```python\ndef calculate_sum(numbers):\n total = 0\n for num in numbers:\n total = total + num\n return total\n\nresult = calculate_sum([1, 2, 3, 4, 5])\nprint(result)\n```" // 提示的文本內容}}// ... 可能有更多消息]
}
動態提示
提示可以是動態的,并包含:
嵌入式資源上下文
// 提示定義
{"name": "analyze-project","description": "分析項目日志和代碼", // Analyze project logs and code"arguments": [{"name": "timeframe","description": "要分析日志的時間段", // Time period to analyze logs"required": true},{"name": "fileUri","description": "要審查的代碼文件的 URI", // URI of code file to review"required": true}]
}
當處理 prompts/get
請求時,服務器可以動態獲取資源內容并將其嵌入到消息中:
// prompts/get 的響應
{"messages": [{"role": "user","content": {"type": "text","text": "請分析這些系統日志和代碼文件是否存在任何問題:" // Analyze these system logs and the code file for any issues:}},{"role": "user","content": {"type": "resource", // 內容類型為資源"resource": { // 包含資源詳情"uri": "logs://recent?timeframe=1h", // 資源的 URI (可能是動態生成的)// 服務器動態獲取的資源內容"text": "[2024-03-14 15:32:11] ERROR: Connection timeout in network.py:127\n[2024-03-14 15:32:15] WARN: Retrying connection (attempt 2/3)\n[2024-03-14 15:32:20] ERROR: Max retries exceeded","mimeType": "text/plain"}}},{"role": "user","content": {"type": "resource","resource": {"uri": "file:///path/to/code.py", // 另一個資源的 URI// 該資源的內容"text": "def connect_to_service(timeout=30):\n retries = 3\n for attempt in range(retries):\n try:\n return establish_connection(timeout)\n except TimeoutError:\n if attempt == retries - 1:\n raise\n time.sleep(5)\n\ndef establish_connection(timeout):\n # Connection implementation\n pass","mimeType": "text/x-python"}}}]
}
多步驟工作流
提示可以定義包含多個交互輪次的工作流:
// 服務器端的邏輯示例
const debugWorkflow = {name: "debug-error",async getMessages(error: string) {// 返回一個預設的對話流程return [{role: "user",content: {type: "text",text: `我遇到了這個錯誤:${error}` // Here's an error I'm seeing: ${error}}},{role: "assistant", // 預設的助手回應content: {type: "text",text: "我來幫你分析這個錯誤。你目前嘗試了哪些方法?" // I'll help analyze this error. What have you tried so far?}},{role: "user", // 預設的用戶后續輸入提示content: {type: "text",text: "我嘗試重啟了服務,但錯誤依舊存在。" // I've tried restarting the service, but the error persists.}}// ... 后續可以由 LLM 或用戶繼續];}
};
實現示例
這是一個在 MCP 服務器中實現提示的完整示例:
from mcp.server import Server
import mcp.types as types# Define available prompts
PROMPTS = {"git-commit": types.Prompt(name="git-commit",description="Generate a Git commit message",arguments=[types.PromptArgument(name="changes",description="Git diff or description of changes",required=True)],),"explain-code": types.Prompt(name="explain-code",description="Explain how code works",arguments=[types.PromptArgument(name="code",description="Code to explain",required=True),types.PromptArgument(name="language",description="Programming language",required=False)],)
}# Initialize server
app = Server("example-prompts-server")@app.list_prompts()
async def list_prompts() -> list[types.Prompt]:return list(PROMPTS.values())@app.get_prompt()
async def get_prompt(name: str, arguments: dict[str, str] | None = None
) -> types.GetPromptResult:if name not in PROMPTS:raise ValueError(f"Prompt not found: {name}")if name == "git-commit":changes = arguments.get("changes") if arguments else ""return types.GetPromptResult(messages=[types.PromptMessage(role="user",content=types.TextContent(type="text",text=f"Generate a concise but descriptive commit message "f"for these changes:\n\n{changes}"))])if name == "explain-code":code = arguments.get("code") if arguments else ""language = arguments.get("language", "Unknown") if arguments else "Unknown"return types.GetPromptResult(messages=[types.PromptMessage(role="user",content=types.TextContent(type="text",text=f"Explain how this {language} code works:\n\n{code}"))])raise ValueError("Prompt implementation not found")
最佳實踐
在實現提示時:
- 使用清晰、描述性的提示名稱
- 為提示和參數提供詳細的描述
- 驗證所有必需的參數
- 優雅地處理缺失的參數
- 考慮對提示模板進行版本控制
- 在適當時緩存動態內容
- 實現錯誤處理
- 記錄預期的參數格式
- 考慮提示的可組合性
- 使用各種輸入測試提示
UI 集成
提示可以在客戶端 UI 中呈現為:
- 斜杠命令 (Slash commands)
- 快捷操作 (Quick actions)
- 上下文菜單項 (Context menu items)
- 命令面板條目 (Command palette entries)
- 引導式工作流 (Guided workflows)
- 交互式表單 (Interactive forms)
更新與變更
服務器可以通知客戶端關于提示的變更:
- 服務器能力聲明:
prompts.listChanged
(表明服務器支持此通知) - 通知消息:
notifications/prompts/list_changed
- 客戶端收到通知后重新獲取提示列表
安全注意事項
在實現提示時:
- 驗證所有參數
- 凈化用戶輸入
- 考慮速率限制
- 實施訪問控制
- 審計提示使用情況
- 適當地處理敏感數據
- 驗證生成的內容(如果適用)
- 實現超時機制
- 考慮提示注入 (prompt injection) 風險
- 記錄安全要求