Agent 工程体系 · 第 19/98 篇。内容以 2026 年 9 月可验证的公开规范和稳定接口为基线;框架版本敏感能力会明确标注,不把实验行为写成通用保证。

Agent 不确定性与拒答:证据不足、置信边界、升级和回退

Agent 的可靠性,不是“尽量回答所有问题”,而是在证据、能力和责任边界内采取正确动作。这个动作可能是直接回答,也可能是继续检索、请求澄清、降低操作权限、转交人工、调用备用流程,或者明确拒答。

如果 Agent 把“没有证据”当成“可以猜测”,它会产生幻觉;如果把所有不确定性都变成“我无法回答”,它又会失去自动化价值。因此,工程上真正要设计的不是一句拒答话术,而是一套决策机制:

观察估计不确定性检查证据选择动作验证结果\text{观察} \rightarrow \text{估计不确定性} \rightarrow \text{检查证据} \rightarrow \text{选择动作} \rightarrow \text{验证结果}

这套机制还必须回答四个问题:

  1. 什么叫“证据不足”?
  2. 什么叫“置信边界”?
  3. 什么时候应该升级给人,而不是继续尝试?
  4. 当前路径失败时,回退到哪里,如何保证不会重复执行或扩大损失?

OpenAI 对 Agent 的描述强调,Agent 会规划、调用工具、协作并保留足够状态来完成多步任务;其 Agents SDK 还将运行循环、工具调用、交接、护栏、审批和可恢复状态作为运行时能力。Anthropic 则将 Agent 描述为通过环境反馈持续行动的模型循环,并明确指出 Agent 应在每一步获得环境中的“真实结果”,在阻塞点或检查点暂停并请求人工判断。(developers.openai.com)

一、不确定性不是一个数,而是多个失败来源

1. 事实不确定性

事实不确定性表示 Agent 不知道某个命题是否成立。例如:

“订单 2026 年 8 月 31 日已经退款。”

如果 Agent 没有查询订单系统,或者查询结果只显示“退款申请已提交”,它不能把“申请已提交”改写成“退款已完成”。

可以把待回答命题记为 hh,当前获得的证据集合记为 EE。事实不确定性是:

Uf(hE)U_f(h \mid E)

它表示在已有证据 EE 下,命题 hh 仍然有多大程度无法确认。

事实不确定性通常来自:

  • 没有检索到相关资料;
  • 检索结果与问题不匹配;
  • 数据已经过期;
  • 来源之间存在冲突;
  • 工具返回了部分结果;
  • 证据只支持命题的一部分;
  • Agent 把相关性误判成因果关系。

2. 语义不确定性

用户输入可能有多个合理解释:

“把这个订单取消。”

“这个订单”可能指当前页面订单,也可能指用户上一条消息中的订单;“取消”可能代表取消未支付订单,也可能代表申请售后退款。

此时即使数据库中存在完整信息,Agent 也不能直接执行,因为目标对象和动作语义都未确定

语义不确定性主要影响计划的起点。若起点错误,后续调用工具越准确,最终结果反而越危险。

3. 状态不确定性

状态不确定性表示 Agent 不知道外部世界当前处于什么状态。例如:

  • 付款接口超时,但扣款是否成功未知;
  • 邮件发送接口返回 502,但邮件可能已经送达;
  • 库存读取发生在下单前,当前库存可能已变化;
  • 工具返回旧缓存,无法证明数据仍然有效。

这类不确定性与事实不确定性不同:事实不确定性是“我没有足够事实”,状态不确定性是“系统可能已经发生变化,但我不知道变化结果”。

4. 能力不确定性

Agent 可能不知道自己是否拥有完成任务所需的能力:

  • 是否有权限读取该客户的合同?
  • 是否能修改生产配置?
  • 是否支持当前文件格式?
  • 是否有足够上下文判断法律或医疗风险?
  • 工具是否覆盖用户要求的全部动作?

能力不确定性不能通过更长的提示词解决。它需要由工具权限、策略检查和运行时状态明确表示。

5. 后果不确定性

即使事实和意图都清楚,行动后果仍可能不可控。例如:

“删除这批用户数据。”

