第8章 提示模板(Prompts)开发
前言
提示模板是MCP中最强大的功能——它将专家级的知识、最佳实践和复杂的推理逻辑编码到可复用的模板中。本章讲解如何设计和管理高效的提示模板。
8.1 提示模板的定义与作用
8.1.1 什么是提示模板
graph TB
A["提示模板 Prompt"] --> B["本质"]
A --> C["特征"]
A --> D["价值"]
B --> B1["预定义的提示词"]
B --> B2["参数化的指令"]
B --> B3["专家知识的编码"]
C --> C1["参数可变"]
C --> C2["动态生成"]
C --> C3["可复用"]
C --> C4["版本控制"]
D --> D1["标准化输出"]
D --> D2["质量保证"]
D --> D3["知识复用"]
D --> D4["降低成本"]
提示模板的核心定义:
提示模板是预定义的、参数化的、可复用的文本模板,用于:
- 标准化推理 - 确保一致的分析方法
- 知识编码 - 将专家经验转化为通用流程
- 质量控制 - 降低LLM输出的变异性
- 成本优化 - 减少需要调整的提示词数量
8.1.2 提示模板与工具/资源的区别
graph TB
A["MCP三大核心功能"] --> B["工具 Tools"]
A --> C["资源 Resources"]
A --> D["提示模板 Prompts"]
B --> B1["执行操作"]
B --> B2["有副作用"]
B --> B3["返回数据"]
C --> C1["存储数据"]
C --> C2["持久化"]
C --> C3["可订阅"]
D --> D1["指导推理"]
D --> D2["文本生成"]
D --> D3["无副作用"]
E["关键区别"] --> E1["工具=做什么"]
E --> E2["资源=在哪里"]
E --> E3["提示=如何做"]
| 维度 | 工具 | 资源 | 提示模板 |
|---|---|---|---|
| 目的 | 执行操作 | 存储数据 | 指导推理 |
| 特性 | 有副作用 | 持久化 | 无副作用 |
| 复用性 | 低 | 中 | 高 |
| 参数化 | 少 | 无 | 多 |
| 使用场景 | 数据修改 | 数据访问 | 思路引导 |
8.2 提示模板的设计原则
8.2.1 清晰性原则
❌ 不清晰的提示模板:
"分析数据并给出建议"
✅ 清晰的提示模板:
"""您是一位资深销售分析师。
任务:分析{period}期间{region}地区的销售数据
分析维度:
1. 销售额趋势变化
2. 产品结构分布
3. 客户群体特征
4. 地区对标表现
输出格式:
- 核心指标摘要(3-5项)
- 关键发现(3-5项)
- 建议和改进措施(3-5项)
"""
清晰性检查清单:
- 角色明确(你是谁?)
- 任务明确(做什么?)
- 范围界定(分析什么?)
- 输出格式定义(如何输出?)
- 优先级排列(什么最重要?)
8.2.2 一致性原则
# ✅ 一致的模板结构
TEMPLATE_STRUCTURE = """
## 角色定义
{role}
## 背景信息
{context}
## 具体任务
{task}
## 输入数据
{input_data}
## 处理流程
1. {step_1}
2. {step_2}
3. {step_3}
## 输出要求
{output_format}
## 成功标准
{success_criteria}
"""
所有提示模板遵循统一的结构,帮助用户快速理解和应用。
8.2.3 参数化原则
参数分类:
graph TB
A["提示模板参数"] --> B["上下文参数"]
A --> C["业务参数"]
A --> D["控制参数"]
B --> B1["role - 角色设定"]
B --> B2["context - 背景信息"]
B --> B3["domain - 领域知识"]
C --> C1["entity - 分析对象"]
C --> C2["period - 时间范围"]
C --> C3["scope - 分析范围"]
D --> D1["language - 输出语言"]
D --> D2["style - 风格"]
D --> D3["detail - 详细程度"]
8.3 提示模板的实现
8.3.1 基础提示模板类
from typing import Dict, Optional, List
from dataclasses import dataclass
from datetime import datetime
import json
@dataclass
class PromptArgument:
"""提示模板参数定义"""
name: str
description: str
type: str # string, number, boolean, array
required: bool = True
default: Optional[str] = None
enum_values: Optional[List[str]] = None
class PromptTemplate:
"""提示模板基类"""
def __init__(self, name: str, description: str, template: str):
self.name = name
self.description = description
self.template = template
self.arguments: Dict[str, PromptArgument] = {}
self.created_at = datetime.now()
self.version = "1.0.0"
def add_argument(self, arg: PromptArgument):
"""添加参数定义"""
self.arguments[arg.name] = arg
def validate_arguments(self, **kwargs) -> bool:
"""验证提供的参数"""
# 检查必需参数
for name, arg in self.arguments.items():
if arg.required and name not in kwargs:
raise ValueError(f"Missing required argument: {name}")
# 检查枚举值
if arg.enum_values and name in kwargs:
value = kwargs[name]
if value not in arg.enum_values:
raise ValueError(
f"Invalid value for {name}: {value}. "
f"Must be one of {arg.enum_values}"
)
return True
def render(self, **kwargs) -> str:
"""
渲染提示模板
Args:
**kwargs: 模板参数
Returns:
渲染后的提示词
"""
# 验证参数
self.validate_arguments(**kwargs)
# 填充默认值
for name, arg in self.arguments.items():
if name not in kwargs and arg.default:
kwargs[name] = arg.default
# 使用参数渲染模板
return self.template.format(**kwargs)
def to_dict(self) -> Dict:
"""转换为字典(用于MCP协议)"""
return {
"name": self.name,
"description": self.description,
"arguments": [
{
"name": arg.name,
"description": arg.description,
"type": arg.type,
"required": arg.required,
"default": arg.default,
"enum": arg.enum_values
}
for arg in self.arguments.values()
]
}
8.3.2 常见提示模板实例
销售分析模板:
class SalesAnalysisTemplate(PromptTemplate):
"""销售数据分析提示模板"""
def __init__(self):
template = """您是一位资深销售分析师,拥有15年的数据分析经验。
## 分析目标
分析 {period} 期间 {region} 地区的销售表现
## 可用数据
- 销售总额:{total_sales}
- 订单数量:{order_count}
- 平均订单值:{average_order_value}
- 同比增长率:{growth_rate}%
- 产品分布:{product_distribution}
## 分析框架
请从以下维度进行分析:
1. **销售趋势分析**
- 与上期对比(环比)
- 与去年同期对比(同比)
- 发展趋势评估
2. **产品结构分析**
- 各类别销售占比
- 增长驱动因素
- 产品竞争力评估
3. **客户洞察**
- 客户群体特征
- 消费行为变化
- 客户满意度信号
4. **地区对标**
- 与其他地区对比
- 排名和优劣势
- 标杆学习机会
## 输出要求
以结构化的方式呈现分析结果:
### 执行摘要
- 最重要的3个指标
- 核心发现
- 风险预警
### 详细分析
[各维度的深入分析]
### 建议措施
1. 短期行动(1-3月)
2. 中期策略(3-6月)
3. 长期规划(6-12月)
### 预期影响
[各项建议的预期结果]
---
分析时要求:
- 深入但不冗长
- 数据驱动
- 可行性强
- 具有商业洞察力
"""
super().__init__(
name="sales_analysis",
description="进行销售数据深度分析并提出改进建议",
template=template
)
# 添加参数
self.add_argument(PromptArgument(
name="period",
description="分析时间段,如'2025年10月'",
type="string",
required=True
))
self.add_argument(PromptArgument(
name="region",
description="地区代码",
type="string",
required=True,
enum_values=["CN", "US", "EU", "APAC"]
))
self.add_argument(PromptArgument(
name="total_sales",
description="销售总额(单位:万元)",
type="number",
required=True
))
# ... 其他参数
8.3.3 高级特性:条件逻辑
class ConditionalPromptTemplate(PromptTemplate):
"""支持条件逻辑的提示模板"""
def render(self, **kwargs) -> str:
"""渲染模板,支持条件渲染"""
# 基础渲染
content = self.template.format(**kwargs)
# 条件处理
if kwargs.get("include_benchmarking", False):
content += "\n\n## 地区对标分析\n[对标内容]"
if kwargs.get("detail_level", "normal") == "detailed":
content += "\n\n## 深度分析\n[更详细的分析]"
return content
8.4 提示模板的参数化与动态生成
8.4.1 参数注入
class ParameterizedPromptTemplate(PromptTemplate):
"""支持复杂参数注入的提示模板"""
def render(self, **kwargs) -> str:
"""渲染模板,支持参数的高级处理"""
# 1. 参数验证与转换
processed_args = self._process_arguments(kwargs)
# 2. 参数补充(生成派生参数)
enriched_args = self._enrich_arguments(processed_args)
# 3. 模板渲染
return self.template.format(**enriched_args)
def _process_arguments(self, kwargs: Dict) -> Dict:
"""处理参数(验证、转换、清理)"""
processed = {}
for name, arg in self.arguments.items():
value = kwargs.get(name, arg.default)
# 类型转换
if arg.type == "number" and isinstance(value, str):
value = float(value)
processed[name] = value
return processed
def _enrich_arguments(self, args: Dict) -> Dict:
"""
从基础参数生成派生参数
例如:从时间范围生成"分析周期描述"
"""
enriched = args.copy()
# 示例:从period生成description
if "period" in args:
period = args["period"]
if "month" in period.lower():
enriched["period_desc"] = f"{period}的月度数据"
elif "quarter" in period.lower():
enriched["period_desc"] = f"{period}的季度数据"
return enriched
8.4.2 动态提示生成
class DynamicPromptGenerator:
"""动态生成提示模板"""
def __init__(self):
self.templates: Dict[str, PromptTemplate] = {}
def generate_context_aware_prompt(self, context: Dict) -> str:
"""
根据上下文智能生成提示
Args:
context: 包含用户背景、任务类型、数据规模等信息
Returns:
生成的提示词
"""
# 1. 分析上下文
user_level = context.get("user_level", "intermediate") # beginner/intermediate/expert
task_complexity = context.get("complexity", "medium") # simple/medium/complex
data_volume = context.get("data_volume", "small") # small/medium/large
# 2. 选择合适的提示策略
prompt_parts = []
# 根据用户级别调整指令复杂度
if user_level == "beginner":
prompt_parts.append(self._get_beginner_instructions())
elif user_level == "expert":
prompt_parts.append(self._get_expert_instructions())
# 根据任务复杂度调整分析深度
if task_complexity == "complex":
prompt_parts.append(self._get_detailed_analysis_steps())
# 根据数据量调整处理方式
if data_volume == "large":
prompt_parts.append(self._get_data_sampling_instructions())
# 3. 组合生成最终提示
return "\n\n".join(prompt_parts)
def _get_beginner_instructions(self) -> str:
"""初级用户的指导"""
return """## 分析指引
这个分析帮您理解数据的基本模式。
按以下步骤进行:
1. 首先观察整体趋势
2. 然后对比变化
3. 最后给出简单建议
"""
def _get_expert_instructions(self) -> str:
"""专家级用户的指导"""
return """## 深度分析框架
进行多维度分析,包括:
1. 统计显著性检验
2. 因果关系分析
3. 对标企业对比
4. 预测模型建议
"""
def _get_detailed_analysis_steps(self) -> str:
"""详细的分析步骤"""
return """## 分析步骤
1. 数据清洗与预处理
2. 描述性统计分析
3. 趋势与周期性分析
4. 异常值检测
5. 深层因素探讨
6. 对标与基准对比
7. 预测与建议
"""
def _get_data_sampling_instructions(self) -> str:
"""大数据处理指导"""
return """## 大数据处理
由于数据量大,建议:
1. 采样关键子集进行深度分析
2. 计算汇总统计指标
3. 聚焦异常和关键数据点
"""
8.5 提示模板的管理与版本控制
8.5.1 模板库管理
class PromptTemplateLibrary:
"""提示模板库"""
def __init__(self):
self.templates: Dict[str, Dict[str, PromptTemplate]] = {}
self.version_history: Dict[str, List[Dict]] = {}
def register_template(self, category: str, template: PromptTemplate):
"""注册模板"""
if category not in self.templates:
self.templates[category] = {}
self.templates[category][template.name] = template
# 记录版本历史
if template.name not in self.version_history:
self.version_history[template.name] = []
self.version_history[template.name].append({
"version": template.version,
"timestamp": datetime.now().isoformat(),
"description": "Template registered"
})
def get_template(self, category: str, name: str) -> Optional[PromptTemplate]:
"""获取模板"""
return self.templates.get(category, {}).get(name)
def list_templates(self, category: str = None) -> List[Dict]:
"""列出模板"""
if category:
templates = self.templates.get(category, {})
else:
templates = {}
for cat_templates in self.templates.values():
templates.update(cat_templates)
return [
{
"name": t.name,
"description": t.description,
"version": t.version,
"arguments": len(t.arguments)
}
for t in templates.values()
]
def update_template(self, category: str, template: PromptTemplate,
change_description: str):
"""更新模板"""
old_version = None
if category in self.templates and template.name in self.templates[category]:
old_version = self.templates[category][template.name].version
# 自动升级版本号
if old_version:
template.version = self._increment_version(old_version)
self.register_template(category, template)
# 记录变更
self.version_history[template.name][-1]["description"] = change_description
def _increment_version(self, version: str) -> str:
"""版本号递增"""
parts = version.split(".")
parts[-1] = str(int(parts[-1]) + 1)
return ".".join(parts)
8.5.2 模板复用与组合
class CompositePromptTemplate(PromptTemplate):
"""组合模板:由多个子模板组成"""
def __init__(self, name: str, description: str):
super().__init__(name, description, "")
self.sub_templates: List[PromptTemplate] = []
def add_sub_template(self, template: PromptTemplate, position: str = "end"):
"""添加子模板"""
if position == "end":
self.sub_templates.append(template)
elif position == "start":
self.sub_templates.insert(0, template)
def render(self, **kwargs) -> str:
"""渲染组合模板"""
rendered_parts = []
for template in self.sub_templates:
# 每个子模板只使用它需要的参数
sub_kwargs = {
k: v for k, v in kwargs.items()
if k in template.arguments
}
rendered_parts.append(template.render(**sub_kwargs))
return "\n\n---\n\n".join(rendered_parts)
# 使用示例
def create_comprehensive_analysis_prompt():
"""创建综合分析提示"""
composite = CompositePromptTemplate(
"comprehensive_analysis",
"综合数据分析模板"
)
# 添加多个子模板
composite.add_sub_template(SalesAnalysisTemplate())
composite.add_sub_template(RiskAssessmentTemplate())
composite.add_sub_template(RecommendationTemplate())
return composite
本章总结
| 核心概念 | 关键点 |
|---|---|
| 定义 | 预定义、参数化、可复用的文本模板 |
| 设计原则 | 清晰性、一致性、参数化 |
| 参数分类 | 上下文参数、业务参数、控制参数 |
| 参数化 | 验证、转换、补充、派生 |
| 动态生成 | 上下文感知的智能生成 |
| 版本管理 | 语义版本号、变更记录 |
| 模板复用 | 组合模板、模板库 |
| 质量保证 | 验证规则、枚举约束 |
常见问题
Q1: 提示模板与系统提示有什么区别? A: 系统提示是固定的行为指令,提示模板是参数化的可复用指引。模板更灵活。
Q2: 提示模板是否会增加LLM的token消耗? A: 是的,但能通过规范化和复用减少调整需求,总体成本通常降低。
Q3: 如何评估提示模板的质量? A: 通过一致性、准确率、完成度、用户反馈等指标评估。
Q4: 可以在提示模板中嵌入其他提示吗? A: 可以。组合模板支持多层嵌套。
Q5: 提示模板与Few-shot示例的关系? A: 提示模板定义结构,Few-shot示例是具体例子,常配合使用。
实战要点
✅ 推荐做法
- 设计清晰的参数化结构
- 提供详细的参数说明
- 创建模板变体库
- 定期收集用户反馈
- 建立版本管理制度
- 编写模板使用指南
❌ 避免的做法
- 不要过度参数化
- 不要忽视输出格式定义
- 不要缺乏版本管理
- 不要忘记参数验证
- 不要把所有逻辑都放在提示中
- 不要设计过于复杂的模板
延伸阅读
- 提示工程最佳实践:spec.modelcontextprotocol.io/prompts
- 模板设计模式:en.wikipedia.org/wiki/Templa…
- 提示优化技术:www.promptingguide.ai/
- 语义版本控制:semver.org/
下一章预告:第9章将讲述如何开发MCP客户端——包括连接管理、工具发现、异步处理等关键内容。