AI定价没坏:从token单价到单任务成本的5个工程真相

发布时间:2026/8/28 14:12:42
AI定价没坏:从token单价到单任务成本的5个工程真相 AI定价并没有坏比“每百万token多少钱”更重要的5个工程真相如果你最近在做 AI 应用落地大概率遇到过这种场景早会讨论预算技术说“我们用的大模型很便宜”财务打开账单却脸色难看或者更常见——你对比了市面上所有大模型 API 的价格表选了一个“单价最低”的模型结果跑完一批真实的业务任务后总成本反而比旗舰模型还高。然后很多人得出结论AI 定价是乱的价格模型是 broken 的。这个判断我可以直接给出相反意见AI 定价并不是坏了而是我们一直在用传统软件的定价思维去评估它。如果把“按 token 计价”看成一个 API 的单一维度你看到的一定是混乱和不可控但如果把定价还原成“你为完成一项任务所消耗的全部计算资源来买单”你就能理解它为什么这样设计以及怎么在工程项目里去控制它。这篇文章我会从工程视角拆解 AI 定价的结构、开发者的成本误区、以及真正可落地的成本建模和模型选择方案。不追求把每一条价格都写到纸面上因为定价变动太快但我可以告诉你一套能长期起作用的分析和控制方法。读完你会得到三个具体的东西一个判断、一个成本估算的代码模板、一套适合中小团队的分层模型选择思路。1. 为什么有人说“AI 定价是乱的”这个“乱”的观感主要来自三个现实错位。第一选择维度太多。光是主流厂商就提供好几代模型每一代又按上下文长度、推理能力、响应速度分成不同版本。API 价格表里同时出现输入价格、输出价格、缓存命中的价格、缓存未命中的价格、批量任务价格外行看到就是一张密密麻麻的矩阵。第二单价与最终成本脱节。很多模型“每百万 token”的单价确实很低但推理时如果上下文很长或者任务本身需要多次调用模型反复生成实际消耗会成倍放大。不是按单价乘一个固定倍数那么简单。第三定价逻辑不透明。有的模型非常便宜但能力不足完成同样任务需要更多的重新生成次数、更长的思考链、或者需要外挂 RAG 才能得到可接受的结果。最终一算便宜模型的单位任务成本反而更高。用一句直白的话概括觉得 AI 定价坏是因为我们在用“商品单价”的思维理解“服务账单”。传统软件是买一个固定能力的副本价格和真实使用量关系不大AI 是“每次推理都在消耗真实算力资源”的服务定价天然和资源消耗绑定。这不是设计失误而是新模式和旧心智之间的冲突。从材料上看类似的困惑也集中出现在 AI 应用开发、AI 工程实践和模型部署相关的讨论里。“模型很强大但是不敢用”“token 太贵了”“上下文一长就心疼”这些声音背后其实都指向同一个问题大家缺少一套把模型能力、计费结构和业务价值放在一起评估的方法论。2. 从“每百万 token 多少钱”到“单任务成本”要解决上面的困惑第一个要升级的认知就是不要以 token 作为成本核算的第一单位要以“完成一个业务任务需要消耗多少资源”作为核算单位。token 是计费单位不是业务单位。用户不会说“我今天需要消费 5 万 token”用户说的是“我要做一次文档总结”“我要跑一批客服工单分类”“我要把用户聊天记录去识别出关键实体”。这些业务单元背后的 token 消耗各不相同真正的成本核算应该挂在这些任务上。举一个具体的对比场景。假设你有一个客服系统需要把每一通客服对话做“用户意图识别 情绪判断 摘要生成”。如果直接用旗舰模型完成每次调用消耗可能包含中等的输入和中等输出结果一个月的账单是 6000 元。如果换成中等能力模型看起来单价低了 60%但由于该模型对长文本的理解能力较弱你需要额外写规则做后处理还要为复杂对话触发两到三次重试最终总消耗可能只便宜了 20%甚至因为任务失败率升高反而要人工介入隐形成本更贵。所以评估一个模型的真实价格应该是一个公式单任务真实成本 单次调用的平均 token 消耗 × token 单价 × 完成任务的尝试次数 失败后的额外调用成本 人工兜底成本这个公式里面最容易被忽略的就是后面的两个变量。很多模型单价便宜但“完成任务的尝试次数”非常高或者在特定业务实例下根本没输出,需要外部兜底总成本立刻失控。这也是为什么我的判断是AI 定价没有坏至少现在的发展方向是合理的真正坏掉的是很多团队完全没有建立“按任务核算成本”的工程意识。想知道这个 API 贵不贵先别急着看价格表先问一个问题你的业务里一类任务需要平均多少次调用、多少上下文、多少输出才能达成目标3. AI 定价的基本盘到底在为什么付钱理解定价结构之前先理解 AI 服务的成本构成。这部分可以帮你在和老板沟通预算、和财务解释账单时有一套靠谱的说辞不再是“反正就这么多钱”。3.1 训练是一次性的推理是持续的大模型的训练成本极高包含数据清洗、预训练、对齐、评测等多个环节。但训练完成后这个成本就沉淀在模型权重里。你在 API 账单上看到的费用绝大部分不是训练成本而是推理成本inference cost每次输入给模型、模型为你生成答案时底层 GPU 集群消耗的电费、算力、显存、带宽和运维成本。理解这一点很重要。因为如果哪天一个厂商宣布“模型降价”它通常意味着推理侧的工程优化取得了突破比如更高效的注意力机制、更小的模型蒸馏版本、更好的批量调度策略而不是单纯在做市场补贴。反过来如果一个模型在快速推理、长上下文上的能力更强它的资源占用更高定价自然更贵。这不是乱定价这是算力供给和需求的真实映射。3.2 上下文是成本的大头很多开发者对 token 计价的直觉理解只有一层输入一段话输出一段话按量计费。但在实际工程里上下文窗口才是成本差异的核心变量。举一个例子你要把一份 5 万字的技术文档交给模型让它总结要点。如果直接把全文塞进 prompt那么这次调用的输入 token 消耗就是 5 万字对应的 token 量。假设这份文档占总上下文的 80%你实际上只是在最后一步才用到模型前三步都是在传输和存储文本。输出只有几百字但输入消耗几乎是固定的巨大。这种情况下用贵的模型和便宜的模型差距会被放大得很厉害。所以工程上几乎都会优先做文本预处理先截断、先分块、先做检索再填充 prompt。你省下的不是“prompt 里那几行字”而是每次调用时那段文字的全程传输和注意力计算成本。3.3 缓存、并发与批量任务改变了真实价格再看 API 价格表通常会看到几种价格标准价格、缓存命中价格、批量任务价格。它们的原理不同缓存命中价格如果同一个 prompt 前缀在短时间内被重复请求服务商可以复用之前的计算结果所以你只需要付一个很低的价格就能拿到结果。这在 RAG 场景、知识库问答场景、Agent 工具调用场景里非常常见。批量任务价格服务商把你的任务排队、等算力不那么紧张时统一执行单位成本会低很多。适合对延迟不敏感的离线任务比如晚上跑一批数据清洗、批量生成摘要。这解释了为什么同一个模型在不同的调用模式下面真实成本可以差出好几倍。也可以理解为AI 定价不是“一刀切”的而是鼓励你在工程上做资源调优。延迟敏感度低的做批量重复提问的做缓存长问答的做缓存前缀这些都能直接影响账单而不是只能被动接受一个固定单价。4. 从“能力选型”到“预算选型”你真的每次都需要最大模型吗很多人选模型的心态是能力越强越好预算够就上最强的。但在一个真实业务系统里这是成本失控最常见的原因之一。不是所有任务都需要同样的智能水平。一次“给用户生成个性化营销文案”的任务和一次“解析用户退款诉求并生成结构化工单”的任务复杂度和风险等级不同调用同一个模型显然不合理。我自己在实际项目中比较认可的做法是模型分层model tiering按任务的复杂度、风险等级、对输出的要求把流量分成不同路径每个路径使用不同的模型能力等级。一个典型的分层方案任务类型示例建议模型等级成本级别简单分类/抽取判断用户消息是否为投诉、提取日期地点小型推理模型或规则小模型最低中等生成/改写产品评论摘要、话术推荐中型能力模型中等复杂推理/长文档合同风险分析、复杂代码生成旗舰模型最高这个策略的关键在于分层不是降配而是让每类任务用“够用且不浪费”的模型完成。对于有价值的复杂任务仍然需要旗舰模型保证质量对于简单任务没必要每次都让最大的模型跑一遍这是成本上最立竿见影的优化。实际开发中这种分流逻辑并不难实现。你可以在业务层为每一个使用大模型的功能点打一个标签比如“extract_entities”“summary_short”“review_contract”然后由一个统一的 ModelRouter 根据标签分配模型。这样做的另一个好处是以后某个模型降价了或者新出了一个更好的模型你只需要改路由配置不需要改业务代码。5. 成本估算的代码模板先算清楚再做这里给出一个可以直接运行的成本估算脚本。你应该把它放在项目里作为“预算计算器”在每次接入新模型或设计新功能前先估算一轮单任务成本。注意脚本中的价格是演示用的示例值真实项目一定要以你实际签约的 API 价格为准。# 文件路径cost_estimator.py AI 调用成本的简单估算工具。 使用示例 python cost_estimator.py --model claude-sonnet --input_chars 3000 --output_chars 500 --trials 1.2 def get_price_per_million(model: str) - dict: 返回模型每百万 token 的价格示例数据。 真实项目中可以换成从配置中心读取价格表 或者调用厂商提供的 pricing API。 prices { flagship: {input: 15.0, output: 75.0, cached_input: 1.5}, medium: {input: 3.0, output: 15.0, cached_input: 0.3}, mini: {input: 0.5, output: 2.0, cached_input: 0.05}, } return prices.get(model, prices[medium]) def estimate_cost( model: str, input_chars: int, output_chars: int, trials: float 1.0, use_cache: bool False, ) - dict: 估算一次业务任务的平均成本。 参数说明 model: 模型档位如 flagship/medium/mini input_chars: 平均输入文本字符数不含系统提示词额外叠加的部分 output_chars: 平均输出文本字符数 trials: 完成一个任务平均需要调用的次数含重试、多次生成 use_cache: 是否命中缓存会显著降低输入成本 说明中文场景下一个汉字大约对应 1~2 个 token 这里保守按 1.5 个字符每 token 估算实际可调整。 price get_price_per_million(model) # 中文文本近似 token 数字符数 / 1.5 input_tokens input_chars / 1.5 output_tokens output_chars / 1.5 input_price price[cached_input] if use_cache else price[input] input_cost input_tokens / 1_000_000 * input_price output_cost output_tokens / 1_000_000 * price[output] single_call_cost input_cost output_cost total_cost single_call_cost * trials return { model: model, input_tokens_approx: round(input_tokens), output_tokens_approx: round(output_tokens), single_call_cost: round(single_call_cost, 6), trials: trials, total_cost_per_task: round(total_cost, 6), } def batch_estimate(configs: list[dict]) - None: 批量打印一组任务估算结果。 for cfg in configs: result estimate_cost(**cfg) print( f[{result[model]:8s}] f输入约 {result[input_tokens_approx]:7} token, f输出约 {result[output_tokens_approx]:6} token, f单次 ${result[single_call_cost]:.5f}, f任务期望调用 {result[trials]} 次, f单任务成本 ${result[total_cost_per_task]:.5f} ) if __name__ __main__: # 输入系统 prompt 不重复计算时业务输入约 3000 字 # 输出摘要约 500 字 # trials1.2约 20% 的情况需要重试或二次调用 result estimate_cost(medium, 3000, 500, trials1.2) print(单个中等任务的估算成本) print(result) print(\n对比三个档位处理同一个任务的成本) batch_estimate([ {model: flagship, input_chars: 3000, output_chars: 500, trials: 1.0}, {model: medium, input_chars: 3000, output_chars: 500, trials: 1.2}, {model: mini, input_chars: 3000, output_chars: 500, trials: 2.0}, ])这个脚本解决的是“拍脑袋决定用哪个模型”的问题。接入新功能之前先把你预估的输入长度、输出长度、期望的重试次数填进去算出单任务成本再乘以预估的每日/每月任务量。即使估算有偏差也比完全无依据地选模型靠谱得多。关键点是trials这个参数它代表一个任务平均要调用多少次模型才能拿到可接受的结果。很多团队只看到一次调用的价格完全忽略了这个参数导致选了一个便宜但“试用率”很低的模型最后总成本反而上涨。如果你不知道自己的trials是多少说明你还缺少一个基础的调用日志系统后面会讲。6. 引入一个简单的 ModelRouter让模型选型可以在配置层完成成本控制不能只靠估算还要落到代码里。这里给出一个 ModelRouter 的最小实现。它的作用是业务代码不直接指定具体模型而是指定一个逻辑路由名由 Router 从配置中读取出真实的模型名。# 文件路径model_router.py 极简模型路由按任务类型路由到对应模型。 import json from typing import Optional # 这里模拟从配置文件读取路由规则。 # 实际项目中建议把这份配置放到配置中心或 JSON 文件里 # 这样调整模型时不需要改代码和重新发布。 ROUTING_CONFIG { # 任务类型 - 模型档位 extract_entities: mini, classify_intent: mini, summarize_short: medium, summarize_long_doc: flagship, review_contract: flagship, generate_marketing: medium, default: medium, } class ModelRouter: def __init__(self, config: Optional[dict] None): self.config config or ROUTING_CONFIG def route(self, task_type: str) - str: 根据任务类型返回模型档位。 如果任务类型不在配置里返回 default 档位。 可以在这一层加监控埋点统计每个任务类型的路由命中次数。 model_level self.config.get(task_type, self.config[default]) # 在这里加日志或监控方便观察路由分布 print(f[router] task_type{task_type} - model{model_level}) return model_level def main(): router ModelRouter() # 模拟业务侧不同类型的请求 tasks [ (classify_intent, 用户说我收到的商品有破损要求退货), (summarize_short, 请用三句话总结这段客服对话的主要内容), (review_contract, 请分析这份合同中的违约责任条款是否存在风险), (unknown_task, 你好今天天气怎么样), ] for task_type, prompt in tasks: model_level router.route(task_type) # 真正的调用逻辑可以放在这里根据 model_level 选择真实 API 端点 print(f 将使用 {model_level} 处理: {prompt[:20]}...\n) if __name__ __main__: main()这个 Router 本身不复杂但它解决了一个关键的工程问题模型选型和业务代码解耦。业务侧只需要明确“任务类型”模型档位、具体模型、API 版本都归路由层管理。如果你上了这个 Router后面的模型升级、降本优化都会非常顺手。比如某一天中等能力的模型降价了或者某个新模型在摘要任务上表现更好你只需要改路由配置把summarize_short指向新的模型档位不需要动业务代码。这在模型迭代速度极快的当前阶段是一个投入产出比很高的架构决策。再进一步可以在这个 Router 里叠加模型质量监控对每个任务类型把模型的输出做一个简单评分记录到日志里定期分析“中等模型在 summarize_short 上的表现是否仍然够用”。如果出现质量下滑就把它升级回旗舰模型如果没有问题就一直保持低成本运行。7. 建立一套最简单的成本观测数据比感觉可靠我发现很多团队控制 AI 成本的困难不是因为模型太贵而是因为他们根本没有观测系统。月底看到账单数字只能“感觉”某个功能比较费钱但具体哪类任务在烧钱、每天烧多少、哪个调用链路的浪费最严重全都不知道。解决这个问题不需要上一套很重的平台。你只需要在调用大模型的地方统一封装一个 SDK然后在里面加三行日志业务任务类型、模型档位、本次调用的输入和输出 token 数。有这三样你就能够回答“我这个月成本主要是哪几个任务贡献的”这个问题。7.1 一个带日志的调用封装示例下面给出一个简单的封装假设你已经把模型调用统一收敛到call_llm这一个函数里# 文件路径llm_client.py 带日志统计的大模型调用封装。 import json import time from typing import Optional class LLMClient: def __init__(self, router, log_sinkNone): self.router router self.log_sink log_sink # 可以传入一个日志收集器比如写文件或发到消息队列 def call(self, task_type: str, prompt: str, **kwargs): 统一调用入口。 这里不关注具体模型 API只关注: 1. 通过 router 拿到模型档位 2. 调用真实的模型 SDK 3. 记录 token 用量和任务信息 model_level self.router.route(task_type) # 实际项目中这里会根据 model_level 选择不同的 SDK 和模型 ID。 # 下面这行是伪代码表示真实模型调用返回结果 # response real_sdk.chat(modelmodel_id, messages[...], **kwargs) # 为了演示这里构造一个模拟返回值 response self._mock_call(prompt) usage response.get(usage, {}) input_tokens usage.get(input_tokens, 0) output_tokens usage.get(output_tokens, 0) self._log_usage(task_type, model_level, input_tokens, output_tokens) return response[content] def _mock_call(self, prompt: str) - dict: # 模拟一次模型调用真实项目中替换为 SDK 调用 import random return { content: f模拟输出: {prompt[:8]}..., usage: { input_tokens: random.randint(100, 500), output_tokens: random.randint(50, 200), }, } def _log_usage(self, task_type: str, model_level: str, input_tokens: int, output_tokens: int) - None: log_entry { timestamp: time.time(), task_type: task_type, model_level: model_level, input_tokens: input_tokens, output_tokens: output_tokens, } # 打印日志会导入 stdout生产环境中应该写入结构化日志或监控系统 print(json.dumps(log_entry, ensure_asciiFalse)) if __name__ __main__: from model_router import ModelRouter router ModelRouter() client LLMClient(router) client.call(classify_intent, 用户反馈商品破损要求退款) client.call(summarize_short, 这是客服对话记录……) client.call(review_contract, 请分析合同风险……)有了这份日志你就能回答几个很关键的问题本周哪些任务类型的调用量最大每个任务类型的平均输入 token 是多少旗舰模型一周烧掉多少钱其中有多少是本来可以用中等模型解决的如果日志系统再往前一步就是给每个任务类型设一个成本预算。比如“classify_intent 每天预计 10 万次调用单次预算不超过 0.0001 美元”如果某天超过了立刻触发告警。很多成本失控不是一次性发生的而是某次 prompt 设计出了问题让输入长度翻了好几倍调用日志就能尽早暴露这类异常。7.2 观察三个核心指标建立观测后建议你每周盯三个核心指标。第一个是单任务成本趋势。同一个任务类型的平均成本是平稳、上涨还是下降上涨往往意味着 prompt 越来越长、模型回答越来越复杂或者有异常的重复调用。第二个是任务类型成本占比。哪个任务类型烧的钱最多通常会发现 20% 的任务类型贡献了 80% 的成本。分析这个 Top 成本来源是成本优化优先级最高的切入点。第三个是模型档位分布。当前流量在不同模型档位上的分布是否合理如果旗舰模型承担了 60% 的请求但其中 40% 是简单抽取任务你就知道分层策略没有执行到位。8. 一个不一定被讨论的真相Agent 项目的成本会指数级增长聊到 AI 应用开发尤其是 AI Agent 的场景有一个必须提前说的风险Agent 类项目的 token 消耗不是“调用一次”的量级而是“调用很多次 每次调用的信息都在变长”的量级。一个典型的 agent 任务流程是这样的系统先让模型决定调用什么工具然后模型输出中间的思考步骤程序拿着这个结果去调外部 API再把返回结果拼回上下文让模型继续决策直到完成整个任务。每一步都在增加上下文长度每一步都是一次完整的模型调用。这意味着什么意味着一个看起来简单的“帮我查一下这个订单的物流信息”的 agent 任务可能对应 5 到 8 次模型调用而且每次调用都需要把前面的历史轨迹重新传给模型输入 token 会呈线性甚至超线性增长。但这不意味着“不要做 Agent”。恰恰相反我认为 Agent 是高价值的应用形态只是它的成本模型要求你在设计阶段就考虑“这个任务真的需要让模型做决策那么多次吗”。具体有用的优化手段有三个给 Agent 设计更明确的终止条件。不要让 Agent 无限探索每一个工具调用都应该有边界超时、超步数就强制终止并进入兜底流程。做上下文压缩。不要让历史消息无限累积每隔几轮做一次摘要把旧消息压缩成一段精简过程记录可以显著降低后续调用的输入 token。把重复决策固化下来。如果某个 Agent 任务每天都在重复同一套工具调用序列就应该考虑是否可以做成一个定时任务或规则流程只在异常时才上升到模型决策。从工程实践的角度看Agent 的成本控制不是“调优 prompt 让模型变聪明”而是“设计一个流程让模型在最短决策路径上完成任务”。不要害怕让模型多做几步但要及时发现那些本可以一步完成却绕了三步的 agent 路径这是 Agent 项目成本优化的真正核心。9. 常见误区与排查思路为了让这篇文章更有实操性我用表格整理一下我在 AI 成本控制上最常见的几个问题和排查思路。误区现象排查方向改进办法只看单价不看总成本选了最便宜模型月底账单没省多少梳理单任务的调用次数和重试率建立单任务成本估算见第 5 节代码模板所有任务都用同一个旗舰模型大量简单请求都在消耗最高档位算力看路由日志统计模型档位分布引入 ModelRouter 分层见第 6 节上下文不压缩无限拼历史同一任务的输入 token 越来越长检查 prompt 历史和拼接逻辑增加摘要压缩、滑动窗口策略没有 token 用量日志账单异常无法定位是哪类任务引起的看是否对接了 token 级日志统一封装调用 SDK记录任务类型和 token 用量Agent 不做步数限制一个任务产生了大量调用链成本不可控看调用链路统计平均步数设置最大步数、终止条件、工具调用白名单不做批量任务调度离线任务也走实时通道成本偏高检查任务是否有延迟要求对非实时任务使用批量调用享受更低单价忽略缓存命中RAG 场景重复查询仍按全价计算检查是否启用上下文缓存设计固定前缀 prompt提高缓存命中率这个表格的核心是每一个误区背后都有一个“计价单位”错位的问题。只要把核算单位从“token”提升到“任务”大部分问题都会清晰很多。10. 一些可复用的工程经验最后说几点我自己的工程经验不一定适合所有团队但可以当作一份参考清单。第一给每个接入大模型的业务功能点做“预算预检”。功能开发完先按预估的调用量和输入长度用成本估算脚本跑一遍算出“上线后每月大概会花多少钱”。如果数字超过预算先不要上线先优化 prompt 或路由策略。这项预检应该写进开发流程而不是事后看账单再后悔。第二** prompt 设计对成本的影响往往大于模型选型**。两个同样功能的 prompt一个加了大量示例、又把整段文档塞进上下文另一个用了精简的指令、只把命中检索的片段放入上下文成本差距可以达到数倍。与其纠结用哪个模型不如先检查 prompt 里有没有大段不必要的文本。第三模型会迭代和降价你的路由器配置一定要跟上。我见过不少团队因为“上线后没再关注模型价格变化”一直用着已经过时的昂贵模型。每季度审视一次路由器配置看看有没有更好更便宜的模型可以替换是一个低成本但持续生效的优化习惯。第四一定不要绕过统一封装直接调模型 SDK。就算是最小的项目也建议把所有大模型调用收敛到一个模块里。这不是为了代码整洁而是为了将来你能给所有调用加上日志、路由、监控和限流。如果业务代码里到处散落着openai.ChatCompletion.create这样的直调代码后面任何成本优化都只能靠重构。第五成本优化结束的标志是“可预期的账单”而不只是“更低的账单”。你不需要追求把成本压到最低你需要的是“这周我知道下周大概会花多少钱并且这个数字是合理的”。可预期比极端优化重要因为团队可以把精力放在业务功能上而不是每天盯着账单担心它爆炸。11. 结论回到开头的判断AI 定价不是坏的它是新的。它从“商品定价”变成了“服务和资源定价”从“买一个软件副本”变成了“按每次推理真实消耗付费”。觉得它“坏了”更多是因为我们还在用旧的评估方式比如只看 token 单价、不看单任务成本、不建立观测、不做模型分层。正确的应对方式不是等待厂商改变定价模式而是主动建立一套适合自己的成本控制方法论以“单任务成本”为核算单位用 ModelRouter 把模型选型变成配置统一封装调用记录任务类型和 token 用量对 Agent 类项目提前设计终止条件和上下文压缩定期审视模型价格变化和路由配置。如果你手上正在做一个 AI 应用我的建议是不要等账单给你上一课下周就从第 5 节的成本估算脚本开始把你最常用的 3 个任务类型跑一遍看看单任务成本到底是多少。这一步做完你对 AI 定价的认知就已经比大多数团队领先了。

相关新闻