面向 Agent 封装业务流程:把状态、约束和判据搬进 schema

92% 的官方 MCP 服务器只是端点的薄壳,而写在散文里的参数约束会让 Agent 静默失败、41% 直接对用户说“没有数据”。本文给出一套封装方法:把状态、约束、判据从人脑和界面搬进 schema,按“可回滚的最小承诺单元”重切刀口,并说明新能力具体开在哪四处。

有一个数字值得先摆出来。一个 Agent 调你为人写的 API,参数值不在服务端接受的词表里——服务端不报错,返回 HTTP 200 和一个空列表。在完整的 Agent 循环里,模型察觉到这次静默失败的比例是 12%,修复的比例是 0%,直接对用户断言「没有这个数据」的比例是 41%,凭记忆编一个数字的比例是 12%SilentProbe, 2026)。而修好它需要的是:把那个词表从字段说明的散文里挪进 schema 的 enum。同一篇的对照是 88/88 全错降到 0/89。

这就是「面向 Agent 封装业务流程」的真实工作量所在——不在协议,在于原产品把哪些东西留在了人身上。

这篇只扛一个主张:为人设计的业务流程,把「状态」存在人的短期记忆里、把「约束」写在散文里、把「判据」留给人的眼睛。面向 Agent 封装的本质就是把这三样搬进机器可检查的 schema。搬完之后,流程第一次变成可组合、可试算、可批量、可回放的对象——所谓「开出新花」,全部开在这三样被外化之后腾出的空间里。

这不是「换个协议再暴露一遍」。本站面向 Agent 的门禁产品设计讲的是某一个品类怎么重画;这篇讲的是给定任意一条已有的、为人跑通的业务流程,怎么切、切完能长出什么。读者画像:手里有一个成熟产品、被要求「接上 Agent」的产品或平台负责人。

名词速查

术语一句话解释
MCPModel Context Protocol,Agent 调外部工具的开放协议;工具带输入输出 schema;本站专文
tool schema一个工具的机器可读契约:参数名、类型、取值范围、必填与否。Agent 只能看到 schema 和描述,看不到你的实现
静默失败(silent failure)调用「成功」了(HTTP 200、结构合法),但语义上没做你要它做的事,且没有任何字段能让调用方判断出来
机器可检查约束能被 schema 校验器直接执行的约束(enumminimumpattern);反面是只写在文字描述里的约束
pass^k同一个任务独立跑 k 次全部成功的比例。衡量稳定性,比「跑一次成功率」严苛得多
幂等键调用方生成的唯一标识,服务端凭它识别重试,保证同一个操作不会被执行两次
dry-run(试算)走完全部校验和影响面计算、但不落库不产生副作用的一次调用;返回「如果真做会发生什么」
复合工具(composite tool)一个工具对应一段真实工作流(如「查客户 + 排回访」),而不是一个 API 端点

一、先看行业默认做法:它正在做薄壳

「面向 Agent 封装」目前的事实默认值是 1:1 包一层。有一份实证研究把这件事量化了:分析 116 个官方 MCP 服务器,88.6% 完全或部分依赖底层 REST API,其中 92% 的工具就是裸的 API 包装(bare API wrappers)From REST to MCP, 2026)。

同一篇里还有一个反向的数字,比上面那个更有意思:这些服务器暴露的操作数中位数只占底层 API 可用操作的 19%

把这两个数字放在一起读,能读出行业的真实状态:形态上是薄壳,选择上却已经在做重度筛选。做得能用的那些服务器,实际上偷偷干了「删掉八成端点」这件苦活;只是这件苦活没有被当成方法论说出来,于是新入场的团队默认去做 1:1 全量暴露。

全量暴露的代价能算出来

为什么 19% 不是偷懒而是必需?两笔账。

第一笔,上下文预算。 拿一个有公开数字的规模做参照:AppWorld 的环境是 9 个日常应用、457 个 APIAppWorld, ACL 2024)。假设每个工具的 schema 加描述占 150–250 token(这是我的估算前提,不是实测值),全量暴露的工具定义就是 6.9 万到 11.4 万 token;取中间值 9.1 万,占 200k 上下文窗口的 45.7%。任务还没开始,一半的窗口先给了目录。

