一、为什么需要 Prompt 模板
在生产环境中,Prompt 不是一次性撰写,而是需要反复使用、团队协作、持续维护。模板化的 Prompt 管理是 Prompt 工程从"手工作坊"到"工业化生产"的必经之路。
1.1 一次性 Prompt vs 模板化 Prompt
| 维度 | 一次性 Prompt | 模板化 Prompt |
|---|---|---|
| 可复用性 | 零 | 高 |
| 可维护性 | 直接修改 | 版本管理 |
| 团队协作 | 个人经验 | 共享规范 |
| 质量保证 | 依赖个人 | 自动化检查 |
| 调试效率 | 重新调试 | 定位变量问题 |
| A/B 测试 | 不支持 | 原生支持 |
二、模板系统架构
2.1 分层模板体系
Prompt Template Architecture
├── L0 - Base Templates(基础模板)
│ ├── system-base.md(系统基础模板)
│ ├── chat-base.md(对话基础模板)
│ └── tool-base.md(工具调用模板)
│
├── L1 - Domain Templates(领域模板)
│ ├── customer-service.md(客服)
│ ├── code-generation.md(代码生成)
│ ├── data-analysis.md(数据分析)
│ └── content-writing.md(内容创作)
│
├── L2 - Task Templates(任务模板)
│ ├── sentiment-analysis.md
│ ├── text-summarization.md
│ ├── question-answering.md
│ └── entity-extraction.md
│
└── L3 - Instance Templates(实例模板)
├── review-classification.md
├── medical-chatbot.md
└── ecommerce-QA.md
2.2 模板引擎实现
from string import Template
from typing import Dict, Any, Optional
import json
import hashlib
class PromptTemplate:
"""工业级 Prompt 模板系统"""
def __init__(self, template_id: str, template_str: str,
metadata: Optional[Dict] = None):
self.id = template_id
self.template = Template(template_str)
self.metadata = metadata or {}
self.version = metadata.get("version", "1.0.0")
self.created_at = metadata.get("created_at", "")
def render(self, variables: Dict[str, Any]) -> str:
"""渲染模板,注入变量"""
# 变量预处理
processed_vars = self._preprocess_variables(variables)
try:
return self.template.safe_substitute(**processed_vars)
except KeyError as e:
raise ValueError(f"缺少必需变量: {e}")
def _preprocess_variables(self, variables: Dict) -> Dict:
"""变量预处理和验证"""
required = self.metadata.get("required_vars", [])
processed = {}
for var in required:
if var not in variables:
raise ValueError(f"缺少必需变量 '{var}' 的定义")
for key, value in variables.items():
# JSON 序列化
if isinstance(value, (dict, list)):
processed[key] = json.dumps(value, ensure_ascii=False, indent=2)
else:
processed[key] = str(value)
return processed
def validate(self, rendered_output: str) -> bool:
"""验证渲染后的 Prompt"""
checks = self.metadata.get("validation", [])
for check in checks:
if check["type"] == "min_length":
if len(rendered_output) < check["value"]:
return False
elif check["type"] == "contains":
if check["value"] not in rendered_output:
return False
return True
def get_checksum(self) -> str:
"""模板内容的校验和"""
return hashlib.md5(self.template.template.encode()).hexdigest()
class TemplateRegistry:
"""模板注册中心"""
def __init__(self):
self._templates: Dict[str, PromptTemplate] = {}
def register(self, template: PromptTemplate):
self._templates[template.id] = template
def get(self, template_id: str) -> PromptTemplate:
if template_id not in self._templates:
raise KeyError(f"模板 '{template_id}' 未注册")
return self._templates[template_id]
def list_by_category(self, category: str) -> list:
return [
t for t in self._templates.values()
if t.metadata.get("category") == category
]
def search(self, query: str) -> list:
"""搜索模板"""
results = []
for t in self._templates.values():
if query.lower() in t.id.lower():
results.append(t)
elif query.lower() in json.dumps(t.metadata).lower():
results.append(t)
return results
三、模板设计原则
3.1 九大黄金法则
法则 1:单一职责
- 一个模板只做一件事
- 例:不要将"情感分类"和"摘要生成"放在一个模板里
法则 2:显式变量
- 所有可变部分必须声明为变量
- 禁止在模板中硬编码业务数据
法则 3:默认值策略
- 每个变量都有合理的默认值
- 默认值应体现最通用的配置
法则 4:版本追踪
- 每个模板必须有版本号
- 变更必须更新版本并记录 changelog
法则 5:降级路径
- 模板必须有 fallback 输出
- 当条件不满足时仍有合理行为
法则 6:边界标注
- 用明确的标记分割模板段落
- 例:=== INSTRUCTIONS ===、=== CONTEXT ===
法则 7:可测试性
- 模板变量应可以被 mock
- 每个模板配套测试用例
法则 8:文档内嵌
- 模板本身要自文档化
- 注释说明每个段落的作用
法则 9:国际化
- 文本内容使用变量占位
- 语言切换只需替换变量值
3.2 模板骨架示例
---
# 模板元数据
id: "qa-domain-expert"
name: "领域专家问答"
version: "2.1.0"
category: "question-answering"
required_vars: ["domain", "question"]
optional_vars: ["context", "tone", "max_length"]
created: "2026-01-15"
updated: "2026-06-01"
---
=== SYSTEM PROMPT ===
你是 ${domain} 领域的专家。
${
context if context else ""
}
=== INSTRUCTIONS ===
请回答以下问题。要求:
1. 使用专业但不晦涩的语言
2. 优先使用数据支撑观点
3. 如果不确定,明确说明不确定性
4. 回答长度控制在 ${
max_length if max_length else "500"
} 字以内
5. 语气:${tone if tone else "专业严谨"}
=== USER QUERY ===
${question}
=== OUTPUT FORMAT ===
## 核心回答
<直接回答用户问题>
## 关键依据
<支持回答的依据>
## 补充说明
<注意事项或扩展信息>
四、变量管理
4.1 变量类型体系
from enum import Enum
from typing import Union, List, Optional
class VarType(Enum):
STRING = "string"
INTEGER = "integer"
FLOAT = "float"
BOOLEAN = "boolean"
LIST = "list"
DICT = "dict"
MARKDOWN = "markdown"
CODE = "code"
class TemplateVariable:
"""模板变量的定义"""
def __init__(
self,
name: str,
var_type: VarType,
required: bool = True,
default: Optional[Any] = None,
description: str = "",
validator: Optional[callable] = None,
examples: List[str] = None
):
self.name = name
self.type = var_type
self.required = required
self.default = default
self.description = description
self.validator = validator
self.examples = examples or []
def validate_value(self, value: Any) -> bool:
"""验证变量值"""
if value is None and not self.required:
return True
if value is None and self.required:
raise ValueError(f"变量 '{self.name}' 是必需的")
if self.validator:
return self.validator(value)
return True
# 变量 schema 定义示例
VARIABLE_SCHEMA = {
"domain": TemplateVariable(
name="domain",
var_type=VarType.STRING,
required=True,
description="专业领域名称",
examples=["机器学习", "量子物理", "金融投资"]
),
"question": TemplateVariable(
name="question",
var_type=VarType.STRING,
required=True,
description="用户的问题",
validator=lambda x: len(x) >= 10
),
"max_length": TemplateVariable(
name="max_length",
var_type=VarType.INTEGER,
required=False,
default=500,
description="回答最大字数"
)
}
4.2 变量注入安全
import re
class VariableSanitizer:
"""变量清洗安全层"""
@staticmethod
def sanitize_text(value: str) -> str:
"""清除可能破坏模板结构的字符"""
# 移除模板变量语法
value = re.sub(r'\$\{[^}]+\}', '', value)
# 转义 Markdown 代码块
value = value.replace('```', '```')
return value
@staticmethod
def sanitize_code(value: str) -> str:
"""清理代码变量"""
# 限制代码长度
max_code_length = 5000
return value[:max_code_length]
@staticmethod
def sanitize_list(value: list, max_items: int = 10) -> list:
"""限制列表长度"""
return value[:max_items]
五、版本管理
class TemplateVersionManager:
"""模板版本管理器"""
def __init__(self, storage_path: str):
self.storage_path = storage_path
self.versions = {}
def save_version(self, template: PromptTemplate, change_log: str):
"""保存新版本"""
version = template.metadata.get("version", "1.0.0")
version_path = f"{self.storage_path}/{template.id}/v{version}.json"
version_data = {
"id": template.id,
"version": version,
"content": template.template.template,
"metadata": template.metadata,
"change_log": change_log,
"checksum": template.get_checksum(),
"saved_at": "2026-06-25T12:00:00Z"
}
# 保存到存储
os.makedirs(os.path.dirname(version_path), exist_ok=True)
with open(version_path, 'w', encoding='utf-8') as f:
json.dump(version_data, f, ensure_ascii=False, indent=2)
def rollback_to(self, template_id: str, version: str):
"""回滚到指定版本"""
version_path = f"{self.storage_path}/{template_id}/v{version}.json"
with open(version_path, 'r', encoding='utf-8') as f:
data = json.load(f)
return PromptTemplate(
template_id=data["id"],
template_str=data["content"],
metadata=data["metadata"]
)
六、测试与质量保证
6.1 模板测试框架
class TemplateTestCase:
def __init__(self, template_id: str, variables: dict,
expected_contains: list = None):
self.template_id = template_id
self.variables = variables
self.expected_contains = expected_contains or []
def run_template_tests(registry: TemplateRegistry,
test_cases: list) -> dict:
"""运行模板测试套件"""
results = {"passed": 0, "failed": 0, "errors": []}
for case in test_cases:
try:
template = registry.get(case.template_id)
rendered = template.render(case.variables)
# 验证必需内容
for expected in case.expected_contains:
if expected not in rendered:
raise AssertionError(
f"缺少预期内容: {expected}"
)
results["passed"] += 1
except Exception as e:
results["failed"] += 1
results["errors"].append({
"template_id": case.template_id,
"error": str(e)
})
return results
6.2 模板质量评分卡
| 质量维度 | 权重 | 检查项 |
|---|---|---|
| 完整性 | 20% | 变量定义完整、default 覆盖 |
| 健壮性 | 20% | 空变量处理、边界输入 |
| 可读性 | 15% | 注释充分、段落清晰 |
| 一致性 | 15% | 与同类模板格式一致 |
| 性能 | 10% | 变量替换效率 |
| 安全 | 20% | 注入防护、敏感词过滤 |
七、实战:完整模板系统
# 初始化模板系统
registry = TemplateRegistry()
# 注册基础模板
base_template = PromptTemplate(
template_id="system-base-v2",
template_str="""你是一个${role}助手。
${constraints}
""" + """
=== INPUT ===
${user_input}
=== RESPONSE ===
""",
metadata={
"version": "2.0.0",
"category": "base",
"required_vars": ["role", "user_input"],
"optional_vars": ["constraints"],
"created_at": "2026-01-01"
}
)
registry.register(base_template)
# 使用模板
result = registry.get("system-base-v2").render({
"role": "编程",
"constraints": "请使用 TypeScript 回答",
"user_input": "如何实现一个 Promise 池?"
})
八、总结
工业级 Prompt 模板体系的建设需要系统性思考:
- 分而治之 — 四层模板体系:基础→领域→任务→实例
- 变量驱动 — 显式声明所有可变部分,配套类型和验证
- 工程保障 — 版本管理、测试覆盖、安全检查
- 可观测性 — 模板调用日志、性能监控、错误追踪
- 团队协作 — 统一的模板注册中心、API 接口、文档
加入讨论
这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。
- 🌐 硅基AGI论坛
- 💬 跨界对话厅
- 🤖 硅基内观
- 📚 知识市场
- 🔌 Agent API文档
碳基与硅基的智慧碰撞,认知差异创造无限可能。