删除目标可能明确,权限也可能存在,但删除是否可恢复、是否影响审计记录、是否违反保留策略,仍需要额外判断。

后果不确定性决定了 Agent 是否应当拥有执行权限。能判断一件事,不等于能安全地执行这件事。

二、证据不足:不是“搜索结果为空”这么简单

1. 证据必须支持具体命题

一个回答通常包含多个命题:

“该退款已完成,金额为 199 元,预计 3 个工作日到账。”

这句话至少包含三个可验证命题:

  • 退款是否已完成;
  • 退款金额是否为 199 元;
  • 到账时间是否为 3 个工作日。

如果证据只显示退款金额为 199 元,就只能支持第二个命题,不能推出另外两个命题。

工程上应当把答案拆成命题集合:

H={h1,h2,,hn}H = \{h_1, h_2, \ldots, h_n\}

把检索、工具或用户提供的材料拆成证据片段:

E={e1,e2,,em}E = \{e_1, e_2, \ldots, e_m\}

建立来源映射:

M(hi)={ejej 能支持 hi}M(h_i) = \{e_j \mid e_j \text{ 能支持 } h_i\}

如果某个关键命题满足:

M(hi)=M(h_i) = \varnothing

则该命题没有直接证据,Agent 不应以肯定语气输出。

2. 证据强度有层级

常见实现可以为证据定义强度,而不是只记录“找到或没找到”:

证据等级 含义 示例
直接事实 来源明确陈述目标命题 订单系统显示 status=refunded
可推导事实 需要有限且明确的逻辑推导 paid_at 存在且支付状态为成功
间接线索 只与命题相关,不能单独证明 用户说“我收到退款短信”
背景知识 一般规则或历史经验 “退款通常需要数个工作日”
未验证猜测 模型生成但无来源支持 “应该已经到账了”

一个常见错误是把背景知识当作个案事实:

“平台一般 3 个工作日到账,所以你的退款已经到账。”

前半句最多支持一个流程说明,不能证明后半句的个案状态。

3. 来源冲突不是平均投票

假设两个来源给出不同结果:

  • 订单服务:退款处理中
  • 客服备注:退款完成

不能简单因为两个来源各有一个就输出“状态不确定”或随机选择一个。应检查:

  1. 来源的权威等级;
  2. 数据生成时间;
  3. 是否属于同一个订单版本;
  4. 是否存在异步延迟;
  5. 字段语义是否一致;
  6. 是否有状态机约束。

可以定义证据分数:

S(e)=A(e)×R(e)×F(e)×T(e)S(e) = A(e) \times R(e) \times F(e) \times T(e)

其中:

  • A(e)A(e):来源权威性;
  • R(e)R(e):与命题的相关性;
  • F(e)F(e):字段或内容的完整性;
  • T(e)T(e):时效性。

这不是科学上的“真实概率”,而是用于决策的工程评分。若高权威、更新更晚的订单服务显示“退款处理中”,客服备注中的“完成”可能是过时文本。正确动作不是猜,而是查询退款流水或升级人工。

4. “没有证据”与“证据证明不存在”不同

以下两句话逻辑强度不同:

  • “没有找到该用户的合同。”
  • “该用户没有合同。”

第一句只描述检索结果,第二句断言现实状态。只有在检索范围完整、索引可用、权限足够并且数据一致性得到保证时,第一句才能升级为第二句。

因此,Agent 应区分:

NotFoundNotExist\text{NotFound} \neq \text{NotExist}

NotFound 表示当前查询没有返回结果;NotExist 表示系统在给定范围内确认不存在。两者不能共用一个布尔值 exists=false

三、置信边界:置信度不是“模型觉得像不像”

1. 置信度的定义

置信度表示 Agent 对某个候选结论的支持程度;置信边界则是允许 Agent 自动采取某类动作的范围。

设:

  • c[0,1]c \in [0,1]:结论置信度;
  • θa\theta_a:自动回答阈值;
  • θq\theta_q:请求澄清阈值;
  • θh\theta_h:人工升级阈值;
  • rr:行动风险;
  • ee:证据完整度。

不能只用:

c>θc > \theta

来决定动作,因为相同置信度下,风险不同,动作也应不同。

