| 编辑推荐: |
本文是
Agent 应用系统设计系列的第一篇,从演示 Demo 与生产系统的现实差距出发,梳理
agentic AI 系统的通用模块与设计原则:模型层与路由、工具契约与边界、记忆与工作流状态、编排与控制流、评估、审批门控与策略控制,并给出可靠性与降级、成本与延迟、上下文与检索设计、可观测性安全与隐私四条生产原则。
本文来自于微信公众号AI Engineer编程,由火龙果软件Alice编辑、推荐。 |
|
具体业务要具体分析,本篇只是说明模型路由、工具契约、状态、编排、评估与审批等通用常见的模块和设计原则
本篇是系列的第一篇,主要从三个方面看看agentic AI 系统的工程设计:界定系统概念及单
Agent、多 Agent 的适用条件;通用的模块和生产原则。
注意,具体落地要看业务场景和团队等方面,我主要是用于说明控制流与接口约束,不构成特定业务的实现规范!
至于Harness、Loop之类的也不在本篇范畴内,虽然很多概念能描述一个或一组实际现象,但回到实际生产问题具体描述更好一点~
01 演示Demo与生产的现实差距
演示Demo怎么花哨怎么玩,哪怕现场不能演示,整个视频播放一下也算成功。
通常我们看到的演示Demo形态的 Agent 只是接收用户输入,由模型生成回复,其间可能调用一次外部接口。
做过开发的朋友都知道,实际应用系统,我们可能会遇到:
- 工具调用失败或超时时,系统如何处置;
- 涉及资金、权限或具有明确业务副作用的操作,例如扣款、取消预约、变更套餐,应由谁确认或审批;
- 业务事实的权威来源是数据库、工具返回,还是模型记忆与检索片段;
- 更换模型或修改提示词之后,如何判断行为是否退化;
- 用户数据进入模型供应商、向量库、日志与观测平台之后如何管控。
一般来说,Demo只能验证模型能否生成内容和调用工具。
生产系统必须保证路由、工具边界、状态管理、编排、评估和审批门控能够在可靠性、成本、上下文及可观测性约束下协同运行。
不同团队的Agent系统的差距通常在模型之外的工程结构,而不只是模型能力本身。
02 Agentic AI 系统是什么
2.1 核心能力与可选能力
除了传统应用锁必须具备的能力之外,一个最简单的agentic AI
系统通用能力可能有很多(各种模式就不展开说了),比如:
1.分解目标、意图识别;
2.决定下一步采取哪个步骤;
3.调用外部工具(包括Skills、Mcp);
4.检查工具返回结果;
5.更新工作流状态;
6.继续推进工作流
按照Agent常见的的几个组成部分划分,除核心循环之外,生产系统还需要一组控制能力,它们不属于“推进任务”的范畴,但决定了系统能否安全停止或转向:
- 请求澄清,也就是经常遇到的模型瞎猜问题的处理;
- 拒绝执行,很多人说模型讨好型人格,为了完成必须完成;
- 升级人工,而非继续循环,人工有时候不是兜底而是必要流程;
- 在无法安全继续时,终止当前流程并说明原因。
生产我们需要的更多的有效控制手段,概率性、不确定性的底层要转成可靠的、确定的任务流程这就是为什么叫工程设计的原因之一,只会“继续推进”、不会“安全停止”的系统,遇到越权请求、信息不足或高风险操作时,往往错误执行或陷入无限循环。
Agent还不怎么火热的时候,很多人实现容易只关注第 3 项,也即“模型会调用工具”。可实际生产实现的难点在第
4 至第 6 项,以及上述控制能力:工具返回失败时如何分类处置,状态写到哪里、由谁读取,循环在什么条件下终止。
小到在传统系统中嵌入一个LLM调用,大到整个Harness系统,我们始终在工程上做约束、做规范,保证模型的主动性、智能性的同时,也保障系统的稳定性和可靠性。
03 单 Agent 与多 Agent
3.1 职责可以拆开,但拆开不等于必须多实例
拿我们常见的编程Agent来说,职责通常可以划分为五个角色:制定计划、检索知识、编写代码、审查输出和执行变更。
同一组职责既可以由单个 Agent 分步骤完成,也可以分配给多个 Agent
实例。多Agent最直接的具体收益主要如下:
- 上下文隔离:审查者不需要携带实现过程的全部历史,实现者也不需要持有全部审查规范;
- 模型与权限差异化:规划、检索、生成可以使用不同档位的模型,只有执行角色需要持有具备副作用的工具;
- 强制分工:编写与审查由不同主体完成,避免自我审查。
若拆分后缺少明确的协调机制、共享状态约定和“审查未通过则返回编写”的反馈闭环,得到的通常只是若干松散的对话系统,难以形成可控的多
Agent 工作流。
3.2 适用条件
判断是否采用多 Agent,可以参考下面几个方面:
| 特征 |
含义 |
不满足时的后果 |
| 明确的专业化分工 |
各角色所需工具集、权限集、上下文切片不同 |
拆分只增加协调成本,收益接近于零 |
| 可并行的工作 |
子任务之间无强制串行依赖 |
只增加跳数、延迟与费用 |
| 审查闭环 |
需要独立于生成路径的检查 |
无法实现互相校验 |
| 长周期工作流 |
执行跨越会话、人工等待或进程生命周期 |
单次调用无法承载,必须依赖外置状态 |
审查闭环通常伴随专业化分工,长周期工作流往往也涉及并行子任务。不能只按照“满足几项”机械计数,这个时候需要估算拆分收益与协调成本。协调成本至少包括编排器复杂度、状态一致性维护、trace
长度与归因难度、跨 Agent 的 token 与延迟开销。
优先或者说默认选择仍是单 Agent 多步骤。一上来就多Agent可能会放大后续所有生产问题,只有收益可量化且超过协调成本时才引入。
审查闭环的有效性还取决于审查者与被审者是否共享系统性盲区。若二者使用同一模型和版本,其错误相关性可能较高,审查的发现能力会下降。使用不同模型或引入规则化检查有助于降低相关错误,但实际收益仍需通过评估验证。
归根结底,还是要很具体业务场景和团队来决定到底是单agent还是多agent。
04 构建模块一:模型层与路由
4.1 模型层需要回答的三个问题
模型层覆盖的是需要模型推理或生成的步骤。对于不需要模型的步骤,例如数据库查询、缓存读取、规则判定,编排层直接映射到相应组件,这些确定性或者可程序化验证的一般不进入模型路由。
在覆盖范围内,模型层通常需要思考一些决策和不确定性问题,比如:
1.这一步使用哪个模型;
2.它返回什么、输出契约怎么样的;
3.模型失败或返回非法输出时会发生什么。
这三个问题都针对具体步骤。模型路由应以单次调用为粒度,避免为整个应用统一配置一个模型。
4.2 这一步用哪个模型
以账单场景为例,各步骤对模型的要求并不相同:
| 步骤 |
主要要求 |
合理选择 |
| 请求分类 |
输出取值在闭集内、延迟低、单价低 |
小规模模型或专用分类器 |
| 检索账户上下文 |
准确、可审计 |
数据库查询,不经过生成模型 |
| 解释账单、生成回复 |
语言表达质量 |
中等或以上对话模型 |
| 复杂退款策略提案或例外解释 |
推理能力、解释能力 |
高能力模型;策略判定由规则引擎或策略服务执行 |
注意,多 Agent 场景其实也适用这一原则:规划、编写、审查最好是不要默认共用同一模型配置。演示Demo系统可能为了方便通常只有一个全局调用入口;但实际生产系统则需要模型路由器,根据步骤类型、风险等级、延迟预算与成本预算,输出模型标识、解码参数、token
上限与超时等
注意,我将解码参数归属于路由决策的一部分。分类与抽取步骤的下游是分支判定,输出多样性没有价值,通常使用确定性解码;生成面向用户的文本时才需要放宽。
4.3 输出契约是什么
契约这东西传统开发应该是非常熟悉了;对于Agent来说,系统必须把模型输出视为受契约约束的数据,不能简单粗暴的按普通自然语言处理。契约通常包括:输出形状,例如结构化对象、枚举或工具调用结构;必填字段;取值范围;禁止项,例如分类结果中不得夹带面向用户的话术。
特别注意,需要驱动分支、工具调用或审批的步骤,模型输出应遵守显式契约。纯生成步骤也最好是有最小输出契约,例如长度、语言、是否允许包含外部链接等,但其结构约束可以弱于分类与抽取步骤。
契约可以说是最有效的将模型不确定性转为确定性的手段,不然就一步错,步步错,因为下游需要依据确定字段执行稳定的分支判断。比如支付,如果意图字段有时是 refund,有时是一句自由文本,编排层就很难稳定判定。
模型层负责定义输出契约,编排层负责校验契约,并据此执行分支、工具调用与审批门控。
千万不要搞混,schema 合规只保证形状正确,不保证语义正确。
4.4失败与非法输出处理
相比于传统开发来说,对于Agent系统开发,有时候我们需要有一个不过脑子的刻板观念:失败和异常是系统常态。
模型失败是常态的话,那么我们就需要进入常规控制流,包括超时、限流、空回复、解析失败、字段缺失和枚举越界等等。模型层需要预先规定处理方式,不能把异常直接抛给对话界面,比如:
| 情形 |
可能的处理方案 |
| 瞬时错误,例如限流、网络抖动 |
有上限的退避重试 |
| 主模型不可用 |
切换备用模型 |
| 输出违反契约 |
带 schema 的有限次修复请求 |
| 分类或抽取失败 |
转澄清、转人工,或走最安全的只读回复 |
| 高风险步骤上语义不确定 |
拒绝执行并告警,不得以猜测值继续 |
这里需要区分两类问题:接口调用失败属于基础设施问题,适合重试与切换;调用成功但
schema 不符属于输出契约问题,应由在线校验立即拦截,并作为质量事件纳入评估。
修复循环必须有次数上限,否则成本与延迟都会失控,甚至还可能引发重试风暴!
完整的模型层同时覆盖路由、输出校验和失败处理:
05 构建模块二:工具契约与边界
5.1 工具契约的完整字段
就像传统开发设计API接口一样,越是清晰的设计和文档,越能提升协作效率;一个可对外暴露的工具,在设计的时候,要保证清晰的职责,以及模型可理解的契约。
确保模型正确选择工具并构造参数
- 名称:语义化且稳定,它本身就是最直接的路由条件;
- 描述:写明适用条件与不适用条件,描述含糊会导致变更类请求被路由到查询接口;
- 输入 schema:类型、必填、枚举与取值范围。缺少约束时模型会自造字段,或把自然语言填入标识字段。
确保下游能够稳定消费结果
- 输出 schema:成功返回的稳定字段。编排层需要读取确定字段,而不是解析文本;
- 版本标识:schema 变更后旧 trace 仍可复现,评估回归结果可对应到具体版本。
让失败可预期
- 权限边界:可访问的资源与可执行的操作集合。最基本的,查询工具不得越权读取其他账户;写工具不得退化为任意字段更新;
- 超时行为:超时应视为失败还是状态未知。写操作超时最为危险,副作用可能已经产生,因此必须规定是查询幂等结果、转人工,还是禁止重试;
- 重试行为:哪些错误码可以重试。读接口遇到限流可以重试,退款类接口在缺少幂等键时不得重试;
- 错误格式:结构化错误码,例如权限不足、资源不存在、超时、参数非法。返回非结构化错误页面时,模型无法据结果分支,“检查工具返回”这一步就不成立。
让调用可控
- 速率限制与配额:模型在高频循环中可能反复调用同一工具,导致费用失控或对下游系统造成压力。工具契约应声明调用频率上限与总量配额;
- 幂等性要求:是否强制要求来源请求标识或等价幂等键。未声明时,编排层无法判断重试是否安全。
工具层同样需要明确工具选择、输入输出契约和失败处理。
| 模型层 |
工具层 |
| 这一步用哪个模型 |
名称与描述为工具选择提供语义依据 |
| 输出契约 |
输入 schema 与输出 schema |
| 失败与非法输出的处理 |
超时、重试、错误格式、权限边界、速率与配额 |
5.2 写工具的执行契约
以支付来说,账户变更应封装为结构化操作任务清单或者叫提案,需要包含用户标识、待更新字段、新取值、变更原因和来源请求标识,标识在快照生成后产生,执行判断条件在适用的确认、审批或自动授权完成后触发。
各字段承担的约束不同:
| 字段 |
作用 |
| 用户标识 |
作用对象必须显式,且需要校验该标识与当前会话主体或操作者权限一致 |
| 待更新字段 |
限定在服务端白名单内,禁止整对象覆盖 |
| 新取值 |
受该字段自身的类型与取值范围约束 |
| 变更原因 |
供审计与审查使用,也是评估样本的一部分 |
| 来源请求标识 |
幂等与溯源。同一请求重复投递不产生两次变更,事后可回溯到触发的对话 |
| 任务标识或执行凭证 |
绑定已经校验并通过适用门控的任务快照,执行时不得重新由模型生成参数 |
注意,确认要求本身不应作为模型可见、可填的调用字段。最好是在工具注册元数据或服务端策略配置中声明,比如,类似requires_confirmation 或 approval_policy,由编排层强制执行。
模型只输出任务或调用意图,不拥有决定“是否需要确认”的权限。适用的确认、审批或自动授权完成后,由编排层持有批准令牌,并以任务标识、批准令牌和来源请求标识调用写工具。
安全上来说,如果允许模型传入 false 一类字段会形成绕过控制权限的可能。
任务标识与批准令牌的生成、绑定与校验机制需要明确定义:
- 生成:任务由编排层在代码校验通过后生成不可变快照;批准令牌由服务端签发,不由模型产生;
- 绑定:令牌与任务哈希绑定,执行时服务端重新计算哈希并比对;
- 有效期:令牌设有有效期,过期需重新提案与批准;
- 一次性:令牌一次性使用,重复提交应被拒绝并记录;
- 撤销:用户或操作者在执行前撤回批准时,令牌立即失效。
模型最好禁止接触令牌生成逻辑,也无法通过修改提案字段绕过校验,因为执行参数取自服务端存储的提案快照,而非模型在确认后新生成的文本。
可将两种形式直接对照:
- 不安全:比如,updateUser(payload),模型可修改任意字段,无原因、无幂等、无确认;
- 安全:仅能修改白名单字段,必须提供原因、来源标识与批准令牌,写操作默认要求确认。
这份清单描述字段要求,不表示执行顺序。缺少来源请求标识,或服务端无法验证门控状态与批准令牌时,编排层不得执行该工具。
用户标识虽出现在契约中,但不应由模型从对话内容中自由抽取后直接生效。应由服务端依据已认证会话与权限查询结果绑定,模型提议的值仅作校验对象。否则任何能影响上下文的输入都可能改变作用对象。
能用代码验证的或者说能通过传统程序工程上进行控制的,都不应该参与到模型中去。
06 构建模块三:记忆与工作流状态
Agent系统循环中的“更新状态”在生产中对应两类数据,在数据模型和访问路径上明确区分,但不要求采用不同的物理存储。
当然,其实很多时候,我们也需要综合业务考虑,我们的系统真的需要记忆吗?
6.1 记忆的范围比对话历史宽
记忆的实际范围包括:对话历史、用户偏好、过去的动作、检索到的知识、文档上下文、摘要、长文本信息、工具执行结果等等。
这些内容都是提供给模型的原材料,可被检索、压缩、过期,且不完全可信。用户偏好可能已变,检索片段可能命中错误文档,摘要可能丢失关键数值。记忆适合作为生成依据,不建议作为流程判定的唯一来源。
6.2 对话与工作流状态属于系统数据库
存储可选用 Redis、DynamoDB、PostgreSQL 或
MongoDB。具体框架其实并不重要,但存储最好是支持按主键读写、过期管理和备份;涉及一致性要求时,还需要支持事务。
一般来说,会话进度与流程状态不能仅存在于提示窗口,比如:
- 进程重启或请求落到另一台实例时,提示窗口中的内容不复存在;
- 多 Agent 协作或等待人工确认期间,状态必须在模型之外存活;
- “是否已确认变更”这类判定必须是明确字段,不能简单的从一段对话中推断。
选型可按数据特征区分,比如:Redis 适合短存活期的会话与进行中的步骤;关系型数据库适合预约、账单、确认记录这类需要事务与审计的数据;键值数据库适合按请求标识高并发存取工作流;文档数据库适合结构尚在变化的会话记录。
最最重要的还是看现有系统的架构来选型~
6.3 知识检索走另一条路径
RAG之类的知识检索走另一类系统,如 pgvector、Weaviate、Elasticsearch。它与上一组存储建议是分开维护的:
- 查询知识,例如政策条款、说明文档、历史工单全文,走检索;
- 推进流程,例如当前预约标识、是否已确认,走状态存储。
再说一遍,审批行为,“是否已确认”不能交给语义检索;长篇文档解析后的全文也不应放进状态存储充当工作流状态。检索产物属于记忆中的“检索到的知识”,可注入提示辅助生成,但不应回写为权威字段。比如,账单余额、预约时间应来自账单接口与预约表,不能来自模型对检索片段的推断。
6.4 工作流状态的具体形态
拿我们OA中的一些审批改期流程来说,工作流状态至少包含四个字段:当前预约标识、拟议的新时间、确认状态、工作流步骤。
四者都必须能被代码直接判定:
- 确认状态不等于已确认时,不得调用写入日程的工具;
- 步骤为等待确认时,用户的肯定答复应理解为对当前提案的确认,而不是新的规划请求;
- 预约标识错误或串号,可能导致修改他人的预约;
- 步骤枚举决定失败恢复时从何处继续。
与记忆对照:用户说“还是原来的时间吧”、偏好上午、上次改期的原因,都可以进入对话历史或摘要;而当前标识、拟议时间、确认状态、步骤枚举必须单独、结构化地存储。模型可以建议下一步,但不能充当这些字段的存储层。
与当前工作流实例相关、会被代码用于控制流判定的事实,应结构化存储。比如,余额、库存、当前时段余量等实时业务事实,应从权威源读取,或使用满足既定新鲜度与一致性要求的缓存;高风险写入执行前必须重新校验。控制流事实不能仅保存在可能被压缩或改写的模型上下文中。
07 构建模块四:编排与控制流
前三块给出的组合组件,编排需要决定它们以什么顺序运行、在哪里分支、何时停止等
7.1 主干链路
一般来说,主干流程可以分为理解、行动、收口和留痕四段。理解阶段接收消息、写入状态并分类;行动阶段装配上下文、选择工具并校验参数;写路径随后进入提案与门控流程;最后更新状态、生成回复、记录
trace 并投递评估数据。
按职责分为四段:
理解:接收消息时应先写入工作流状态,包括新的一轮与请求标识,再进入分类;分类是模型层的路由点,不同意图走不同后续路径;上下文按意图装配,预约记录来自状态存储与业务库,政策说明来自检索;决策节点判断是否需要工具、是否可以直接结束。很多查询类请求应在此结束,而不是一律进入工具链。
行动:工具选择不应完全交给模型自由挑选,编排层可根据意图与权限先限定候选集合;参数校验在调用前进行,非法标识与不在白名单内的字段在此拒绝,而不是等接口报错;执行之后按输出
schema 与错误码检查结果,把超时、无可用时段等情况转化为控制流事件。
收口:写路径进入确认节点,状态转为等待确认,流程可以在此挂起,这也是长流程得以成立的原因。确认或审批通过后才调用写工具,并在执行后检查结果、更新工作流状态。之后才生成面向用户的回复。顺序不可颠倒:先取得事实,即工具结果与状态,再生成表述。只读查询可以跳过确认节点,但仍需执行权限、访问范围与参数校验,并检查结果。
留痕:记录 trace 供评估与可观测性使用;评估数据的投递使业务执行过程可以转化为评估样本。
有些简单的Agent实现常把整条链路简化为“模型要求调用工具就调用”,但是一个较好工程方案,校验、确认、留痕与评估由框架强制插入,不依赖模型输出是否表达相应意愿。
7.2 失败分支
主干只描述成功路径。编排的完备性取决于失败是否也有明确的下一跳,比如,审批流程改期场景中有三条典型分支:
| 可观测条件 |
预定处置 |
| 抽取失败 |
换用不同提示或不同模型重试;仍失败则向用户澄清 |
| 无可用预约 |
给出替代方案,例如邻近时段、排队或转人工 |
| 取消请求 |
进入确认路径 |
三条分支的共性是:左侧是可检测的状态或错误,右侧是预先写好的策略。
抽取不出时间或预约标识时,不能直接结束,也不能用生成值填充必填参数。系统应先尝试降级,例如使用更明确的抽取提示或更擅长结构化输出的模型;仍然失败时再转为澄清,且重试次数必须有上限。
无可用预约属于业务失败,并非系统故障。系统检查结果后应分支到替代方案,依据工作流状态与工具输出给出候选时间,不能让模型编造可用时段。
取消请求即使分类正确,也不能直接执行。取消属于具有业务副作用、通常需要用户确认的操作;是否还需人工审批,应由风险等级与业务规则决定。
完整形态更接近带守卫条件的状态机:
这些分支应由过程代码、状态机或工作流引擎明确控制。模型只出现在分类、抽取、生成等节点内部,提示词不能改变既定的校验和确认流程。我们之前所要求状态结构化,因为步骤枚举、抽取是否成功、工具错误码都是分支判定条件。
08 构建模块五:评估
8.1 合法 JSON 也可能语义错误
模型可以返回合法 JSON,同时在业务上是错的,比如:
- 调用了正确的工具,但参数错误;
- 检索到无关的上下文;
- 使用过期信息作答;
- 未能请求确认;
- 拒绝了合法请求,或执行了不安全的请求。
这些情形都能通过 schema 校验:标识字段类型合法、动作取值在枚举内,拒绝也是合法输出。评估对象是“这一步在业务上是否正确”,不是“模型是否输出了合法结构”。
传统APM三板斧依旧有效,错误常发生在链路中间某一步,而最终回复在文字上仍然通顺。仅比较最终回复,发现不了参数错误与确认缺失。
8.2 沿链路逐步评估
评估贯彻整个编排流程,对应:意图分类、检索质量、工具选择、工具参数、策略合规、确认行为、最终答复质量,最后评估任务是否成功。
三点要求:
中间步骤单独评分。 最终答案正确可能来自检索错误后的偶然命中;最终答案错误则必须能归因到具体环节,否则无法判断该修改提示词、检索逻辑还是工具
schema。
策略合规与确认行为属于一等指标。 它们衡量的是控制流是否被正确执行,而不是文案质量。
任务成功位于末端。 判定标准是业务目标是否达成,包括查询数值是否正确、预约是否真的改成、取消是否真的写入,而不是回复是否流畅。
分步评估依赖完整 trace,因此主流程必须记录并投递各节点数据。
8.3 评估集必须覆盖真实场景
应长期维护的场景类型包括:正常路径、含糊请求、超出范围的请求、工具失败、恶意输入、信息不完整、策略边角情形、需要升级人工的情形。
一些常见的类型对应的检验目标:
| 场景类型 |
检验目标 |
| 正常路径 |
主干是否走通 |
| 含糊请求 |
是否澄清而非猜测 |
| 超出范围 |
是否拒绝或转人工,而非强行处理 |
| 工具失败 |
超时与无可用资源时是否走备用路径 |
| 恶意输入 |
越权与注入尝试是否被拒 |
| 信息不完整 |
缺少标识或时间时是否补充询问 |
| 策略边角 |
例如时限内不可取消的规则是否被遵守 |
| 升级人工 |
是否在恰当条件下移交 |
这些类型基本是跟编排中的失败分支基本一一对应。Agent 评估集不应只是对话样例集合,还应覆盖控制流、检索、工具参数、策略合规和最终回复质量。只测正常路径的系统,演示中可能表现良好,上线后则容易在异常场景中集中失败。
8.4 变更时作为回归测试
上述场景在下列任一项发生变化时都应作为回归测试运行:模型、提示词、检索逻辑、工具
schema。
传统软件中修改函数签名通常触发编译失败或测试失败;Agent 系统中修改提示词表面上只是文案调整,实际可能使确认行为整体消失。这套场景应固定下来反复运行,不能每次上线靠人工试用几条。
回归判读不能只看任务完成率。更换模型后完成率可能维持较高,而安全处置召回率明显下降,不安全请求开始被执行。这种“总体指标尚可、单步退化”的情况,只能由分步指标捕获。
要让回归结论可信,最起码要满足两项条件:其一,记录足以归因的版本字段,包括模型标识与版本、提示词版本、工具
schema 版本、检索索引版本、解码参数,否则指标变化无法对应到具体变更;其二,注意运行间方差,同一评估集在新旧配置下应配对运行并关注差值幅度,而不是对单次运行的小幅波动做过度解读。
8.5 线上指标
需要长期观察的指标有很多,包括:意图准确率、工具调用技术成功率、输出契约不合规率、权威依据覆盖率、安全处置召回率、误拒率、升级率、任务完成率、用户标记率、成功任务单位成本等等,实际上咱们传统开发中的APM那一套进行拓展,难度并不大,系统上线后指标能成为故障处理、优化、报表等提供详细的数据支撑。
简单的按用途分组来看指标:
| 组 |
指标 |
用途 |
| 契约与工具 |
意图准确率、工具调用技术成功率、输出契约不合规率 |
判断模型层与工具层是否健康 |
| 检索与策略 |
权威依据覆盖率、安全处置召回率、误拒率、升级率 |
判断知识供给与安全边界是否恰当 |
| 业务 |
任务完成率、用户标记率 |
判断实际交付质量 |
| 成本 |
总任务单位成本、成功任务单位成本 |
判断可持续性 |
几个指标需要明确口径:
- 意图准确率:分类结果与标注意图一致的比例;
- 工具调用技术成功率:工具调用已完成、返回成功状态且通过输出
schema 校验的比例;
- 输出契约不合规率:模型输出未通过输出契约的比例;
- 权威依据覆盖率:检索结果包含回答或决策所需权威依据的比例;
- 安全处置召回率:在应拒绝或应转人工的标注样本中,系统正确拒绝或移交的比例;
- 误拒率:在应正常处理的样本上,系统错误拒绝或要求额外确认的比例;
- 升级率:转人工或上级处理的比例;
- 任务完成率:业务目标达成的比例,查询类以结果正确为准,写路径以副作用正确且经批准为准;
- 用户标记率:用户投诉、点踩、要求转人工或人工复核标记的比例;
- 总任务单位成本:总增量成本除以总任务数;
- 成功任务单位成本:总增量成本除以成功任务数。
成本范围应显式声明,至少说明是否包含模型、检索、工具、评估、观测与人工审批成本。同时报告总任务单位成本与成功任务单位成本,可以避免系统通过拒绝困难任务来压低成功任务单位成本。
安全处置召回率提高时,更多请求可能转交人工;过度压低升级率,则可能放过本应拒绝或移交的请求。两项指标应与误拒率和漏拒率联合观察,升级率不宜单独作为优化目标。
线上指标还需考虑基准真值(ground truth)的获取方式。查询类任务的结果正确性、拒识样本的“应拒绝”标签,都需要持续维护的标注集。实践中通常采用两种方式:
- 代理指标:用户标记、转人工率、工具返回错误码、重复请求率,用于日常监控;
- 抽样人工评估:按任务类型分层抽样,由人工判定结果正确性与合规性,用于校准代理指标与计算任务完成率。
标注偏差需要通过定期复核、双人标注与争议样本处理来控制。
注意!注意!注意!指标需要组合判读,单一指标可能会有局部效果。
比如,输出契约不合规率低而任务完成率低,说明形状合规但语义失败;安全处置召回率下降而完成率上升,可能说明系统通过放宽拒绝条件换取完成率;单位成本下降而用户标记率上升,可能说明成本优化损害了用户体验。升级率异常偏高可能反映系统能力不足,异常偏低则可能表示应移交的任务未被识别。
09 构建模块六:审批门控与策略控制
9.1 写操作的门控流程
写操作一般分为四步:模型提出建议、代码进行校验、执行适用的门控、工具执行。
顺序不可调换,也不允许模型跳步。
模型提出建议。 模型输出的是一份任务清单或者说提案:修改哪个预约、改到什么时间、是否取消。它包含工具层提到过的契约中的字段,但此时工具尚未执行。
代码校验。 策略规则位于代码、规则引擎或策略服务,不在提示词中,内容包括:字段是否在白名单内、资源是否属于当前用户、是否在可变更时间窗口内、schema
与幂等键是否完备。校验失败回到失败分支(换抽取、追问、拒绝),不得执行。提示词无法可靠拦截的部分,由代码拦截。
执行适用的门控。 门控类型取决于风险等级与业务规则,可分为三类:
- 用户确认:用户同意改期、取消、扣款;
- 人工审批:客服主管、风控或运营人员批准;
- 策略自动授权:小额、低风险、白名单内的可逆操作由规则自动放行。
策略自动授权由独立于模型的策略引擎执行。校验规则不读取模型生成的“风险等级”或“是否高风险”等字段,而依据金额、对象类型、操作类型、频次等客观字段。自动授权的上限包括单笔金额、日累计金额、单用户频次与批量对象数,超出任一上限即转人工审批。所有自动授权均须记录审计
trace,并接受定期抽样复核。
通过代码校验的提案仍可能偏离用户意图,例如模型可能抽取了错误时间。确认或审批的对象应是已经校验通过的提案快照,不能重新开启一轮自由对话。相关门控完成后,工作流状态才从等待确认转为已授权执行。
工具执行。 代码校验以及适用的确认、审批或自动授权全部完成后,编排层才可调用写工具。执行参数取自校验并授权后的结构化提案,不能使用模型在确认后新生成的文本。
9.2 风险与拦截位置
之前提到的失败情形与本节各关对应如下
| 风险情形 |
拦截位置 |
| 工具正确、参数错误 |
代码校验 |
| 该确认而未确认 |
适用的确认或审批是强制节点,门控要求由工具元数据或策略配置声明,而非模型可选行为 |
| 执行了不安全请求 |
代码校验中的权限与策略判定 |
| 拒绝了合法请求 |
校验通过后进入适用的门控流程,而不是由模型直接终止 |
| 使用过期信息修改数据 |
校验时读取当前状态与源系统,而非记忆 |
实际上,并非所有工具都需要走满四步。只读查询通常遵循“生成调用请求、校验、执行”;取消预约、变更账单、对外发送通知等具有副作用或较高风险的操作,还需经过适用的用户确认、人工审批或策略自动授权。门控要求由工具注册元数据或服务端策略配置声明,并由编排层强制执行。
提案字段形状来自工具契约;拟议值、门控状态和步骤枚举记录在工作流状态中;取消分支在执行前插入适用的门控步骤;策略合规与确认行为指标用于检查校验与门控是否被跳过。
门控完成与执行之间可能存在时间间隔。若执行时重新向模型索取参数,授权对象与执行对象可能不一致,因此提案应固化为不可变快照,并设有效期与一次性使用限制。单次门控也不能覆盖总量风险,还需设置频次、金额和批量对象数上限,以识别每次均合规但累计行为异常的情况。
10 生产原则一:可靠性与降级
10.1 反模式:单一提示承担全部职责
典型反模式是让一条大型提示同时承担意图分类、检索决策、策略判定、工具选择和最终回复生成。
这个即便不是Agent开发,我们在传统应用开发时候也一样成立,软件工程方法论都不知道有多少类似名词来解释这个单一职责。
它把前面拆开的职责重新合并进一次模型调用:
| 大型提示中承担的事 |
本应所在的层 |
| 分类意图 |
模型层路由,可使用小规模模型 |
| 决定是否检索上下文 |
编排层调用检索与状态存储 |
| 判定策略 |
代码、规则引擎或策略服务中的策略控制,而非提示中的“请遵守规定” |
| 调用工具 |
校验、批准、执行三步之后 |
| 生成最终回复 |
最后一步,且必须基于工具结果 |
可靠性视角下的问题是单一提示成为单点故障。
10.2 具体代价
失败无法局部恢复。 抽取失败时应只重跑抽取;大型提示把分类、策略、调用混在一次输出中,只能整段重跑,代价更高,且可能改变原本正确的分类结果。
策略退化为建议。 策略判定写在提示中时,模型可以输出合法结构同时跳过确认或执行不安全操作。可靠系统中策略是代码门控或策略服务判定,不是模型的一个子任务。
检索与状态被模型内化。 检索本应访问接口、数据库或检索系统。大型提示容易使用训练记忆或对话摘要替代账户事实,导致过期信息与误检文档直接进入最终回复,中间缺少结果检查。
评估失明。 意图、检索、参数、确认无法分别评分。线上出现问题时只能观察到“这次回复不对”,无法定位,回归测试也无法锁定单一环节。
缺少降级挂载点。 降级策略需要挂在步骤边界上:分类失败时切换模型、检索为空时转澄清、工具超时时按幂等键核对、策略不通过时拒绝执行。合并为一次生成后,这些边界不存在。
10.3 可靠性的实质要求
可靠性不等于使用能力更强的模型。
最起码要四项同时成立:职责拆分到可独立失败的步骤;每一步具备契约与失败语义;失败进入预先定义的分支;写路径始终遵循提议、校验、批准、执行。
降级有边界:可用性可以下降,安全约束不能下降。允许的降级包括切换备用模型、退化为只读回答、转人工、拒绝并说明原因;不允许的降级包括跳过参数校验、跳过确认、放宽字段白名单,或在写操作结果不确定时重复提交。
重试预算可以在工作流层统一,而不是每步独立设定。若每步允许三次尝试而链路包含多个模型步骤,最坏路径上的调用次数会成倍增长,这个与成本目标直接冲突。
11 生产原则二:成本与延迟
11.1 拆分带来的跳数
拆分后的完整链路通常是:意图分类、查询改写、检索、规划、工具选择、工具参数生成、工具结果解释、最终回复生成、评估。
用户只发送了一句话,系统内部已经是一条多跳流水线。每一跳可能是一次模型调用、一次检索或一次接口调用。两种设计的差异如下:
|
大型提示 |
拆分后的链路 |
| 故障隔离能力 |
较弱,职责耦合且难以局部降级 |
较强,可分步校验、审批和降级 |
| 成本与延迟 |
单次调用,但上下文庞大 |
多次调用,默认更贵更慢 |
| 适用边界 |
不宜承担策略判定、门控和执行控制等全部职责 |
拆分后按调用步骤优化 |
为提高可靠性而拆分流程后,还必须配合模型路由、上下文裁剪和缓存策略,否则从演示转入生产时往往会先在费用与超时上失败。优化目标应是编程层提到的成功任务单位成本,而非单次
token 单价。
11.2 按跳分配模型与裁剪跳数
结合模型策略,各跳的合理策略可以如下:
| 步骤 |
策略 |
| 意图分类 |
小规模模型或分类器,要求稳定与低延迟 |
| 查询改写 |
中小模型;查询已足够明确时跳过 |
| 检索 |
主要是检索延迟,适合缓存 |
| 规划 |
简单意图可跳过,仅复杂工作流需要 |
| 工具选择 |
意图闭集较小时由编排层映射,不必再经模型 |
| 工具参数生成 |
需要结构化输出;schema 简单时可用小模型 |
| 工具结果解释 |
结构化结果可用模板渲染 |
| 最终回复生成 |
此处才需要语言表达能力强的模型 |
生产中两类常见错误:把评估同步放在回复之前,用户需额外等待一次评审调用;九跳全部使用最高档模型并叠加无上限重试,降级策略会反过来推高费用。
优化顺序是先减少跳数,再降低单跳成本。决策节点应尽早结束链路:查询类请求不需要规划、工具选择与确认。
11.3 缓存对象与约束
可缓存的内容一般有四类:检索结果、重复的策略查询、工具元数据、表结构上下文。
各自的适用条件:
- 检索结果:同一用户连续询问相邻问题时,可以复用符合新鲜度要求的检索结果,避免重复进行查询向量化和检索。缓存键应包含意图、查询指纹与知识库版本;一旦条件变化,例如用户改了日期,预约类检索不得沿用旧结果;
- 重复的策略查询:诸如“时限内不可取消”这类规则会被分类、校验、生成反复读取,适合缓存,同时要求规则更新时能够失效。这也避免让模型每次“推理”策略,策略应当是查表或策略服务查询;
- 工具元数据:名称、描述、输入
schema 变化很慢,却每次都进入提示并消耗大量 token。缓存工具目录,并按意图只注入允许集合,可同时降低费用与误选概率;
- 表结构上下文:表结构说明、字段含义、枚举取值属于
schema 层上下文,不必每轮从数据库拼装。注意缓存的是结构说明,不是用户数据行。
不应缓存的内容与前几节一致:确认状态、拟议时间、余额、库存、未经校验的模型提案。缓存这些字段等于用陈旧值驱动判定,会直接导致“使用过期信息作答”。
缓存键须区分公共知识与私有数据。公共政策文档对所有用户相同,缓存键可只含知识库版本与文档权限级别,不必含主体,否则命中率会明显下降。私有数据,例如账户信息、预约记录、检索结果中涉及用户上下文的片段,缓存键必须包含租户与主体,否则跨用户共享会造成数据泄露。所有缓存键都应包含内容版本,否则策略更新后系统仍按旧规则回答。
策略类条目可以使用较长有效期,账户数据应使用很短的有效期或不缓存。
两条原则相互冲突时的优先级是明确的:安全路径不因延迟而删减,校验与批准不得跳过;评估可以异步;降低延迟的正确方向是减少非必要的模型跳数。
12 生产原则三:上下文与检索设计
12.1 上下文的来源不止检索文档
一次模型调用的上下文来源包括:用户消息、会话状态、应用数据库、检索到的文档、工具结果、用户画像、长期记忆。
检索只是其中一项。演示实现常把上下文简化为“对话历史加若干检索片段”。各来源性质不同:
| 来源 |
内容 |
可信度 |
主要用途 |
| 用户消息 |
本轮原话 |
意图信号,可能含糊或含攻击性内容 |
分类、抽取、生成 |
| 会话状态 |
步骤、拟议值、确认状态 |
对流程进度具有权威性;拟议值仍需校验 |
控制流判定 |
| 应用数据库 |
预约、账单、账户记录 |
权威 |
业务事实 |
| 检索到的文档 |
政策、常见问题、说明 |
辅助,可能过期或误检 |
解释规则 |
| 工具结果 |
本轮接口返回 |
本轮事实 |
生成依据、结果检查 |
| 用户画像 |
偏好、语言、等级 |
半权威,可能过期 |
个性化 |
| 长期记忆 |
跨会话摘要、历史行为 |
最弱,经过压缩 |
参考,需回源核对 |
记忆模块中我们说,记忆包含多类信息。工具执行应依据已认证主体、经校验的工作流状态、权威业务事实、策略判定及适用的确认或审批;用户消息与长期记忆只能提供候选输入。
12.2 装配顺序与冲突消解
上下文窗口有限,各来源会争夺空间。合理的装配顺序是分层注入:
1.先放权威且体积小的数据:工作流状态字段、当前业务记录、刚刚返回的工具结果;
2.再放本轮用户消息与必要的近期轮次;
3.按意图检索文档,例如改期意图只检索改期相关政策,而不是注入整个知识库;
4.最后放用户画像与长期记忆,并且是可裁剪的部分。
冲突消解规则须预先定义,不能交给模型自行权衡:
- 当政策规则与账户属性共同决定改期资格时,由策略服务结合当前有效政策和账户事实作出判定,模型不能自行选择一个来源覆盖另一个;
- 长期记忆称预约在周三,而状态中的标识对应周四时,以状态为准;
- 用户要求某个时间,而工具返回该时段无号时,以工具返回为准,并进入替代方案路径。
检索命中错误与记忆过期,对应评估中的检索质量与“使用过期信息作答”。应标注来源并确立权威顺序,而不是单纯扩大上下文窗口:在提示中明确某段来自数据库、某段来自检索文档,以便评估系统是否正确处理信息冲突,以及答复是否忠于权威来源。
12.3 检索层的工程约束
与 Agent 结合时,检索还需满足几项要求:
- 访问控制在检索层强制执行,过滤条件由服务端按主体注入,不依赖提示词要求模型只看可见文档;
- 文档需带生效时间与版本,过期版本应从召回中排除或明确标注,否则会产生既符合 schema 也“忠实于所给材料”的错误答复;
- 上下文预算不足时的截断顺序应保护权威短字段,优先丢弃长期记忆与低分文档,而不是丢弃状态字段或工具结果;
- 检索失败或结果为空时必须有分支:转澄清、仅依据数据库作答,或升级人工,不得用模型参数记忆填补业务事实。
策略判定仍由代码、规则引擎或策略服务执行;检索到的政策文档只用于向用户解释,不作策略判定依据,与代码校验一致。
13 生产原则四:可观测性、安全与隐私
13.1 trace 需要记录的内容
trace 字段可以分为两组。第一组回答“是谁、在哪一步、做了什么”:模型名称、模型版本、提示词版本、步骤名称、工作流标识、会话标识、工具名称、工具版本、工具参数。
| 字段 |
用途 |
| 模型名称与版本 |
更换模型导致行为变化时可归因;也用于确认降级实际切换到了哪个模型 |
| 提示词版本 |
与回归评估集绑定,使提示修改成为可追踪变更 |
| 步骤名称 |
对应第 7 节主干节点,否则只能看到最终回复 |
| 工作流标识与会话标识 |
把多跳、多轮以及等待确认的过程串成一次任务 |
| 工具名称、版本与参数 |
语义错误常出现在参数上;版本用于复现旧 trace;参数是审计“修改了哪个对象”的依据 |
第二组回答“做得怎样”:延迟、首个 token 时延、输入与输出 token、成本、重试次数、是否发生降级、是否出现错误、是否有用户反馈、评估分数。
这组字段是计算成功任务单位成本的原料,也是降级路径是否生效的证据。缺少它们,分步评估无法在线上落地,无法判断问题出在检索质量、参数语义,还是降级导致的延迟上升。
建议补充记录门控判定结果,例如权限判定是否通过、批准是否存在、批准主体类型,否则两道门在线上不可验证。
13.2 数据会离开原有边界
数据的四类去处是:模型供应商、向量数据库、可观测性平台、日志系统。
| 去处 |
可能包含的内容 |
主要风险 |
| 模型供应商 |
提示中的对话、画像、工具结果、检索片段 |
留存策略、跨区域传输、是否用于训练 |
| 向量数据库 |
文档及其嵌入,有时包含工单与对话 |
多租户隔离失效 |
| 可观测性平台 |
完整 trace,往往比业务库更完整 |
第三方留存与访问范围过宽 |
| 日志系统 |
工具参数与异常栈 |
无意写入身份、联系方式等敏感信息 |
每一处都是新的信任边界。账单场景中的“检索账户上下文”一旦整段进入提示,账户数据便可能同时进入模型供应商的处理环境和日志系统。写入模型上下文的内容已进入相应供应商或运行环境的信任边界,其留存与使用方式取决于部署模式和合同条款。
13.3 控制手段
常见的可采用以下控制措施:
- 最小注入:只发送当前步骤判定所需的字段,不把整条客户记录送入分类模型;
- 参数脱敏后记录:trace
需要工具参数用于定位语义错误,但可只保留结构化标识,对敏感取值做哈希或截断;
- 分级留存:受控环境保留完整载荷,导出到第三方观测平台使用脱敏副本;
- 供应商与存储条款作为架构决策:供应商是否用于训练、向量库的租户隔离方式、日志与
trace 的保留期,应在设计阶段确定;
- 权限仍由代码门控:日志与索引中存在某份数据,不构成模型可以跨主体操作的依据。
可观测性与隐私存在冲突:字段越完整越便于诊断,数据暴露范围和跨系统传输风险也越大。应对数据分级处理:高基数诊断字段留在受控环境,导出侧保留足以做聚合与归因的最小集合。
审计记录不宜一刀切要求全量。高并发写操作全量审计可能产生巨大存储与写入成本,甚至影响主流程性能。更可行的是分级:
- 高风险写操作,例如资金、权限、不可逆变更,审计记录全量保留,不采样;
- 低风险操作,全量记录结构化元数据,例如操作类型、对象标识、时间、主体、结果,详细载荷按策略采样或脱敏后保留。
审计记录应与调试 trace 分开存储,并明确保留期、归档策略与访问控制。对具有副作用的执行,审计记录不应采样;调试
trace 可以采样,用于性能与质量分析。
14
通用业务 Agent 系统
整条链路可以表述为:
生产可用的 Agent 系统不能只验证模型是否会调用工具,还必须保证每个步骤有明确契约、外置状态、失败分支和审批边界。模型负责推理,系统正确性由这些工程约束共同保证。
最后,最重要的还是要结合具体业务,而更多的思考可能是我们引入模型后期望替代什么、要带来什么样的价值,否则,为了All
in AI这个超大的战略故事就只能玩虚的,到头来只能安慰一下自己“没有银弹”~ |