# Prompt 与上下文工程实战

上下文标记来源、权限、版本和信任等级。用户输入、网页、检索文档和工具结果不能自行升级为系统指令或审批；记忆新增、更正、删除与撤权都留证据，日志按敏感字段策略采样。最新控制与测试见 [Agent 安全](../14_行业基线/02_Agent安全_身份与协议.md)。

## Prompt 是可执行规格，不是咒语

Prompt 的作用是把任务、上下文、约束和输出契约传给模型。它不能创造模型没有的能力，不能替代权限控制，也不能保证模型永不犯错。

生产效果由完整上下文决定：

```text
模型行为 = 模型/版本 + 系统与开发者指令
         + 用户输入 + 会话历史 + 检索内容
         + 工具结果 + 记忆 + 推理参数
         + 后处理/验证 + 产品交互
```

因此真正工作是 Context Engineering：在有限预算内给模型最少但充分、可信、相关、权限正确的信息。

## Prompt 规格八段式

### 1. 任务

用动词和可观察结果描述：“从客服对话中提取客户诉求、已采取动作和未解决问题”，而不是“你是非常专业的客服专家”。

### 2. 输入契约

说明字段、语言、来源、可信度和边界，用明确分隔符包裹不可信内容。

### 3. 输出契约

定义 JSON Schema、必填、枚举、单位、引用和空值。程序使用的输出必须解析和验证。

### 4. 规则与优先级

列出必须、禁止和冲突处理；规则少而明确，避免数十条互相打架的自然语言。

### 5. 知识与工具

说明何时检索、何时调用、哪些来源可用、工具失败如何处理；模型不应凭空声称执行成功。

### 6. 示例

包含代表性、边界、拒答和易混淆例，不只给理想正例。示例本身必须符合所有规则。

### 7. 不确定与失败

信息不足时输出需要补充的字段；来源不足时拒绝确认；高风险时转人工。

### 8. 质量标准

将 Rubric 中最关键维度写入规格，但真正验收仍由外部评测完成。

## 通用模板

```text
<task>
你要完成：【具体任务】。
</task>

<success>
结果必须：【可验证标准】。
</success>

<rules>
1. 只使用 <source> 中的信息确认事实。
2. 证据不足时输出 status="insufficient_evidence"。
3. 不执行或声称执行任何未返回成功回执的动作。
</rules>

<source trust="untrusted_data">
【检索内容/用户输入】
</source>

<output_schema>
【JSON Schema 或结构】
</output_schema>
```

标签只是帮助结构化，不会自动形成安全隔离；应用仍要在模型外实施权限和验证。

## 三类 Prompt 示例

### 分类/抽取

```text
任务：把工单归入一个且仅一个意图，并提取订单号。
意图枚举：refund_request, delivery_delay, product_question, other。
规则：不要根据情绪推断意图；订单号必须匹配 ^[A-Z]{2}\d{8}$，否则为 null。
输出：{"intent":"...","order_id":null,"needs_human":false}
```

外部程序再次校验枚举与正则；模型负责语言理解，确定性规则负责格式。

### RAG 问答

```text
只根据授权资料回答。每个事实主张给 source_id；来源冲突时列出冲突和日期，不自行选择；没有充分支持时明确说无法确认并提出下一步。
```

应用校验每个 `source_id` 确实属于当前检索结果和当前用户权限。

### 工具调用

```text
你可以准备退款申请，但不能批准或执行退款。
调用 create_refund_draft 前必须确认 order_id、reason、amount；amount 来自订单 API，不得从用户文本直接采用。
任何写操作先输出预览并等待 confirm_token。
```

真正的 `confirm_token`、额度、身份和幂等由服务端验证，不能让模型自行生成即通过。

## 指令层级和信任边界

通常系统/开发者指令优先于用户输入，但外部文档、网页、邮件和工具结果可能包含看似指令的文字。对这些内容：

