创建可重复使用的提示词模板和工作流
Prompts使服务器能够定义可重用的提示词模板和工作流,客户端可以轻松地将这些模板和工作流呈现给用户和llm。它们提供了一种强大的方式来标准化和共享常见的LLM交互。
概述
MCP中的提示词是预定义的模板,可以:
接受动态参数
包括来自资源的上下文
链式多重交互
指导特定的工作流程
曲面作为UI元素 (如斜线命令)
提示词结构
每个提示词都定义为:
{
name: string; // Unique identifier for the prompt
description?: string; // Human-readable description
arguments?: [ // Optional list of arguments
{
name: string; // Argument identifier
description?: string; // Argument description
required?: boolean; // Whether argument is required
}
]
}
探索提示词
客户端可以通过prompts/list
端点:
// Request
{
method: "prompts/list";
}
// Response
{
prompts: [
{
name: "analyze-code",
description: "Analyze code for potential improvements",
arguments: [
{
name: "language",
description: "Programming language",
required: true,
},
],
},
];
}
使用提示词
要使用提示词,客户端会生成一个prompts/get
请求:
// Request
{
method: "prompts/get",
params: {
name: "analyze-code",
arguments: {
language: "python"
}
}
}
// Response
{
description: "Analyze Python code for potential improvements",
messages: [
{
role: "user",
content: {
type: "text",
text: "Please analyze the following Python code for potential improvements:\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 of code file to review",
"required": true
}
]
}
当处理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",
"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",
"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: `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.",
},
},
];
},
};
示例实现
下面是在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")
最佳实践
实现Prompts时:
使用清晰的描述性提示名称
提供提示和参数的详细说明
验证所有必需的参数
优雅地处理缺少的参数
考虑对提示模板进行版本控制
适当时缓存动态内容
实现错误处理
文档所需的参数格式
考虑提示可组合性
具有各种输入的测试提示
UI集成
提示可以在客户端ui中显示为:
斜杠命令
快速行动
上下文菜单项
命令调色板条目
引导式工作流
交互式窗体
更新和更改
服务器可以通知客户端有关提示更改:
服务器功能:
prompts.listChanged
通知:
notifications/prompts/list_changed
客户端重新提取提示列表
安全注意事项
实现Prompts时:
验证所有参数
清理用户输入
考虑速率限制
实施访问控制
审计提示用法
适当处理敏感数据
验证生成的内容
实现超时
考虑及时注射的风险
文件安全要求
评论区