共计 2331 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点:新手开发者的常见困境
刚接触对话系统开发时,我踩过不少坑。最典型的问题是 意图识别漂移 (Intent Detection Drift)——用户说 ” 我想订明天的机票 ”,系统却识别成 ” 查询航班动态 ”。另一个头疼的是 上下文丢失(Context Loss),比如用户问 ” 那家餐厅人均多少 ” 后接着说 ” 订个位子 ”,系统却忘记前文指的哪家餐厅。

传统解决方案需要维护庞大的规则库:
- 正则表达式匹配规则随业务增长呈指数级膨胀
- 基于关键词的 FAQ 库无法处理语义相近但表述不同的请求
- 硬编码的对话流程让系统显得机械呆板
技术对比:提示工程 vs 传统方案
| 维度 | 传统规则引擎 /NLP 管道 | Anthropic 提示工程 |
|---|---|---|
| 响应延迟 | 50-200ms(依赖规则复杂度) | 300-800ms(模型推理时间) |
| 维护成本 | 需要持续添加新规则 / 语料 | 通过 few-shot 学习自动泛化 |
| 上下文处理 | 需手动设计状态机 | 自动保持多轮对话记忆 |
| 冷启动难度 | 需收集大量标注数据 | 5-10 个示例即可初见成效 |
关键差异在于:传统方案像编程,提示工程像教学。前者需要精确描述每个逻辑分支,后者则是通过示例教会模型理解需求。
核心实现:构建对话状态机
from typing import Dict, Any
from enum import Enum, auto
class DialogState(Enum):
GREETING = auto()
COLLECT_INFO = auto()
CONFIRMATION = auto()
COMPLETION = auto()
class DialogManager:
def __init__(self):
self.state = DialogState.GREETING
self.context: Dict[str, Any] = {}
def process_input(self, user_input: str) -> str:
try:
if self.state == DialogState.GREETING:
self.context['user_name'] = extract_name(user_input)
self.state = DialogState.COLLECT_INFO
return f"您好{self.context['user_name']},请问需要什么帮助?"
# 其他状态处理...
except Exception as e:
self.state = DialogState.GREETING # 出错时重置对话
return "抱歉,我有点困惑,我们重新开始好吗?"
# 示例调用
dialog = DialogManager()
print(dialog.process_input("我是张三")) # 输出:您好张三,请问需要什么帮助?
多轮对话上下文保持
使用 CLAUDE 模型的对话 API 时,关键是将历史对话作为上下文传入:
import anthropic
client = anthropic.Client(api_key="your_api_key")
def chat_with_context(history: list[str], new_query: str) -> str:
prompt = "\n\n".join(history + [new_query])
response = client.completion(prompt=f"{anthropic.HUMAN_PROMPT}{prompt}{anthropic.AI_PROMPT}",
max_tokens_to_sample=1000
)
return response.completion
# 使用示例
history = [
"用户:推荐一家上海本帮菜",
"AI:推荐老吉士酒家,米其林一星"
]
new_query = "用户:人均消费多少?"
print(chat_with_context(history, new_query)) # 会关联前文回答老吉士的价格
生产环境考量
幂等性设计
- 为每个对话会话生成唯一 session_id
- 对相同输入 + 上下文组合缓存响应结果
- 用户说 ” 没听清 ” 时能重复最后回答而不会推进状态
敏感词过滤
from fastapi import FastAPI, Request
import re
app = FastAPI()
banned_words = [...] # 从数据库加载
def filter_sensitive(text: str) -> str:
for word in banned_words:
text = re.sub(rf"(?i){re.escape(word)}", "***", text)
return text
@app.post("/chat")
async def chat_endpoint(request: Request):
data = await request.json()
cleaned_input = filter_sensitive(data["query"])
# ... 处理逻辑
避坑指南:提示工程反模式
- 过度嵌套的条件判断
- 反模式:在提示中写 ” 如果 A 则 B,否则如果 C 则 D …” 超过 3 层
-
优化:拆分成多个专用提示模板,用元提示(meta-prompt)选择合适模板
-
模糊的指令表述
- 反模式:” 请友好地回答用户 ”
-
优化:” 用 2 - 3 句话回答,包含 1 个表情符号,避免专业术语 ”
-
忽略负样本训练
- 反模式:只给模型看正确示例
- 优化:添加类似 ” 以下是错误回答示例:…[解释错误原因]”
开放思考题
- 当业务领域专业术语很多时(如医疗、法律),如何设计提示模板才能平衡专业性和通俗性?
- 对于需要精确数值计算的场景(如订单金额核对),怎样结合传统编程与提示工程最有效?
从我的实践来看,提示工程最像教小朋友——要用具体例子说话,及时纠正错误,但也要给模型留出推理空间。建议先用 5 个典型对话场景验证基础流程,再逐步扩展复杂用例。
正文完