按 19% 筛过之后是 87 个工具、约 1.7 万 token(8.7%);再叠加那篇论文提到的「过滤 + 重组把每个 API 的工具数中位数降低三分之一」,约 58 个工具、1.2 万 token(5.8%)。我用 python 手算验过这几个数;但要说清楚:457 这个数字来自 AppWorld,19% 和三分之一来自 From REST to MCP,两者是不同研究——这是一次说明量级的估算,不是任何一篇论文的测量结果。

第二笔,选择准确率。 这笔账比上下文更硬。有研究把工具池从 1 个压力测试到 11,100 个、跨 26 个区间量化选择准确率的衰减,基线在大池子下的工具选择准确率是 13.62%,加检索之后 43.13%RAG-MCP, 2026)。另一篇指出衰减的原因未必是数量本身,而是语义冗余——真实工具集里大量名字和描述重叠的工具制造歧义,合并加过滤能带来 8.38%–38.6% 的选择准确率提升(ToolScope, 2026)。还有一篇专门泼冷水:检索召回率不是对的指标,K=100 时召回接近 100%,但模型准确率反而掉 10–16 个百分点、token 成本涨 10 倍(The 99% Success Paradox, 2026)。

所以第一节的结论是一句反直觉的话:暴露不是封装,删减才是封装的第一个动作。这是供给侧的活,不是靠给模型加检索能补回来的。

顺带一个更早的对照:本站解剖 search 工具那篇里,SWE-agent 把翻页式搜索工具直接删掉,解决率从 12.0% 涨到 15.7%。同一个能力,删掉比给出去更好——这件事在单个工具上早就成立了。


二、为人设计的流程,漏在哪三处

删减解决的是「给多少」,不解决「给什么」。要回答给什么,得先看清人机界面帮人类承担了什么。

我的拆法是三处,它们分别对应流程的三个不可省略的要素:

要素人机界面把它放在哪Agent 拿不到会怎样该搬到哪
状态向导的「第 3 步 / 共 5 步」、session、以及人的短期记忆每次调用都是失忆的;多轮流程走到一半无法自证进度搬进显式的、可查询的流程实例对象(含当前步骤、已满足的前置条件)
约束帮助文档、客服话术、字段说明的散文、以及运营的经验静默失败、或规则在交接中被弱化搬进 schema 的机器可检查字段 + 服务端校验
判据人的眼睛看页面上那行绿字把「做过了」当成「做完了」搬进终态断言:调用返回可核对的证据,而不只是 success: true

三处都有实证支撑,不是我拍的。

约束这一处最触目。 SilentProbe 审计了 2,501 份独立发布的 OpenAPI 文档、721,320 个参数:只有 7.5% 声明了枚举,只有 15.2% 声明了任何机器可检查的约束,而 40.1% 的文档在散文里写了至少一条 schema 没有编码的约束。然后对 27 家厂商的线上端点做 219 次扰动,结论是约束的形式而不是厂商身份决定诚实度:机器可检查的约束在 111/111 个案例里给出了诚实的报错;只写在散文里的约束,61 次里有 44 次静默失败(p = 2e-13)。

同一篇还分离出一个我没料到的细节:模型对写全的词表遵守得挺好(88–91% 正确使用),但对只用「例如」举了个例子的词表,12 个模型、8 个家族、88 次尝试无一例外全部失败。也就是说「披露」和「机器可读」是两个独立的维度——你把词表在描述里写全,模型会照做;你只给一个 e.g.,它一定猜。

