Skip to content

Prompt 工程

🎯 学习目标

  • 能编写含角色、目标、上下文、任务、格式的五段式 Prompt
  • 运用 Zero-shot、Few-shot、CoT 等技巧并知道何时用
  • 建立 Prompt 版本管理与 Eval 回归流程
  • 通过代码模板化 Prompt,避免字符串散落

引言

Prompt Engineering(提示工程) 是通过自然语言指令塑造模型行为的技术——不是玄学,而是 可版本化、可测、可迭代 的接口层。弱 Prompt 浪费 Token、引发幻觉、输出难解析;强 Prompt Often 比换更大模型更便宜有效。

本节给出 五段式结构(角色、目标、上下文、任务、格式),演示 Zero-shot / Few-shot / CoT(Chain-of-Thought,思维链) 的代码化写法,并强调 Eval 回归:Prompt 改动必须像改 API 一样跑测试集。你会把 Prompt 从聊天框里的临时文字,变成仓库里的 prompts/support-v1.3.md 或 TypeScript 模板函数。

章节正文

第 1 步:五段式 Prompt 结构

高质量 Prompt 可拆为:

  1. Role(角色):你是谁、擅长什么
  2. Goal(目标):成功标准是什么
  3. Context(上下文):RAG 片段、用户画像、业务规则
  4. Task(任务):这一步具体做什么
  5. Format(格式):Markdown 标题 / JSON / 表格 / 字数限制

示例模板:

javascript
export function buildSupportPrompt({ context, question }) {
  return `## 角色
你是 Acme 公司技术支持,熟悉 SaaS 账单与权限。

## 目标
准确回答用户问题;无依据时不编造。

## 上下文
${context || '(无检索结果)'}

## 任务
回答用户问题:${question}

## 格式
- 先一句话直接回答
- 再用 bullet 列步骤(如有)
- 不超过 200 字
`
}

const messages = [
  { role: 'system', content: '遵循用户消息中的结构化指令。' },
  { role: 'user', content: buildSupportPrompt({ context: '...', question: '如何开发票?' }) },
]

System 可保持短稳定;可变部分放 user 便于 A/B 与日志。

第 2 步:Zero-shot、Few-shot 与示例选择

Zero-shot(零样本):无示例,纯指令。适合简单、模型已熟悉的任务。

javascript
const zero = '将下列评论分类为 positive/negative/neutral,只输出标签:\n评论:物流很快,包装破损。'

Few-shot(少样本):给 1–N 个输入输出示范,对齐格式与边界。

javascript
const few = `
示例1
输入:物流很快,包装破损。
输出:mixed

示例2
输入:完全不满意,退货!
输出:negative

请分类:
输入:性价比高,会复购。
输出:
`

技巧:示例要 覆盖边界 case(混合情感、空输入);示例过多占 Token——通常 2–5 个够。选择与生产分布相似的例子,而非随机编造。

动态 few-shot:从向量库检索 相似历史 QA 作为示例(与 RAG 结合),效果常优于固定示例。

第 3 步:Chain-of-Thought 与 Self-Consistency

CoT(Chain-of-Thought,思维链) 要求模型 先推理再结论,提升多步逻辑题准确率。

javascript
const cot = `
问题:一个会议室有 3 排椅子,每排 8 把,来了 15 人,每人占 1 把,还剩几把空椅子?

请按步骤思考,最后一行以「答案:数字」结尾。
`

Reasoning Model(R1/o 系列) 可能内置长推理;通用模型用 CoT 显式指令即可。

Self-consistency:同一 Prompt 高温采样 N 次,对最终答案 投票——成本 N 倍,用于高价值决策或 offline Eval,少用于在线默认路径。

javascript
async function voteAnswer(client, prompt, n = 5) {
  const answers = []
  for (let i = 0; i < n; i++) {
    const res = await client.chat.completions.create({
      model: 'gpt-4o-mini',
      messages: [{ role: 'user', content: prompt }],
      temperature: 0.7,
    })
    const m = res.choices[0].message.content.match(/答案:(\d+)/)
    if (m) answers.push(m[1])
  }
  const freq = {}
  for (const a of answers) freq[a] = (freq[a] ?? 0) + 1
  return Object.entries(freq).sort((a, b) => b[1] - a[1])[0]?.[0]
}

第 4 步:Prompt 版本管理与 Eval 回归

目录建议:

prompts/
  support/
    v1.2.0.md
    v1.3.0.md
  extract/
    invoice-v2.md
eval/
  support_cases.jsonl

support_cases.jsonl 每行:

json
{"input":"如何退款?","context":"...","expected_contains":["7天","未使用"]}

回归脚本核心:

javascript
import fs from 'fs'

const cases = fs.readFileSync('eval/support_cases.jsonl', 'utf8').trim().split('\n').map(JSON.parse)

let pass = 0
for (const c of cases) {
  const userContent = buildSupportPrompt({ context: c.context, question: c.input })
  const res = await client.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: userContent }],
    temperature: 0,
  })
  const out = res.choices[0].message.content
  const ok = c.expected_contains.every((s) => out.includes(s))
  if (ok) pass++
  else console.log('FAIL', c.input, out)
}
console.log(`${pass}/${cases.length} passed`)

Prompt 变更 PR 必须附 Eval 结果;记录 model + temperature + prompt_version 三元组,避免「模型升级导致 Prompt 静默失效」。

第 5 步:反模式与与 RAG/工具的边界

反模式

  • 在 Prompt 里堆 几十条重复禁止项 → 改 system 精简 + 护栏模块
  • 要求模型 心算大数、查实时股价 → 交工具/API
  • 用 Prompt 塞 整本手册 → RAG 检索 Top-K
  • 无 Eval 的「我觉得更好」上线 → silent regression

Prompt vs RAG vs 微调(决策简表):

需求优先手段
注入最新文档RAG
固定格式/风格Prompt + JSON mode
海量领域术语 consistently 错考虑 LoRA
实时精确数据工具调用

Prompt 是 ** cheapest layer**——先把它做好,再考虑更重的方案。

动手练习

  1. 为你业务写一版五段式 Prompt 模板函数,含 Format 约束。
  2. 同一分类任务分别 Zero-shot 与 3-shot,记录准确率差异(人工或 10 条小集)。
  3. 添加 5 条 jsonl Eval case,改 Prompt 一词跑回归对比 pass rate。
  4. 写 prompts/README 说明版本号规则(semver)与何时 bump minor/major。

常见问题

Q:System 放长 Prompt 还是 User?

极稳定全局规则放 system;频繁变的上下文、任务放 user。部分厂商对 system 有 caching 优惠,查文档。

Q:CoT 会泄露推理过程给用户吗?

会,若不需要展示,可指令「推理内部进行,只输出最终 JSON」或用 reasoning 模型的摘要输出模式。

Q:英文 Prompt 还是中文?

视模型训练分布而定。中文业务常中文即可;复杂推理可试英文指令 + 中文输出 A/B。

本节小结

Prompt 工程用五段式结构组织角色、目标、上下文、任务与格式;Zero-shot/Few-shot/CoT 按任务复杂度选用。Prompt 应版本化并与 Eval 集绑定,变更跑回归。Prompt 不能替代 RAG 与工具;先优化 Prompt 再考虑更重定制。