前言

很多人以为写 Prompt 就是"把问题说清楚",但当你需要在生产环境中稳定地获取 LLM 输出时,你就需要一套系统化的方法。这篇文章不讲玄学,全部来自线上实践。

Prompt 的四个原子组件

任何复杂的 Prompt 都可以拆解为四个基础组件:

┌──────────────────────────────────────────────┐
│  1. 角色定义(WHO)—— 模型应该扮演什么角色     │
│  2. 指令描述(WHAT)—— 需要模型做什么          │
│  3. 上下文(CONTEXT)—— 完成任务所需的背景信息  │
│  4. 输出格式(FORMAT)—— 输出的结构和样式       │
└──────────────────────────────────────────────┘

1. 角色定义

角色不是让你"扮演一个 AI 助手"这种废话,而是明确的能力边界和行为规范

❌ 差:"你是一个 AI 助手。"
✅ 好:"你是一个资深的 Python 后端工程师,精通 FastAPI 和 SQLAlchemy。
       你习惯写出有类型注解、有单元测试、遵循 PEP 8 的代码。
       你的回答应该简洁务实,必要时才给出完整代码。"

好的角色定义能显著提升输出质量——本质上是激活了模型预训练中对应领域的能力分布。

2. 指令描述

指令要遵循单一职责原则:一条指令只做一件事。

❌ 差:"分析这段代码,找出 bug,优化性能,然后重写它,再写测试。"
✅ 好(分步):
   Step 1: 分析以下代码中的 bug,列出每行代码的问题
   Step 2: 针对每个问题,给出修复方案
   Step 3: 修复代码后,为关键函数编写 pytest 测试

3. 上下文

上下文是 prompt 中最容易被低估的部分。好的上下文包含:

## 背景信息
- 项目:电商后台管理系统
- 技术栈:FastAPI + SQLAlchemy + PostgreSQL
- 用户角色:运营人员,非技术人员
- 关键约束:接口响应时间 
你是一个翻译助手。将用户输入从英文翻译为中文。



这是一篇技术文档,用词要专业准确。



Transformer architecture
Transformer 架构


{user_input}

模式 3:Few-shot 示例

Few-shot 不是随便举几个例子就行。好的 Few-shot 设计:

提取用户评论中的关键信息。

示例 1:
输入:"这个手机的电池太差了,半天就没电"
输出:{"aspect": "电池", "sentiment": "负面", "detail": "续航时间短"}

示例 2:
输入:"拍照效果惊艳,夜景模式非常清晰"
输出:{"aspect": "拍照", "sentiment": "正面", "detail": "夜景模式清晰"}

示例 3(边界情况):
输入:"还行吧,一般般"
输出:{"aspect": "整体", "sentiment": "中性", "detail": ""}

现在请分析:{user_review}

Few-shot 要点
- 示例覆盖:正向、负向、边界情况各一个
- 示例的格式必须与预期输出完全一致
- 示例数量:2-5 个效果最好,再多边际效益递减

思维链(Chain-of-Thought)

Zero-shot CoT

最简单有效的方法——加一句话:

❌ "计算 25 * 48 的结果。"
✅ "计算 25 * 48 的结果。请逐步思考。"

就这么简单,在复杂推理任务上准确率提升 10-30%。

Few-shot CoT

给出完整的推理步骤示例:

问:一个长方形的长是 12 米,宽是 8 米,求面积。
答:面积 = 长 × 宽 = 12 × 8 = 96 平方米。所以面积是 96 平方米。

问:一个正方形的边长是 15 厘米,求周长。
答:周长 = 4 × 边长 = 4 × 15 = 60 厘米。所以周长是 60 厘米。

问:一个三角形底边长 10 厘米,高 6 厘米,求面积。
答:

CoT 的最佳实践

  1. 分步指令:在 prompt 中明确要求"一步一步分析"
  2. 格式约束:让 CoT 推理过程以结构化方式输出(JSON、列表等)
  3. 自我校验:让模型在给出最终答案前先自我检查
任务:解决数学问题

第一步:理解问题(用自己的话重述问题)
第二步:拆解步骤(列出需要计算的中间结果)
第三步:逐步计算(每个步骤给出计算过程和结果)
第四步:验证答案(用另一种方法验证结果是否合理)

问题:{question}

生产级的 Prompt 管理系统

写几条 prompt 很简单,但你很快就会面临这些问题:

  • 100 条 prompt 散落在代码里,改一个要到处找
  • 产品说"这个翻译不对",你分不清是 prompt 问题还是模型问题
  • 新 prompt 上线了,效果变好了还是变差了?

Prompt 版本管理

# prompts/translator.py
PROMPTS = {
    "v1.0": {
        "system": "你是一个翻译助手。",
        "template": "将以下内容翻译成{target_lang}
{text}",
    },
    "v2.0": {
        "system": "你是一个专业的翻译助手,精通技术文档翻译。保持原文的格式和标点,专业术语要准确。",
        "template": "# 翻译任务
源语言{source_lang}
目标语言{target_lang}
领域{domain}

原文
{text}

翻译",
        "context": {"domain": "technology"},
    },
}

Prompt A/B 测试

import hashlib

def get_prompt_version(user_id: str) -> str:
    # 根据用户 ID 哈希决定使用哪个 prompt 版本
    hash_val = hashlib.md5(user_id.encode()).hexdigest()
    return "v2.0" if int(hash_val[:8], 16) % 2 == 0 else "v1.0"

# 统计两个版本的效果
metrics = {"v1.0": {"total": 0, "good": 0}, "v2.0": {"total": 0, "good": 0}}

Prompt 监控指标

prompt_metrics = {
    "avg_output_length": 0,
    "parse_success_rate": 0.98,    # 结构化输出解析成功率
    "empty_response_rate": 0.01,   # 空回复率
    "avg_latency_ms": 1200,        # 平均延迟
    "token_usage": 850,            # 平均 token 消耗
}

定期检查这些指标,任何一个指标偏离基线都要追查原因。

常见问题与调试方法

模型不遵循指令怎么办?

按优先级排查:

  1. 指令是否清晰 → 让另一个人读一遍,看能不能理解
  2. 角色是否明确 → 角色越具体,遵循度越高
  3. 指令是否在 prompt 末尾被其他内容淹没 → 把核心指令放到 prompt 开头和结尾(首尾效应)
  4. 示例是否足够 → 加 1-2 个 Few-shot 示例
  5. 模型本身能力不足 → 换更强的模型

输出格式不稳定怎么办?

# 在 prompt 中强调格式约束
"你的输出必须是合法的 JSON,不要包含任何多余的说明文字。
不要使用 markdown 代码块包裹 JSON。
直接输出 JSON 对象。"

如果还是不稳定,改用 Function Calling / Tool Use——模型对结构化工具调用的支持远好于自由格式。

总结

好的 Prompt Engineering 不是玄学,而是工程方法

  1. 用四个原子组件(角色、指令、上下文、格式)搭建 prompt 骨架
  2. 选择合适的设计模式(Markdown、XML、Few-shot)
  3. 复杂推理任务启用 CoT
  4. 生产环境必须做 prompt 版本管理和 A/B 测试
  5. 持续监控输出质量指标

把 prompt 当做代码来管理——写测试、做版本控制、逐步迭代。