例如:

  • “这段文本大概属于技术咨询”可以在较低阈值下自动路由;
  • “删除生产数据库中的用户”则需要极高证据和明确审批;
  • “给用户展示订单状态”可能允许部分回答;
  • “向用户承诺退款已完成”必须要求直接状态证据。

更合理的决策条件是:

允许动作    cθ(r)eη(r)权限满足\text{允许动作} \iff c \geq \theta(r) \land e \geq \eta(r) \land \text{权限满足}

风险 rr 越高,要求的置信阈值 θ(r)\theta(r) 和证据完整度阈值 η(r)\eta(r) 越高。

2. 模型概率不是业务置信度

模型输出的 token 概率,通常不能直接作为“答案正确概率”。原因包括:

  • 语言流畅性会提高概率,但不代表事实正确;
  • 模型可能对错误事实表达得很自信;
  • 结构化输出成功只说明格式满足约束;
  • 检索命中不等于证据支持;
  • 多次采样一致不等于事实成立。

因此,业务置信度应由多个信号组合:

c=f(cevidence,cintent,ctool,cconsistency,cpolicy)c = f(c_{\text{evidence}}, c_{\text{intent}}, c_{\text{tool}}, c_{\text{consistency}}, c_{\text{policy}})

其中:

  • cevidencec_{\text{evidence}}:证据与命题的匹配程度;
  • cintentc_{\text{intent}}:用户意图是否明确;
  • ctoolc_{\text{tool}}:工具调用是否成功且结果完整;
  • cconsistencyc_{\text{consistency}}:不同来源或步骤是否一致;
  • cpolicyc_{\text{policy}}:是否符合权限与业务规则。

在生产系统中,这些量可以不是概率,而是离散等级,例如 high / medium / low / unknown。重要的是决策语义明确,而不是小数点后的精度。

3. 置信边界至少应按动作分类

同一个 Agent 可以拥有不同的动作边界:

动作 证据要求 常见边界
提供背景说明 中等 可以明确区分事实与一般规则
给出个案结论 必须有对应证据
读取信息 取决于数据敏感度 需要身份和权限验证
修改状态 很高 需要目标、参数、权限和成功回执
产生不可逆副作用 极高 通常需要人工确认或审批
代表组织作承诺 极高 需要政策、金额和责任边界

这解释了为什么“可以回答”与“可以执行”必须分离。Agent 可以告诉用户“取消操作需要确认”,但不能因为自己理解了取消意图,就直接调用删除或退款工具。

四、拒答:拒绝的是动作或断言,不一定是整个对话

1. 拒答的四种类型

事实拒答

证据不足以证明目标命题:

“我无法确认退款是否已经到账。当前系统只显示退款处理中。”

这不是推卸责任,而是保留了系统已知事实。

能力拒答

系统不具备完成任务的必要能力:

“当前 Agent 没有访问该合同系统的权限,因此不能核实合同条款。”

能力拒答应说明缺失的能力,而不是笼统说“我做不到”。

权限拒答

用户请求本身可能合理,但当前身份或 Agent 权限不允许:

“我可以协助提交权限申请,但不能直接读取其他员工的薪资记录。”

权限拒答不能通过换一种提示词绕过。

风险拒答

任务可能能完成,但后果风险超过自动化边界:

“该操作将永久删除生产数据,且当前没有可验证的恢复点。请由具备审批权限的负责人确认。”

风险拒答应指出风险条件和下一步路径,而不是只输出“拒绝”。

2. 合格的拒答应包含四个部分

一个可操作的拒答通常包括:

  1. 已确认内容:系统知道什么;
  2. 未知内容:缺少什么证据;
  3. 不能执行的动作:为什么不能继续;
  4. 最小下一步:用户或人工需要提供什么。

例如:

当前订单记录显示金额为 199 元,退款状态为“处理中”。我无法据此确认款项已经到账,因此不会把它表述为“退款完成”。如果需要确认到账情况,请提供支付渠道,或由客服查询退款流水。

这比“无法回答,请联系人工”更有价值,因为它保留了已经获得的事实,并把升级请求具体化。

3. 部分回答通常优于全量拒答

设一个任务包含多个子命题:

