提示工程是AI应用开发中的关键环节,而MCP框架提供了强大的提示模板系统,使开发者能够创建结构化、可复用的提示模板。本文将深入探讨MCP的提示模板系统,介绍如何创建从简单到复杂的各类提示模板,包括字符串模板、消息列表、嵌入资源和复合提示。通过这些示例,你将了解如何设计高效的AI交互模式,为用户提供更加智能和个性化的体验。
提示模板系统简介
MCP的提示模板系统允许开发者定义结构化的提示,这些提示可以根据输入参数动态生成。提示模板系统的主要优势包括:
- 参数化设计:通过参数化提示,可以根据不同情境生成定制内容
- 结构化格式:支持多种提示格式,从简单文本到复杂的消息列表
- 资源嵌入:可以在提示中嵌入代码、数据等资源
- 可复用性:模板可以在不同场景中重复使用,提高开发效率
提示模板类型与实现
1. 简单字符串提示模板
最基本的提示模板是返回字符串的函数,这些字符串会自动转换为用户消息:
@mcp.prompt()
def simple_greeting(name: str, role: str = "用户") -> str:
"""简单的问候语提示模板"""
return f"""你好,我是{name},作为一名{role},我希望你能帮助我解决一些问题。
请用简洁专业的语言回答我的问题,避免过多的客套话。
如果你不确定答案,请直接告诉我你不知道,而不是猜测可能的回答。
"""
这种简单模板适用于创建基本的用户指令,通过参数可以个性化问候语和角色设定。
2. 消息列表提示模板
对于更复杂的场景,我们可以返回消息列表,模拟多轮对话:
@mcp.prompt()
def debug_error(error: str) -> List[base.Message]:
"""调试错误的多轮对话模板"""
return [
base.UserMessage("我遇到了以下错误:"),
base.UserMessage(error),
base.AssistantMessage("我会帮你调试这个问题。你之前尝试过哪些解决方法?"),
]
消息列表模板可以创建包含上下文的对话历史,帮助AI理解问题背景和预期的回答方式。
3. 嵌入资源提示模板
嵌入资源提示模板允许在提示中包含代码、数据等结构化内容:
@mcp.prompt()
def review_code(code_snippet: str, language: str = "python") -> base.Message:
"""代码审查提示模板,带嵌入资源"""
mime_type = {
"python": "text/x-python",
"javascript": "text/javascript",
# 其他语言映射...
}.get(language.lower(), "text/plain")
return base.UserMessage(
content=EmbeddedResource(
type="resource",
resource=TextResourceContents(
uri=f"data://code-snippet.{language}",
text=code_snippet,
mimeType=mime_type,
),
)
)
通过指定适当的MIME类型,AI可以更好地理解和处理嵌入的代码或数据。
4. 复合提示模板
复合提示模板结合了文本和嵌入资源,适用于更复杂的场景:
@mcp.prompt()
def data_analysis_request(dataset_description: str, data_sample: str) -> List[base.Message]:
"""数据分析请求模板"""
# 检测数据格式是CSV还是JSON
mime_type = "application/json" if data_sample.strip().startswith("{") else "text/csv"
return [
base.UserMessage(f"""我需要分析以下数据集:
{dataset_description}
我希望能够了解数据中的主要趋势和模式,并获得一些数据可视化的建议。
"""),
base.UserMessage(
content=EmbeddedResource(
type="resource",
resource=TextResourceContents(
uri="data://sample-data",
text=data_sample,
mimeType=mime_type,
),
)
),
base.AssistantMessage("我将帮助你分析这些数据。请告诉我你最关心的指标是什么?")
]
复合提示模板可以同时包含问题描述和数据样本,为AI提供完整的上下文。
5. 文件引用提示模板
有时我们需要引用文件而不是直接嵌入内容:
@mcp.prompt()
def file_analysis_request(file_path: str, analysis_type: str = "general") -> base.Message:
"""文件分析请求模板"""
analysis_descriptions = {
"general": "对文件进行一般性分析,包括代码结构、逻辑和最佳实践",
"security": "对文件进行安全分析,识别潜在的安全漏洞和风险",
"performance": "对文件进行性能分析,找出可能的性能瓶颈和优化机会"
}
description = analysis_descriptions.get(analysis_type, analysis_descriptions["general"])
return base.UserMessage(f"""请对以下文件进行{analysis_type}分析:
文件路径: {file_path}
分析要求: {description}
请提供详细的分析结果和改进建议。
""")
文件引用提示模板适用于需要分析特定文件的场景,可以指定分析类型和要求。
客户端使用提示模板
在客户端,我们可以使用session.get_prompt()方法来渲染提示模板:
# 列出所有可用的提示模板
prompts = await session.list_prompts()
# 渲染简单字符串提示模板
result = await session.get_prompt("simple_greeting", {
"name": "张三",
"role": "软件开发者"
})
# 渲染消息列表提示模板
result = await session.get_prompt("debug_error", {
"error": "TypeError: Cannot read property 'value' of undefined"
})
# 渲染嵌入资源提示模板
result = await session.get_prompt("review_code", {
"code_snippet": code,
"language": "python"
})
# 渲染复合提示模板
result = await session.get_prompt("data_analysis_request", {
"dataset_description": "学生成绩数据集,包含学生ID、姓名、年龄和分数",
"data_sample": data_sample
})
# 渲染文件分析提示模板
result = await session.get_prompt("file_analysis_request", {
"file_path": "mcp/05_content_types.py",
"analysis_type": "performance"
})
渲染结果可能是简单的字符串,也可能是包含多个消息和嵌入资源的复杂结构,具体取决于提示模板的定义。
提示模板设计最佳实践
- 参数化关键信息:将可变部分作为参数,使模板更加灵活
- 提供合理默认值:为可选参数提供合理的默认值,简化使用
- 添加清晰描述:为模板和参数提供详细的文档字符串
- 设置适当的上下文:在提示中包含足够的上下文信息,帮助AI理解任务
- 使用正确的MIME类型:为嵌入资源指定正确的MIME类型
- 模块化设计:将复杂提示拆分为可复用的小模板
- 考虑多轮对话:设计模板时考虑多轮对话的可能性
- 验证输入参数:在模板函数中验证输入参数,确保生成有效的提示
提示模板应用场景
提示模板系统可以应用于多种场景:
- 代码审查:创建代码审查提示模板,包含代码片段和审查要求
- 数据分析:设计数据分析提示模板,包含数据样本和分析目标
- 错误调试:开发错误调试提示模板,包含错误信息和上下文
- 内容生成:构建内容生成提示模板,指定风格、长度和主题
- 知识问答:设计知识问答提示模板,包含问题和背景信息
- 个性化交互:创建个性化交互提示模板,根据用户偏好调整交互方式