Prompt Engineering
Prompt Engineering 不是寻找一句“神奇咒语”,而是把目标、允许使用的信息、约束和输出契约写清楚,再用固定 cases 验证模型是否稳定完成任务。
Prompt 在 AI System 中的位置
Product requirement
↓
Task contract ── input / success / constraints / output
↓
Prompt + Context + Model controls
↓
Model output
↓
Schema checks + business rules + human review + evals
Prompt 只负责告诉模型要完成什么。最新事实来自 RAG 或工具,业务动作由 tools 执行,跨请求状态属于 memory,权限和发布门槛属于 harness/governance。
1. 先写 Task Contract
| 字段 | 要回答的问题 | 示例 |
|---|---|---|
| Objective | 本次任务真正要完成什么? | 从已确认 transcript 生成 progress-note draft |
| Inputs | 有哪些字段和来源? | transcript、resident ID、shift ID |
| Success | 什么算完成? | schema 合法、无新增事实、需人工确认 |
| Constraints | 哪些事禁止做? | 不做诊断、不补写未提供信息 |
| Output | 下游怎样消费? | ProgressNoteDraft structured output |
| Failure | 缺信息时怎么办? | 返回 missing fields / human review |
如果这张表写不清,继续堆角色、形容词和示例只会掩盖需求问题。
2. 可复用 Prompt 结构
# Objective
Produce a progress-note draft from confirmed transcript facts.
# Inputs
- resident_id: {{resident_id}}
- shift_id: {{shift_id}}
- confirmed_transcript: {{confirmed_transcript}}
# Allowed evidence
Use only confirmed_transcript. Do not infer diagnoses or events.
# Decision rules
- Missing resident_id or shift_id → status=invalid_input
- Ambiguous statement → add to review_flags
- Never mark the draft as confirmed
# Output contract
Return the configured ProgressNoteDraft structured output.
# Success criteria
Every factual statement must be traceable to the transcript.
稳定 instructions 与 schema 放在受版本控制的模板中,动态用户内容通过变量注入;不要用字符串拼接让用户输入伪装成系统规则。
3. Instructions、Context 与 Schema 各做什么
| 组件 | 负责 | 不负责 |
|---|---|---|
| Instructions | 目标、规则、边界、失败行为 | 提供最新企业事实 |
| Context | 本次调用可见的事实、状态、例子 | 自动保证可信或有权限 |
| Structured Output | 字段、类型、枚举、必填项 | 保证事实正确 |
| Business validation | 权限、ID、状态流、跨字段规则 | 替代模型生成 |
| Human review | 高风险判断与最终确认 | 修复所有系统设计问题 |
4. Zero-shot、Few-shot 与 Prompt Chaining
Zero-shot
适合 contract 清楚、输出简单、case 边界有限的任务。先用最简 Prompt 建 baseline,不要默认示例越多越好。
Few-shot
示例用来展示难以只靠规则表达的边界。选择少量、典型且相互一致的 examples,并覆盖至少一个 failure/abstain case。
{
"input": "Resident may have felt dizzy; nurse will verify.",
"expected": {
"status": "needs_review",
"review_flags": ["uncertain_symptom"]
}
}
Prompt Chaining
当中间结果需要检查、批准或复用时,把任务拆成固定 stages:
Extract facts → deterministic validation → draft note → human review
每增加一次模型调用都会增加延迟、费用与失败点。只有 eval 表明拆分更可靠时才保留 chain。
5. Reasoning Prompt 的边界
不要把 “think step by step” 当成跨模型通用配置。对 reasoning models,优先描述 outcome、success criteria 和可验证证据,并使用该模型实际支持的 reasoning control。产品通常需要最终答案、引用、decision summary 或检查结果,不需要暴露隐藏推理。
6. 结构化输出:Prompt 不能代替 Schema
生产实现优先使用 provider 支持的 Structured Outputs 或 schema 工具,而不是只在 Prompt 中写“请返回 JSON”。应用侧仍需检查:
- JSON Schema:字段、类型、required、enum;
- Domain rules:resident/shift 是否存在且匹配;
- Permission:当前操作者是否可查看或确认;
- Lineage:每个 draft fact 是否来自允许的 source;
- State transition:Draft 不能由模型直接变成 Confirmed。
7. Prompt Version 与 Regression Dataset
prompt_id: progress-note-draft
prompt_version: 0.3.0
model_id: runtime-configured
schema_version: progress-note.v2
dataset_version: care-docs.v1
change_reason: clarify uncertain statements
owner: ai-platform
每次变更只解决一个可观察 failure,并在相同 dataset 上比较 before/after:schema pass、事实支持、review flag、refusal、latency 和 usage。不要边换模型、边改 Prompt、边换 dataset。
8. 三个工程案例
案例 A:结构化信息提取
目标是提取已有事实。Prompt 明确 allowed evidence,schema 控制输出形状,业务规则阻止未知 resident ID。失败时进入 review,不让模型补全。
案例 B:政策问答
Prompt 要求只基于带 source ID 的 retrieved context 回答。没有足够证据就 abstain。Citation 是否存在可 deterministic check,但引用是否真正支持结论仍需评估。
案例 C:工具决策
Prompt 说明工具用途和选择条件;tool description 声明参数、副作用、权限与错误。模型提出调用,应用执行 authorization。Prompt 无法授予数据库权限。
9. Prompt Debugging Matrix
| 症状 | 先检查 | 可能的正确修复 |
|---|---|---|
| 格式漂移 | 是否使用 Structured Output | 增加 schema 与 validation |
| 缺少最新事实 | Context 是否含可信来源 | RAG/tool,不是堆 Prompt |
| 越权动作 | 应用是否做 authorization | 在 tool boundary 拦截 |
| 忽略条件 | 条件是否冲突或被噪声淹没 | 精简/重组 Context,加入 case |
| 结果偶发失败 | dataset 是否覆盖边界 | 多次运行,按 failure cluster 修 |
| 成本过高 | history/examples/tool schema | selection、compression、routing |
10. 动手练习
选择“Confirmed Transcript → Progress Note Draft”任务:
- 写 Task Contract 和 output schema。
- 准备 8–12 条 cases:正常、缺字段、含糊、矛盾、越权、prompt injection。
- 保存最小 Prompt baseline。
- 只针对一种 failure 增加规则或 example。
- 重新运行相同 dataset,报告改善、退化和未解决问题。
完成标准
- Prompt 有 objective、inputs、success、constraints、output 和 failure 行为。
- 动态数据与稳定规则分开,输入不会被拼接成高权限指令。
- 输出经过 schema、业务和权限校验。
- 变更有 prompt version、dataset version 和 change reason。
- 结论来自 regression cases,不来自单次人工感觉。
- 能说明何时应该使用 RAG、tool、memory 或 fine-tuning,而不是继续改 Prompt。
官方参考
📚 相关资源
❓ 常见问题
点击问题,查看本章对应的实践答案。
Prompt 写不好通常输出乱、格式不稳定,有没有标准模板?
用 6 段结构:[角色/风格] + [任务] + [输入约束] + [输出格式] + [边界] + [示例]。这个模板能解决 80% 的 prompt 质量问题。最常见的错误就是只写了任务没给输出格式,导致每次返回结构不一样、下游代码解析炸。明确写「仅输出 JSON」+ 给一个 schema 示例,立刻稳定。
Few-shot、CoT、ToT、Self-critique、ReAct 哪个该用?
Few-shot:固定输出格式,2-5 个一致示例(3 个高质量 > 10 个低质量);CoT:复杂计算/逻辑,必须限制步骤数否则 token 暴增;ToT:创意/规划要多方案选优;Self-critique:代码生成让模型自查 edge case;ReAct:tool calling / 搜索循环。任务驱动选策略,别堆砌。
怎么降低模型「编造事实」(幻觉)?
三件事:(1) 写「仅根据提供的上下文回答,未找到则返回'未在上下文中找到'」,实测幻觉率降 60%+;(2) 要求附引用编号 [1][2];(3) 让模型先列依据再给结论。如果上下文超过 50K tokens,注意力会分散,要先做检索缩短上下文。配合「如果不确定,回复'我不确定,建议人工确认'」兜底。
JSON 输出经常格式错怎么办?
三层防御:(1) 用 OpenAI `response_format={"type":"json_object"}` JSON Mode 或 prompt 里给 schema 示例;(2) 接收后用 JSON schema 校验;(3) 校验失败时让模型「只修复结构重试」,最多 3 次。3 次都失败说明 prompt 本身有问题,要改 prompt 不是继续重试。
多轮对话越聊越漂移、模型「忘了」最初指令怎么办?
20+ 轮对话很容易漂移。解法:(1) 关键约束放 system 每轮都带,user/assistant 只放必要历史;(2) 话题切换时重新声明角色和输出格式;(3) 偶尔让模型复述当前约束做粘性检查;(4) 用 conversation_id / traceId 关联日志方便复现。history 要瘦身,否则 token 膨胀加剧漂移。