约束还会在流程内部被稀释。 上面讲的是单次调用;多阶段流程里有另一种失效:约束在 Agent 之间交接时丢掉「约束力」。有研究把这个现象叫 operational state preservation 的失败——交接产物(摘要、计划、工单、备忘)可能提到了那个未解决的前置条件,却把它从「执行前必须解决的要求」降格成「可供参考的信息」,于是 must 变成了 maybe。他们给出的修复很具体:把四个字段显式还原——前置条件(prerequisite)、权限(authority)、兜底(fallback)、执行后果(consequence)——保留率回到 100.0%,越权动作降到 0.0%(When “Must” Becomes “Maybe”, 2026)。同时他们也诚实地报了一个分离现象:只加下游校验能消掉越权动作,但产物本身的降格仍然有 95.3% ——你能拦住坏动作,却没有修好那份被稀释的交接产物

这四个字段我认为可以直接抄成工具 schema 的设计清单,它们比「写清楚描述」这种建议可执行得多。

判据这一处,评测圈已经给了答案。 τ-bench 的做法是不看对话说了什么,只比对话结束时数据库的终态与标注的目标态,并额外用 pass^k 衡量多次重跑的一致性。结果是:即便是 SOTA 的函数调用 Agent(如 gpt-4o)成功率不到 50%,pass^8 低于 25%(τ-bench, ICLR 2025)。它同时给 Agent 一份领域策略文档要求遵守——注意这个设计:策略文档在 τ-bench 里被明确称为「对领域世界模型的部分描述」。这与本站Agent 缺的是可执行世界模型那篇是同一件事的两个说法。

判据的工程含义在本站Agent 最难的不是开始而是知道什么时候结束里展开过,这里不重复。


三、换一把刀:从「端点」切到「可回滚的最小承诺单元」

前两节都是诊断。这一节是我的方法主张,请当作我的提炼读,不是行业共识。

原产品的切法是页面/端点。这个切法不是错的,它是为人的手速和短期记忆优化的:一次只让人填五个字段,因为人填二十个会填错。Agent 没有这个瓶颈,它有另一个瓶颈——它不会犹豫,也不会在点「确认」之前停下来看一眼。

所以我主张按承诺(commitment)切:

一个工具应该正好对应一次承诺:要么完整发生、要么完整不发生,并且有一条明确的撤销路径。

判断某个切法是否合格,用三条可复核的判据(不是打分,是能当场回答是/否的问题):

  1. 原子性:这个工具中途失败时,业务数据处于哪个状态?如果答案是「取决于失败在第几步」,切错了——那是端点,不是承诺。
  2. 可撤销性:调用完成后,撤销它需要几次调用、需不需要人?如果答案是「要联系客服」,这个工具不该给 Agent 单独调用。
  3. 自足性:Agent 只看这一个工具的 schema,能不能判断出「我现在有资格调它吗」?如果需要它记得三步前页面上的某个值,状态没搬完。

两种切法并排

下面是伪代码,用来对比同一个业务动作(电商售后的「改地址后重发」)在两种切法下的样子。这是根据我对典型电商售后流程的理解写的示意,不对应任何真实代码库。

# 切法 A:端点式(1:1 包装,行业默认)
# Agent 需要自己编排,且中途失败留下半成品状态
get_order(order_id)                      # 返回 40+ 字段的原始对象
validate_address(addr)                   # 约束写在 description 散文里
update_order_address(order_id, addr)     # 已落库
cancel_shipment(shipment_id)             # 这一步失败 → 地址已改、旧包裹还在飞
create_shipment(order_id, warehouse_id)  # warehouse_id 怎么来?Agent 猜
# 切法 B:承诺式(我主张的切法)
reship_to_new_address(
    order_id,                # 幂等键由调用方给,重试不会寄两次
    idempotency_key,
    new_address,             # schema 内嵌 enum:省份/配送区域词表写全,不用 e.g.
    reason_code,             # enum,来自业务策略而非自由文本
    dry_run=False,           # True 时走完全部校验与影响面计算,不落库
)
# 返回:
#   decision      = COMMITTED | REJECTED | NEEDS_HUMAN
#   preconditions = 每条前置条件的通过/未通过 + 未通过的具体原因
#   effect        = 受影响的实体清单(订单/包裹/优惠券)
#   undo_handle   = 撤销句柄(NEEDS_HUMAN 时为空)
#   evidence      = 可独立核对的终态字段,不是 success: true
# 省略:鉴权、限流、部分退款的分支——它们不影响这里的切法结论