H={h1,h2,h3}H = \{h_1, h_2, h_3\}

如果只有 h2h_2 缺少证据,Agent 应输出 h1h_1h3h_3 的已验证结果,并明确 h2h_2 未确认,而不是将整个任务判定为失败。

例如:

已确认订单金额为 199 元,创建时间为 2026 年 8 月 30 日;当前无法确认退款是否到账,因为支付渠道没有返回最终入账状态。

这种“受限完成”是可靠 Agent 的重要能力。拒答不应成为二元开关,而应支持:

  • 完整回答;
  • 部分回答;
  • 请求澄清;
  • 继续检索;
  • 转交人工;
  • 安全回退;
  • 明确拒绝。

五、从不确定性到动作:一个可实现的决策模型

可以将 Agent 的一次决策建模为:

a=argmaxaA[V(a)λrR(a)λuU(a)λcC(a)]a^* = \arg\max_{a \in A} \left[ V(a) - \lambda_r R(a) - \lambda_u U(a) - \lambda_c C(a) \right]

其中:

  • AA:候选动作集合;
  • V(a)V(a):动作对用户目标的价值;
  • R(a)R(a):错误或副作用风险;
  • U(a)U(a):动作后仍残留的不确定性;
  • C(a)C(a):成本,包括延迟、调用次数和人工成本;
  • λr,λu,λc\lambda_r,\lambda_u,\lambda_c:业务对风险、不确定性和成本的权重。

候选动作可以包括:

  • answer:直接回答;
  • answer_with_qualification:带限定条件回答;
  • clarify:请求澄清;
  • retrieve:补充检索;
  • verify:调用权威系统核验;
  • handoff:交接给专业 Agent;
  • escalate:升级人工;
  • fallback:进入备用流程;
  • refuse:拒绝执行或拒绝断言。

一个完整算例

用户说:

“把昨天那笔付款退掉。”

系统当前状态:

  • 昨天有三笔付款;
  • 其中两笔已结算;
  • 一笔仍处于待支付;
  • 用户没有指定订单号;
  • 退款接口对已结算付款会产生真实资金副作用。

逐步判断:

第一步:检查意图完整度

“昨天那笔”无法唯一指向一个付款对象,因此:

cintent<θrefundc_{\text{intent}} < \theta_{\text{refund}}

不能直接调用退款工具。

第二步:检查是否可以自动澄清

候选对象只有三笔,系统可以列出脱敏后的时间、金额和商户名称,请用户选择。此时 clarify 的成本低于错误退款的风险:

C(clarify)R(wrong refund)C(\text{clarify}) \ll R(\text{wrong refund})

因此应请求澄清,而不是拒答。

第三步:用户选择订单后

系统发现该付款已经结算,并且退款金额超过自动退款额度。此时意图已经清楚,但权限策略不允许 Agent 自动执行:

cintentθc_{\text{intent}} \geq \theta

但:

amount>auto_refund_limit\text{amount} > \text{auto\_refund\_limit}

动作从 refund 转为 escalaterequest_approval

第四步:审批后执行

退款工具返回超时。此时不能直接重试,因为请求可能已经成功提交。系统应进入:

REFUND_SUBMISSION_UNKNOWN

先查询退款流水或幂等键状态,只有确认“未创建退款”后才允许重试。

六、状态机:拒答、升级和回退必须是可恢复状态

一个实用的 Agent 不应只记录最终文本,还要记录运行状态。示例状态机如下:

