提示
创建可重用的提示模板和工作流
提示使服务器能够定义可重用的提示模板和工作流,客户端可以轻松地向用户和 LLM 显示这些模板和工作流。它们提供了一种强大的方法来标准化和共享常见的 LLM 交互。
一、概述
MCP 中的提示是预定义的模板,可以:
- 接受动态参数
- 包括来自资源的上下文
- 链接多个交互
- 指导特定工作流程
- Surface 作为 UI 元素(如斜杠命令)
二、提示结构
每个提示都定义如下:
typescript
{
name: string; // 提示(prompt)的唯一标识符
description?: string; // 可选,提示的人类可读描述
arguments?: [ // 可选,参数列表
{
name: string; // 参数的标识符
description?: string; // 可选,参数的描述信息
required?: boolean; // 可选,表示该参数是否必填
}
]
}
三、发现提示
客户端可以通过终端节点发现可用的提示:prompts/list
typescript
// 请求
{
method: "prompts/list"
}
//响应
{
prompts: [
{
name: "analyze-code",
description: "分析代码,找出可能的改进之处",
arguments: [
{
name: "language",
description: "编程语言",
required: true //该参数必传
}
]
}
]
}
四、使用提示
要使用提示,客户端会发出请求:prompts/get
typescript
// 请求
{
method: "prompts/get",
params: {
name: "analyze-code",
arguments: {
language: "python"
}
}
}
// 响应
{
description: "分析 Python 代码,寻找可能的改进",
messages: [
{
role: "user",
content: {
type: "text",
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```"
}
}
]
}
五、动态提示
提示可以是动态的,包括:
1、嵌入式资源上下文
json
{
"name": "analyze-project",
"description": "分析项目日志和代码",
"arguments": [
{
"name": "timeframe",
"description": "分析日志的时间段",
"required": true
},
{
"name": "fileUri",
"description": "要审查的代码文件的 URI",
"required": true
}
]
}
处理请求时:prompts/get
json
{
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "分析这些系统日志和代码文件,查找任何问题:"
}
},
{
"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"
}
}
}
]
}
2、多步骤工作流
typescript
const debugWorkflow = {
name: "debug-error",
async getMessages(error: string) {
return [
{
role: "user",
content: {
type: "text",
text: `下面是我看到的一个错误: ${error}`
}
},
{
role: "assistant",
content: {
type: "text",
text: "我来帮你分析这个错误。 您目前尝试了哪些方法?"
}
},
{
role: "user",
content: {
type: "text",
text: "我试过重启服务,但错误依然存在."
}
}
];
}
};
六、示例实现
以下是在 MCP 服务器中实现提示的完整示例:
TypeScript范例
typescript
// 从 MCP SDK 中导入 Server 类
import { Server } from "@modelcontextprotocol/sdk/server";
// 从 MCP SDK 中导入请求的类型定义,用于处理“获取提示列表”和“获取单个提示”请求
import {
ListPromptsRequestSchema,
GetPromptRequestSchema
} from "@modelcontextprotocol/sdk/types";
// 定义提示(prompts)集合,键是提示名称,值是提示的详细信息
const PROMPTS = {
// 第一个提示:生成 Git 提交信息
"git-commit": {
name: "git-commit", // 唯一标识符
description: "生成一个 Git commit 消息", // 描述
arguments: [ // 参数列表
{
name: "changes", // 参数名
description: "Git diff 或更改说明", // 参数说明
required: true // 必填
}
]
},
// 第二个提示:解释代码含义
"explain-code": {
name: "explain-code", // 唯一标识符
description: "解释代码如何工作", // 描述
arguments: [
{
name: "code", // 代码文本
description: "需要解释的代码", // 参数说明
required: true // 必填
},
{
name: "language",
description: "编程语言", // 参数说明
required: false // 非必填
}
]
}
};
// 创建 MCP 服务器实例
const server = new Server(
{
name: "example-prompts-server", // 服务器名称
version: "1.0.0" // 版本号
},
{
capabilities: {
prompts: {} // 声明支持 "prompts" 能力
}
}
);
// 注册请求处理器:列出可用的 prompts(提示模板)
server.setRequestHandler(ListPromptsRequestSchema, async () => {
return {
prompts: Object.values(PROMPTS) // 返回所有提示模板的数组
};
});
// 注册请求处理器:获取指定的 prompt,并根据参数生成消息
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
// 根据请求参数中的 name 获取对应的提示
const prompt = PROMPTS[request.params.name];
// 如果没有找到提示,抛出错误
if (!prompt) {
throw new Error(`Prompt not found: ${request.params.name}`);
}
// 针对 git-commit 提示的处理
if (request.params.name === "git-commit") {
return {
messages: [
{
role: "user", // 消息角色
content: {
type: "text", // 消息类型是文本
text: `为这些更改生成简明扼要的提交信息:\n\n${request.params.arguments?.changes}`
// 生成的文本,将请求参数中的 changes 插入提示中
}
}
]
};
}
// 针对 explain-code 提示的处理
if (request.params.name === "explain-code") {
const language = request.params.arguments?.language || "Unknown"; // 获取语言参数,默认 Unknown
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `请解释这些 ${language} 代码如何工作:\n\n${request.params.arguments?.code}`
// 生成的文本,将请求参数中的 code 和 language 插入提示中
}
}
]
};
}
// 如果没有实现对应的提示处理逻辑,抛出错误
throw new Error("未找到提示执行");
});
其他
《模型上下文协议中文网》附注:下面部分新手可先不关注
1、最佳实践
实施提示时:
- 使用清晰、描述性的提示名称
- 提供提示和参数的详细说明
- 验证所有必需的参数
- 优雅地处理缺失的参数
- 考虑对提示模板进行版本控制
- 在适当时缓存动态内容
- 实施错误处理
- 记录预期的参数格式
- 考虑提示可组合性
- 使用各种输入的测试提示
2、UI 集成
提示可以在客户端 UI 中显示为:
- 斜杠命令
- 快速作
- 上下文菜单项
- 命令面板条目
- 引导式工作流
- 交互式表单
3、更新和更改
服务器可以通知客户端提示更改:
- 服务器功能:
prompts.listChanged
- 通知:
notifications/prompts/list_changed
- 客户端重新获取提示列表
4、安全注意事项
实施提示时:
- 验证所有参数
- 清理用户输入
- 考虑速率限制
- 实施访问控制
- 审核提示使用情况
- 适当处理敏感数据
- 验证生成的内容
- 实施超时
- 考虑及时注射风险
- 文档安全要求