切法 B 里没有一样是新技术。幂等键、枚举、dry_run、撤销句柄,全部是十年前就有的工程手段。新的是:它们第一次必须同时出现在同一个接口契约上,因为消费者从「会看文档、会犹豫、会打电话问客服的人」换成了「只读 schema、不犹豫、失败后会编数字的模型」。

这和 Anthropic 的工具写作指南是同一个方向:不要一个端点一个工具,而是做支持真实工作流的复合工具(他们给的例子是「查客户 + 排回访」),返回紧凑高价值的数据;错误信息要写成「具体且可行动的改进建议」而不是错误码或堆栈,因为读它的是模型,它要靠这句话自我修正后重试(Anthropic Engineering: Writing effective tools for AI agents)。同一篇还有两个能直接抄的约束:Claude Code 默认把单次工具响应限制在 25,000 token;以及返回人类可读的自然语言标识符而不是内部技术 ID,模型对可读字段的推理明显更好。

落在架构上是加一层,不是改后端

这一点对「成本谁付」很关键:承诺层是出来的,原产品不动。

flowchart TB
    subgraph AGENT["Agent 侧"]
        A["业务或编码 Agent"]
    end
    subgraph COMMIT["承诺层 新增且薄"]
        T["承诺工具<br>enum schema 前置条件 撤销句柄"]
        D["试算镜像<br>dry-run 无副作用"]
        L["流程账本<br>幂等键 调用轨迹"]
    end
    subgraph LEGACY["原产品 尽量不改"]
        API["既有 REST 端点"]
        DB["业务数据库"]
        RULE["规则散落在文档 话术 运营经验里"]
    end
    EVAL["评测与流程挖掘"]
    A -->|MCP| T
    A -->|MCP| D
    T --> API
    D --> API
    T --> L
    API --> DB
    RULE -. 一次性人工搬迁 .-> T
    L -. 喂回下一版策略 .-> EVAL
    EVAL -.-> T

图里唯一昂贵的箭头是那条虚线:把散落在文档、话术和运营经验里的规则一次性搬进 schema。这件事没有捷径,也是整个封装工程里最不像技术活、却最决定成败的部分。SilentProbe 那句话值得贴在工位上:修复是一行 schema,不是一个更好的模型(the fix is one line of schema rather than a better model)。


四、新花开在哪:四处原产品做不到的地方

前三节都在讲怎么不出错。这一节回答标题后半句——为什么值得做,而不只是不得不做。

我的判断是:新能力不是封装的副产品,而是「状态/约束/判据被外化」这件事的直接推论。原产品做不到它们,是因为这三样一直存在人脑里,而人脑不可复制、不可并行、不可回放。

花一:试算面(dry-run)从内部调试手段变成可售卖的产品

人的界面不需要试算,因为人自带试算——人会在点「确认」前犹豫、会先问同事。Agent 不犹豫。ToolEmu 的数字给了这件事一个价格:即便最安全的 LM Agent 也有 23.9% 的时候出现风险性失败,且人工核验确认其中 68.8% 是真实世界会发生的失败;典型失效模式包括「凭空编造或做出没有依据的假设」(ToolEmu, ICLR 2024 Spotlight)。

所以给 Agent 的接口必须配一个无副作用的镜像。这是被迫的。但注意它顺手产出了什么:一个能回答「如果真做,会发生什么」的引擎。这个能力原产品从来没有过——它一直是「先做,再看结果」。

于是新形态出现了:把 dry-run 的结果本身当产品卖给人。「这次批量改价会影响 1,243 个订单,其中 37 个已发货、9 个跨境」——这句话在封装之前根本没有地方能产生。这是我的产品判断,不是已验证的结论;但它的技术前提(影响面必须在承诺层可计算)是上面那套切法的硬性要求,不是额外投入。

花二:长尾流程第一次有正 ROI

流程一旦是可组合、可重试、有幂等键的对象,跑一次和跑一万次的边际成本差别只剩算力。

