## 从一次惊艳到长期可靠

很多 AI 产品在演示时让人眼前一亮，上线后却很快变得不可预测。问题通常不在模型不够强，而在于我们把一次生成误当成了一个完整产品。

一次演示只需要在理想输入下得到好答案；一个真实产品却要面对模糊请求、过期资料、不同权限、工具超时、模型波动、长会话和不可逆操作。两者之间的差距，不是再补一句提示词，而是一整套工程系统。

&gt; 提示词定义一次意图，系统负责兑现长期承诺。

这里的“长期承诺”包括：在不同时间、不同用户和不同异常条件下，产品仍然知道该做什么、能做什么、何时停止，以及怎样证明结果可信。

## 提示词不是系统

提示词当然重要。它负责告诉模型角色、目标、约束、输出格式和判断标准。好的提示词可以显著改善一次调用的质量，但它无法独立解决以下问题：

- 用户现在是否有权执行这个动作。
- 检索到的资料是否最新、相关并且完整。
- 工具调用失败后应该重试还是换一条路径。
- 写操作是否已经成功，重试会不会产生重复数据。
- 长任务中断后从哪里恢复。
- 新版本是否让某一类真实任务悄悄退化。
- 最终答案是否有事实依据，而不只是语言流畅。

这些都属于系统责任。

把所有问题继续塞进提示词，常见结果是指令越来越长、规则互相冲突、Token 成本增加，真正的权限、状态和可靠性问题却依然没有解决。

提示词应该表达决策原则，程序应该强制执行安全边界，评估体系应该判断结果是否达标。三者不能互相代替。

## 从四层骨架到七层系统

原始的 Prompt、Context、Tools、Evals 四层，是理解 AI 产品的好骨架：

| 层次 | 负责什么 | 核心问题 |
| --- | --- | --- |
| Prompt | 定义意图、约束与输出契约 | 要做什么？ |
| Context | 组装此刻相关的事实和状态 | 需要知道什么？ |
| Tools | 读取事实并执行现实动作 | 可以做什么？ |
| Evals | 发现错误、退化并形成反馈 | 做得好吗？ |

要进入生产环境，还需要补上三个经常被忽略的层次：

| 层次 | 负责什么 | 核心问题 |
| --- | --- | --- |
| Runtime | 编排调用、超时、重试、取消和停止 | 怎样持续运行？ |
| State | 保存会话、进度、检查点和幂等信息 | 已经发生了什么？ |
| Guardrails | 管理权限、审批、沙箱和敏感数据 | 哪些动作被允许？ |

这七层共同构成一个可维护的 AI 系统。模型只是其中的推理与生成能力，不是整个产品。

## Prompt：把意图写成任务契约

高质量 Prompt 不是堆砌形容词，而是把产品要求变成明确契约。

一个实用的任务契约通常包含：

- 目标：最终要交付什么。
- 背景：模型理解任务必须知道的领域信息。
- 约束：不能违反的规则和范围。
- 授权：本次请求允许读取、修改或发布到什么程度。
- 成功标准：什么证据能够证明任务完成。
- 输出格式：用户或下游程序怎样消费结果。
- 求助条件：什么情况下必须停止并请求用户决定。

例如，“分析这个故障”与“定位过去一小时支付失败的主要原因，只读诊断，不修改线上配置，并给出日志和指标证据”之间，差别不是文风，而是任务边界是否可执行。

提示词也要保持精简。重复规则、相互冲突的示例和无关工具说明会稀释真正重要的信息。规则应该各自只出现一次，并按优先级组织。

## Context：不是越长越好，而是越相关越好

上下文决定模型此刻能看到的世界。上下文错误，再强的模型也只能在错误前提上推理。

上下文工程需要处理五件事：

### 选择

只取与当前任务有关的文件、记录、历史和政策。不要为了“保险”把整个知识库塞进上下文。

### 排序

目标、硬约束和最新事实应该优先于背景资料。高影响信息要靠近决策位置，并明确来源。

### 新鲜度

价格、状态、权限、版本和业务数据都可能变化。系统要知道哪些事实可以复用，哪些必须重新查询。

### 压缩

长会话需要压缩旧内容，但不能丢失目标、已确认事实、用户修正、未完成事项和关键证据。

### 隔离

系统规则、用户输入、工具结果和模型推断应该清楚区分。外部内容不能伪装成高优先级指令。

上下文质量可以用一个简单问题检验：如果把当前内容交给一名新同事，他是否能理解目标、知道哪些事实可信，并继续完成任务？

## Tools：把语言能力连接到现实

没有工具时，模型主要负责解释和生成；接入工具后，系统可以搜索资料、读取文件、执行代码、查询数据库和写入外部服务。

工具设计直接影响模型表现。一个好工具应当具备：

- 单一、明确的职责。
- 清楚的名称和使用条件。
- 强类型参数、必填项和范围限制。
- 稳定的返回结构。
- 可行动的错误信息。
- 明确的只读或写入语义。
- 最小权限与凭据隔离。
- 必要时支持幂等和结果查询。