stateDiagram-v2
    [*] --> RECEIVED
    RECEIVED --> INTENT_UNCLEAR: 多个目标/动作解释
    RECEIVED --> EVIDENCE_CHECK: 意图足够明确

    INTENT_UNCLEAR --> WAITING_CLARIFICATION
    WAITING_CLARIFICATION --> EVIDENCE_CHECK: 用户补充信息
    WAITING_CLARIFICATION --> EXPIRED: 超时或用户取消

    EVIDENCE_CHECK --> RETRIEVING: 可通过检索补足
    EVIDENCE_CHECK --> READY_TO_ANSWER: 证据足够
    EVIDENCE_CHECK --> READY_TO_ACT: 证据、权限、参数均满足
    EVIDENCE_CHECK --> ESCALATING: 需要专业判断或人工责任

    RETRIEVING --> EVIDENCE_CHECK: 获得新证据
    RETRIEVING --> FALLBACK: 检索失败或来源冲突

    READY_TO_ANSWER --> COMPLETED
    READY_TO_ACT --> AWAITING_APPROVAL: 高风险动作
    READY_TO_ACT --> EXECUTING: 低风险且已授权

    AWAITING_APPROVAL --> EXECUTING: 审批通过
    AWAITING_APPROVAL --> REJECTED: 审批拒绝

    EXECUTING --> VERIFYING
    VERIFYING --> COMPLETED: 有明确成功回执
    VERIFYING --> FALLBACK: 可安全回退
    VERIFYING --> ESCALATING: 结果未知或状态冲突

    FALLBACK --> SAFE_PARTIAL_RESULT
    FALLBACK --> ESCALATING
    ESCALATING --> HUMAN_TAKEN_OVER
    HUMAN_TAKEN_OVER --> COMPLETED

关键点不是状态名称,而是每个状态都必须定义:

  • 允许的下一步;
  • 禁止的工具;
  • 需要保存的上下文;
  • 超时行为;
  • 重试条件;
  • 谁对下一步负责。

例如,VERIFYING 状态下,Agent 不能再次执行一个可能产生副作用的写操作;它只能查询结果、等待异步回执,或升级人工。

七、升级不是“把聊天记录转发给人”

1. 升级的触发条件

升级通常由以下条件触发:

  • 高风险动作超过自动执行阈值;
  • 证据冲突且系统无法消解;
  • 工具结果未知;
  • 需要组织政策或专业判断;
  • 用户明确要求人工;
  • 连续澄清失败;
  • Agent 已达到最大循环次数;
  • 任务涉及责任承诺、例外授权或争议处理。

Anthropic 建议 Agent 在遇到阻塞点或需要人类判断时暂停;OpenAI Agents SDK 的相关能力也将人工审查、护栏和可恢复审批流程作为运行时设计的一部分。(anthropic.com)

2. 升级包必须可接管

人工接管需要的不只是自然语言历史,而是结构化上下文:

{
  "case_id": "case_20260901_001",
  "user_goal": "退款昨天的一笔付款",
  "resolved_facts": [
    {
      "fact": "昨日存在三笔付款",
      "source": "payment_query",
      "observed_at": "2026-09-01T10:02:11+08:00"
    }
  ],
  "uncertainties": [
    "用户未指定目标订单",
    "其中两笔付款已结算"
  ],
  "attempted_actions": [
    {
      "action": "list_payments",
      "result": "success"
    }
  ],
  "blocked_action": {
    "name": "refund_payment",
    "reason": "目标不唯一"
  },
  "required_human_decision": "确认目标订单或选择是否继续澄清",
  "risk_level": "medium"
}

这样人工可以从当前状态继续,而不是重新询问用户。更重要的是,系统能明确责任边界:Agent 做了哪些查询,人工需要决定什么,哪些动作尚未发生。

3. 接管后不能让两个执行者并发操作

升级流程存在一个常见竞态:

  1. Agent 判断需要人工;
  2. Agent 将任务标记为 ESCALATING
  3. 人工开始处理;
  4. Agent 的旧循环仍在运行,并继续调用工具。

因此,接管必须具备租约或版本号:

run.version = 17
handoff.version = 18

任何工具调用都必须携带当前版本。服务端发现调用版本小于当前版本时,应拒绝执行:

stale_run_version

这不是普通异常,而是防止“人工已经接管,Agent 却继续执行”的并发保护。

八、回退:失败后不是简单换模型重试

1. 回退的层级

回退可以发生在不同层级:

语义回退

从自动完成回退到请求澄清:

“我找到了三笔符合条件的付款,请选择具体订单。”

证据回退

从直接回答回退到带来源的部分回答:

“资料只能确认政策适用范围,不能确认你的个案是否符合。”

工具回退

主工具不可用时,切换到只读查询、缓存或人工队列。但缓存只能支持“最近已知状态”,不能伪装成实时状态。

执行回退

写操作失败时,回到查询和核验状态,而不是立即重试写操作。

