从一次惊艳到长期可靠

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

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

> 提示词定义一次意图,系统负责兑现长期承诺。

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

提示词不是系统

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

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

这些都属于系统责任。

把所有问题继续塞进提示词,常见结果是指令越来越长、规则互相冲突、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