“调用失败”不是足够的工具反馈。系统应该说明失败阶段、是否可重试、是否产生了部分结果，以及下一步有哪些安全选择。

工具数量同样不是越多越好。用途重叠、描述含糊的工具会增加选择成本。只向当前任务暴露必要工具，往往比提供一整套万能接口更可靠。

## Runtime：让多步任务可控地运行

只要任务需要多轮观察和行动，就需要 Runtime 管理生命周期。

Runtime 负责：

- 调用模型与工具。
- 把工具结果返回给下一轮判断。
- 控制并发、步骤和成本预算。
- 处理超时、有限重试和取消。
- 检测重复调用和无效循环。
- 在外部写入前触发审批。
- 判断任务完成、受阻或需要用户介入。
- 对最终结果执行验证。

运行时不应该把“工具返回成功”直接等同于“用户目标完成”。代码写入成功后还要测试，文章提交前还要校验，数据更新后还要确认回执。

对于固定步骤，普通程序或工作流更可靠；只有在中间结果会改变下一步路径时，才需要让模型参与动态决策。

## State：让任务记得自己走到了哪里

多轮和长时间任务必须管理状态。否则一次网络中断、进程重启或用户离开，就会让系统重新开始。

状态通常包括：

- 当前目标和任务阶段。
- 已确认事实与尚未验证的假设。
- 已完成步骤和工具结果。
- 用户授权、审批和修正。
- 文件或数据的变更记录。
- 检查点、重试次数和幂等键。
- 最终验证证据。

状态不等于把所有历史原样保留。系统需要区分工作记忆、可复用知识和必须实时核验的事实。

特别是发布文章、发送消息、创建订单等外部写入，应该记录稳定幂等键。网络超时并不代表操作失败，盲目重试可能造成重复结果。

## Guardrails：把安全边界做成系统机制

“请谨慎操作”不是安全机制。

生产系统需要把关键边界强制化：

- 认证用户身份，并按任务授予最小权限。
- 区分读取、修改、外部写入和破坏性操作。
- 对删除、购买、发送和发布设置明确审批条件。
- 使用文件系统、网络和代码执行沙箱。
- 校验命令、路径、目标对象和参数范围。
- 把密钥留在执行层，不写入 Prompt、正文或日志。
- 限制调用速率、并发、时间和成本。
- 允许用户随时取消、纠正或接管。

Guardrails 的目标不是让系统失去行动能力，而是让它在授权范围内顺畅推进，在越界前可靠停下。

## Evals：把“感觉不错”变成可度量质量

传统软件的错误往往表现为程序崩溃、状态码异常或断言失败。AI 系统多了一类更棘手的问题：程序成功运行了，但结果并不好。

因此，评估不能只看 API 是否返回成功，还要判断：

- 结果是否正确。
- 关键结论是否有证据支撑。
- 是否遗漏用户要求。
- 输出格式是否可用。
- 是否调用了不必要或错误的工具。
- 是否发生越权或高风险操作。
- 延迟和成本是否在预算内。
- 相同任务重复运行是否稳定。

评估可以分为四层：

### 确定性校验

检查 JSON Schema、字段完整性、链接、文件格式、代码编译和业务规则。这类规则能用普通程序判断，就不应该交给模型猜。

### 参考答案评估

对有明确正确答案的任务，比较关键事实、步骤和最终结果。测试集应覆盖正常输入、边界情况和已知失败案例。

### 模型评分

对文案质量、解释完整性和开放式分析，可以使用模型评分，但要先用人工样本校准标准，避免评分器只偏好更长、更流畅的答案。

### 人工评审

高影响、难量化或新类型任务仍需要人工判断。人工评审结果应该进入测试集，而不是停留在聊天记录里。

## 把评估放进开发循环

评估的价值不只是发布前打分，而是形成持续反馈回路：

1. 从真实使用中收集失败案例。
2. 去除敏感数据，整理成可重复测试。
3. 标注期望结果、允许差异和失败类型。
4. 在当前版本上建立基线。
5. 每次只修改一个主要变量。
6. 重新运行相同评估集。
7. 比较质量、成本、延迟和风险。
8. 通过后再逐步发布并监控线上指标。

需要特别警惕“只优化平均分”。少数高风险失败可能被漂亮的总体数据掩盖。除了平均质量，还要单独观察越权率、事实错误率、重复写入率和严重失败数。

把真实失败固化成测试案例，是 AI 产品从经验驱动走向工程驱动的关键一步。

## 可观察性：没有记录就无法改进

AI 系统需要同时记录结果和过程。否则一个回答出错时，团队很难判断问题来自 Prompt、Context、Tools、Runtime 还是模型本身。

建议记录：

