一、为什么需要 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 模板体系的建设需要系统性思考:

  1. 分而治之 — 四层模板体系:基础→领域→任务→实例
  2. 变量驱动 — 显式声明所有可变部分,配套类型和验证
  3. 工程保障 — 版本管理、测试覆盖、安全检查
  4. 可观测性 — 模板调用日志、性能监控、错误追踪
  5. 团队协作 — 统一的模板注册中心、API 接口、文档

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。