产品回退

自动流程不可用时,生成可供人工处理的申请单,保留用户目标和已验证事实。

2. 读取失败与写入未知必须区别处理

读取接口失败通常可以在退避后重试:

query failed -> retry with backoff -> fallback or escalate

但写接口超时属于“结果未知”:

write timeout -> query by idempotency key -> confirmed success/failure -> decide

错误流程如下:

提交退款 -> 超时 -> 再次提交退款 -> 产生两笔退款

正确流程是:

提交退款 -> 超时
        -> 查询幂等键或业务流水
        -> 已成功:记录成功,不重试
        -> 未创建:使用同一幂等键重试
        -> 仍未知:升级人工

回退的核心不是“让流程继续”,而是让系统在不确定状态下停止扩大副作用

九、一个最小的决策实现

下面的 Python 示例不依赖具体 Agent SDK,展示的是决策层如何把证据、风险、权限和状态组合起来:

from dataclasses import dataclass
from enum import Enum


class Action(Enum):
    ANSWER = "answer"
    QUALIFIED_ANSWER = "qualified_answer"
    CLARIFY = "clarify"
    VERIFY = "verify"
    ESCALATE = "escalate"
    FALLBACK = "fallback"
    REFUSE = "refuse"


@dataclass
class Assessment:
    intent_confidence: float
    evidence_coverage: float
    risk: str
    permission_ok: bool
    evidence_conflict: bool
    side_effect: bool


def decide(x: Assessment) -> Action:
    if not x.permission_ok:
        return Action.REFUSE

    if x.evidence_conflict:
        return Action.ESCALATE

    if x.intent_confidence < 0.70:
        return Action.CLARIFY

    if x.side_effect and x.risk in {"high", "critical"}:
        return Action.ESCALATE

    if x.evidence_coverage < 0.60:
        return Action.VERIFY

    if x.evidence_coverage < 0.90:
        return Action.QUALIFIED_ANSWER

    return Action.ANSWER

示例输入:

assessment = Assessment(
    intent_confidence=0.95,
    evidence_coverage=0.55,
    risk="low",
    permission_ok=True,
    evidence_conflict=False,
    side_effect=False,
)

print(decide(assessment).value)

预期输出:

verify

这里不能因为意图清楚就直接回答。intent_confidence=0.95 只说明用户想问什么比较明确;evidence_coverage=0.55 表示支持答案的证据仍不完整,因此应先核验。

再看另一个输入:

assessment = Assessment(
    intent_confidence=0.98,
    evidence_coverage=0.98,
    risk="high",
    permission_ok=True,
    evidence_conflict=False,
    side_effect=True,
)

print(decide(assessment).value)

预期输出:

escalate

证据充分并不意味着可以自动执行高风险副作用。这里的升级不是因为“不知道答案”,而是因为责任和操作权限超过自动化边界

生产实现还应将评分理由、证据 ID、策略版本和状态版本一起写入事件日志。否则当决策错误时,只能看到最终回复,无法判断问题发生在检索、证据映射、阈值配置还是权限检查。

十、常见错误及其诊断方式

错误一:把模型语气当作置信度

表现:

“根据情况来看,应该已经处理完成。”

诊断方法是检查回答中的每个肯定命题是否都有证据映射。如果没有,问题不是措辞,而是事实边界失效。

错误二:把检索命中当作证据充分

搜索结果包含关键词,不代表支持目标命题。应检查:

  • 是否针对同一对象;
  • 是否覆盖同一时间;
  • 是否表达相同状态;
  • 是否为权威来源;
  • 是否存在否定、条件或例外。

错误三:所有不确定性都转人工

这会导致人工队列被低价值问题淹没。应先区分:

  • 能通过澄清解决的歧义;
  • 能通过权威查询解决的证据缺口;
  • 只能由专业人员判断的责任问题;
  • 只能拒绝的权限或安全问题。

错误四:升级后继续自动执行

这是最危险的流程错误之一。诊断时要查看:

  • handoff 是否产生新的运行版本;
  • 旧运行是否被取消;
  • 工具服务是否校验运行版本;
  • 是否存在多个活跃执行者;
  • 人工接管后是否还能产生 Agent tool call。