- 请求使用的模型、版本和关键配置。
- 上下文来源、时间和截断情况。
- 工具调用、参数摘要、耗时和结果状态。
- 重试、回退、审批和停止原因。
- 最终输出与验证结果。
- 用户纠正、人工接管和后续反馈。
- Token、延迟和外部服务成本。

日志必须注意隐私和凭据隔离。可观察性不是把完整上下文永久保存，而是保存足以复盘、又符合数据治理要求的证据。

## 一个从 Demo 到产品的例子

假设我们要做一个“根据内部资料回答客户问题”的功能。

### 第一版：只有 Prompt

把用户问题和一段固定说明发送给模型。演示很快，但答案可能使用过期信息，也无法说明来源。

### 第二版：加入 Context

从知识库检索相关资料，只提供最新、最相关的段落，并要求答案附带来源。系统开始具备事实基础。

### 第三版：加入 Tools

允许查询订单状态、产品配置和服务记录。工具只返回必要字段，并按用户权限过滤数据。

### 第四版：加入 Runtime 与 State

当资料冲突时继续查询；工具超时时有限重试；长对话保留目标和关键事实；创建工单时使用幂等键。

### 第五版：加入 Guardrails

普通咨询保持只读；退款、补偿和修改订单需要明确授权或人工审批；敏感信息在进入模型前脱敏。

### 第六版：加入 Evals 与反馈

用真实问题建立评估集，检查事实正确性、引用覆盖、拒答质量、工具选择、延迟和成本。线上收集人工修正，持续补充回归案例。

同一个模型没有变化，产品却从一次生成变成了可验证、可恢复、可治理的服务。

## 常见故障应该查哪一层

| 现象 | 更可能的问题层 |
| --- | --- |
| 回答方向错误 | Prompt 的目标或完成标准不清 |
| 事实过期或缺失 | Context 的检索、新鲜度或压缩失效 |
| 选错工具、参数混乱 | Tools 的职责、描述或返回语义不清 |
| 重复调用、任务卡住 | Runtime 缺少预算、重复检测或停止条件 |
| 重试后产生两条数据 | State 缺少幂等和调用记录 |
| 普通请求触发外部写入 | Guardrails 的授权边界失效 |
| 新版本悄悄变差 | Evals 覆盖不足或没有持续回归 |
| 出错后无法复盘 | 可观察性缺少上下文和调用证据 |

先定位层次，再选择修复方式。很多“再改一下 Prompt”的需求，实际根因可能是工具错误信息含糊、上下文过期或没有结果验证。

## 一条务实的落地路径

不要一开始就建设庞大的 Agent 平台。可以按风险和价值逐步演进：

1. 先定义一个具体、高频、可验证的任务。
2. 用最短 Prompt 和少量示例建立基线。
3. 补齐真实 Context，并标注来源和新鲜度。
4. 只接入任务真正需要的窄工具。
5. 增加超时、取消、有限重试和停止条件。
6. 对写操作加入最小权限、审批和幂等。
7. 把真实失败沉淀为评估集。
8. 记录质量、延迟、成本和严重失败。
9. 证明稳定后，再扩大自主范围和使用场景。

每次只改变一个主要变量，才能知道质量变化究竟来自模型、Prompt、Context 还是工具。

## 上线前检查清单

准备把 AI 功能交给真实用户前，至少确认：

- 目标、约束和成功标准清楚。
- Prompt 没有重复或互相冲突的规则。
- 上下文来源可信、相关并且足够新。
- 工具职责单一，参数和错误语义明确。
- 只读与写入权限已经分离。
- 外部写入支持审批、幂等或结果查询。
- 任务有超时、取消、预算和停止条件。
- 长任务有状态和中断恢复方案。
- 最终结果有确定性校验或证据要求。
- 真实失败已经进入回归评估集。
- 线上质量、延迟、成本和风险可观察。
- 用户能够看到关键进度并安全接管。
- 敏感数据不会泄露到 Prompt、日志或不必要的外部服务。

如果这些条件还没有建立，系统更接近 Demo，而不是可以长期承诺结果的产品。

## 让智能变得可维护

模型会继续变强，调用成本也可能继续下降。但产品真正的壁垒，不是某一句“神奇提示词”，而是把不稳定的生成能力组织成稳定、透明、可恢复、可持续改进的体验。

Prompt 决定系统如何理解意图，Context 决定它掌握哪些事实，Tools 决定它能做什么，Runtime 与 State 决定任务能否持续推进，Guardrails 决定哪些行为被允许，Evals 和可观察性决定系统能否发现错误并不断变好。

这才是 AI 产品真正的工程分水岭：从追求一次好答案，转向兑现一个可以长期验证的产品承诺。

## 参考资料

OpenAI 的官方模型指导建议提供目标、背景、硬约束、所需证据、成功标准和输出格式，并明确工具路由、权限边界、重试停止条件与最终验证。这些原则可以作为 AI 系统设计的工程检查项：[OpenAI Model guidance](https://developers.openai.com/api/docs/guides/latest-model)。