原产品里有一大类流程是已知有价值但因为人力不划算而从未做的:逐单核对对账差异、给每个长尾客户单独议价、每个 SKU 单独写文案再 A/B。它们的共同点不是难,是单位人力产出太低。

这里要克制一点:不是所有长尾都值得跑。判据我认为是这一条——这个流程的判据能不能自动核对?能,边际成本才真的降下来;不能,你只是把人力从「执行」搬到了「审核 Agent 的执行」,总量可能更大。这也是业务 Agent 评测样本构造那篇的落点:判据不硬,规模化只会放大错误。

花三:流程账本不用埋点就有了

人在界面上的操作要靠埋点才能观测,埋点永远缺、永远不准。Agent 的每一步都是一次带 schema 的结构化调用——观测数据是执行的副产品,不是额外工程。

这意味着流程挖掘(process mining)的输入第一次是免费且完整的:哪条前置条件最常拦人、哪个 reason_code 从来没被用过、哪一步平均要重试几次。这些问题在人机界面时代要专门做一个数据项目才能回答。

它还能闭环回去:轨迹是评测样本的原料,评测结论是下一版策略的依据。本站Veral 那篇论证过这个回路的产品单位——不是一次调用,而是一次有证据、可灰度、可回滚的策略变化。承诺层让业务流程也具备了同样的性质。

花四:业务规则本身变成一个可版本化的层

这是我认为最被低估的一处。

规则从散文搬进 schema 之后,它获得了散文永远没有的三个性质:可版本化、可灰度、可 A/B。「满 200 减 30 且不与新人券叠加」这条规则今天写在运营的飞书文档里,改它靠通知;变成承诺层里带版本号的可执行约束之后,改它是一次发布——能回滚、能只对 5% 流量生效、能拿两版的终态数据对比。

于是「规则」从成本项变成了产品的一层。这条路本站门禁那篇走过一遍(判决 schema + 状态机 + 服务端防钻空子),只不过那篇的对象是交付质量,这篇的对象是业务流程本身。

回头看,这四处的共同结构是:人机界面为了适配人,把流程压成了一条不可分叉、不可试算、不可回放的单行道。封装的收益不在于换了协议,而在于流程终于从单行道变回了一张图。


五、三个我预期会被问到的反问

「这不就是 API 治理、契约优先、幂等设计的老话重提?」

有很大重叠,我不装作没有。差别在两点,都很具体。第一,判据和撤销路径过去从不进接口契约——REST 的最佳实践里没有一条要求你返回「可独立核对的终态证据」和「撤销句柄」,因为调用方是会看 dashboard 的人。第二,容错方向反过来了。传统 API 设计假设调用方是确定性的程序,参数错就该 4xx;面向 Agent,错误消息本身是控制信号——它要能让一个非确定性的消费者自我修正后重试。SilentProbe 那 41% 的假阴性断言就是老范式在新消费者面前的破口:接口没坏,坏的是「200 空列表」在新语境下的语义。

「先改流程再接 Agent,成本谁付?」

按投入产出排序,可以分三步走,前两步都不动后端:

步骤做什么成本立即收益
1把散文里的约束搬进 schema(enum 写全,不用 e.g.;补 pattern/minimum最低,改 schema 不改实现静默失败转为诚实报错,Agent 能自我修正
2按承诺聚合出一薄层复合工具,删掉八成端点不暴露中,一层新服务工具选择准确率与上下文预算同时改善
3建试算镜像与流程账本高,需要影响面计算能力第四节的四处新能力才真正可用

第 1 步之所以排第一,不是因为它简单,是因为它的收益/成本比在有实测支撑:88/88 全错 → 0/89。

「Agent 会不会绕过约束?」

会,所以约束必须在服务端执行。写在 prompt 或工具描述里的规则是提示,不是约束——第二节那篇 constraint weakening 的结论已经说清楚:语义上「提到了」不等于操作上「仍然有约束力」。而且那篇分离出的 95.3% 提醒我们,下游加一道校验能拦住坏动作,但不会修好上游被稀释的产物;两处都得治。本站门禁那篇的三条防钻空子规则可以直接套用。


六、带得走的东西

封装体检清单

针对每一个你准备暴露给 Agent 的工具,逐条回答。每条都是能当场答是/否的判据,不是打分。

约束(搬进 schema)

  • 所有有限取值的参数都声明了 enum,且词表写全而不是用「例如」举例?
  • 文字描述里提到的每一条约束,都有对应的机器可检查字段?(对照 SilentProbe 的 40.1%)
  • 非法输入返回的是「具体且可行动」的错误消息,而不是错误码或堆栈?
  • 约束在服务端执行,而不是只写在工具描述里?

状态(搬出人脑)

  • Agent 只看这一个工具的 schema,能判断「我现在有资格调它吗」?
  • 多步流程有显式的、可查询的流程实例对象,而不是靠 Agent 记住上一步?
  • 交接产物显式带了前置条件 / 权限 / 兜底 / 执行后果四个字段?

判据(搬出人眼)

  • 返回值里有可独立核对的终态证据,而不只是 success: true
  • 你能像 τ-bench 那样,只比对终态就判断这次调用做对了没有?
  • 同一任务重跑 8 次,你敢看 pass^8 吗?

切法与规模

  • 每个工具是一次完整承诺(原子、可撤销、自足),而不是一个端点?
  • 有幂等键,重试不会执行两次?
  • dry_run,且它真的无副作用?
  • 工具总数经过删减和去语义冗余,而不是全量暴露?
  • 单次工具响应有上限(可参考 Claude Code 的 25k token 默认值)与分页/过滤/截断?

一个成本最低的亲手验证实验

不需要 Agent 框架,不需要评测平台,一小时能跑完,我认为它能复现本文最硬的那个结论:

  1. 从你自己的产品里挑一个有限取值参数(订单状态、退款原因、配送方式都行),确认它当前只在文字描述里写了词表。
  2. 构造 10 次调用:5 次用词表内的值,5 次用词表外但看起来合理的值(例如把 REFUND_REQUESTED 写成 refund_pending)。
  3. 记录服务端返回什么。如果 5 次非法调用里有任何一次返回 200 且结构合法,你就在生产环境里有一个静默失败面。
  4. 把词表加进 schema 的 enum,重跑同样 10 次,对比。
  5. 加分项:把这个工具挂给一个 Agent,给它一个必须用到这个参数的任务,看它写错值之后是否对你断言「没有数据」

第 3 步的答案基本决定了你要不要读第二遍这篇文章。


诚实的提醒

  • 本文所有带链接的数字都来自我这次检索并核实过的论文摘要与官方博客原文,但我没有亲手复现其中任何一项实验(SilentProbe 的扰动集、RAG-MCP 的 11,100 工具压力测试、τ-bench 的 pass^8 都未在我的环境跑过)。SilentProbe 公开了代码与逐次调用的 run identifier,是最容易复核的一篇。
  • 第一节那笔 token 账是估算:457 个 API 来自 AppWorld,19% 与「降低三分之一」来自 From REST to MCP,两者不是同一个数据集;每工具 150–250 token 是我设的前提。乘法我用 python 验算过,前提本身没有实测支撑,请当量级参考。
  • 「承诺层」这个切法、三条切法判据、四处新能力,是我的设计判断,不是行业共识,也没有在两个独立场景验证过——所以我没有把它命名成任何「定律」。它目前的证据地位是:诊断部分(三处漏点)有实证支撑,处方部分(怎么切)只有推理支撑。
  • 「dry-run 结果可以作为产品卖给人」是猜想,我没有见过明确采用这个形态的商业案例。
  • 我暂时没有找到直接测量「承诺式聚合 vs 端点式暴露」端到端任务成功率差异的公开实验。From REST to MCP 的过滤与重组变换是最接近的证据,但它优化的目标是工具集复杂度与生成正确率,不是业务任务成功率。这是我认为这个方向上最值得做、也最缺的一个实验。

参考来源

工程实践

arXiv 论文

本站相关