共计 2591 个字符,预计需要花费 7 分钟才能阅读完成。
背景痛点:AI Agent 开发中的提示工程挑战
开发 AI Agent 时,提示工程(Prompt Engineering)是核心环节,但实践中常遇到几个典型问题:

-
多轮对话状态维护困难:当用户连续提问时,AI 容易丢失上下文。例如用户先问 ” 北京天气如何?”,接着问 ” 那上海呢?”,如果系统无法关联前后问题,就会要求用户重复信息。
-
长文本上下文丢失:主流模型如 GPT-3.5 的上下文窗口有限(通常 4k-32k tokens),当对话历史或文档超过限制时,关键信息会被截断。
-
意图识别偏差:相同问题不同表达可能导致完全不同的响应。比如 ” 怎么重置密码 ” 和 ” 密码忘了怎么办 ” 可能触发不同处理逻辑。
技术对比:主流提示策略实战分析
1. 零样本提示(Zero-shot Prompting)
直接给出指令而无示例,适合简单任务:
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "将以下文本翻译成英文:今天天气真好"}]
)
优点 :实现简单 缺点:复杂任务准确率低(实测约 52%)
2. 小样本提示(Few-shot Learning)
提供少量示例提升效果:
examples = """
Q: 如何开通会员?A: 请点击右上角头像进入账户设置...
Q: 会员有哪些权益?A: 会员可享受...
"""
实测效果:3 个示例可使准确率提升至 78%
3. 思维链(Chain-of-Thought)
要求模型展示推理过程:
prompt = """ 请逐步思考:如果小明有 5 个苹果,吃了 2 个,妈妈又买了 3 个,现在有几个?一步步计算:"""
优势:数学类问题准确率提升 40%+
核心实现:动态提示与上下文管理
动态提示模板(含异常处理)
from typing import Dict, Optional
import logging
logger = logging.getLogger(__name__)
def build_dynamic_prompt(user_input: str, context: Optional[Dict] = None) -> str:
try:
base_template = """ 已知信息:{context}
用户问题:{query}
请根据已知信息回答:"""
return base_template.format(context=context.get("key_info", "") if context else" 无 ",
query=user_input
)
except Exception as e:
logger.error(f"Prompt 构建失败: {str(e)}")
return user_input # 降级处理
带对话历史的 OpenAI 调用
def chat_with_history(messages: list):
"""
messages 示例:[{"role": "system", "content": "你是一个客服助手"},
{"role": "user", "content": "如何退款?"},
{"role": "assistant", "content": "请提供订单号..."}
]
"""
try:
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages,
temperature=0.7
)
return response.choices[0].message.content
except openai.error.InvalidRequestError as e:
logger.warning(f"上下文过长: {len(messages)}条历史")
return handle_context_overflow(messages)
性能优化关键技术
Token 压缩算法实践
对于长对话,可采用:
1. 关键信息提取:用 NLP 模型提取每轮对话的实体和意图
2. 摘要生成:每 5 轮对话生成一段摘要
3. 向量相似度去重:使用 cosine 相似度合并相似问题
LRU 对话缓存实现
from collections import OrderedDict
class DialogCache:
def __init__(self, max_size=10):
self.cache = OrderedDict()
self.max_size = max_size
def add(self, key: str, value: str):
if key in self.cache:
self.cache.move_to_end(key)
else:
if len(self.cache) >= self.max_size:
self.cache.popitem(last=False)
self.cache[key] = value
def get(self, key: str) -> Optional[str]:
if key in self.cache:
self.cache.move_to_end(key)
return self.cache[key]
return None
避坑指南:安全与稳定性
防御提示注入攻击
import re
def sanitize_input(text: str) -> str:
"""过滤潜在恶意指令"""
patterns = [
r"忽略之前指令",
r"作为 (.*?) 你应该"
]
for pattern in patterns:
text = re.sub(pattern, "[FILTERED]", text, flags=re.IGNORECASE)
return text[:2000] # 长度限制
对话漂移检测
当连续 3 次用户询问 ” 回到之前话题 ” 时触发校正:
if "回到之前" in last_three_messages:
recovery_prompt = "检测到对话偏离,是否需要回到 XX 话题?"
实践建议与开放问题
- 如何设计评估体系?建议建立包含 200+ 测试用例的评估集,检查:
- 意图识别准确率
- 多轮对话连贯性
-
异常输入鲁棒性
-
模型微调 vs 提示工程?对于领域专用场景,微调 + 提示工程结合效果最佳
-
成本优化方向:
- 对简单查询使用小模型
- 实现异步延迟加载复杂回答
留给读者的思考题:
1. 当用户说 ” 不是这个意思 ” 时,如何设计对话修复机制?
2. 如何平衡上下文长度与 API 调用成本?
3. 对于医疗 / 法律等专业领域,提示工程有哪些特殊注意事项?
正文完
