Agent Plan x DeepSeek Harness --- Token 预算管理与成本追踪体系技术
版本:v1.0 | 编写日期:2026-08-24 | 适用对象:架构师、SRE、平台运营、财务核算、产品负责人
关键词:Token 预算、成本追踪、多租户配额、实时计费、告警治理、DeepSeek Harness、Agent Plan
目录
- 文档概述
- 系统背景与设计目标
- 总体架构设计
- [Token 预算管理设计](#Token 预算管理设计)
- 成本追踪体系
- 核心模块详解
- 数据模型与存储设计
- 多租户配额隔离
- 监控告警机制
- 高可用与容灾
- 性能优化策略
- 安全与合规
- 部署与运维
- 总结与展望
1. 文档概述
1.1 编写目的
本白皮书系统阐述 Agent Plan x DeepSeek Harness 平台中的 Token 预算管理与成本追踪体系(下文简称 "预算体系")的设计理念、架构组成、关键模块、数据模型、运维流程与安全规范。其核心目标在于:
- 在大模型推理成本高速攀升的背景下,为平台提供 可预测、可观测、可治理 的成本控制能力;
- 在多 Agent、多租户、多模型并发的复杂场景中,确保 Token 消费行为透明、可追溯、可审计;
- 通过预算 → 配额 → 计费 → 告警 → 复核的闭环机制,将"事后账单"转变为"事前预算 + 事中熔断 + 事后复盘"的全生命周期治理。
1.2 读者对象
| 角色 | 关注重点 |
|---|---|
| 架构师 | 系统分层、关键模块、扩展点、容灾方案 |
| SRE / DevOps | 部署拓扑、监控指标、告警阈值、扩缩容 |
| 平台运营 | 租户配额、计费策略、账单生成、对账规则 |
| 财务核算 | 单价、折扣、汇率、发票口径、跨期分摊 |
| 产品负责人 | 用户旅程、计费体验、限流反馈、商业模型 |
1.3 术语表
| 术语 | 含义 |
|---|---|
| Token | 模型推理的最小计费单位,分为输入 Token 与输出 Token |
| Budget(预算) | 在某时间窗口内允许消费的 Token 上限 |
| Quota(配额) | 分配给租户 / Agent / 任务的运行时额度 |
| Harness | DeepSeek 推理调度引擎,承接请求路由与执行 |
| Agent Plan | 上层任务编排框架,负责子任务拆分与工具调用 |
| Reconciliation(对账) | 平台账单与上游模型供应商账单的核对 |
| Meltdown(熔断) | 预算耗尽或风险触发时对请求的强制拦截 |
| COGS | Cost of Goods Sold,单位 Token 成本 |
2. 系统背景与设计目标
2.1 业务背景
随着 Agent Plan × DeepSeek Harness 在企业内部被广泛接入,单日 Token 消费量从早期的百万级迅速攀升至十亿级。这一增长带来了三类典型痛点:
- 预算失控风险:单个长链路 Agent 任务可能产生数十次子调用,缺乏预算约束时极易导致单任务成本超出业务可承受范围;
- 成本归因模糊:多租户共享推理集群时,Token 消费难以精确归因到具体业务线、产品线或客户,财务对账面临"分不清、说不明"的窘境;
- 告警滞后失效:传统以账单 T+1 出具再回溯的方式,无法在异常暴涨的瞬间形成拦截,往往导致损失已经发生。
为系统性解决上述问题,平台引入"Token 预算管理与成本追踪体系",将成本治理内嵌入推理调度的全链路。
2.2 设计目标
预算体系在 v1.0 阶段需达成以下五项硬性指标:
| 指标类别 | 目标值 |
|---|---|
| 预算校验延迟 P99 | ≤ 5ms(同步路径) |
| 计费事件落地延迟 | ≤ 200ms(异步链路) |
| 单日计费事件吞吐 | ≥ 5 亿条 |
| 预算耗尽熔断生效时间 | ≤ 100ms |
| 账单对账误差率 | ≤ 0.01% |
2.3 设计原则
- 预算先行:任何模型调用必须先经过预算校验,未通过则直接熔断,杜绝"先消费后追账";
- 可观测优先:每一笔 Token 消费均产生结构化事件,可通过 TraceID 贯穿编排、调度、计费三段;
- 分层治理:组织 → 租户 → 项目 → Agent → 任务五级预算,逐级继承、可独立超限;
- 幂等与最终一致:计费事件以幂等键写入,重试不会造成重复扣减;
- 可插拔计费:模型单价、阶梯折扣、峰谷计费以策略对象注入,便于商业策略迭代;
- 故障弱化:预算体系本身异常时降级为"按租户上限硬熔断 + 异步补账",避免拖垮主链路。
3. 总体架构设计
3.1 架构总览
预算体系在 Agent Plan × DeepSeek Harness 中以 旁路治理层 的形式存在,与主推理链路解耦但又紧密协同。整体由五层构成:接入层、决策层、执行层、数据层、治理层。
#mermaid-svg-XxEL7Qgz2RTEZxKj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XxEL7Qgz2RTEZxKj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XxEL7Qgz2RTEZxKj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XxEL7Qgz2RTEZxKj .error-icon{fill:#552222;}#mermaid-svg-XxEL7Qgz2RTEZxKj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XxEL7Qgz2RTEZxKj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XxEL7Qgz2RTEZxKj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XxEL7Qgz2RTEZxKj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XxEL7Qgz2RTEZxKj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XxEL7Qgz2RTEZxKj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XxEL7Qgz2RTEZxKj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XxEL7Qgz2RTEZxKj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XxEL7Qgz2RTEZxKj .marker.cross{stroke:#333333;}#mermaid-svg-XxEL7Qgz2RTEZxKj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XxEL7Qgz2RTEZxKj p{margin:0;}#mermaid-svg-XxEL7Qgz2RTEZxKj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-XxEL7Qgz2RTEZxKj .cluster-label text{fill:#333;}#mermaid-svg-XxEL7Qgz2RTEZxKj .cluster-label span{color:#333;}#mermaid-svg-XxEL7Qgz2RTEZxKj .cluster-label span p{background-color:transparent;}#mermaid-svg-XxEL7Qgz2RTEZxKj .label text,#mermaid-svg-XxEL7Qgz2RTEZxKj span{fill:#333;color:#333;}#mermaid-svg-XxEL7Qgz2RTEZxKj .node rect,#mermaid-svg-XxEL7Qgz2RTEZxKj .node circle,#mermaid-svg-XxEL7Qgz2RTEZxKj .node ellipse,#mermaid-svg-XxEL7Qgz2RTEZxKj .node polygon,#mermaid-svg-XxEL7Qgz2RTEZxKj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XxEL7Qgz2RTEZxKj .rough-node .label text,#mermaid-svg-XxEL7Qgz2RTEZxKj .node .label text,#mermaid-svg-XxEL7Qgz2RTEZxKj .image-shape .label,#mermaid-svg-XxEL7Qgz2RTEZxKj .icon-shape .label{text-anchor:middle;}#mermaid-svg-XxEL7Qgz2RTEZxKj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-XxEL7Qgz2RTEZxKj .rough-node .label,#mermaid-svg-XxEL7Qgz2RTEZxKj .node .label,#mermaid-svg-XxEL7Qgz2RTEZxKj .image-shape .label,#mermaid-svg-XxEL7Qgz2RTEZxKj .icon-shape .label{text-align:center;}#mermaid-svg-XxEL7Qgz2RTEZxKj .node.clickable{cursor:pointer;}#mermaid-svg-XxEL7Qgz2RTEZxKj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-XxEL7Qgz2RTEZxKj .arrowheadPath{fill:#333333;}#mermaid-svg-XxEL7Qgz2RTEZxKj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-XxEL7Qgz2RTEZxKj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-XxEL7Qgz2RTEZxKj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XxEL7Qgz2RTEZxKj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-XxEL7Qgz2RTEZxKj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XxEL7Qgz2RTEZxKj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-XxEL7Qgz2RTEZxKj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-XxEL7Qgz2RTEZxKj .cluster text{fill:#333;}#mermaid-svg-XxEL7Qgz2RTEZxKj .cluster span{color:#333;}#mermaid-svg-XxEL7Qgz2RTEZxKj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-XxEL7Qgz2RTEZxKj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-XxEL7Qgz2RTEZxKj rect.text{fill:none;stroke-width:0;}#mermaid-svg-XxEL7Qgz2RTEZxKj .icon-shape,#mermaid-svg-XxEL7Qgz2RTEZxKj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XxEL7Qgz2RTEZxKj .icon-shape p,#mermaid-svg-XxEL7Qgz2RTEZxKj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-XxEL7Qgz2RTEZxKj .icon-shape .label rect,#mermaid-svg-XxEL7Qgz2RTEZxKj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XxEL7Qgz2RTEZxKj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-XxEL7Qgz2RTEZxKj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-XxEL7Qgz2RTEZxKj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-XxEL7Qgz2RTEZxKj .layer>*{fill:#1f2a44!important;color:#fff!important;stroke:#3b82f6!important;}#mermaid-svg-XxEL7Qgz2RTEZxKj .layer span{fill:#1f2a44!important;color:#fff!important;stroke:#3b82f6!important;}#mermaid-svg-XxEL7Qgz2RTEZxKj .layer tspan{fill:#fff!important;} 治理层 Governance Layer
数据层 Data Layer
执行层 Execution Layer
决策层 Brain Layer
接入层 Edge Layer
放行
熔断
计费事件
API Gateway
租户鉴权 / 配额上下文加载
Budget Guard 预算校验
Harness Router 路由策略
Policy Engine 计费策略
Agent Plan 编排
DeepSeek Harness 推理
Tool Sandbox 工具沙箱
实时账本 Ledger
Quota Store 配额存储
Event Bus 事件总线
Bill Engine 账单引擎
Alert Center 告警中心
Audit & Recon 对账审计
Ops Dashboard 运维看板
3.2 上下文视图
通过 C4 Context 图描述预算体系与外部系统的边界关系:
3.3 核心流程概览
整个预算体系围绕一条主链路展开:鉴权 → 预算校验 → 路由 → 编排 → 推理 → 计费落地 → 告警 → 对账。预算校验不通过则跳过执行,直接进入告警与拒绝路径。
#mermaid-svg-udn0We9MxCxjAKag{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-udn0We9MxCxjAKag .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-udn0We9MxCxjAKag .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-udn0We9MxCxjAKag .error-icon{fill:#552222;}#mermaid-svg-udn0We9MxCxjAKag .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-udn0We9MxCxjAKag .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-udn0We9MxCxjAKag .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-udn0We9MxCxjAKag .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-udn0We9MxCxjAKag .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-udn0We9MxCxjAKag .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-udn0We9MxCxjAKag .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-udn0We9MxCxjAKag .marker{fill:#333333;stroke:#333333;}#mermaid-svg-udn0We9MxCxjAKag .marker.cross{stroke:#333333;}#mermaid-svg-udn0We9MxCxjAKag svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-udn0We9MxCxjAKag p{margin:0;}#mermaid-svg-udn0We9MxCxjAKag .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-udn0We9MxCxjAKag .cluster-label text{fill:#333;}#mermaid-svg-udn0We9MxCxjAKag .cluster-label span{color:#333;}#mermaid-svg-udn0We9MxCxjAKag .cluster-label span p{background-color:transparent;}#mermaid-svg-udn0We9MxCxjAKag .label text,#mermaid-svg-udn0We9MxCxjAKag span{fill:#333;color:#333;}#mermaid-svg-udn0We9MxCxjAKag .node rect,#mermaid-svg-udn0We9MxCxjAKag .node circle,#mermaid-svg-udn0We9MxCxjAKag .node ellipse,#mermaid-svg-udn0We9MxCxjAKag .node polygon,#mermaid-svg-udn0We9MxCxjAKag .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-udn0We9MxCxjAKag .rough-node .label text,#mermaid-svg-udn0We9MxCxjAKag .node .label text,#mermaid-svg-udn0We9MxCxjAKag .image-shape .label,#mermaid-svg-udn0We9MxCxjAKag .icon-shape .label{text-anchor:middle;}#mermaid-svg-udn0We9MxCxjAKag .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-udn0We9MxCxjAKag .rough-node .label,#mermaid-svg-udn0We9MxCxjAKag .node .label,#mermaid-svg-udn0We9MxCxjAKag .image-shape .label,#mermaid-svg-udn0We9MxCxjAKag .icon-shape .label{text-align:center;}#mermaid-svg-udn0We9MxCxjAKag .node.clickable{cursor:pointer;}#mermaid-svg-udn0We9MxCxjAKag .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-udn0We9MxCxjAKag .arrowheadPath{fill:#333333;}#mermaid-svg-udn0We9MxCxjAKag .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-udn0We9MxCxjAKag .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-udn0We9MxCxjAKag .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-udn0We9MxCxjAKag .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-udn0We9MxCxjAKag .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-udn0We9MxCxjAKag .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-udn0We9MxCxjAKag .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-udn0We9MxCxjAKag .cluster text{fill:#333;}#mermaid-svg-udn0We9MxCxjAKag .cluster span{color:#333;}#mermaid-svg-udn0We9MxCxjAKag div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-udn0We9MxCxjAKag .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-udn0We9MxCxjAKag rect.text{fill:none;stroke-width:0;}#mermaid-svg-udn0We9MxCxjAKag .icon-shape,#mermaid-svg-udn0We9MxCxjAKag .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-udn0We9MxCxjAKag .icon-shape p,#mermaid-svg-udn0We9MxCxjAKag .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-udn0We9MxCxjAKag .icon-shape .label rect,#mermaid-svg-udn0We9MxCxjAKag .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-udn0We9MxCxjAKag .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-udn0We9MxCxjAKag .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-udn0We9MxCxjAKag :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 通过
不通过
请求接入
预算校验
路由选择
Agent 编排
Harness 推理
计费事件
账本更新
告警评估
熔断拒绝
对账入库
账单生成
运营看板
4. Token 预算管理设计
4.1 预算层级模型
预算体系采用 五级继承式预算 模型:组织 → 租户 → 项目 → Agent → 任务。上级预算对下级形成天然上限,下级预算之和不得超过上级预算,但可在上级预算内动态分配。
| 层级 | 默认周期 | 校验方式 | 超限策略 |
|---|---|---|---|
| 组织 Organization | 月度 | 软上限 | 告警 + 审批追加 |
| 租户 Tenant | 月度 | 硬上限 | 直接熔断 |
| 项目 Project | 周度 | 硬上限 | 直接熔断 |
| Agent | 日度 | 软上限 | 降级模型 |
| 任务 Task | 单次 | 硬上限 | 立即拒绝 |
4.2 预算状态机
每个预算实例拥有独立生命周期,状态机如下:
#mermaid-svg-Ms0HwDVvDbBzvEB7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .error-icon{fill:#552222;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .marker.cross{stroke:#333333;}#mermaid-svg-Ms0HwDVvDbBzvEB7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 p{margin:0;}#mermaid-svg-Ms0HwDVvDbBzvEB7 defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-Ms0HwDVvDbBzvEB7 g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-Ms0HwDVvDbBzvEB7 g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-Ms0HwDVvDbBzvEB7 g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ms0HwDVvDbBzvEB7 .edgeLabel .label text{fill:#333;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .label div .edgeLabel{color:#333;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 #statediagram-barbEnd{fill:#333333;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .cluster-label,#mermaid-svg-Ms0HwDVvDbBzvEB7 .nodeLabel{color:#131300;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .note-edge{stroke-dasharray:5;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-note text{fill:black;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram-note .nodeLabel{color:black;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagram .edgeLabel{color:red;}#mermaid-svg-Ms0HwDVvDbBzvEB7 #dependencyStart,#mermaid-svg-Ms0HwDVvDbBzvEB7 #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-Ms0HwDVvDbBzvEB7 .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Ms0HwDVvDbBzvEB7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 创建草稿
提交审批
审批通过
审批驳回
修订重提
到达生效时间
运营手动暂停
恢复
用量 ≥ 80%
用量 ≥ 95%
用量 ≥ 100%
运营追加预算
周期结束
周期结束
周期结束
Draft
Pending
Approved
Rejected
Active
Paused
Warn
Critical
Exhausted
Closed
4.3 预算校验算法
预算校验运行在决策层,使用 滑动窗口 + 桶预估 + 预占 三段式算法:
- 滑动窗口统计:以 Redis 的有序集合 + 时间戳记录窗口内已消费 Token;
- 桶预估:对未完成的 Agent 任务,按历史中位数预估剩余 Token 用量,提前占用预算;
- 预占提交 :推理前对预算进行
tryReserve(tokenEst),推理完成后commit(actual),超时未提交则release。
Harness Ledger Redis 配额 Budget Guard 调用方 Harness Ledger Redis 配额 Budget Guard 调用方 #mermaid-svg-jjZyBBqMQs7CaE0D{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jjZyBBqMQs7CaE0D .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jjZyBBqMQs7CaE0D .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jjZyBBqMQs7CaE0D .error-icon{fill:#552222;}#mermaid-svg-jjZyBBqMQs7CaE0D .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jjZyBBqMQs7CaE0D .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jjZyBBqMQs7CaE0D .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jjZyBBqMQs7CaE0D .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jjZyBBqMQs7CaE0D .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jjZyBBqMQs7CaE0D .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jjZyBBqMQs7CaE0D .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jjZyBBqMQs7CaE0D .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jjZyBBqMQs7CaE0D .marker.cross{stroke:#333333;}#mermaid-svg-jjZyBBqMQs7CaE0D svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jjZyBBqMQs7CaE0D p{margin:0;}#mermaid-svg-jjZyBBqMQs7CaE0D .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-jjZyBBqMQs7CaE0D text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-jjZyBBqMQs7CaE0D .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-jjZyBBqMQs7CaE0D .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-jjZyBBqMQs7CaE0D .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-jjZyBBqMQs7CaE0D .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-jjZyBBqMQs7CaE0D #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-jjZyBBqMQs7CaE0D .sequenceNumber{fill:white;}#mermaid-svg-jjZyBBqMQs7CaE0D #sequencenumber{fill:#333;}#mermaid-svg-jjZyBBqMQs7CaE0D #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-jjZyBBqMQs7CaE0D .messageText{fill:#333;stroke:none;}#mermaid-svg-jjZyBBqMQs7CaE0D .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-jjZyBBqMQs7CaE0D .labelText,#mermaid-svg-jjZyBBqMQs7CaE0D .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-jjZyBBqMQs7CaE0D .loopText,#mermaid-svg-jjZyBBqMQs7CaE0D .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-jjZyBBqMQs7CaE0D .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-jjZyBBqMQs7CaE0D .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-jjZyBBqMQs7CaE0D .noteText,#mermaid-svg-jjZyBBqMQs7CaE0D .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-jjZyBBqMQs7CaE0D .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-jjZyBBqMQs7CaE0D .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-jjZyBBqMQs7CaE0D .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-jjZyBBqMQs7CaE0D .actorPopupMenu{position:absolute;}#mermaid-svg-jjZyBBqMQs7CaE0D .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-jjZyBBqMQs7CaE0D .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-jjZyBBqMQs7CaE0D .actor-man circle,#mermaid-svg-jjZyBBqMQs7CaE0D line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-jjZyBBqMQs7CaE0D :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} alt 预算充足 预算不足 推理请求 + traceId 1 滑动窗口查询已用 Token 2 usedTokens 3 估算本次 tokenEst 4 tryReserve(tokenEst, ttl=120s) 5 reserveId / 超限拒绝 6 下发推理指令 7 actualTokens 8 commit(reserveId, actualTokens) 9 写计费事件 10 ack 11 200 + 计费摘要 12 429 + 熔断原因 13 写拒绝事件 14
4.4 预算追加与回收
预算并非静态分配,运营可在运行期动态追加、回收、跨层级转移:
- 追加:组织层预算富余时可向下"投放",需审批通过;
- 回收:长期闲置预算可被上级回收,回收前需校验是否有进行中任务依赖;
- 借调:兄弟 Agent 间可短期借调预算,借调金额、利率、归还周期以"借条对象"管理,到期自动归还或转为追加。
4.5 阶梯与峰谷计费
为贴合上游供应商计费模型,预算体系支持多种 计费策略 的策略模式注入:
- 阶梯折扣:累计 Token 越高,单 价越低(鼓励规模客户);
- 峰谷分时:高峰时段单价上浮,低谷时段下调(削峰填谷);
- 模型分级:大模型 / 小模型 / 嵌入模型分别计价;
- 上下文分别计价:输入 Token、输出 Token、缓存命中 Token 分别核算。
5. 成本追踪体系
5.1 计费事件模型
每一次模型推理都会产生一条结构化计费事件,作为成本追踪的最小颗粒度。事件结构核心字段如下:
| 字段 | 类型 | 说明 |
|---|---|---|
| eventId | string | 全局唯一幂等键 |
| traceId | string | 贯穿编排---调度---计费的追踪 ID |
| tenantId | string | 租户标识 |
| projectId | string | 项目标识 |
| agentId | string | Agent 标识 |
| taskId | string | 任务标识 |
| modelId | string | 模型版本 |
| inputTokens | int | 输入 Token 数 |
| outputTokens | int | 输出 Token 数 |
| cachedTokens | int | 缓存命中 Token |
| unitPrice | decimal | 单价(元 / 千 Token) |
| discount | decimal | 折扣率 |
| currency | enum | CNY / USD |
| cost | decimal | 实际成本(元) |
| ts | long | 事件时间戳 |
| region | string | 推理区域 |
5.2 计费事件流转
计费事件采用"双写 + 最终一致"路径:同步路径只更新 Redis 实时账本,异步路径落库并对账,避免影响推理主链路时延。
Reconciler ClickHouse Ledger Kafka Producer Harness Reconciler ClickHouse Ledger Kafka Producer Harness #mermaid-svg-8XTCMOETJ5dSEDFZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8XTCMOETJ5dSEDFZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8XTCMOETJ5dSEDFZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8XTCMOETJ5dSEDFZ .error-icon{fill:#552222;}#mermaid-svg-8XTCMOETJ5dSEDFZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8XTCMOETJ5dSEDFZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8XTCMOETJ5dSEDFZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8XTCMOETJ5dSEDFZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8XTCMOETJ5dSEDFZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8XTCMOETJ5dSEDFZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8XTCMOETJ5dSEDFZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8XTCMOETJ5dSEDFZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8XTCMOETJ5dSEDFZ .marker.cross{stroke:#333333;}#mermaid-svg-8XTCMOETJ5dSEDFZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8XTCMOETJ5dSEDFZ p{margin:0;}#mermaid-svg-8XTCMOETJ5dSEDFZ .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-8XTCMOETJ5dSEDFZ text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-8XTCMOETJ5dSEDFZ .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-8XTCMOETJ5dSEDFZ .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-8XTCMOETJ5dSEDFZ .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-8XTCMOETJ5dSEDFZ .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-8XTCMOETJ5dSEDFZ #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-8XTCMOETJ5dSEDFZ .sequenceNumber{fill:white;}#mermaid-svg-8XTCMOETJ5dSEDFZ #sequencenumber{fill:#333;}#mermaid-svg-8XTCMOETJ5dSEDFZ #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-8XTCMOETJ5dSEDFZ .messageText{fill:#333;stroke:none;}#mermaid-svg-8XTCMOETJ5dSEDFZ .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-8XTCMOETJ5dSEDFZ .labelText,#mermaid-svg-8XTCMOETJ5dSEDFZ .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-8XTCMOETJ5dSEDFZ .loopText,#mermaid-svg-8XTCMOETJ5dSEDFZ .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-8XTCMOETJ5dSEDFZ .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-8XTCMOETJ5dSEDFZ .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-8XTCMOETJ5dSEDFZ .noteText,#mermaid-svg-8XTCMOETJ5dSEDFZ .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-8XTCMOETJ5dSEDFZ .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-8XTCMOETJ5dSEDFZ .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-8XTCMOETJ5dSEDFZ .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-8XTCMOETJ5dSEDFZ .actorPopupMenu{position:absolute;}#mermaid-svg-8XTCMOETJ5dSEDFZ .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-8XTCMOETJ5dSEDFZ .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-8XTCMOETJ5dSEDFZ .actor-man circle,#mermaid-svg-8XTCMOETJ5dSEDFZ line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-8XTCMOETJ5dSEDFZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 上报 actualTokens 1 发送计费事件(幂等键) 2 同步更新 Redis 账本 3 消费写账本明细 4 异步落 ClickHouse 5 日终对账 6 比对供应商账单 7
5.3 成本归因维度
为支撑多维度成本分析,事件携带丰富的归因标签,可在 BI 中按以下维度自由切片:
- 业务线(产品线)
- 客户 / 部门
- 模型 / 版本
- 区域 / 集群
- 调用类型(推理 / 重排 / 嵌入)
- 任务模板 / 工作流 ID
5.4 成本构成示例
以下为某租户一周内成本构成的饼图示例,凸显"输出 Token 仍是主要成本项":
#mermaid-svg-OG9yIruoQdnpwKlC{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OG9yIruoQdnpwKlC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OG9yIruoQdnpwKlC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OG9yIruoQdnpwKlC .error-icon{fill:#552222;}#mermaid-svg-OG9yIruoQdnpwKlC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OG9yIruoQdnpwKlC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OG9yIruoQdnpwKlC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OG9yIruoQdnpwKlC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OG9yIruoQdnpwKlC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OG9yIruoQdnpwKlC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OG9yIruoQdnpwKlC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OG9yIruoQdnpwKlC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OG9yIruoQdnpwKlC .marker.cross{stroke:#333333;}#mermaid-svg-OG9yIruoQdnpwKlC svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OG9yIruoQdnpwKlC p{margin:0;}#mermaid-svg-OG9yIruoQdnpwKlC .pieCircle{stroke:#000000;stroke-width:2px;opacity:0.7;}#mermaid-svg-OG9yIruoQdnpwKlC .pieOuterCircle{stroke:#000000;stroke-width:1px;fill:none;}#mermaid-svg-OG9yIruoQdnpwKlC .pieTitleText{text-anchor:middle;font-size:25px;fill:#000000;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-OG9yIruoQdnpwKlC .slice{font-family:"trebuchet ms",verdana,arial,sans-serif;fill:#000000;font-size:17px;}#mermaid-svg-OG9yIruoQdnpwKlC .legend text{fill:#000000;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:17px;}#mermaid-svg-OG9yIruoQdnpwKlC :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 52% 38% 6% 4% 周成本构成(单位:万元) 输入 Token 38 输出 Token 52 缓存命中 6 工具调用 4
5.5 对账与差异处理
账单对账分为 三段对账:
- 实时对账:Ledger 与 Harness 上报事件计数对齐;
- 日终对账:与上游供应商 T+0 计费文件比对,差异阈值 0.01%;
- 月度对账:与供应商发票核对,差异生成工单并触发复核。
差异处理流程:定位差异事件 → 抓取原始上下文 → 复算单价 / 折扣 → 生成调账凭证 → 财务复核入账。
6. 核心模块详解
6.1 模块关系总览
预算体系内部以策略模式 + 领域服务组织,模块之间通过事件总线解耦:
#mermaid-svg-cGDGzsDS2Oe2eoj7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-cGDGzsDS2Oe2eoj7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .error-icon{fill:#552222;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .marker.cross{stroke:#333333;}#mermaid-svg-cGDGzsDS2Oe2eoj7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cGDGzsDS2Oe2eoj7 p{margin:0;}#mermaid-svg-cGDGzsDS2Oe2eoj7 g.classGroup text{fill:#9370DB;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-cGDGzsDS2Oe2eoj7 g.classGroup text .title{font-weight:bolder;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .cluster-label text{fill:#333;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .cluster-label span{color:#333;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .cluster-label span p{background-color:transparent;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .cluster text{fill:#333;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .cluster span{color:#333;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .nodeLabel,#mermaid-svg-cGDGzsDS2Oe2eoj7 .edgeLabel{color:#131300;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .label text{fill:#131300;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .labelBkg{background:#ECECFF;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .classTitle{font-weight:bolder;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .node rect,#mermaid-svg-cGDGzsDS2Oe2eoj7 .node circle,#mermaid-svg-cGDGzsDS2Oe2eoj7 .node ellipse,#mermaid-svg-cGDGzsDS2Oe2eoj7 .node polygon,#mermaid-svg-cGDGzsDS2Oe2eoj7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 g.clickable{cursor:pointer;}#mermaid-svg-cGDGzsDS2Oe2eoj7 g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-cGDGzsDS2Oe2eoj7 g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .dashed-line{stroke-dasharray:3;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-cGDGzsDS2Oe2eoj7 #compositionStart,#mermaid-svg-cGDGzsDS2Oe2eoj7 .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 #compositionEnd,#mermaid-svg-cGDGzsDS2Oe2eoj7 .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 #dependencyStart,#mermaid-svg-cGDGzsDS2Oe2eoj7 .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 #dependencyStart,#mermaid-svg-cGDGzsDS2Oe2eoj7 .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 #extensionStart,#mermaid-svg-cGDGzsDS2Oe2eoj7 .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 #extensionEnd,#mermaid-svg-cGDGzsDS2Oe2eoj7 .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 #aggregationStart,#mermaid-svg-cGDGzsDS2Oe2eoj7 .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 #aggregationEnd,#mermaid-svg-cGDGzsDS2Oe2eoj7 .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 #lollipopStart,#mermaid-svg-cGDGzsDS2Oe2eoj7 .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 #lollipopEnd,#mermaid-svg-cGDGzsDS2Oe2eoj7 .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-cGDGzsDS2Oe2eoj7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-cGDGzsDS2Oe2eoj7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} BudgetGuard
+check(ctx) : Result
+tryReserve(amount, ttl) : ReserveId
+commit(id, actual) : void
+release(id) : void
BudgetRepository
+load(id) : Budget
+save(b) : void
+append(id, delta) : void
PricingPolicy
<>interface
+price(event) : Cost
TieredPricing
PeakValleyPricing
ModelTierPricing
Ledger
+append(event) : void
+sumByTenant(tenantId, from, to) : Cost
AlertCenter
+evaluate(event) : void
+emit(level, ctx) : void
Reconciler
+daily() : Report
+monthly() : Report
QuotaCache
+get(tenantId) : Quota
+cas(tenantId, delta) : bool
6.2 Budget Guard 预算守卫
Budget Guard 是预算体系在请求链路上的同步拦截器,承担三项核心职责:
- 预占:根据估算 Token 在 Redis 中以原子 CAS 操作进行预占;
- 提交:推理完成后以实际 Token 提交,差额回补;
- 释放:超时未提交的预占会被 TTL 自动释放,由后台扫描任务补偿。
Budget Guard 内部维护一个"乐观预占池",使用 Lua 脚本保证原子性,避免并发请求超额放行。
6.3 Pricing Policy 计费策略
计费策略采用策略模式,主路径在事件落地时调用 PricingPolicy.price(event) 计算成本。策略可热插拔,并通过特性开关按租户启用:
- TieredPricing:基于累计 Token 分档计价;
- PeakValleyPricing:基于时间窗口的峰谷系数;
- ModelTierPricing:按模型等级差异计价;
- CompositePricing:以上策略的组合策略。
6.4 Ledger 账本引擎
Ledger 是事件流式写入的实时账本,承担三件事:写账、查账、推账。
- 写账:消费 Kafka 计费事件,按幂等键去重,写入明细表;
- 查账:提供租户 / 项目 / Agent 维度的实时余额查询(P99 ≤ 50ms);
- 推账:日终推送对账文件至数仓与财务系统。
Ledger 内部使用"窗口聚合表 + 明细冷热分离",7 天内热查询走聚合表,历史明细走 ClickHouse。
6.5 Alert Center 告警中心
Alert Center 负责事件驱动型告警评估,规则引擎基于 Drools 风格 DSL 编写,支持复合条件、滑动窗口、同比环比。
- 告警级别:Info / Warn / Critical / Fatal;
- 通知通道:IM、邮件、工单、WebHook;
- 抑制策略:相同告警 5 分钟内仅通知一次,避免告警风暴。
7. 数据模型与存储设计
7.1 ER 模型
预算体系以"预算---配额---事件---账单"为核心实体,ER 模型如下:
#mermaid-svg-SeMVV5xFwimV5k8U{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-SeMVV5xFwimV5k8U .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-SeMVV5xFwimV5k8U .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-SeMVV5xFwimV5k8U .error-icon{fill:#552222;}#mermaid-svg-SeMVV5xFwimV5k8U .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SeMVV5xFwimV5k8U .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-SeMVV5xFwimV5k8U .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SeMVV5xFwimV5k8U .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SeMVV5xFwimV5k8U .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-SeMVV5xFwimV5k8U .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SeMVV5xFwimV5k8U .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SeMVV5xFwimV5k8U .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SeMVV5xFwimV5k8U .marker.cross{stroke:#333333;}#mermaid-svg-SeMVV5xFwimV5k8U svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SeMVV5xFwimV5k8U p{margin:0;}#mermaid-svg-SeMVV5xFwimV5k8U .entityBox{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-SeMVV5xFwimV5k8U .relationshipLabelBox{fill:hsl(80, 100%, 96.2745098039%);opacity:0.7;background-color:hsl(80, 100%, 96.2745098039%);}#mermaid-svg-SeMVV5xFwimV5k8U .relationshipLabelBox rect{opacity:0.5;}#mermaid-svg-SeMVV5xFwimV5k8U .labelBkg{background-color:rgba(248.6666666666, 255, 235.9999999999, 0.5);}#mermaid-svg-SeMVV5xFwimV5k8U .edgeLabel .label{fill:#9370DB;font-size:14px;}#mermaid-svg-SeMVV5xFwimV5k8U .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-SeMVV5xFwimV5k8U .edge-pattern-dashed{stroke-dasharray:8,8;}#mermaid-svg-SeMVV5xFwimV5k8U .node rect,#mermaid-svg-SeMVV5xFwimV5k8U .node circle,#mermaid-svg-SeMVV5xFwimV5k8U .node ellipse,#mermaid-svg-SeMVV5xFwimV5k8U .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-SeMVV5xFwimV5k8U .relationshipLine{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-SeMVV5xFwimV5k8U .marker{fill:none!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-SeMVV5xFwimV5k8U .edgeLabel{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-SeMVV5xFwimV5k8U .edgeLabel .label rect{fill:rgba(232,232,232, 0.8);}#mermaid-svg-SeMVV5xFwimV5k8U .edgeLabel .label text{fill:#333;}#mermaid-svg-SeMVV5xFwimV5k8U :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} owns
contains
registers
executes
allocates
allocates
allocates
produces
snapshots
settles
belongs_to
ORGANIZATION
string
orgId
PK
string
name
decimal
monthlyCap
TENANT
string
tenantId
PK
string
orgId
FK
string
tier
decimal
monthlyBudget
PROJECT
string
projectId
PK
string
tenantId
FK
string
bizLine
AGENT
string
agentId
PK
string
projectId
FK
string
template
TASK
string
taskId
PK
string
agentId
FK
long
ts
string
status
BUDGET
string
budgetId
PK
string
scopeType
string
scopeId
decimal
amount
string
period
string
status
BILLING_EVENT
string
eventId
PK
string
taskId
FK
int
inputTokens
int
outputTokens
decimal
cost
long
ts
QUOTA_SNAPSHOT
string
snapshotId
PK
string
budgetId
FK
decimal
used
long
ts
INVOICE_LINE
string
lineId
PK
string
invoiceId
FK
string
eventId
FK
decimal
amount
INVOICE
string
invoiceId
PK
string
tenantId
FK
decimal
total
long
periodStart
long
periodEnd
7.2 存储选型
| 数据类别 | 选型 | 理由 |
|---|---|---|
| 预算元数据 | PostgreSQL | 强一致、事务、外键约束 |
| 实时配额 | Redis Cluster | 高 QPS、原子 CAS、TTL |
| 计费事件 | Kafka → ClickHouse | 高吞吐写入、列存分析友好 |
| 账单明细 | ClickHouse | 海量明细 + 多维聚合 |
| 对账文件 | 对象存储 + Parquet | 归档与下游消费 |
| 监控指标 | Prometheus + VictoriaMetrics | 时序指标标准栈 |
7.3 冷热分层
计费事件按时间分层存储:7 天内热点数据放 ClickHouse 本地盘,30 天内温数据迁移至对象存储 + Parquet,超过 1 年的冷数据压缩归档至 Glacier 类存储,按需拉回查询。
8. 多租户配额隔离
8.1 隔离模型
预算体系在多租户场景下采用 逻辑隔离 + 物理校验 双重保障:
- 逻辑隔离 :所有预算 / 配额数据以
tenantId作为分区键,查询强制走租户索引; - 物理校验:Redis 集群为高优先级租户单独划分逻辑 DB,避免 noisy neighbor 风险。
8.2 配额校验时序
Harness Quota Cache Budget Guard Tenant Context Loader API Gateway 调用方 Harness Quota Cache Budget Guard Tenant Context Loader API Gateway 调用方 #mermaid-svg-XU72PNIbDiqiGqcX{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XU72PNIbDiqiGqcX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XU72PNIbDiqiGqcX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XU72PNIbDiqiGqcX .error-icon{fill:#552222;}#mermaid-svg-XU72PNIbDiqiGqcX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XU72PNIbDiqiGqcX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XU72PNIbDiqiGqcX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XU72PNIbDiqiGqcX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XU72PNIbDiqiGqcX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XU72PNIbDiqiGqcX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XU72PNIbDiqiGqcX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XU72PNIbDiqiGqcX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XU72PNIbDiqiGqcX .marker.cross{stroke:#333333;}#mermaid-svg-XU72PNIbDiqiGqcX svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XU72PNIbDiqiGqcX p{margin:0;}#mermaid-svg-XU72PNIbDiqiGqcX .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-XU72PNIbDiqiGqcX text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-XU72PNIbDiqiGqcX .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-XU72PNIbDiqiGqcX .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-XU72PNIbDiqiGqcX .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-XU72PNIbDiqiGqcX .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-XU72PNIbDiqiGqcX #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-XU72PNIbDiqiGqcX .sequenceNumber{fill:white;}#mermaid-svg-XU72PNIbDiqiGqcX #sequencenumber{fill:#333;}#mermaid-svg-XU72PNIbDiqiGqcX #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-XU72PNIbDiqiGqcX .messageText{fill:#333;stroke:none;}#mermaid-svg-XU72PNIbDiqiGqcX .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-XU72PNIbDiqiGqcX .labelText,#mermaid-svg-XU72PNIbDiqiGqcX .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-XU72PNIbDiqiGqcX .loopText,#mermaid-svg-XU72PNIbDiqiGqcX .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-XU72PNIbDiqiGqcX .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-XU72PNIbDiqiGqcX .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-XU72PNIbDiqiGqcX .noteText,#mermaid-svg-XU72PNIbDiqiGqcX .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-XU72PNIbDiqiGqcX .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-XU72PNIbDiqiGqcX .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-XU72PNIbDiqiGqcX .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-XU72PNIbDiqiGqcX .actorPopupMenu{position:absolute;}#mermaid-svg-XU72PNIbDiqiGqcX .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-XU72PNIbDiqiGqcX .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-XU72PNIbDiqiGqcX .actor-man circle,#mermaid-svg-XU72PNIbDiqiGqcX line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-XU72PNIbDiqiGqcX :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} alt 配额充足 配额不足 请求 + apiKey 1 加载租户上下文 2 tenantCtx(配额、优先级、限流) 3 转发 + 上下文 4 读取租户实时配额 5 剩余预算 6 放行推理 7 actualTokens 8 扣减并写入事件 9 200 + 成本摘要 10 429 + 配额耗尽原因 11 写拒绝事件 12
8.3 优先级与抢占
租户被划分为不同优先级(Standard / Pro / Enterprise),在集群资源紧张时:
- Standard 租户请求会被限流甚至排队;
- Pro 租户请求保证一定吞吐下限;
- Enterprise 租户在预算充足时享有抢占权,可回收 Standard 已分配但未启动的资源。
8.4 配额变更生效
配额变更通过"延迟生效 + 灰度推送"机制落地,避免一次变更打满缓存:
- 运营在控制台提交配额调整;
- 配置中心广播变更版本号;
- 各 Budget Guard 节点拉取后 5 分钟内灰度替换;
- 替换完成前后台对账任务比对差额。
9. 监控告警机制
9.1 监控指标体系
预算体系的指标体系遵循 USE + RED 双框架:
- USE(资源层):Redis CPU / 内存 / 连接数、Kafka 堆积;
- RED(服务层):请求 Rate、错误 Error、延迟 Duration;
- 业务层:预算使用率、熔断次数、对账差异率、单租户 P99 成本。
9.2 告警决策流
#mermaid-svg-MvNAuLnIUCzLhjhx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MvNAuLnIUCzLhjhx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MvNAuLnIUCzLhjhx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MvNAuLnIUCzLhjhx .error-icon{fill:#552222;}#mermaid-svg-MvNAuLnIUCzLhjhx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MvNAuLnIUCzLhjhx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MvNAuLnIUCzLhjhx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MvNAuLnIUCzLhjhx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MvNAuLnIUCzLhjhx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MvNAuLnIUCzLhjhx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MvNAuLnIUCzLhjhx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MvNAuLnIUCzLhjhx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MvNAuLnIUCzLhjhx .marker.cross{stroke:#333333;}#mermaid-svg-MvNAuLnIUCzLhjhx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MvNAuLnIUCzLhjhx p{margin:0;}#mermaid-svg-MvNAuLnIUCzLhjhx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MvNAuLnIUCzLhjhx .cluster-label text{fill:#333;}#mermaid-svg-MvNAuLnIUCzLhjhx .cluster-label span{color:#333;}#mermaid-svg-MvNAuLnIUCzLhjhx .cluster-label span p{background-color:transparent;}#mermaid-svg-MvNAuLnIUCzLhjhx .label text,#mermaid-svg-MvNAuLnIUCzLhjhx span{fill:#333;color:#333;}#mermaid-svg-MvNAuLnIUCzLhjhx .node rect,#mermaid-svg-MvNAuLnIUCzLhjhx .node circle,#mermaid-svg-MvNAuLnIUCzLhjhx .node ellipse,#mermaid-svg-MvNAuLnIUCzLhjhx .node polygon,#mermaid-svg-MvNAuLnIUCzLhjhx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MvNAuLnIUCzLhjhx .rough-node .label text,#mermaid-svg-MvNAuLnIUCzLhjhx .node .label text,#mermaid-svg-MvNAuLnIUCzLhjhx .image-shape .label,#mermaid-svg-MvNAuLnIUCzLhjhx .icon-shape .label{text-anchor:middle;}#mermaid-svg-MvNAuLnIUCzLhjhx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MvNAuLnIUCzLhjhx .rough-node .label,#mermaid-svg-MvNAuLnIUCzLhjhx .node .label,#mermaid-svg-MvNAuLnIUCzLhjhx .image-shape .label,#mermaid-svg-MvNAuLnIUCzLhjhx .icon-shape .label{text-align:center;}#mermaid-svg-MvNAuLnIUCzLhjhx .node.clickable{cursor:pointer;}#mermaid-svg-MvNAuLnIUCzLhjhx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MvNAuLnIUCzLhjhx .arrowheadPath{fill:#333333;}#mermaid-svg-MvNAuLnIUCzLhjhx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MvNAuLnIUCzLhjhx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MvNAuLnIUCzLhjhx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MvNAuLnIUCzLhjhx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MvNAuLnIUCzLhjhx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MvNAuLnIUCzLhjhx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MvNAuLnIUCzLhjhx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MvNAuLnIUCzLhjhx .cluster text{fill:#333;}#mermaid-svg-MvNAuLnIUCzLhjhx .cluster span{color:#333;}#mermaid-svg-MvNAuLnIUCzLhjhx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MvNAuLnIUCzLhjhx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MvNAuLnIUCzLhjhx rect.text{fill:none;stroke-width:0;}#mermaid-svg-MvNAuLnIUCzLhjhx .icon-shape,#mermaid-svg-MvNAuLnIUCzLhjhx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MvNAuLnIUCzLhjhx .icon-shape p,#mermaid-svg-MvNAuLnIUCzLhjhx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MvNAuLnIUCzLhjhx .icon-shape .label rect,#mermaid-svg-MvNAuLnIUCzLhjhx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MvNAuLnIUCzLhjhx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MvNAuLnIUCzLhjhx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MvNAuLnIUCzLhjhx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 预算 80%
预算 95%
预算 100%
异常暴涨 3x
对账差异 > 0.01%
是
否
计费 / 拒绝事件
规则引擎评估
Warn 告警
Critical 告警
Fatal + 熔断
异常告警
差异告警
抑制窗口命中?
抑制丢弃
多通道路播
值班 IM
邮件
工单
WebHook
9.3 告警分级与响应
| 级别 | 触发示例 | 响应 SLA | 处置动作 |
|---|---|---|---|
| Warn | 单 Agent 日预算 80% | 4 小时 | 关注,无需立即介入 |
| Critical | 租户月预算 95% | 30 分钟 | 值班介入、调整策略 |
| Fatal | 租户月预算 100% | 5 分钟 | 自动熔断、追加工单 |
| Anomaly | 同比环比异常 | 1 小时 | 安全与财务联动排查 |
9.4 用户使用旅程
通过用户体验旅程梳理租户从接入到对账的端到端感受:
#mermaid-svg-ilsQbwFW6pZXOWCz{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ilsQbwFW6pZXOWCz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ilsQbwFW6pZXOWCz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ilsQbwFW6pZXOWCz .error-icon{fill:#552222;}#mermaid-svg-ilsQbwFW6pZXOWCz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ilsQbwFW6pZXOWCz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ilsQbwFW6pZXOWCz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ilsQbwFW6pZXOWCz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ilsQbwFW6pZXOWCz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ilsQbwFW6pZXOWCz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ilsQbwFW6pZXOWCz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ilsQbwFW6pZXOWCz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ilsQbwFW6pZXOWCz .marker.cross{stroke:#333333;}#mermaid-svg-ilsQbwFW6pZXOWCz svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ilsQbwFW6pZXOWCz p{margin:0;}#mermaid-svg-ilsQbwFW6pZXOWCz .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ilsQbwFW6pZXOWCz .mouth{stroke:#666;}#mermaid-svg-ilsQbwFW6pZXOWCz line{stroke:#333;}#mermaid-svg-ilsQbwFW6pZXOWCz .legend{fill:#333;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-ilsQbwFW6pZXOWCz .label text{fill:#333;}#mermaid-svg-ilsQbwFW6pZXOWCz .label{color:#333;}#mermaid-svg-ilsQbwFW6pZXOWCz .face{fill:#FFF8DC;stroke:#999;}#mermaid-svg-ilsQbwFW6pZXOWCz .node rect,#mermaid-svg-ilsQbwFW6pZXOWCz .node circle,#mermaid-svg-ilsQbwFW6pZXOWCz .node ellipse,#mermaid-svg-ilsQbwFW6pZXOWCz .node polygon,#mermaid-svg-ilsQbwFW6pZXOWCz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ilsQbwFW6pZXOWCz .node .label{text-align:center;}#mermaid-svg-ilsQbwFW6pZXOWCz .node.clickable{cursor:pointer;}#mermaid-svg-ilsQbwFW6pZXOWCz .arrowheadPath{fill:#333333;}#mermaid-svg-ilsQbwFW6pZXOWCz .edgePath .path{stroke:#333333;stroke-width:1.5px;}#mermaid-svg-ilsQbwFW6pZXOWCz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ilsQbwFW6pZXOWCz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ilsQbwFW6pZXOWCz .edgeLabel rect{opacity:0.5;}#mermaid-svg-ilsQbwFW6pZXOWCz .cluster text{fill:#333;}#mermaid-svg-ilsQbwFW6pZXOWCz div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ilsQbwFW6pZXOWCz .task-type-0,#mermaid-svg-ilsQbwFW6pZXOWCz .section-type-0{fill:#ECECFF;}#mermaid-svg-ilsQbwFW6pZXOWCz .task-type-1,#mermaid-svg-ilsQbwFW6pZXOWCz .section-type-1{fill:#ffffde;}#mermaid-svg-ilsQbwFW6pZXOWCz .task-type-2,#mermaid-svg-ilsQbwFW6pZXOWCz .section-type-2{fill:hsl(304, 100%, 96.2745098039%);}#mermaid-svg-ilsQbwFW6pZXOWCz .task-type-3,#mermaid-svg-ilsQbwFW6pZXOWCz .section-type-3{fill:hsl(124, 100%, 93.5294117647%);}#mermaid-svg-ilsQbwFW6pZXOWCz .task-type-4,#mermaid-svg-ilsQbwFW6pZXOWCz .section-type-4{fill:hsl(176, 100%, 96.2745098039%);}#mermaid-svg-ilsQbwFW6pZXOWCz .task-type-5,#mermaid-svg-ilsQbwFW6pZXOWCz .section-type-5{fill:hsl(-4, 100%, 93.5294117647%);}#mermaid-svg-ilsQbwFW6pZXOWCz .task-type-6,#mermaid-svg-ilsQbwFW6pZXOWCz .section-type-6{fill:hsl(8, 100%, 96.2745098039%);}#mermaid-svg-ilsQbwFW6pZXOWCz .task-type-7,#mermaid-svg-ilsQbwFW6pZXOWCz .section-type-7{fill:hsl(188, 100%, 93.5294117647%);}#mermaid-svg-ilsQbwFW6pZXOWCz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ilsQbwFW6pZXOWCz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ilsQbwFW6pZXOWCz :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 业务方 平台运营 财务 接入 接入 平台运营 申请租户 申请租户 平台运营 颁发 apiKey 颁发 apiKey 业务方 首次调用 首次调用 日常使用 日常使用 业务方 查看实时成本 查看实时成本 业务方 调整预算 调整预算 业务方 收到告警 收到告警 业务方 追加预算 追加预算 月末对账 月末对账 平台运营 账单生成 账单生成 财务 财务复核 财务复核 财务 差异调账 差异调账 业务方 下月预算规划 下月预算规划 租户 Token 成本管理旅程
10. 高可用与容灾
10.1 高可用拓扑
预算体系以"同城双活 + 异地灾备"为标准部署形态:
#mermaid-svg-uDPJT2N03n8IPFaE{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-uDPJT2N03n8IPFaE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-uDPJT2N03n8IPFaE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-uDPJT2N03n8IPFaE .error-icon{fill:#552222;}#mermaid-svg-uDPJT2N03n8IPFaE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-uDPJT2N03n8IPFaE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-uDPJT2N03n8IPFaE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-uDPJT2N03n8IPFaE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-uDPJT2N03n8IPFaE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-uDPJT2N03n8IPFaE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-uDPJT2N03n8IPFaE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-uDPJT2N03n8IPFaE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-uDPJT2N03n8IPFaE .marker.cross{stroke:#333333;}#mermaid-svg-uDPJT2N03n8IPFaE svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-uDPJT2N03n8IPFaE p{margin:0;}#mermaid-svg-uDPJT2N03n8IPFaE .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-uDPJT2N03n8IPFaE .cluster-label text{fill:#333;}#mermaid-svg-uDPJT2N03n8IPFaE .cluster-label span{color:#333;}#mermaid-svg-uDPJT2N03n8IPFaE .cluster-label span p{background-color:transparent;}#mermaid-svg-uDPJT2N03n8IPFaE .label text,#mermaid-svg-uDPJT2N03n8IPFaE span{fill:#333;color:#333;}#mermaid-svg-uDPJT2N03n8IPFaE .node rect,#mermaid-svg-uDPJT2N03n8IPFaE .node circle,#mermaid-svg-uDPJT2N03n8IPFaE .node ellipse,#mermaid-svg-uDPJT2N03n8IPFaE .node polygon,#mermaid-svg-uDPJT2N03n8IPFaE .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-uDPJT2N03n8IPFaE .rough-node .label text,#mermaid-svg-uDPJT2N03n8IPFaE .node .label text,#mermaid-svg-uDPJT2N03n8IPFaE .image-shape .label,#mermaid-svg-uDPJT2N03n8IPFaE .icon-shape .label{text-anchor:middle;}#mermaid-svg-uDPJT2N03n8IPFaE .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-uDPJT2N03n8IPFaE .rough-node .label,#mermaid-svg-uDPJT2N03n8IPFaE .node .label,#mermaid-svg-uDPJT2N03n8IPFaE .image-shape .label,#mermaid-svg-uDPJT2N03n8IPFaE .icon-shape .label{text-align:center;}#mermaid-svg-uDPJT2N03n8IPFaE .node.clickable{cursor:pointer;}#mermaid-svg-uDPJT2N03n8IPFaE .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-uDPJT2N03n8IPFaE .arrowheadPath{fill:#333333;}#mermaid-svg-uDPJT2N03n8IPFaE .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-uDPJT2N03n8IPFaE .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-uDPJT2N03n8IPFaE .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-uDPJT2N03n8IPFaE .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-uDPJT2N03n8IPFaE .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-uDPJT2N03n8IPFaE .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-uDPJT2N03n8IPFaE .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-uDPJT2N03n8IPFaE .cluster text{fill:#333;}#mermaid-svg-uDPJT2N03n8IPFaE .cluster span{color:#333;}#mermaid-svg-uDPJT2N03n8IPFaE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-uDPJT2N03n8IPFaE .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-uDPJT2N03n8IPFaE rect.text{fill:none;stroke-width:0;}#mermaid-svg-uDPJT2N03n8IPFaE .icon-shape,#mermaid-svg-uDPJT2N03n8IPFaE .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-uDPJT2N03n8IPFaE .icon-shape p,#mermaid-svg-uDPJT2N03n8IPFaE .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-uDPJT2N03n8IPFaE .icon-shape .label rect,#mermaid-svg-uDPJT2N03n8IPFaE .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-uDPJT2N03n8IPFaE .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-uDPJT2N03n8IPFaE .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-uDPJT2N03n8IPFaE :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Region B 灾备
Region A 主活
可用区 2
可用区 1
跨 AZ 同步
逻辑复制
Budget Guard
Ledger
Budget Guard
Ledger
Redis 主从
PostgreSQL 主从
Budget Guard
Ledger
Redis 异步副本
PostgreSQL 异步副本
10.2 故障降级策略
预算体系自身故障时按"分级降级"原则处理:
| 故障 | 降级策略 | 影响范围 |
|---|---|---|
| Redis 不可用 | 切本地配额快照硬熔断 | 实时精度下降 |
| Kafka 写失败 | 同步双写 PG,重试补偿 | 时延略升 |
| ClickHouse 写失败 | 写本地文件,T+1 补录 | 报表延迟 |
| Harness 无响应 | 视为失败,释放预占 | 业务可见错误 |
10.3 数据一致性保障
- 幂等键 :每条计费事件以
eventId唯一约束,重复消费直接丢弃; - CAS 扣减:Redis 配额使用 Lua CAS,保证原子;
- WAL + CQRS:写路径与读路径分离,写走事件流,读走聚合表;
- 校验任务:每 10 分钟跑一次"账本---配额"对账,差异自动告警。
11. 性能优化策略
11.1 关键路径优化
预算校验位于请求主链路,对时延极其敏感。优化手段包括:
- 本地缓存:租户上下文在 Gateway 本地缓存 30 秒,避免每次回查;
- 批量化:批量推理请求合并预占,减少 Redis 往返;
- Pipeline:Redis 使用 pipeline 提交多个 CAS;
- Lua 内嵌:预占 + 校验合并为一段 Lua 脚本,单次 RTT;
- 熔断短路:预算已耗尽时直接返回,无需查询。
11.2 异步链路优化
- 批写:事件以 1ms / 1000 条为批次写 Kafka;
- 背压控制:消费侧使用 reactive 拉模式,避免堆积;
- 冷热分离:明细落 ClickHouse 异步执行,不阻塞写账;
- 聚合预计算:日 / 周 / 月汇总表通过物化视图预聚合。
11.3 容量评估
以 5 亿条 / 日计费事件为基线,容量规划如下:
| 组件 | 资源 | 峰值 QPS | 利用率目标 |
|---|---|---|---|
| Budget Guard | 32C / 64G × 16 节点 | 60k | 60% |
| Redis Cluster | 32 分片 | 120k | 70% |
| Kafka | 24 分区 | 80k | 65% |
| ClickHouse | 8 节点 | 写 30k 行 / 秒 | 50% |
12. 安全与合规
12.1 访问控制
预算体系所有接口均接入平台统一鉴权,使用 RBAC + ABAC 混合模型:
- RBAC:财务、运营、SRE、业务方四类基础角色;
- ABAC:基于租户、项目、Agent 的属性策略;
- 审计:所有变更类操作记录"谁---何时---何变更---为何"四要素,留存 1 年。
12.2 数据安全
- 计费事件中的 prompt / completion 内容默认不落明细,仅保留 hash 用于追溯;
- 跨域传输使用 TLS 1.3 + 双向证书;
- 对账文件加密落对象存储,KMS 托管密钥;
- 测试与生产数据严格隔离,禁止使用生产真实账单数据回归。
12.3 合规与发票
- 发票口径与供应商计费周期对齐,避免跨期;
- 多币种采用当日汇率折算,月末调整;
- 跨境业务按所在国税法申报,预留税务字段;
- 数据留存满足等保三级 / GDPR 要求。
13. 部署与运维
13.1 部署拓扑
预算体系以容器化 + Helm 编排部署于 K8s,分三命名空间:budget-prod、budget-stage、budget-dr。核心组件以 Deployment + HPA + PDB 形式运行。
13.2 版本演进路线
13.3 实施甘特图
预算体系 v1.0 的关键里程碑以甘特图呈现:
#mermaid-svg-6wjkYBDg9Au0oU4I{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-6wjkYBDg9Au0oU4I .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6wjkYBDg9Au0oU4I .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6wjkYBDg9Au0oU4I .error-icon{fill:#552222;}#mermaid-svg-6wjkYBDg9Au0oU4I .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6wjkYBDg9Au0oU4I .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6wjkYBDg9Au0oU4I .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6wjkYBDg9Au0oU4I .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6wjkYBDg9Au0oU4I .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6wjkYBDg9Au0oU4I .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6wjkYBDg9Au0oU4I .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6wjkYBDg9Au0oU4I .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6wjkYBDg9Au0oU4I .marker.cross{stroke:#333333;}#mermaid-svg-6wjkYBDg9Au0oU4I svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6wjkYBDg9Au0oU4I p{margin:0;}#mermaid-svg-6wjkYBDg9Au0oU4I .mermaid-main-font{font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-6wjkYBDg9Au0oU4I .exclude-range{fill:#eeeeee;}#mermaid-svg-6wjkYBDg9Au0oU4I .section{stroke:none;opacity:0.2;}#mermaid-svg-6wjkYBDg9Au0oU4I .section0{fill:rgba(102, 102, 255, 0.49);}#mermaid-svg-6wjkYBDg9Au0oU4I .section2{fill:#fff400;}#mermaid-svg-6wjkYBDg9Au0oU4I .section1,#mermaid-svg-6wjkYBDg9Au0oU4I .section3{fill:white;opacity:0.2;}#mermaid-svg-6wjkYBDg9Au0oU4I .sectionTitle0{fill:#333;}#mermaid-svg-6wjkYBDg9Au0oU4I .sectionTitle1{fill:#333;}#mermaid-svg-6wjkYBDg9Au0oU4I .sectionTitle2{fill:#333;}#mermaid-svg-6wjkYBDg9Au0oU4I .sectionTitle3{fill:#333;}#mermaid-svg-6wjkYBDg9Au0oU4I .sectionTitle{text-anchor:start;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-6wjkYBDg9Au0oU4I .grid .tick{stroke:lightgrey;opacity:0.8;shape-rendering:crispEdges;}#mermaid-svg-6wjkYBDg9Au0oU4I .grid .tick text{font-family:"trebuchet ms",verdana,arial,sans-serif;fill:#333;}#mermaid-svg-6wjkYBDg9Au0oU4I .grid path{stroke-width:0;}#mermaid-svg-6wjkYBDg9Au0oU4I .today{fill:none;stroke:red;stroke-width:2px;}#mermaid-svg-6wjkYBDg9Au0oU4I .task{stroke-width:2;}#mermaid-svg-6wjkYBDg9Au0oU4I .taskText{text-anchor:middle;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-6wjkYBDg9Au0oU4I .taskTextOutsideRight{fill:black;text-anchor:start;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-6wjkYBDg9Au0oU4I .taskTextOutsideLeft{fill:black;text-anchor:end;}#mermaid-svg-6wjkYBDg9Au0oU4I .task.clickable{cursor:pointer;}#mermaid-svg-6wjkYBDg9Au0oU4I .taskText.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-6wjkYBDg9Au0oU4I .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-6wjkYBDg9Au0oU4I .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-6wjkYBDg9Au0oU4I .taskText0,#mermaid-svg-6wjkYBDg9Au0oU4I .taskText1,#mermaid-svg-6wjkYBDg9Au0oU4I .taskText2,#mermaid-svg-6wjkYBDg9Au0oU4I .taskText3{fill:white;}#mermaid-svg-6wjkYBDg9Au0oU4I .task0,#mermaid-svg-6wjkYBDg9Au0oU4I .task1,#mermaid-svg-6wjkYBDg9Au0oU4I .task2,#mermaid-svg-6wjkYBDg9Au0oU4I .task3{fill:#8a90dd;stroke:#534fbc;}#mermaid-svg-6wjkYBDg9Au0oU4I .taskTextOutside0,#mermaid-svg-6wjkYBDg9Au0oU4I .taskTextOutside2{fill:black;}#mermaid-svg-6wjkYBDg9Au0oU4I .taskTextOutside1,#mermaid-svg-6wjkYBDg9Au0oU4I .taskTextOutside3{fill:black;}#mermaid-svg-6wjkYBDg9Au0oU4I .active0,#mermaid-svg-6wjkYBDg9Au0oU4I .active1,#mermaid-svg-6wjkYBDg9Au0oU4I .active2,#mermaid-svg-6wjkYBDg9Au0oU4I .active3{fill:#bfc7ff;stroke:#534fbc;}#mermaid-svg-6wjkYBDg9Au0oU4I .activeText0,#mermaid-svg-6wjkYBDg9Au0oU4I .activeText1,#mermaid-svg-6wjkYBDg9Au0oU4I .activeText2,#mermaid-svg-6wjkYBDg9Au0oU4I .activeText3{fill:black!important;}#mermaid-svg-6wjkYBDg9Au0oU4I .done0,#mermaid-svg-6wjkYBDg9Au0oU4I .done1,#mermaid-svg-6wjkYBDg9Au0oU4I .done2,#mermaid-svg-6wjkYBDg9Au0oU4I .done3{stroke:grey;fill:lightgrey;stroke-width:2;}#mermaid-svg-6wjkYBDg9Au0oU4I .doneText0,#mermaid-svg-6wjkYBDg9Au0oU4I .doneText1,#mermaid-svg-6wjkYBDg9Au0oU4I .doneText2,#mermaid-svg-6wjkYBDg9Au0oU4I .doneText3{fill:black!important;}#mermaid-svg-6wjkYBDg9Au0oU4I .doneText0.taskTextOutsideLeft,#mermaid-svg-6wjkYBDg9Au0oU4I .doneText0.taskTextOutsideRight,#mermaid-svg-6wjkYBDg9Au0oU4I .doneText1.taskTextOutsideLeft,#mermaid-svg-6wjkYBDg9Au0oU4I .doneText1.taskTextOutsideRight,#mermaid-svg-6wjkYBDg9Au0oU4I .doneText2.taskTextOutsideLeft,#mermaid-svg-6wjkYBDg9Au0oU4I .doneText2.taskTextOutsideRight,#mermaid-svg-6wjkYBDg9Au0oU4I .doneText3.taskTextOutsideLeft,#mermaid-svg-6wjkYBDg9Au0oU4I .doneText3.taskTextOutsideRight{fill:black!important;}#mermaid-svg-6wjkYBDg9Au0oU4I .crit0,#mermaid-svg-6wjkYBDg9Au0oU4I .crit1,#mermaid-svg-6wjkYBDg9Au0oU4I .crit2,#mermaid-svg-6wjkYBDg9Au0oU4I .crit3{stroke:#ff8888;fill:red;stroke-width:2;}#mermaid-svg-6wjkYBDg9Au0oU4I .activeCrit0,#mermaid-svg-6wjkYBDg9Au0oU4I .activeCrit1,#mermaid-svg-6wjkYBDg9Au0oU4I .activeCrit2,#mermaid-svg-6wjkYBDg9Au0oU4I .activeCrit3{stroke:#ff8888;fill:#bfc7ff;stroke-width:2;}#mermaid-svg-6wjkYBDg9Au0oU4I .doneCrit0,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCrit1,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCrit2,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCrit3{stroke:#ff8888;fill:lightgrey;stroke-width:2;cursor:pointer;shape-rendering:crispEdges;}#mermaid-svg-6wjkYBDg9Au0oU4I .milestone{transform:rotate(45deg) scale(0.8,0.8);}#mermaid-svg-6wjkYBDg9Au0oU4I .milestoneText{font-style:italic;}#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText0,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText1,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText2,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText3{fill:black!important;}#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText0.taskTextOutsideLeft,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText0.taskTextOutsideRight,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText1.taskTextOutsideLeft,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText1.taskTextOutsideRight,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText2.taskTextOutsideLeft,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText2.taskTextOutsideRight,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText3.taskTextOutsideLeft,#mermaid-svg-6wjkYBDg9Au0oU4I .doneCritText3.taskTextOutsideRight{fill:black!important;}#mermaid-svg-6wjkYBDg9Au0oU4I .vert{stroke:navy;}#mermaid-svg-6wjkYBDg9Au0oU4I .vertText{font-size:15px;text-anchor:middle;fill:navy!important;}#mermaid-svg-6wjkYBDg9Au0oU4I .activeCritText0,#mermaid-svg-6wjkYBDg9Au0oU4I .activeCritText1,#mermaid-svg-6wjkYBDg9Au0oU4I .activeCritText2,#mermaid-svg-6wjkYBDg9Au0oU4I .activeCritText3{fill:black!important;}#mermaid-svg-6wjkYBDg9Au0oU4I .titleText{text-anchor:middle;font-size:18px;fill:#333;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-6wjkYBDg9Au0oU4I :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 2026-03-01 2026-03-08 2026-03-15 2026-03-22 2026-03-29 2026-04-05 2026-04-12 2026-04-19 2026-04-26 2026-05-03 2026-05-10 2026-05-17 2026-05-24 2026-05-31 2026-06-07 架构设计 数据模型 Budget Guard Ledger Alert Center Reconciler 集成测试 压测 灰度发布 全量上线 对账试运行 设计 研发 联调 上线 预算体系 v1.0 实施计划
13.4 运维巡检
SRE 团队每日执行巡检清单:
- 检查 Redis 主从延迟、配额一致性;
- 检查 Kafka 消费滞后、死信队列;
- 检查 ClickHouse 写入成功率;
- 检查告警中心最近 24h 抑制次数与误报率;
- 检查对账差异工单闭环情况。
13.5 应急预案
针对预算体系故障,制定了三类标准应急预案:
- P0:预算校验整体不可用 → 全局切本地配额快照硬熔断,1 分钟内生效;
- P1:实时账本延迟显著 → 异步链路切换至 PG 同步双写,关键看板降级;
- P2:对账差异超阈值 → 自动暂停月度账单生成,触发人工复核。
14. 总结与展望
14.1 当前能力小结
Agent Plan × DeepSeek Harness 的 Token 预算管理与成本追踪体系 v1.0 已实现以下能力:
- 预算先行:五级预算继承式管理,预占---提交---释放三段式校验;
- 实时计费:毫秒级预算校验、亿级事件落地;
- 多维归因:组织---租户---项目---Agent---任务全链路成本归因;
- 闭环治理:告警---对账---调账---发票的全流程自动化;
- 高可用:同城双活 + 异地灾备,故障分级降级。
14.2 能力脑图
以下脑图直观展示预算体系的整体能力域:
#mermaid-svg-yZc9agVf8AgrQrVF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yZc9agVf8AgrQrVF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yZc9agVf8AgrQrVF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yZc9agVf8AgrQrVF .error-icon{fill:#552222;}#mermaid-svg-yZc9agVf8AgrQrVF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yZc9agVf8AgrQrVF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yZc9agVf8AgrQrVF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yZc9agVf8AgrQrVF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yZc9agVf8AgrQrVF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yZc9agVf8AgrQrVF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yZc9agVf8AgrQrVF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yZc9agVf8AgrQrVF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yZc9agVf8AgrQrVF .marker.cross{stroke:#333333;}#mermaid-svg-yZc9agVf8AgrQrVF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yZc9agVf8AgrQrVF p{margin:0;}#mermaid-svg-yZc9agVf8AgrQrVF .edge{stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .section--1 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section--1 path,#mermaid-svg-yZc9agVf8AgrQrVF .section--1 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section--1 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section--1 text{fill:#ffffff;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth--1{stroke-width:17;}#mermaid-svg-yZc9agVf8AgrQrVF .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-0 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-0 path,#mermaid-svg-yZc9agVf8AgrQrVF .section-0 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-0 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-0 text{fill:black;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon-0{font-size:40px;color:black;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth-0{stroke-width:14;}#mermaid-svg-yZc9agVf8AgrQrVF .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-1 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-1 path,#mermaid-svg-yZc9agVf8AgrQrVF .section-1 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-1 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-1 text{fill:black;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon-1{font-size:40px;color:black;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth-1{stroke-width:11;}#mermaid-svg-yZc9agVf8AgrQrVF .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-2 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-2 path,#mermaid-svg-yZc9agVf8AgrQrVF .section-2 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-2 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-2 text{fill:#ffffff;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth-2{stroke-width:8;}#mermaid-svg-yZc9agVf8AgrQrVF .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-3 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-3 path,#mermaid-svg-yZc9agVf8AgrQrVF .section-3 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-3 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-3 text{fill:black;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon-3{font-size:40px;color:black;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth-3{stroke-width:5;}#mermaid-svg-yZc9agVf8AgrQrVF .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-4 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-4 path,#mermaid-svg-yZc9agVf8AgrQrVF .section-4 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-4 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-4 text{fill:black;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon-4{font-size:40px;color:black;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth-4{stroke-width:2;}#mermaid-svg-yZc9agVf8AgrQrVF .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-5 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-5 path,#mermaid-svg-yZc9agVf8AgrQrVF .section-5 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-5 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-5 text{fill:black;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon-5{font-size:40px;color:black;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth-5{stroke-width:-1;}#mermaid-svg-yZc9agVf8AgrQrVF .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-6 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-6 path,#mermaid-svg-yZc9agVf8AgrQrVF .section-6 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-6 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-6 text{fill:black;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon-6{font-size:40px;color:black;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth-6{stroke-width:-4;}#mermaid-svg-yZc9agVf8AgrQrVF .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-7 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-7 path,#mermaid-svg-yZc9agVf8AgrQrVF .section-7 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-7 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-7 text{fill:black;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon-7{font-size:40px;color:black;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth-7{stroke-width:-7;}#mermaid-svg-yZc9agVf8AgrQrVF .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-8 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-8 path,#mermaid-svg-yZc9agVf8AgrQrVF .section-8 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-8 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-8 text{fill:black;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon-8{font-size:40px;color:black;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth-8{stroke-width:-10;}#mermaid-svg-yZc9agVf8AgrQrVF .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-9 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-9 path,#mermaid-svg-yZc9agVf8AgrQrVF .section-9 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-9 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-9 text{fill:black;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon-9{font-size:40px;color:black;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth-9{stroke-width:-13;}#mermaid-svg-yZc9agVf8AgrQrVF .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-10 rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-10 path,#mermaid-svg-yZc9agVf8AgrQrVF .section-10 circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-10 polygon,#mermaid-svg-yZc9agVf8AgrQrVF .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-10 text{fill:black;}#mermaid-svg-yZc9agVf8AgrQrVF .node-icon-10{font-size:40px;color:black;}#mermaid-svg-yZc9agVf8AgrQrVF .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .edge-depth-10{stroke-width:-16;}#mermaid-svg-yZc9agVf8AgrQrVF .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled,#mermaid-svg-yZc9agVf8AgrQrVF .disabled circle,#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:lightgray;}#mermaid-svg-yZc9agVf8AgrQrVF .disabled text{fill:#efefef;}#mermaid-svg-yZc9agVf8AgrQrVF .section-root rect,#mermaid-svg-yZc9agVf8AgrQrVF .section-root path,#mermaid-svg-yZc9agVf8AgrQrVF .section-root circle,#mermaid-svg-yZc9agVf8AgrQrVF .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-yZc9agVf8AgrQrVF .section-root text{fill:#ffffff;}#mermaid-svg-yZc9agVf8AgrQrVF .section-root span{color:#ffffff;}#mermaid-svg-yZc9agVf8AgrQrVF .section-2 span{color:#ffffff;}#mermaid-svg-yZc9agVf8AgrQrVF .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-yZc9agVf8AgrQrVF .edge{fill:none;}#mermaid-svg-yZc9agVf8AgrQrVF .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-yZc9agVf8AgrQrVF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Token 预算与成本追踪
预算管理
五级继承
状态机
预占提交释放
借调追加回收
成本追踪
计费事件
多维归因
双写一致性
三段对账
多租户隔离
逻辑物理双隔离
优先级抢占
灰度生效
监控告警
USE/RED 指标
规则引擎
多通道路播
抑制策略
高可用容灾
同城双活
异地灾备
分级降级
WAL+CQRS
安全合规
RBAC+ABAC
KMS 加密
发票口径
等保三级
性能优化
本地缓存
批量化
Lua 内嵌
物化视图
14.3 路线图
未来三个版本的能力规划:
- v1.1 预算智能预测:基于历史时序预测租户月度成本,自动给出预算建议;
- v1.2 成本归因图谱:将成本归因从关系模型升级为图模型,支撑任意路径切片;
- v1.3 多云多供应商:接入 Anthropic、OpenAI、Qwen 等多供应商,统一计费与对账。
14.4 结语
Token 已是大模型时代的"新型算力货币",预算管理与成本追踪体系不仅是工程能力,更是商业可持续的基石。Agent Plan × DeepSeek Harness 将持续以"可观测、可治理、可演进"为原则打磨预算体系,让每一份 Token 都花得清楚、花得值、花得稳。
附录 A:关键 SLA 一览
| 维度 | SLA |
|---|---|
| Budget Guard 校验 P99 | ≤ 5ms |
| 计费事件落地延迟 P99 | ≤ 200ms |
| 单日计费事件吞吐 | ≥ 5 亿 |
| 熔断生效 P99 | ≤ 100ms |
| 对账误差率 | ≤ 0.01% |
| 告警通知延迟 | ≤ 30s |
| 系统整体可用性 | 99.95% |
附录 B:常用监控 PromQL 示例
promql
# 5 分钟内预算使用率
sum by (tenant_id) (
rate(budget_used_tokens[5m])
)
/
sum by (tenant_id) (budget_total_tokens)
# 熔断次数
sum by (tenant_id, reason) (
increase(budget_rejected_total[5m])
)
# 计费事件落地延迟 P99
histogram_quantile(0.99,
sum by (le) (rate(billing_event_lag_seconds_bucket[5m]))
)
附录 C:术语缩写速查
| 缩写 | 全称 |
|---|---|
| BGT | Budget Guard |
| LGR | Ledger |
| ALT | Alert Center |
| REC | Reconciler |
| CAS | Compare And Swap |
| COGS | Cost of Goods Sold |
| CQRS | Command Query Responsibility Segregation |
| WAL | Write Ahead Log |
| RBAC | Role-Based Access Control |
| ABAC | Attribute-Based Access Control |
文档结束。如需获取最新版本或反馈建议,请联系平台架构组。