1. 引言:Agent 的狂欢,谁在买单?

2026 年,AI Agent 已经从概念性 demo 全面走向生产环境。智能客服、自动化研发、法律助手、金融风控……几乎每个垂直领域都在部署自己的 Agent。但热闹之余,一个越来越尖锐的问题浮出水面:这些 Agent 真的赚钱吗?

很多企业上 Agent 项目时关注的是「能不能跑通」,很少认真核算「跑通之后每处理一个任务要花多少钱」。结果就是:Agent 越做越多,成本直线上升,ROI 却迟迟算不清楚。LLM 的 API 账单成为新的「云计算黑洞」,比当年的服务器闲置更隐蔽、更难治理。

这篇文章不聊虚的。我们会把 AI Agent 的成本拆到每一次模型调用;讲清楚模型路由为什么是降本的第一杠杆;再给出一个可以落地的 ROI 计算框架。最后,用一个完整的 Python 项目实战,演示如何用「小模型做路由 + 大模型兜底」的方式,在效果几乎不变的前提下把推理成本打下来 60% 以上。

2. 本质:AI Agent 的钱都花在哪了?

要算经济账,先得知道钱是怎么流出去的。一个典型的 ReAct 风格 Agent 执行一次任务,通常会经历这样的过程:

否

是

用户输入任务

规划器(大模型)

选择工具

执行工具

观察结果

是否完成?

生成最终回答(大模型)

关键洞察:图中 B 和 G 两个环节都在烧钱。 而且 ReAct 循环意味着,一次任务可能会触发 3 到 10 次甚至更多的大模型调用。如果中间某个工具调用失败或者返回异常,重试又会成倍放大成本。

我们把成本拆成四层:

成本层级典型构成可优化空间
模型推理成本LLM 的 input/output token 费用高(路由、缓存、压缩)
编排与基础设施API 网关、状态存储、消息队列中(架构设计)
工具调用成本搜索 API、数据库查询、第三方服务中(工具设计、缓存策略)
人工兜底与维护错误处理、标注、运营低但不可忽视

其中,模型推理成本通常是占比最高、也最容易失控的部分。举一个真实感很强的例子:假设你用一个 70B 参数的模型做客服 Agent,单次对话平均 4000 input token + 800 output token。按目前主流云厂商价格(开源 70B 模型约 ¥0.004/1K input token、¥0.008/1K output token 的推理服务),一次对话的模型费用是:

  • input:4000 / 1000 × 0.004 = ¥0.016
  • output:800 / 1000 × 0.008 = ¥0.0064
  • 单轮合计约 ¥0.0224

如果 Agent 平均每通对话要跑 6 轮模型调用,那单次服务的成本就是 ¥0.1344。一天处理 10 万次服务,就是 ¥13,440,一个月超过 40 万。这还只是一个中规模客服系统的模型费用。

3. 模型路由:Agent 降本的第一杠杆

3.1 什么是模型路由?

模型路由(Model Routing)的核心思想非常朴素:不是每个请求都值得让最贵的模型来处理。

在传统开发中,我们习惯把某个 Agent 绑定到一个固定模型上。比如「我的客服 Agent 用 GPT-4 级别的模型」。但现实是,客服请求里可能有 70% 是「如何退款」「订单到哪了」这类简单问题,小模型完全可以答好;真正需要复杂推理的占比可能不到 30%。

模型路由就是用一个轻量级分类器(甚至可以是一个小模型),在请求进来时先判断难度,再动态决定交给哪个模型处理:

简单 / 常见意图

复杂 / 需深度推理

高风险 / 高价值

用户输入

路由模型(小参数)

低成本小模型

高能力大模型

旗舰模型 + 人工复核

返回结果

3.2 路由方式的三条路线

路线一:基于规则的关键词路由。

最简单,零额外成本。比如检测到「退款」「退货」「物流」等词就走小模型。缺点也很明显:规则是静态的,遇到没覆盖的表达就会误判。

路线二:用小模型做语义路由器。

用一个 1B~7B 的小模型做意图分类,输出「简单 / 中等 / 复杂」三个档位。这把规则路由的「关键词匹配」升级为「语义理解」,准确率大幅提升,而每次路由决策的成本非常低。

