原文地址: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 improvements
arguments: [
{
name: "language",
description: "编程语言", // Programming language
required: true
}
]
}
// ... 其他提示
]
}
使用提示
要使用一个提示,客户端发出 prompts/get
请求:
// 请求
{
method: "prompts/get",
params: {
name: "analyze-code", // 要使用的提示名称
arguments: { // 提供的参数
language: "python"
}
}
}
// 响应
{
description: "分析 Python 代码以寻找潜在改进", // Analyze Python code for potential improvements
messages: [ // 生成的、准备发送给 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) 风险
- 记录安全要求