专业Agent也要会拒绝:把职责边界做成运行时协议
专业 Agent 也要会拒绝:把职责边界做成运行时协议
把 Agent 分成客服、运维、法务、数据分析之后,一个常见误区是:只给每个岗位配置专用提示词和工具,就算完成了专业化。
真正危险的故障往往不是“不会调用工具”,而是任务已经越过职责边界,Agent 仍然继续输出。
例如客服 Agent 收到“这笔退款是否构成合同违约”。它能查订单,也能读退款规则,于是给出一段很像法律意见的解释。内容可能通顺,但目标已经从解释业务规则滑向法律判断。问题不在模型是否聪明,而在系统没有一个可执行的停止条件。
职责边界不能只写在岗位说明里
岗位说明通常是自然语言:负责订单咨询、处理退款申请、必要时转人工。这样的描述适合人读,却很难直接参与运行时判定。
更可执行的职责契约至少需要四项检查:
objective_match:目标是否属于该岗位,而不是只看关键词是否相似;evidence_ready:做出结论所需证据是否齐全、可验证且足够新;authority_sufficient:当前 Agent 是否拥有读取、判断或执行所需权限;side_effect_allowed:即将发生的外部动作是否在风险额度内。
这四项不是生成完成后的质量评分,而应放在第一次不可逆动作之前。

不要把所有“不继续”都叫失败
运行结果至少应区分三类:
ACCEPT:目标、证据、权限和副作用均在契约内,可以执行;DECLINE:任务明确不属于本岗位,交还调用方;ESCALATE:任务相关,但需要更高权限、另一专业岗位或人工决定。
DECLINE 与 ESCALATE 的区别很重要。前者表示路由错误,后者表示当前 Agent 已完成职责内的检查,但无权完成下一步。
一种简化实现可以是:
type Decision = "ACCEPT" | "DECLINE" | "ESCALATE";
function decide(ctx: TaskContext): Decision {
if (!matchesObjective(ctx.objective, ctx.contract)) return "DECLINE";
if (!hasRequiredEvidence(ctx) || !hasAuthority(ctx)) return "ESCALATE";
if (!isSideEffectAllowed(ctx.nextAction)) return "ESCALATE";
return "ACCEPT";
}
关键不在这个函数有多复杂,而在于判定发生在执行之前,并且结果能被调度层理解。
升级不能只发一句“请人工处理”
如果升级只返回自然语言,接手者仍要从头重建现场。一个最小升级包可以包含:
{
"reasonCode": "AUTHORITY_INSUFFICIENT",
"confirmedFacts": ["订单已支付", "退款窗口仍开放"],
"unknowns": ["是否存在线下补充协议"],
"attemptedChecks": ["order.read", "refund_policy.read"],
"requiredAuthority": "contract_interpretation",
"recommendedOwner": "legal_review"
}
这样做有三个收益:接手者知道哪些事实已经确认;调度层可以按原因码路由;审计时能解释为什么停止,而不是只看到一段“模型拒绝了”的文本。
Guardrail 也有边界
输入、输出和工具调用的 guardrail 解决的是不同位置的问题。仅检查最终输出太晚:如果工具已经执行了退款、发信或修改配置,拦住最后一句话并不能撤销副作用。对高风险动作,应把检查放在工具执行前,并让权限校验靠确定性代码完成。
转交同样需要独立校验。handoff 看起来像工具调用,但它可能走不同的运行路径;不能假定所有工具 guardrail 会自动覆盖责任转移。尤其当授权依赖转交参数时,应在接收方产生副作用之前检查。
专业化的真正下限
在 Tipkay 的实践里,不同 Agent 可以装配不同职责和能力集合。这解决了“默认能看见什么”,但不能替代运行时的职责判定:工具在手,不等于每个相关任务都应该继续做。
专业化 Agent 的最小闭环应是:明确能力范围,执行前检查证据与权限,越界时生成可路由的升级包,并把未完成责任清楚交给下一位接手者。
会做,是能力;知道何时不该继续,才是岗位。
更多推荐

所有评论(0)