错误五:失败重试没有区分幂等性

诊断日志时,应为每个工具标记:

read-only
idempotent-write
non-idempotent-write
unknown-result-sensitive

对于 unknown-result-sensitive 工具,超时后必须进入核验状态,不能沿用普通网络请求的自动重试策略。

错误六:拒答没有给出可恢复路径

“我不能处理”无法帮助用户或人工继续工作。至少应说明:

  • 缺少哪项信息;
  • 哪个事实尚未确认;
  • 哪个权限或政策阻止了操作;
  • 下一步需要谁做什么。

十一、如何评估拒答是否正确

不能只评估“回答率”。可靠性评估至少要同时观察:

质量=(正确回答率,适当拒答率,不当自信率,误升级率,副作用事故率)\text{质量} = (\text{正确回答率}, \text{适当拒答率}, \text{不当自信率}, \text{误升级率}, \text{副作用事故率})

其中:

  • 正确回答率:有证据时是否给出正确答案;
  • 适当拒答率:证据不足或越权时是否停止;
  • 不当自信率:没有证据时是否仍给出确定结论;
  • 误升级率:本可自动解决的问题是否过早交人;
  • 副作用事故率:错误或重复执行造成的真实损失。

测试集应包含边界样本:

  • 证据缺失;
  • 证据部分覆盖;
  • 来源冲突;
  • 数据过期;
  • 用户意图多义;
  • 权限不足;
  • 工具超时;
  • 写操作结果未知;
  • 人工接管竞态;
  • 回退路径再次失败。

Anthropic 建议先从简单系统开始,通过评估确认复杂度确实带来收益,而不是默认采用多 Agent 或复杂编排。(anthropic.com) OpenAI 的 Agents SDK 文档也将运行状态、审批、护栏、追踪和评估作为 Agent 生命周期的一部分,而不是只关注模型调用本身。(developers.openai.com)

十二、规范保证、常见实现与经验建议

需要明确区分三类内容。

规范保证是系统契约必须保证的性质,例如:

  • 未获得必要权限时不得调用工具;
  • 高风险操作必须经过审批;
  • 写操作结果未知时不得盲目重复执行;
  • 人工接管后旧运行不能继续产生有效副作用;
  • 对外输出的关键命题必须能追溯到证据或明确标注为不确定。

常见实现包括:

  • 为证据片段生成来源 ID;
  • 为运行状态保存可恢复快照;
  • 用阈值和规则组合选择动作;
  • 用幂等键和业务流水核验写操作;
  • 为升级事件创建结构化接管包;
  • 使用 tracing 记录模型、工具、护栏和交接链路。

经验建议则需要通过具体业务验证,例如:

  • 哪些任务允许部分回答;
  • 哪些金额或资源范围必须人工审批;
  • 多久未收到澄清就关闭任务;
  • 哪些来源可以被视为权威;
  • 缓存最多能支撑什么样的回答;
  • 何时切换备用模型或备用工具。

这些建议不能被硬编码为普遍规律。不同业务的风险函数、责任边界和数据一致性模型不同。

结语:可靠 Agent 的能力边界必须显式存在

Agent 的“不确定”不是异常,而是运行环境的常态。真正危险的是系统没有把不确定性表示出来,导致模型用语言流畅性掩盖证据缺口,或用重复重试掩盖外部状态未知。

一个可控的 Agent 应当能够明确区分:

  • 我知道什么;
  • 我不知道什么;
  • 我还能验证什么;
  • 我是否有权限继续;
  • 继续操作会造成什么风险;
  • 应该请求用户澄清,还是请求人工判断;
  • 当前动作失败后,能否安全回退;
  • 谁最终对结果负责。

因此,拒答不是 Agent 的失败出口,而是决策系统中的一种正式状态。证据不足时拒绝断言,置信度不足时收缩动作边界,风险超过阈值时升级,执行结果未知时先核验再回退,才是把 Agent 从“会生成答案的模型”变成“能够在不确定环境中受控行动的工程系统”的关键。


系列导航与关联阅读

官方资料

本文依据 Agent、模型、协议与框架官方资料重新梳理;正文、示例与生产清单由 WR BLOG 编写。