路线三:基于置信度的动态路由。

连续多轮对话场景。小模型先生成回答,同时给出置信度;置信度低于阈值时,自动升级到大模型重新处理。这种方式把「路由」和「兜底」结合在一起,更贴近生产实践。

3.3 成本收益的直觉验证

我们用一个模拟实验来感受路由的价值。假设:

  • 旗舰模型单次调用成本:¥0.05
  • 小模型单次调用成本:¥0.002
  • 路由模型单次调用成本:¥0.0003
  • 流量中 65% 为简单任务,25% 为中等任务,10% 为困难任务

不路由(全部走旗舰模型):均值 ¥0.05

路由后(简单/中等走小模型,困难走旗舰,路由一律消耗):

  • 简单任务成本:¥0.002 + 路由 ¥0.0003 = ¥0.0023
  • 中等任务成本:¥0.002 + 路由 ¥0.0003 = ¥0.0023
  • 困难任务成本:¥0.05 + 路由 ¥0.0003 = ¥0.0503
  • 加权平均:0.65 × 0.0023 + 0.25 × 0.0023 + 0.10 × 0.0503 ≈ ¥0.0071

成本降幅约 86%。 即便算上路由误判导致的部分损失,实践中做到 60%~70% 的降幅是很现实的。这就是为什么「模型路由」会被认为是 Agent 经济学中的第一杠杆。

4. 真实 ROI:一个可落地的计算框架

4.1 别再把 ROI 算成「节约了多少人力」这么简单

很多 Agent 立项书里的 ROI 模型是:「原来 10 个人干的活,Agent 只要 2 个人维护,省 8 个人力。」这个逻辑太粗了,它忽略了三个关键变量:

替代率:Agent 真的能完全替代那 8 个人吗?还是只能承担其中 40% 的重复劳动?

纠错成本:Agent 出错后,需要多少人工去补救?一次错误造成的业务损失可能远超省下的人力。

隐性基础设施:数据清洗、prompt 维护、评测集搭建、监控告警,这些「围绕 Agent 的工作」往往被忽略。

4.2 一个值得推广的单位经济学公式

对「按次服务」的 Agent(比如客服、合同审查、简历筛选),建议用单任务毛利来记账:

单任务毛利 = 单任务收费(或内部结算价值) − 单任务模型成本 − 单任务工具成本 − 单任务人工兜底成本

对「按月服务」的 Agent(比如代码助手、设计助手),建议看两个指标:

月经常性成本 = 模型费用 + 工具费用 + 基础设施 + 运营维护
月创造价值 = 节省的等效人力成本 × 实际替代率 − 事故与纠错损失
月 ROI = (月创造价值 − 月经常性成本) / 月经常性成本

4.3 三个关键阈值,帮你在立项前做判断

  • 路由决策成本 < 最高成本模型单次调用的 1%。否则路由本身就在烧钱。
  • 小模型承担比例 ≥ 60%。如果路由后发现 90% 的请求还是打到了大模型,说明路由器没起作用,需要重训或调阈值。
  • 人工兜底占比 ≤ 10%。如果超过 10% 的任务需要人工介入,说明 Agent 的可靠性还不够,此时「ROI 为正」可能是幻觉。

5. 代码实战:构建一个带路由的降本 Agent

这一节我们从零实现一个可运行的模型路由 Agent。核心架构是:

  • Router:用一个小模型(这里用 Ollama 本地跑的 qwen3:4b 模拟)做意图与难度分级。
  • BackendModels:轻量任务走本地小模型,复杂任务走云端大模型(这里用 OpenAI 兼容接口模拟)。
  • Fallback:小模型回答置信度不足时,自动升级到大模型。
  • CostTracker:精确统计每一次调用的 token 与费用,让「经济账」可视化。

5.1 项目结构

agent-economics/
├── config.py          # 模型配置与价格
├── models.py          # 模型抽象与适配器
├── router.py          # 语义路由
├── agent.py           # Agent 主流程
├── cost_tracker.py    # 成本跟踪与 ROI 测算
└── main.py            # 运行示例

5.2 配置与价格模型

先写 config.py,把所有模型的价格和路由策略集中起来,这是算清经济账的基础。

# config.py
from dataclasses import dataclass


