Prompt 工程实践
大约 10 分钟约 2856 字
Prompt 工程实践
简介
Prompt 工程的本质,不是"凑几个提示词技巧",而是把任务目标、输入上下文、输出格式、安全边界和评估标准组织成一套稳定的人机协作接口。对于企业场景来说,Prompt 更像是"给模型写需求文档",写得越清楚,输出越稳定;边界越模糊,模型越容易失控。
Prompt 工程在企业实践中面临的核心挑战包括:输出不稳定性(相同输入可能产生不同结果)、上下文窗口限制(无法放入所有相关信息)、安全风险(Prompt 注入、越权指令)和版本管理(模型升级后效果可能变化)。解决这些挑战需要从系统设计层面思考,而非仅仅优化提示词本身。
特点
实现
Zero-shot 与 Few-shot
from openai import OpenAI
client = OpenAI()
def zero_shot_sentiment(text: str) -> str:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": f"请判断下面文本是正面、负面还是中性,只返回一个标签:\n{text}"
}
],
temperature=0
)
return response.choices[0].message.contentdef few_shot_sentiment(text: str) -> str:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": f"""
请参考以下示例判断情感标签,只返回:正面 / 负面 / 中性
示例1:
文本:这个产品质量很好,发货也快
标签:正面
示例2:
文本:包装破损严重,体验很差
标签:负面
示例3:
文本:功能一般,价格普通
标签:中性
待判断文本:
{text}
"""
}
],
temperature=0
)
return response.choices[0].message.contentFew-shot 的核心价值通常不是"教模型知识",
而是:
- 对齐输出格式
- 对齐分类边界
- 对齐语气风格System Prompt 与结构化输出
SYSTEM_PROMPT = """
你是一个企业知识助手。
请遵守以下规则:
1. 只基于提供的上下文回答
2. 如果上下文不足,明确说明"资料未覆盖"
3. 输出必须是 JSON
4. 不要输出额外解释
"""
def structured_answer(question: str, context: str):
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{
"role": "user",
"content": f"""
问题:{question}
上下文:{context}
输出格式:
{{
"answer": "答案",
"confidence": "high|medium|low",
"source_used": true
}}
"""
}
],
temperature=0
)
return response.choices[0].message.contentimport json
result = structured_answer(
question="退款后发票怎么处理?",
context="退款成功后原发票作废,如需重开请联系财务。"
)
parsed = json.loads(result)
print(parsed)结构化输出特别适合:
- 信息抽取
- 分类任务
- 表单生成
- 与后端接口联动CoT / ToT 与复杂任务拆解
def cot_reasoning(question: str) -> str:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": f"""
请一步一步思考并回答以下问题:
{question}
请按以下结构输出:
1. 问题理解
2. 分步推理
3. 最终结论
"""
}
],
temperature=0
)
return response.choices[0].message.contentdef tot_plan(problem: str) -> str:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": f"""
针对这个问题,给出 3 条不同解决思路,并比较优缺点,最后选出最优方案:
{problem}
"""
}
],
temperature=0.4
)
return response.choices[0].message.content经验上:
- 简单任务不一定需要 CoT
- 开放规划问题更适合多方案比较
- CoT / ToT 的价值要靠效果和成本一起评估Prompt 注入防护
def safe_prompt(user_input: str, system_prompt: str) -> str:
"""
Prompt 注入防护策略:
1. 输入长度限制
2. 敏感指令检测
3. 输入输出隔离
"""
# 敏感指令关键词
injection_keywords = [
"忽略之前的指令", "ignore previous",
"你现在是", "you are now",
"新的角色", "new role",
"系统提示", "system prompt",
]
# 检测注入
for keyword in injection_keywords:
if keyword.lower() in user_input.lower():
return f"检测到可能的注入尝试,已拒绝处理。关键词: {keyword}"
# 长度限制
if len(user_input) > 2000:
return "输入过长,请缩短后重试。"
return f"{system_prompt}\n\n用户输入:{user_input}"
print("Prompt 注入防护函数已定义")企业场景里的 Prompt 模板化
from dataclasses import dataclass
@dataclass
class PromptTemplate:
name: str
version: str
system: str
user_template: str
invoice_prompt = PromptTemplate(
name="invoice-assistant",
version="v1.2.0",
system="你是财务流程助手,回答必须谨慎,不确定就说明不足。",
user_template="用户问题:{question}\n上下文:{context}\n请输出要点列表。"
)def render_prompt(template: PromptTemplate, question: str, context: str):
return {
"system": template.system,
"user": template.user_template.format(question=question, context=context)
}
payload = render_prompt(invoice_prompt, "发票重开流程是什么?", "企业客户可申请重开发票,需要提交原单号。")
print(payload)Prompt 模板建议版本化管理:
- 名称
- 版本号
- 适用场景
- 最近一次评估结果
- 已知失败样例输出验证与重试
import json
import re
def validate_and_retry(generator_func, max_retries=3):
"""
输出验证与重试机制:
确保模型输出符合预期格式
"""
for attempt in range(max_retries):
try:
result = generator_func()
# JSON 验证
if result.startswith("```"):
# 去掉 markdown 代码块标记
result = re.sub(r'^```\w*\n?', '', result)
result = re.sub(r'\n?```$', '', result)
parsed = json.loads(result)
return parsed
except json.JSONDecodeError:
if attempt < max_retries - 1:
print(f"JSON 解析失败,第 {attempt+1} 次重试...")
continue
return {"error": "输出格式验证失败", "raw": result}
print("输出验证与重试机制已定义")Prompt 版本管理
class PromptRegistry:
"""Prompt 注册中心——管理所有 Prompt 模板版本"""
def __init__(self):
self.prompts = {}
def register(self, template: PromptTemplate, eval_score: float = None):
"""注册 Prompt 模板"""
self.prompts[f"{template.name}:{template.version}"] = {
"template": template,
"eval_score": eval_score,
"registered_at": "2026-04-12"
}
def get_latest(self, name: str) -> PromptTemplate:
"""获取最新版本"""
versions = [k for k in self.prompts if k.startswith(name + ":")]
if not versions:
raise ValueError(f"未找到 Prompt: {name}")
latest = sorted(versions, key=lambda x: self.prompts[x]["template"].version)[-1]
return self.prompts[latest]["template"]
def compare_versions(self, name: str):
"""对比不同版本"""
versions = [k for k in self.prompts if k.startswith(name + ":")]
return {k: self.prompts[k]["eval_score"] for k in versions}
registry = PromptRegistry()
registry.register(invoice_prompt, eval_score=0.87)
print(f"已注册 Prompt: {list(registry.prompts.keys())}")Prompt A/B 测试
import random
class PromptABTest:
"""Prompt A/B 测试框架"""
def __init__(self):
self.variants = {}
self.results = {}
def add_variant(self, name, system_prompt, user_template):
"""添加测试变体"""
self.variants[name] = {
"system": system_prompt,
"user_template": user_template,
}
self.results[name] = {"total": 0, "success": 0, "failures": []}
def run_test(self, eval_cases, model_fn):
"""运行 A/B 测试"""
for case in eval_cases:
variant_name = random.choice(list(self.variants.keys()))
variant = self.variants[variant_name]
prompt = variant["user_template"].format(**case)
try:
result = model_fn(variant["system"], prompt)
is_correct = self._evaluate_result(result, case.get("expected"))
self.results[variant_name]["total"] += 1
if is_correct:
self.results[variant_name]["success"] += 1
else:
self.results[variant_name]["failures"].append(case)
except Exception as e:
self.results[variant_name]["total"] += 1
self.results[variant_name]["failures"].append(case)
return self.get_report()
def get_report(self):
"""生成测试报告"""
report = {}
for name, data in self.results.items():
total = data["total"]
success = data["success"]
report[name] = {
"success_rate": success / total if total > 0 else 0,
"total": total,
"failures": len(data["failures"])
}
return report
def _evaluate_result(self, result, expected=None):
"""评估结果(简化实现)"""
return result is not None and len(result) > 10
print("Prompt A/B 测试框架已定义")多语言 Prompt 技巧
def multilingual_prompt(question, language='zh'):
"""
多语言场景的 Prompt 技巧:
1. 始终用英文写 System Prompt(模型英文理解最好)
2. 用目标语言写 User Prompt
3. 要求输出也用目标语言
"""
prompts = {
'zh': {
'system': 'You are a helpful assistant. Always respond in Chinese (Simplified).',
'instruction': f'请用中文回答以下问题:{question}'
},
'en': {
'system': 'You are a helpful assistant.',
'instruction': f'Please answer the following question: {question}'
},
'ja': {
'system': 'You are a helpful assistant. Always respond in Japanese.',
'instruction': f'日本語で以下の質問に答えてください:{question}'
}
}
config = prompts.get(language, prompts['en'])
return config['system'], config['instruction']
system, user = multilingual_prompt("什么是机器学习?", language='zh')
print(f"System: {system}")
print(f"User: {user}")Prompt 降级与兜底策略
class PromptFallbackChain:
"""
Prompt 降级链:
当主 Prompt 失败时,自动尝试备用 Prompt
"""
def __init__(self):
self.chain = []
def add_prompt(self, name, system_prompt, validator=None):
"""添加 Prompt 到降级链"""
self.chain.append({
"name": name,
"system": system_prompt,
"validator": validator or (lambda r: r is not None and len(r) > 10)
})
def execute(self, user_prompt, model_fn, max_retries=3):
"""执行降级链"""
for prompt_config in self.chain:
for attempt in range(max_retries):
try:
result = model_fn(prompt_config["system"], user_prompt)
if prompt_config["validator"](result):
return {"answer": result, "prompt_used": prompt_config["name"], "attempts": attempt + 1}
except Exception:
continue
print(f"Prompt '{prompt_config['name']}' 全部重试失败,尝试下一个")
return {"answer": None, "prompt_used": None, "attempts": 0, "error": "所有 Prompt 均失败"}
fallback = PromptFallbackChain()
fallback.add_prompt("detailed", "你是一个详细回答的助手")
fallback.add_prompt("simple", "你是一个简洁回答的助手")
fallback.add_prompt("fallback", "请尽量回答用户的问题")
print("Prompt 降级链已定义")优点
缺点
总结
Prompt 工程真正要解决的,不是"写得花哨",而是"让模型按可控方式完成任务"。在真实项目里,Prompt 的价值来自模板化、结构化输出、版本管理、失败样例和持续评估,而不是一两次成功演示。
关键知识点
- 好 Prompt 必须明确:角色、目标、约束、输出格式。
- Few-shot 更适合对齐边界和格式,不只是"举例子"。
- 结构化输出在生产环境里往往比自由文本更重要。
- Prompt 质量不能靠主观感觉,要靠评估集和失败样例复盘。
- Prompt 注入防护是企业场景必须考虑的安全问题。
项目落地视角
- 客服、知识库、信息抽取、总结归纳都高度依赖 Prompt 质量。
- 企业系统里,Prompt 常和 RAG、函数调用、安全审核联动。
- Prompt 要和模型版本、检索版本、数据来源一起治理。
- 对于高风险问题,应优先设计拒答和兜底逻辑,而不是只追求"回答得像"。
常见误区
- 把 Prompt 当咒语,不做版本和评估管理。
- 用很长的 Prompt 试图解决所有问题,结果成本和不稳定性都上升。
- 只看成功案例,不积累失败案例。
- 把系统提示写得非常强,但不考虑用户输入和检索上下文的污染。
进阶路线
- 深入学习 RAG、Tool Use、Agent 与 Prompt 的配合方式。
- 建立 Prompt 评估集和自动化对比流程。
- 研究 Prompt 注入防护、上下文隔离和输出验证。
- 将 Prompt 版本化、可观测化、平台化管理。
适用场景
- 信息抽取、分类、总结、改写、问答。
- 企业知识助手与客服助手。
- 有明确输出结构和业务约束的生成任务。
- 快速试验 AI 场景与需求对齐。
落地建议
- 从一个最小、明确的任务开始,不要用一个 Prompt 承担所有职责。
- Prompt 统一模板化并记录版本号。
- 为高价值场景建立失败案例和回归测试集。
- 对生产输出结果增加结构校验、敏感词检查和安全兜底。
排错清单
- 输出不稳定:先检查任务是否描述过宽、示例是否冲突。
- JSON 解析失败:优先改成更强的结构约束或工具化输出。
- 效果退化:检查模型版本、Prompt 版本、上下文来源是否一起变化。
- 回答越权:检查 system prompt、用户输入过滤和外部上下文污染。
