dispatch + Budget 单案成本控制 — 子任务调度与超限降级
dispatch + Budget 单案成本控制 — 子任务调度与超限降级
日期: 2026-08-19 阶段: Phase 3 - AML 调查 Copilot 标签: #budget-enforcement #cost-cap #graceful-degradation
核心问题
Day 64 把证据汇集 pipeline 拆成五段,Day 65 解决了①段「召回优先」的检索质量。今天回答一个被前两天刻意搁置的工程问题:一个 AML 案件的调查要花多少钱、谁来踩刹车?
证据汇集本质是「fan-out 多源检索 + 多次 LLM 调用」——三源检索(流水/KYC/历史告警)、类型学比对、SAR 起草,每段都可能调一次或多次模型。在 ReAct 式自由编排里,一个案件烧掉 $5 不稀奇;行业基线是「单告警 20-60 分钟人工」(Facctum, 2026-03),若 Copilot 把每案成本推到比人工还贵,整个项目的 ROI 论证就崩了。今天回答三件事:
- dispatch 怎么按案件分发汇集子任务? orchestrator 已有
invokeKnowledgeAgent等 dispatch 工具,P3 要把「证据汇集」这个调查子任务挂上去,且每次 dispatch 前后都要过 Budget 断言。 - 单案成本上限怎么设、超限怎么降级? 不是「报错崩案」——合规场景漏证据代价大(Day 65 的非对称)。要做「soft-cap 降级」:超阈值就换便宜档/砍源数,而不是直接抛异常。
- 单案 token 成本怎么首测? 没有真实计费就无法谈降级阈值。今天给出
budget.addCost的成本估算公式与首测口径。
关键内容
A. dispatch:orchestrator 如何把「证据汇集」挂成可断言的子任务
现有 orchestratorAgent.ts 的 dispatch 工具是一个固定模板——每个 dispatchXxx 都在 execute 头尾包了四条断言:
// src/agent/orchestrator/orchestratorAgent.ts(现有 dispatch 模板)
execute: async ({ subQuery }) => {
opts.budget.assertCanStep(); opts.budget.incrementStep() // 步数闸
opts.budget.assertCostOk(); opts.budget.assertNotTimedOut() // 成本闸 + 超时闸
opts.onSubAgentStart?.('knowledge', subQuery)
opts.budget.resetSubAgent() // 子代理工具计数清零
const r = await runKnowledgeAgent({ /* ... */ })
return { text: r.text }
}
P3 的「证据汇集」要复用完全相同的模板新增一个 dispatchEvidence 工具,子查询是案件 id 而非自然语言 query。关键设计——断言点不变、被调函数变:
// P3 计划新增(dispatchEvidence,沿用四断言模板)
const dispatchEvidence = tool({
description: 'Gather an evidence dossier for an AML case (transactions/KYC/prior alerts).',
inputSchema: z.object({ caseId: z.string().min(1) }),
execute: async ({ caseId }) => {
opts.budget.assertCanStep(); opts.budget.incrementStep()
opts.budget.assertCostOk(); opts.budget.assertNotTimedOut()
opts.budget.resetSubAgent()
const dossier = await gatherEvidence({ caseId, search: hybridSearch, budget: opts.budget })
return { dossier } // 进 Day 64 的②段类型学比对
},
})
为什么把断言放在 dispatch 边界而不是子代理内部?这正是 Agent Contracts (arXiv:2601.08815, 2026-03) 的核心结论——「enforcement must be external to agent code」:子代理(甚至 LLM 自己)不可被信任来自我限流,因为「agents cannot negotiate themselves out of binding resource limits during execution」。断言层必须在编排器、在 LLM 决策逻辑之外。现有 budget 是一个外部闭包对象(makeBudget 返回的接口),子代理只能调用、不能修改其内部 cost/steps,结构上就满足了「external enforcement」。
反直觉洞察①(成本闸的位置比阈值更重要):直觉会把成本检查放在「调用模型之后」——拿到 usage 再判超没超。但这是事后告警,不是闸。Waxell 复盘的一次事故根因正是「no mechanism that could have terminated the session before the next API call completed」(2026)。本项目把
assertCostOk()放在 dispatch 入口——在花下一笔钱之前判,超了就抛在 dispatch 边界,已花的钱不退但不再新增。一个 $75,000/day 的失控 agent 账单(同源报道)就是因为闸装在了出口。
B. soft-cap 降级:合规场景下「砍质量」优于「抛异常」
现有 budget.ts 的 assertCostOk() 是硬闸——cost > costCapUsd 直接 throw。对 Web3 研究 agent 这没问题(用户重试即可),但对 AML 调查是错的:调查到一半抛异常 = 这个案件没有 SAR 草稿、没有审计记录,等于漏报。合规要的是「永远产出一份可复核的结果,哪怕是降级的」。
所以 P3 要在硬闸之前插一道 soft-cap 降级闸,对应业界的「soft-cap-with-degradation」模式(digitalapplied, 2026):counter 越过软阈值就把模型从 premium 档换 budget 档,「Sonnet→Haiku 在常规轮次上不可感知,但在硬推理上才显形」。AML 的降级要更克制——不能在「类型学定性」这种关键段降智,只能砍「锦上添花」的部分:
| 成本区间(占 cap) | 档位 | 降级动作 | 为什么这段可砍 |
|---|---|---|---|
| 0 – 70% | 正常 | 三源全检索 + LLM 起草 SAR | 预算充裕 |
| 70% – 90% | soft-cap 降级 | 历史告警源降级为 BM25-only(不调 embedding);SAR 起草换 budget 档模型 | 历史告警是辅助证据;草稿换档由 HITL 复核兜底 |
| 90% – 100% | 极限降级 | 只跑确定性规则引擎(assessCaseV2,零 LLM)+ 规则模板 SAR(draftSar) | P1 已证明规则引擎 recall=1.0;模板 SAR 非 LLM、零成本 |
| > 100% | 硬闸 | 仅当极限降级仍超时才 throw | 兜底防失控 |
关键洞察:90%-100% 档退回 P1 的纯规则路径,等于把整条 LLM pipeline 降级成「免费且确定性」的 fallback。P1 的 assessCaseV2(规则引擎,recall 1.0×3 类型学)和 draftSar(模板,generatedBy:'rule-template')本就是零 LLM 成本的,它们不是「占位原型」而是成本失控时的安全网。这是 P1 那些"看似被 P3 LLM 版取代"的代码的真正价值——降级目标。
降级闸的判定逻辑(计划新增 budget.degradeLevel()):
function degradeLevel(): 'normal' | 'soft' | 'extreme' | 'hard' {
const ratio = cost / cfg.costCapUsd
if (ratio < 0.70) return 'normal'
if (ratio < 0.90) return 'soft' // 砍辅助源 + 换 budget 档
if (ratio < 1.00) return 'extreme' // 退回纯规则路径
return 'hard' // throw(兜底)
}
gatherEvidence 与 SAR 起草段读 degradeLevel() 决定走哪条路。注意:降级是单调的——一个案件内成本只增不减,所以 level 只会升不会降,不存在抖动。
反直觉洞察②(44% 的浪费在「注定失败」的案件上):BAGEN 的 PoC 发现「LLM agents waste 44.6% of tokens on tasks they'll fail」,且「savings only apply to failed trajectories——成功案件上提前停止会降质」(2026)。映射到 AML:normal 阴性案件(占金标 ~22.5%)根本不该烧 LLM——规则引擎一眼判
topTypology=null就该停。降级的最大省钱点不是给难案降智,而是给「注定无 SAR」的简单阴性案件提前短路。所以 dispatch 入口要先跑一次零成本的assessCase:若topTypology===null且无 hits,直接走模板 SAR 收尾,根本不进 LLM 段。
C. 单案 token 成本首测:addCost 的估算口径
谈降级阈值(70%/90%)的前提是能估出单案成本。现有 budget.addCost(usd) 是个累加器,但没人调它——P2 留了接口没接计费。P3 要在每次 LLM 调用后把 usage 折算成 USD 喂进去:
addCostFromUsage(usage, price):
inUsd = (usage.inputTokens / 1e6) * price.inputPerMTok
outUsd = (usage.outputTokens / 1e6) * price.outputPerMTok
budget.addCost(inUsd + outUsd)
单案成本的量级首测(合成案 + 估算单价,非真实计费):
| 路径 | LLM 调用 | 估算 input tok | 估算 output tok | 估算成本/案 |
|---|---|---|---|---|
| 纯规则(normal 短路) | 0 | 0 | 0 | $0(确定性) |
| 三源汇集 + budget 档起草 | ~4 | ~12,000 | ~2,500 | ~$0.02-0.05 |
| 三源汇集 + premium 档起草 | ~4 | ~12,000 | ~2,500 | ~$0.10-0.20 |
(量级仅供设阈值,单价随模型档位变动;真实数字 W2 接计费后回填。)
对照人工基线「单告警 20-60 分钟」(Facctum, 2026-03),即便 premium 档 ~$0.20/案也远低于人力成本——ROI 论证成立的前提是降级闸把失控尾部摁住:没有 cap,一个进入 LLM 死循环的案件能烧到 $5+,把 100 个案件的平均成本拖垮。cap 的价值不在均值,在截断长尾。
成本估算的一个陷阱(踩坑):
反直觉洞察③(cap 要按「案」不按「请求」):
costCapUsd若设成全局累加,多案件并发跑时会互相挤占——案件 A 烧超了会让案件 B 在入口就被硬闸误杀。AML 调查是单案独立结算:每个dispatchEvidence(caseId)应起一个新的 Budget 实例(makeBudget重新构造),cost从 0 计。现有resetSubAgent()只清工具计数、不清 cost——这是对的(cost 是案件级的,工具计数是子代理级的)。P3 要确保 orchestrator 对每个案件makeBudget一次,而非全局共享一个 budget,否则降级 level 会被串案污染。
设计要点/决策表
| 要点 | 决策 | 理由 |
|---|---|---|
| 断言位置 | 成本/步数/超时闸放 dispatch 入口(调用前) | 事后告警不是闸;超限要在花下一笔钱前拦(Agent Contracts 2026-03) |
| 闸的归属 | Budget 是 orchestrator 外部闭包,子代理只读不可改 | 「enforcement must be external to agent code」 |
| 超限处理 | soft-cap 降级而非 throw(仅兜底 hard 闸 throw) | 合规要永远产出可复核结果,漏证据代价 > 多算代价 |
| 降级路径 | 90%+ 退回 P1 纯规则路径(assessCaseV2 + draftSar) | 规则引擎零成本、recall 1.0,是天然安全网 |
| 阴性短路 | dispatch 入口先跑零成本 assessCase,null 即走模板收尾 | 注定无 SAR 的简单阴性案不该烧 LLM(BAGEN 44% 浪费) |
| cap 粒度 | 按案件结算,每案一个 Budget 实例 | 防并发串案污染降级 level |
| 成本来源 | 每次 LLM 调用后 addCostFromUsage 折算 USD | P2 留了 addCost 接口,P3 接上真实 usage |
对本项目的落地
- 扩展
src/agent/orchestrator/budget.ts:新增degradeLevel(): 'normal'|'soft'|'extreme'|'hard'(B 节阈值 0.70/0.90/1.00)与addCostFromUsage(usage, price)辅助(C 节折算)。assertCostOk()的硬闸语义保留(兜底),但调查路径优先读degradeLevel()软降级。诚实标注:阈值 0.70/0.90 为 v1 设计值,W2 接真实计费后按单案成本分布回填。 - 新增
dispatchEvidence到src/agent/orchestrator/orchestratorAgent.ts:沿用现有四断言 dispatch 模板(assertCanStep/incrementStep/assertCostOk/assertNotTimedOut/resetSubAgent),execute调用 P3 的gatherEvidence(Day 64 ①段),入参为caseId。不改现有三个 dispatch 工具的语义。 - 入口短路:
dispatchEvidence在调任何 LLM 前先跑assessCase(case)(来自src/aml/typology.ts,零成本);若topTypology===null && hits.length===0,直接走draftSar(src/aml/sarDraft.ts,模板)收尾,不进 LLM 段——对应 BAGEN「给注定失败任务提前停」。 - 降级路径复用 P1:极限降级(90%+)走
assessCaseV2+draftSar,两者均零 LLM 成本(generatedBy:'rule-template'),是成本安全网。这把 P1 构建物从「被取代的原型」重新定位为「降级 fallback」。 - 每案独立 Budget:orchestrator 对每个案件
makeBudget({ costCapUsd, ... })新建实例,禁止全局共享(C 节反直觉③),避免并发串案污染。 - 成本首测:W2 在
src/agent/__tests__/budget.test.ts同目录加单案成本估算测试,用合成 usage 验degradeLevel在各成本区间返回正确档位;真实计费数字单独标注「估算/非真实」。
参考资料
- arXiv:2601.08815 — Agent Contracts: A Formal Framework for Resource-Bounded Autonomous AI Systems:token/cost/step 三维预算;enforcement must be external to agent code;超限须 terminate 或 graceful degrade;agents cannot negotiate themselves out of binding limits(引 Zilberstein anytime algorithms / Buttazzo 硬实时)(2026-03)
- Waxell — AI Agent Token Budget Enforcement [2026]:硬闸须在 next API call 完成前终止 session;事故根因「no per-agent budget caps + no termination mechanism before next call」;enforcement layer 必须在 agent code 之外 (2026)
- digitalapplied — LLM Agent Cost Attribution: Complete Production Guide / Agent Token Budget Calculator:soft-cap-with-degradation 模式(越软阈值即换 premium→budget 档,常规轮次不可感知、硬推理才显形);per-user/per-task/per-tenant 三维归因;per-tenant daily cap 是最高杠杆控制 (2026)
- Effloow — BAGEN: LLM Agents Waste 44% of Tokens on Tasks They'll Fail:失败轨迹平均浪费 44.6% token;省钱只对失败轨迹有效,成功任务提前停会降质 (2026)
- Facctum — AML False Positive Rates 2026 Report:单告警人工 20-60 分钟、仅 1-5% 成 SAR(人工成本基线,用于 ROI 对照)(2026-03)
- 本仓库
src/agent/orchestrator/orchestratorAgent.ts(dispatch 四断言模板)、src/agent/orchestrator/budget.ts(makeBudget/assertCostOk/addCost/resetSubAgent)、src/aml/typology.ts(assessCase 零成本规则)、src/aml/sarDraft.ts(模板 SAR)(2026-06)
SOTA 检查 (2026-06-11)
- 「外部强制 + 调用前硬闸 + soft-cap 降级」是 2026-06 agent 成本治理的收敛模式:Agent Contracts (2026-03) 给了形式化框架,Waxell/digitalapplied (2026) 给了工程模式,三者独立收敛到「闸在 agent code 之外、在花钱之前、超限降级而非裸崩」。本项目现有 budget 的「外部闭包 + 入口断言」结构已符合,P3 只需补降级档位。
- 降级 vs 硬闸的取舍随场景反转:通用 agent(可重试)硬闸即可;合规调查(漏报有监管责任)必须降级保产出。本项目的「90%+ 退回纯规则路径」利用了 P1 规则引擎 recall 1.0 的特性——这是领域特定的降级安全网,通用 agent 没有这种零成本 fallback。
- 待跟踪:Agent Contracts 提的「contract 可形式验证」(2026-03) 尚未有成熟工具链;本项目用「断言 + 决策表」的轻量替代对单机原型足够,大规模多 agent 才需形式化合约。真实单价 W2 接计费后回填 C 节估算表。
- 过时警示:「先跑完再看花了多少」的事后成本观在 2026 已被 $75,000/day 失控账单的公开复盘证伪——成本闸必须前置到调用前,这是反直觉洞察①的 live 依据;2024-2025 不少 agent demo 仍把 usage 统计当成本控制,是错把「观测」当「闸」。