@dataclass(frozen=True)
class ModelConfig:
    name: str
    input_price_per_1k: float   # 每 1000 token 单价(元)
    output_price_per_1k: float
    is_remote: bool = True      # 远程大模型 or 本地小模型


# 价格为演示用示例,实际项目中请替换为你的云厂商报价
MODEL_POOL = {
    "tiny": ModelConfig("qwen3:4b", 0.0, 0.0, is_remote=False),
    "small": ModelConfig("qwen3:8b", 0.0, 0.0, is_remote=False),
    "large": ModelConfig("deepseek-chat", 0.002, 0.008, is_remote=True),
    "flagship": ModelConfig("gpt-4o", 0.015, 0.060, is_remote=True),
}

5.3 成本追踪器

cost_tracker.py 让每一笔模型支出的来龙去脉都清清楚楚:

# cost_tracker.py
from dataclasses import dataclass, field
from typing import List


@dataclass
class CallRecord:
    model: str
    input_tokens: int
    output_tokens: int
    cost: float
    stage: str  # router / backend / fallback


@dataclass
class CostTracker:
    records: List[CallRecord] = field(default_factory=list)

    def add(self, model: str, input_tokens: int, output_tokens: int,
            cost: float, stage: str):
        self.records.append(
            CallRecord(model, input_tokens, output_tokens, cost, stage)
        )

    @property
    def total_cost(self) -> float:
        return round(sum(r.cost for r in self.records), 6)

    def breakdown(self) -> dict:
        result = {}
        for r in self.records:
            result.setdefault(r.stage, 0.0)
            result[r.stage] = round(result[r.stage] + r.cost, 6)
        return result

    def report(self) -> str:
        lines = [f"总成本:¥{self.total_cost}"]
        for stage, cost in self.breakdown().items():
            lines.append(f"  - {stage}: ¥{cost}")
        return "\n".join(lines)

5.4 模型抽象层

models.py 做统一的模型接口。真实环境中,本地小模型走 Ollama 的 chat 接口,远程大模型走 OpenAI 兼容协议。为了演示,我们用一个 call 方法把两者统一起来:

# models.py
import random
from config import ModelConfig

from cost_tracker import CostTracker