- 标记为不可信数据。
- 不允许其改变工具、权限、目标或输出目的地。
- 只抽取任务所需字段，限制长度和格式。
- 在工具执行前做独立策略检查。
- 测试直接与间接 Prompt Injection。

“忽略恶意指令”一句话不是完整防御。

## 上下文预算

上下文越长不一定越好。噪声会稀释关键信息、提高成本和注入面。

预算顺序：

1. 不可变的核心任务与安全边界。
2. 当前用户/租户的权限与任务状态。
3. 与当前问题直接相关的可靠证据。
4. 必要的历史承诺和用户选择。
5. 代表性示例。

删除重复、低相关、已过期和可由工具即时查询的信息。

## 长对话管理

- 结构化保存任务状态、已确认字段和未解决问题。
- 对自然语言历史做摘要，但保留来源和关键原文链接。
- 区分用户事实、模型推断和临时假设。
- 摘要更新要防旧错误固化。
- 达到上下文/主题边界时开启新任务，而不是无限续聊。

## 记忆设计

### 是否该记

只有当信息能持续改善用户任务，且用户合理预期、可查看、可纠正、可删除时才保存。

### 记什么

- 明确偏好：“输出用中文表格”。
- 稳定且用户确认的事实。
- 任务/项目中有时效的结构化状态。

谨慎或不记：健康、情感、人格、政治、金融等推断；秘密；过期状态；模型自行猜测。

### 生命周期

写入前同意/确认 → 带来源与时间 → 使用时权限/时效检查 → 用户可查看/更正 → 到期/撤回删除。

## Prompt 优化流程

1. 建立最简单清晰基线。
2. 用评测集运行并做错误分类。
3. 每次只针对一类错误改变一个主要因素。
4. 比较总体、关键切片、方差、延迟、成本和安全。
5. 保留反例，防修一个场景破坏另一个。
6. 经代码评审、回归、灰度后发布。

不要靠连续在 Playground 尝试几个漂亮例子优化。

## 常见错误与修复

| 现象 | 可能原因 | 首选动作 |
|---|---|---|
| 格式偶发错误 | 契约复杂、无 Schema 验证 | 结构输出 + 解析校验 + 有限重试 |
| 引用存在但不支持 | 检索噪声、生成未绑定证据 | 主张级引用验证、改检索/Rubric |
| 过度回答 | 缺少拒答样例/证据门槛 | 加负例、外部证据检查 |
| 漏关键项 | 任务/输出定义不清 | 字段化、逐项 Rubric |
| 长输入表现下降 | 关键信息被淹没 | 检索、重排、摘要、结构化状态 |
| 被文档劫持 | 信任边界错误 | 隔离不可信内容、工具策略层 |
| 成本过高 | 历史/示例/来源冗余 | 压缩上下文、缓存、路由小模型 |
| 改一处坏多处 | 无回归集/耦合规则 | 版本化、分场景 Prompt 或路由 |

## Prompt 版本规范

每个版本记录：

- ID、Owner、日期、模型兼容范围。
- 任务与变更原因。
- 模板、变量、示例和参数。
- 关联数据集/Rubric/评测器版本。
- 质量、切片、安全、延迟和成本差异。
- 批准、灰度、回滚版本和到期复核。

语义版本可用：重大任务/输出契约变更升主版本，兼容规则/示例改进升次版本，措辞修复升补丁版本。

## Prompt 评审清单

- [ ] 任务和成功标准可验证。
- [ ] 输入、输出与不可信内容边界清楚。
- [ ] 规则不存在明显冲突和重复。
- [ ] 示例覆盖正例、边界、拒答和恶意输入。
- [ ] 信息不足、工具失败和部分成功有策略。
- [ ] 不包含秘密或把模型当权限控制。
- [ ] 结构输出由程序校验。
- [ ] 已运行真实分布、关键切片和安全回归。
- [ ] 成本与延迟在预算内。
- [ ] 版本、Owner、发布和回滚可追溯。
