Agent 成本观测体系:Token、任务粒度、模型路由与预算告警
AI Agent 的成本不是单纯的模型单价问题,而是任务粒度、上下文大小、重试次数、工具调用、模型选择和人工干预共同作用的结果。本文设计一套可落地的成本观测体系,让团队知道钱花在哪里、为什么花、怎么优化。
一、成本为什么会失控
常见失控原因有 5 类:
| 原因 | 表现 | 解决方向 |
|---|---|---|
| 上下文过大 | 每次任务都塞整个仓库 | 上下文包分层和裁剪 |
| 模型过强 | 小任务也用最高级模型 | 按任务路由模型 |
| 重试无边界 | 失败后不断自动重试 | 设置重试次数和停止条件 |
| 验证不足 | Agent 改错后反复补救 | 提前定义验收和测试 |
| 缺少归因 | 只知道总账单,不知道任务成本 | 建立 usage event |
二、成本事件模型
每次模型调用、工具调用、重试和验证都应该形成成本事件。
CREATE TABLE agent_usage_events (
id BIGSERIAL PRIMARY KEY,
task_id TEXT NOT NULL,
project_key TEXT NOT NULL,
user_id TEXT NOT NULL,
model TEXT NOT NULL,
phase TEXT NOT NULL,
input_tokens INTEGER NOT NULL DEFAULT 0,
output_tokens INTEGER NOT NULL DEFAULT 0,
cached_tokens INTEGER NOT NULL DEFAULT 0,
tool_calls INTEGER NOT NULL DEFAULT 0,
retry_index INTEGER NOT NULL DEFAULT 0,
latency_ms INTEGER NOT NULL DEFAULT 0,
cost_usd NUMERIC(12, 6) NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_usage_project_time ON agent_usage_events(project_key, created_at);
CREATE INDEX idx_usage_task ON agent_usage_events(task_id);字段说明
| 字段 | 说明 |
|---|---|
phase |
planning、execution、verification、review |
cached_tokens |
被缓存命中的上下文 Token,用于评估缓存收益 |
tool_calls |
当前模型调用触发的工具调用数量 |
retry_index |
第几次重试,0 表示首次 |
cost_usd |
按模型价格计算出的成本 |
三、模型路由策略
模型路由不是为了永远选便宜模型,而是让任务匹配合适模型。
model_routing:
default_model: "gpt-4.1-mini"
rules:
- name: "simple_question"
when:
task_type: ["explain", "summarize"]
risk_level: "low"
estimated_files_lte: 3
use_model: "gpt-4.1-mini"
max_budget_usd: 0.05
- name: "code_patch_medium"
when:
task_type: ["bugfix", "feature"]
estimated_files_lte: 20
use_model: "claude-sonnet"
max_budget_usd: 1.50
- name: "architecture_or_large_refactor"
when:
task_type: ["architecture", "large_refactor"]
use_model: "claude-opus"
max_budget_usd: 8.00
requires_approval: true| 参数 | 说明 |
|---|---|
estimated_files_lte |
预计涉及文件数上限 |
max_budget_usd |
单任务预算上限 |
requires_approval |
是否需要人工确认才能使用高成本模型 |
default_model |
没有命中规则时使用的模型 |
四、预算守卫代码
预算控制应该在任务执行前和执行中都生效。
from decimal import Decimal
class BudgetExceeded(Exception):
pass
class BudgetGuard:
def __init__(self, task_budget_usd: str, project_daily_budget_usd: str):
self.task_budget = Decimal(task_budget_usd)
self.project_daily_budget = Decimal(project_daily_budget_usd)
def check_task(self, current_cost: Decimal, next_estimated_cost: Decimal) -> None:
if current_cost + next_estimated_cost > self.task_budget:
raise BudgetExceeded(
f"task budget exceeded: {current_cost} + {next_estimated_cost} > {self.task_budget}"
)
def check_project_day(self, daily_cost: Decimal, next_estimated_cost: Decimal) -> None:
if daily_cost + next_estimated_cost > self.project_daily_budget:
raise BudgetExceeded(
f"project daily budget exceeded: {daily_cost} + {next_estimated_cost}"
)
guard = BudgetGuard(task_budget_usd="1.50", project_daily_budget_usd="50.00")
guard.check_task(Decimal("0.72"), Decimal("0.18"))五、成本看板指标
看板不要只展示总金额。建议至少展示:
| 指标 | 解释 | 优化动作 |
|---|---|---|
| 成本 / 任务 | 每个任务平均花费 | 拆分大任务、限制重试 |
| 成本 / 通过任务 | 只统计最终成功任务成本 | 评估有效支出 |
| Token / 文件 | 每个涉及文件消耗的 Token | 优化上下文包 |
| 重试成本占比 | 重试产生的成本占总成本比例 | 改善提示词和验证 |
| 高级模型占比 | 高价模型调用比例 | 调整模型路由 |
| 人工接管率 | 需要人工继续修的任务比例 | 衡量自动化质量 |
六、告警规则
alerts:
- name: "single_task_budget_exceeded"
condition: "task.cost_usd > task.max_budget_usd"
severity: "warning"
notify: ["task_owner"]
- name: "project_daily_cost_spike"
condition: "project.daily_cost_usd > project.baseline_daily_cost_usd * 2"
severity: "critical"
notify: ["tech_lead", "engineering_manager"]
- name: "retry_cost_ratio_high"
condition: "project.retry_cost_ratio > 0.35"
severity: "warning"
notify: ["platform_team"]
- name: "premium_model_without_approval"
condition: "model.tier == 'premium' and approval.exists == false"
severity: "critical"
notify: ["security_team"]七、优化流程图
flowchart TD
A["发现成本异常"] --> B{"异常来自哪里"}
B -->|上下文过大| C["裁剪上下文包"]
B -->|模型过强| D["调整路由规则"]
B -->|重试过多| E["增加停止条件和验收标准"]
B -->|验证失败| F["补测试和静态检查"]
C --> G["复测任务成本"]
D --> G
E --> G
F --> G
G --> H["更新模板和预算策略"]八、落地建议
- 每个 Agent 任务都必须绑定项目、发起人和任务类型
- 每次模型调用都记录 Token、模型、阶段和成本
- 高级模型默认需要预算策略命中
- 超预算任务暂停,而不是继续自动重试
- 每周复盘成本最高的 10 个任务
- 把“失败重试成本”作为质量指标,而不是只看总账单
总结
成本观测的目标不是压低每一次调用价格,而是让团队知道哪些任务值得花钱、哪些任务在浪费钱。把 Token、任务、模型路由和预算告警连接起来,Agent 成本才会变成可管理的工程指标。