# 纯演示用的分词近似:中文约 1.5 字符/token,英文约 4 字符/token
def estimate_tokens(text: str) -> int:
    return max(1, len(text) // 2)


class BaseModel:
    def __init__(self, name: str, config: ModelConfig):
        self.name = name
        self.config = config

    def cost_of(self, input_tokens: int, output_tokens: int) -> float:
        c = self.config
        return (input_tokens / 1000) * c.input_price_per_1k + \
               (output_tokens / 1000) * c.output_price_per_1k

    def generate(self, prompt: str, tracker: CostTracker | None = None,
                 stage: str = "backend") -> str:
        # 这里简化实现:本地小模型用轮转模板,远程大模型也模拟
        # 实际项目里应该调用 ollama.chat 或 openai.ChatCompletion
        answer = self._mock_reply(prompt)
        in_tokens = estimate_tokens(prompt)
        out_tokens = estimate_tokens(answer)
        if tracker:
            tracker.add(self.name, in_tokens, out_tokens,
                        self.cost_of(in_tokens, out_tokens), stage)
        return answer

    def _mock_reply(self, prompt: str) -> str:
        if "退款" in prompt or "退货" in prompt:
            return "请登录您的账户,在订单详情页选择对应订单并点击申请退款,系统将在 1-3 个工作日内原路退回。"
        if "物流" in prompt or "到哪" in prompt:
            return "您的包裹正在运输中,预计明天送达,您可以在订单页查看实时物流信息。"
        return "我理解您的问题,建议您提供更多信息,以便我为您提供更准确的方案。"


class VirtualModel:
    """用随机分数模拟置信度,生产环境应使用模型输出的 logprob"""

    def __init__(self, name: str, config: ModelConfig, base: BaseModel):
        self.name = name
        self.config = config
        self.base = base

    def generate_with_confidence(self, prompt: str):
        answer = self.base.generate(prompt)
        confidence = random.uniform(0.2, 1.0)
        return answer, confidence

5.5 语义路由器

router.py 是整个架构的灵魂。它用最小的模型做难度分级,输出的不是最终回答,而是一个「路由标签」。这里我们设计一个三分类:simple、medium、complex。

# router.py
from models import BaseModel
from cost_tracker import CostTracker

ROUTE_PROMPT = """你是 AI Agent 的路由器。请判断用户问题的复杂度。
规则:
- simple:常见问题,有固定答案,无需深度推理(如订单查询、退款流程、账号问题)
- medium:需要结合上下文或稍作推理(如比较、条件判断)
- complex:需要多步推理、专业知识或自由生成(如复杂方案设计、代码调试)

用户问题:{question}

只输出:simple / medium / complex
"""


class SemanticRouter:
    def __init__(self, model: BaseModel, tracker: CostTracker):
        self.model = model
        self.tracker = tracker

    def route(self, question: str) -> str:
        prompt = ROUTE_PROMPT.format(question=question)
        label = self.model.generate(prompt, self.tracker, stage="router")
        label = label.strip().lower()
        if label not in ("simple", "medium", "complex"):
            label = "medium"
        return label

5.6 Agent 主流程

agent.py 把路由、模型选择、兜底升级串起来:

# agent.py
from config import MODEL_POOL
from models import VirtualModel
from router import SemanticRouter
from cost_tracker import CostTracker

# 简化映射:路由标签 => 模型名
ROUTING_TABLE = {
    "simple": "small",
    "medium": "small",
    "complex": "large",
}


class EconomicAgent:
    def __init__(self, tracker: CostTracker | None = None):
        self.tracker = tracker or CostTracker()
        self.router_model = VirtualModel("router", MODEL_POOL["tiny"], None)
        self.models = {
            name: VirtualModel(name, cfg, None) if name != "router"
            else self.router_model
            for name, cfg in MODEL_POOL.items() if name != "router"
        }
        self.router = SemanticRouter(self.router_model.base, self.tracker)

    def handle(self, question: str) -> str:
        label = self.router.route(question)
        backend = ROUTING_TABLE.get(label, "large")
        model = self.models[backend]
        answer, confidence = model.generate_with_confidence(question)

        # 小模型置信度不足时,自动升级到大模型兜底
        if backend in ("small", "tiny") and confidence < 0.6:
            fallback = self.models["large"]
            answer, confidence = fallback.generate_with_confidence(question)

        return answer

5.7 运行与成本对比

main.py 用一个混合流量样本,对比「全旗舰模型」和「路由策略」的最终成本:

# main.py
from config import MODEL_POOL
from agent import EconomicAgent
from cost_tracker import CostTracker, CallRecord

QUESTIONS = [
    "怎么申请退款?",
    "我的订单到哪了?",
    "如何修改收货地址?",
    "我想把账号绑定邮箱换一下",
    "请帮我写一段 Python 实现快速排序",
    "请分析一下我们公司客服系统如何优化",
    "怎么开发票?",
    "优惠券为什么用不了?",
    "如何设计一个高可用的微服务架构?",
    "帮我写一个 SQL 查询用户复购率",
]


def simulate_agent(use_routing: bool) -> CostTracker:
    tracker = CostTracker()
    agent = EconomicAgent(tracker)

    if not use_routing:
        # 不路由:所有请求直接走旗舰模型
        flagship = agent.models["flagship"]
        for q in QUESTIONS:
            in_tokens = len(q) // 2
            out_tokens = 80  # 模拟输出长度
            cost = MODEL_POOL["flagship"].input_price_per_1k * (in_tokens / 1000) + \
                   MODEL_POOL["flagship"].output_price_per_1k * (out_tokens / 1000)
            tracker.add("flagship", in_tokens, out_tokens, cost, "backend")
    else:
        for q in QUESTIONS:
            agent.handle(q)
    return tracker


if __name__ == "__main__":
    no_route = simulate_agent(use_routing=False)
    route = simulate_agent(use_routing=True)

    print("=== 不路由(全旗舰模型)===")
    print(no_route.report())
    print()
    print("=== 模型路由 ===")
    print(route.report())
    print()
    saving = 1 - route.total_cost / no_route.total_cost
    print(f"成本节省:{saving:.1%}")

在这个简化示例里,由于大部分问题是退款、物流这类 simple 问题,路由策略会显著地把请求分流到零成本(或极低成本)的本地小模型。实际项目中即使本地模型也需要服务器成本,依然可以把大模型调用量压缩 70% 以上。

注意:上面的 _mock_reply 和 estimate_tokens 是演示用的简化实现。真实落地时,你需要把 BaseModel.generate 改为:

# 真实实现示意(以 OpenAI 兼容接口为例)
import openai

def generate(self, prompt: str, tracker=None, stage="backend"):
    response = openai.ChatCompletion.create(
        model=self.name,
        messages=[{"role": "user", "content": prompt}],
    )
    answer = response["choices"][0]["message"]["content"]
    usage = response["usage"]
    if tracker:
        tracker.add(
            self.name,
            usage["prompt_tokens"],
            usage["completion_tokens"],
            self.cost_of(usage["prompt_tokens"], usage["completion_tokens"]),
            stage,
        )
    return answer

5.8 把 ROI 也放进代码里

成本追踪器只是第一层,第二层是把「价值」和「成本」同时纳入计算:

# roi.py
from dataclasses import dataclass
from cost_tracker import CostTracker


@dataclass
class TaskInfo:
    question: str
    handled_by: str      # simple / medium / complex
    actual_resolution: bool  # 是否真正解决
    business_value: float    # 该任务解决后创造的价值(元)


def compute_unit_roi(tasks: list[TaskInfo], tracker: CostTracker) -> dict:
    total_value = sum(t.business_value for t in tasks if t.actual_resolution)
    total_cost = tracker.total_cost
    return {
        "total_value": total_value,
        "total_cost": total_cost,
        "net_profit": total_value - total_cost,
        "roi": (total_value - total_cost) / total_cost if total_cost else 0,
    }

把这个模块接入你的生产 Agent 后,每周拉一次报表,就能回答那个最关键的问题:这个 Agent 到底是资产还是负债。

6. 进阶:让路由变得更聪明的三个工程实践

6.1 缓存优先,路由其次

很多 Agent 任务高度重复。把「问题 → 最终答案」的确定性结果放进缓存(Redis 或本地 KV),命中缓存时模型成本直接归零。优先级应当是:缓存 > 路由到小模型 > 大模型兜底。

def handle_with_cache(self, question: str):
    cache_key = hash(question)
    if cache_key in self.cache:
        return self.cache[cache_key]  # 零模型成本
    answer = self.handle(question)
    self.cache[cache_key] = answer
    return answer

6.2 上下文压缩:input token 是隐形成本之王

Agent 的多轮对话里,历史消息会被反复塞进 prompt,input token 膨胀速度远超想象。一个 10 轮对话的 Agent,如果不做压缩,后面几轮的 input 可能比第一轮大 5 倍。建议在每次对话超过 8 轮后,用一个轻量摘要模型把历史压缩成 200 token 以内的摘要,再拼回 prompt。

6.3 路由阈值要「可观测、可回滚」

不要一次性把 100% 流量切成自动路由。推荐的灰度路径:

  1. 影子模式:路由判断照常跑,但所有请求仍走大模型,记录「如果走了路由能省多少」和「路由判断是否合理」。
  2. 10% 流量切小模型:对照两组的核心业务指标(如客服满意度、任务成功率)。
  3. 逐步放量:每轮放量前确保成本下降幅度与业务指标劣化幅度在可接受范围内。

7. 结语:算力便宜了,但「随便用」依然很贵

2025 到 2026 年,大模型的推理成本持续下降,很多人因此产生一个乐观的判断:「模型会越来越便宜,不用那么精打细算。」这个判断只在单次调用量不变时成立。实际上,Agent 化之后,调用量和任务复杂度都在快速增长——成本下降的斜率,往往追不上调用量上升的斜率。

能把 AI Agent 的经济账算清楚的团队,不是抠门,而是在为规模化做准备。模型路由、缓存、上下文压缩、置信度兜底……这些工程手段听起来不性感,但它们共同决定了一个 Agent 产品能不能从「demo 很惊艳」走到「规模化盈利」。

希望这篇文章的框架和代码,能让你的下一个 Agent 项目,从第一天起就把 ROI 装进监控面板。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