提示工程(Prompt Engineering)在2026年已经远超"学会写好提示词"的范畴,它正在演变为一门真正的工程学科。本文聚焦进阶技巧,覆盖从提示模板设计、链式推理优化,到企业级提示系统架构,帮助你系统掌握现代提示工程的精髓。
从"提示词"到"提示系统"
初学者的认知:写一个好提示词,让模型输出更好。
进阶工程师的认知:设计一套提示系统,在各种输入场景下稳定产出高质量结果。
这两种认知的差距,体现在以下几个维度:
- 可维护性:提示系统应该像代码一样有版本控制、可测试、可回滚
- 可扩展性:新增场景时,不需要推倒重来,而是复用现有组件
- 可评估性:有明确的质量指标,能定量判断提示变更的效果
- 健壮性:面对非预期输入时,能降级处理而非彻底失败
提示模板的工程化设计
结构化提示模板
好的提示模板应该像软件模块一样:职责清晰,输入输出定义明确。
from dataclasses import dataclass
from typing import Optional
from string import Template
@dataclass
class PromptTemplate:
"""结构化提示模板"""
name: str
version: str
system_prompt: str
user_template: str
few_shot_examples: list[dict] = None
output_format: Optional[str] = None
def render(self, **kwargs) -> list[dict]:
"""渲染完整的消息列表"""
messages = [{"role": "system", "content": self.system_prompt}]
# 添加few-shot示例
if self.few_shot_examples:
for example in self.few_shot_examples:
messages.append({"role": "user", "content": example["input"]})
messages.append({"role": "assistant", "content": example["output"]})
# 添加当前用户输入
user_content = self.user_template.format(**kwargs)
if self.output_format:
user_content += f"\n\n请以以下格式输出:\n{self.output_format}"
messages.append({"role": "user", "content": user_content})
return messages
# 定义代码审查模板
code_review_template = PromptTemplate(
name="code_review",
version="v2.1",
system_prompt="""你是一位资深的Python工程师,专门负责代码审查。
你关注的重点:
1. 代码正确性和潜在Bug
2. 性能问题和资源泄露
3. 安全漏洞(注入、权限等)
4. 代码可读性和可维护性
5. 是否符合Python最佳实践
审查时要具体指出问题所在的行号,并提供修改建议。""",
user_template="""请审查以下{language}代码:
```{language}
{code}
背景信息:{context}""", output_format=""" 总体评分: X/10 关键问题:
- [严重] 行X: 问题描述
- [警告] 行X: 问题描述 改进建议: ... """, few_shot_examples=[ { "input": "审查:def get_user(id): return db.query(f'SELECT * FROM users WHERE id={id}')", "output": "总体评分: 2/10\n关键问题:\n- [严重] 行1: SQL注入漏洞,直接将id嵌入SQL字符串...", } ] )
### 提示版本管理
```python
import json
from pathlib import Path
class PromptRegistry:
"""提示模板注册表,支持版本管理"""
def __init__(self, registry_dir: str = "./prompts"):
self.registry_dir = Path(registry_dir)
self.registry_dir.mkdir(exist_ok=True)
def save(self, template: PromptTemplate):
"""保存模板到文件"""
filepath = self.registry_dir / f"{template.name}_{template.version}.json"
with open(filepath, 'w', encoding='utf-8') as f:
json.dump({
"name": template.name,
"version": template.version,
"system_prompt": template.system_prompt,
"user_template": template.user_template,
"output_format": template.output_format,
}, f, ensure_ascii=False, indent=2)
def load(self, name: str, version: str = "latest") -> PromptTemplate:
"""加载指定版本的模板"""
if version == "latest":
# 找最新版本
files = list(self.registry_dir.glob(f"{name}_v*.json"))
filepath = sorted(files)[-1]
else:
filepath = self.registry_dir / f"{name}_{version}.json"
with open(filepath, 'r', encoding='utf-8') as f:
data = json.load(f)
return PromptTemplate(**data)
链式推理(Chain-of-Thought)的进阶技巧
Chain-of-Thought(CoT)已广为人知,但有几个进阶变体值得深入了解:
Zero-Shot CoT的触发词优化
# 基础CoT:加"Let's think step by step"
basic_cot = "解答以下问题。Let's think step by step."
# 中文场景下,不同触发词效果差异显著
triggers = [
"请逐步分析:", # 效果:★★★★
"让我们一步一步地思考:", # 效果:★★★★
"请分析推理过程:", # 效果:★★★
"请详细解答:", # 效果:★★
"思考过程:", # 效果:★★★
]
# 对于数学/逻辑问题,结构化步骤更有效
structured_cot = """
请按以下步骤解答:
**第一步:理解问题**
(用自己的话复述问题)
**第二步:分析条件**
(列出已知条件和约束)
**第三步:制定策略**
(选择解题方法)
**第四步:执行计算**
(具体推导过程)
**第五步:验证答案**
(检查答案是否合理)
问题:{question}
"""
Self-Consistency:多路径投票
单次推理可能出错,多次采样后投票能显著提升准确率:
from collections import Counter
from openai import OpenAI
def self_consistency_answer(question: str, n_samples: int = 5) -> str:
"""Self-Consistency:多次采样后投票选出最一致的答案"""
client = OpenAI()
answers = []
for _ in range(n_samples):
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "请逐步分析,最后用'答案:X'格式给出答案"},
{"role": "user", "content": question}
],
temperature=0.7, # 较高温度使得每次推理路径不同
)
# 提取最终答案
text = response.choices[0].message.content
import re
match = re.search(r"答案[::]\s*(.+)", text)
if match:
answers.append(match.group(1).strip())
# 投票选出最多的答案
if answers:
most_common = Counter(answers).most_common(1)[0][0]
return most_common
return "无法确定答案"
Skeleton-of-Thought:并行生成加速
对于长文本生成(如报告、文章),Skeleton-of-Thought先生成骨架,再并行填充细节:
import asyncio
from openai import AsyncOpenAI
async def skeleton_of_thought_generate(topic: str) -> str:
"""先生成骨架,再并行填充各节内容"""
client = AsyncOpenAI()
# 第一步:生成骨架
skeleton_response = await client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": f"为以下主题生成一个包含5-7个小节的文章骨架,只输出标题列表:\n{topic}"
}]
)
sections = skeleton_response.choices[0].message.content.strip().split('\n')
# 第二步:并行生成每个小节内容
async def fill_section(section_title: str) -> str:
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": f"为文章《{topic}》的小节「{section_title}」写300字左右的内容:"
}]
)
return f"## {section_title}\n\n{response.choices[0].message.content}"
section_contents = await asyncio.gather(*[fill_section(s) for s in sections if s.strip()])
return '\n\n'.join(section_contents)
输出结构化:JSON Mode与类型安全
让LLM输出可靠的结构化数据,是生产级应用的核心需求:
from pydantic import BaseModel, Field
from openai import OpenAI
from typing import Literal
client = OpenAI()
# 定义输出Schema
class CodeReviewResult(BaseModel):
overall_score: int = Field(ge=1, le=10, description="代码质量总分1-10")
severity: Literal["critical", "major", "minor", "info"]
issues: list[dict] = Field(description="发现的问题列表")
suggestions: list[str] = Field(description="改进建议")
summary: str = Field(max_length=200)
# 使用Structured Output(OpenAI支持)
response = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[
{"role": "system", "content": "你是代码审查专家"},
{"role": "user", "content": f"审查以下代码:\n{code}"},
],
response_format=CodeReviewResult,
)
result: CodeReviewResult = response.choices[0].message.parsed
print(f"评分: {result.overall_score}/10")
print(f"严重度: {result.severity}")
动态提示组合(Dynamic Prompt Assembly)
复杂应用中,不同情况需要不同的提示策略,动态组合是关键:
class DynamicPromptAssembler:
"""根据上下文动态组装提示"""
def __init__(self):
self.base_system = "你是一个智能助手。"
self.skill_modules = {
"code": "你具备深厚的编程能力,精通Python/JavaScript/Go等语言。",
"analysis": "你擅长数据分析和逻辑推理,能从复杂信息中提取关键洞察。",
"writing": "你是专业的技术写作专家,擅长将复杂技术概念用清晰语言表达。",
"multilingual": "你精通中英日三语,能准确理解各语言的细微含义。",
}
self.output_modules = {
"json": "请以JSON格式输出。",
"markdown": "请以Markdown格式输出,包含适当的标题和代码块。",
"concise": "回答要简洁,控制在100字以内。",
}
def assemble(self, required_skills: list[str], output_format: str = None,
custom_instructions: str = None) -> str:
"""动态组装系统提示"""
parts = [self.base_system]
# 添加技能模块
for skill in required_skills:
if skill in self.skill_modules:
parts.append(self.skill_modules[skill])
# 添加输出格式
if output_format and output_format in self.output_modules:
parts.append(self.output_modules[output_format])
# 添加自定义指令
if custom_instructions:
parts.append(custom_instructions)
return "\n".join(parts)
# 使用
assembler = DynamicPromptAssembler()
system_prompt = assembler.assemble(
required_skills=["code", "analysis"],
output_format="json",
custom_instructions="严格基于提供的文档回答,不要使用外部知识。"
)
提示注入防御
在用户可以输入内容的场景中,提示注入是真实的安全威胁:
import re
class PromptInjectionGuard:
"""提示注入防御"""
# 常见注入模式
INJECTION_PATTERNS = [
r"ignore (previous|all|above) instructions?",
r"forget (everything|your instructions?|what you were told)",
r"you are now (a?|an?)\s+\w+",
r"new instructions?:",
r"system:\s*",
r"OVERRIDE",
]
def __init__(self):
self.patterns = [re.compile(p, re.IGNORECASE) for p in self.INJECTION_PATTERNS]
def scan(self, user_input: str) -> tuple[bool, str]:
"""扫描是否存在注入尝试
返回: (is_safe, reason)
"""
for pattern in self.patterns:
if pattern.search(user_input):
return False, f"检测到潜在的提示注入: {pattern.pattern}"
return True, "安全"
def sanitize(self, user_input: str) -> str:
"""对用户输入进行清理(作为额外防护层)"""
# 用明确的分隔符包裹用户输入
return f"[用户输入开始]\n{user_input}\n[用户输入结束]"
def build_safe_prompt(self, system_prompt: str, user_input: str) -> list[dict]:
"""构建防注入的完整提示"""
is_safe, reason = self.scan(user_input)
if not is_safe:
# 拒绝明显的注入
return [
{"role": "system", "content": system_prompt},
{"role": "user", "content": "[请求因安全原因被过滤]"},
]
sanitized = self.sanitize(user_input)
return [
{"role": "system", "content": system_prompt},
{"role": "user", "content": sanitized},
]
提示工程的评估与迭代
好的提示工程必须可测试:
class PromptABTester:
"""提示A/B测试框架"""
def __init__(self, llm_client, eval_fn):
self.client = llm_client
self.eval_fn = eval_fn # 评估函数,返回0-1的分数
def compare(self, prompt_a: str, prompt_b: str, test_cases: list[dict]) -> dict:
"""对比两个提示的效果"""
scores_a, scores_b = [], []
for case in test_cases:
# 测试提示A
response_a = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "system", "content": prompt_a},
{"role": "user", "content": case["input"]}]
).choices[0].message.content
# 测试提示B
response_b = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "system", "content": prompt_b},
{"role": "user", "content": case["input"]}]
).choices[0].message.content
scores_a.append(self.eval_fn(case["input"], response_a, case.get("expected")))
scores_b.append(self.eval_fn(case["input"], response_b, case.get("expected")))
avg_a = sum(scores_a) / len(scores_a)
avg_b = sum(scores_b) / len(scores_b)
return {
"prompt_a_avg_score": avg_a,
"prompt_b_avg_score": avg_b,
"winner": "A" if avg_a > avg_b else "B",
"improvement": abs(avg_b - avg_a) / avg_a * 100,
}
总结
2026年的提示工程已经是系统工程,核心要素:
- 模板化与版本化:像管理代码一样管理提示
- 链式推理:CoT、Self-Consistency、ToT按需选用
- 结构化输出:用Pydantic定义输出Schema,保证类型安全
- 动态组合:根据任务类型动态组装提示
- 安全防护:防提示注入是生产必须
- 可测试:A/B测试框架支撑持续迭代
从"写好提示词"到"构建提示系统",这是AI工程师走向专业化的必经之路。