共计 2665 个字符,预计需要花费 7 分钟才能阅读完成。
背景痛点:为什么提示词需要工程化?
最近在落地几个 AI 项目时,发现提示词开发存在几个典型问题:

- 效果不稳定 :同样的 prompt 在不同时段调用 API,可能得到差异巨大的结果
- 迭代成本高 :业务逻辑直接硬编码在 prompt 中,每次调整都要全文重写
- 安全风险 :开发过程中曾不小心把内部业务规则泄露到生成内容中
- 难以复用 :不同场景的 prompt 各自为战,无法形成知识沉淀
这些问题在项目初期可能不明显,但当提示词数量超过 20 个时,维护成本就会指数级上升。
技术方案:分层架构设计
借鉴 DDD 思想,我们将提示词系统划分为三层:
-
业务语义层 :用自然语言描述业务意图
# 示例:电商客服场景 BUSINESS_INTENT = """ 你是一名专业的电子产品客服,需要根据用户问题: {user_input} 结合产品知识库回答:- 保持专业且友好的语气 - 不确定时引导用户提供更多信息 """ -
逻辑控制层 :注入动态参数和控制逻辑
def build_prompt(product_info: dict, user_query: str) -> str: return f""" {BUSINESS_INTENT} --- 产品信息 --- {json.dumps(product_info)} --- 用户问题 --- {user_query} """ -
安全过滤层 :防范 Prompt 注入等攻击
import re def sanitize_input(text: str) -> str: # 移除潜在的 SQL 注入特征 return re.sub(r"[;\-\-]", "", text[:1000])
与传统单 prompt 相比,这种架构的优点是:
- 业务意图与技术实现解耦
- 动态内容与静态模板分离
- 安全防护集中化管理
实现细节:Python 实战示例
动态变量注入
from typing import Dict, Optional
from dataclasses import dataclass
@dataclass
class PromptBuilder:
template: str
def render(self, variables: Dict[str, str]) -> str:
try:
return self.template.format(**variables)
except KeyError as e:
raise ValueError(f"Missing variable: {e}")
# 使用示例
builder = PromptBuilder("Hello {name}, your order {order_id} is ready!")
print(builder.render({"name": "张三", "order_id": "#2023-001"}))
输入校验强化
import re
from typing import Tuple
class InputValidator:
PHONE_REGEX = r"^1[3-9]\d{9}$"
@classmethod
def validate_phone(cls, phone: str) -> Tuple[bool, str]:
if not re.match(cls.PHONE_REGEX, phone):
return False, "Invalid phone format"
return True, ""
@classmethod
def sanitize_text(cls, text: str) -> str:
# 移除 HTML 标签和特殊字符
return re.sub(r"<[^>]+>", "", text)
生产环境考量
API 延迟优化
-
批量请求 :对于非实时场景,合并多个提示词请求
import asyncio from openai import AsyncOpenAI async def batch_complete(prompts: list[str]) -> list[str]: client = AsyncOpenAI() tasks = [client.chat.completions.create( model="gpt-4", messages=[{"role":"user", "content": p}] ) for p in prompts] return await asyncio.gather(*tasks) -
缓存策略 :对高频模板启用结果缓存
from diskcache import Cache cache = Cache("./prompt_cache") def get_cached_response(prompt: str) -> Optional[str]: key = hash(prompt) return cache.get(key)
敏感信息过滤
SENSITIVE_WORDS = ["密码", "身份证号", "银行卡"]
def contains_sensitive(content: str) -> bool:
return any(word in content for word in SENSITIVE_WORDS)
def safe_completion(prompt: str) -> str:
if contains_sensitive(prompt):
raise ValueError("Prompt contains sensitive keywords")
# ... 调用 API 逻辑
避坑指南
版本控制方案
- 采用 Git 管理 prompt 模板文件
- 每个模板头部添加元数据注释
# PROMPT_VERSION: v1.2 # LAST_UPDATED: 2023-11-20 # OWNER: @dev_team
自动化评估
-
构建测试用例库
TEST_CASES = [{"input": "怎么退货?", "expected": "退货政策"}, {"input": "手机坏了", "expected": "售后服务"} ] -
实现自动评分
from sklearn.feature_extraction.text import TfidfVectorizer def similarity_score(text1: str, text2: str) -> float: vectorizer = TfidfVectorizer() tfidf = vectorizer.fit_transform([text1, text2]) return (tfidf * tfidf.T).A[0,1]
延伸思考
在项目实践中,我常思考这几个问题:
1. 如何量化提示词复杂度对 Token 消耗的影响?
2. 当 temperature 参数调高时,应该怎样调整评估指标?
3. 对于 few-shot learning 示例的选择,是否有自动化优化方案?
这些问题没有标准答案,但在具体业务场景中持续实验和度量,往往能找到适合的平衡点。
正文完
