日期:2026-08-08
客户是一家集团型企业,内部有十四个部门在用同一套 AI 网关调用大模型,既有私有化部署的模型,也有几个走外部 API 的商用模型。每个月财务要按用量把成本分摊到各部门,这事从年初开始就没顺过。
冲突点很具体。网关侧统计的调用量和模型侧统计的对不上,差异在百分之三到七之间波动。外部 API 的账单和网关记录的更是差得离谱,有个月差了将近一成二。财务拿着两份数字不知道该信哪份,部门被分摊到成本就质疑"我们没用这么多",扯皮到最后往往是财务按上个月的数字拍一个。
我第一次参加他们的月度对账会,会开了两小时四十分钟,结论是"下个月再说"。散会后一位部门信息化负责人跟我说,他们部门被分摊的费用比自己台账多了三万多,但他也拿不出证据,因为自己那边根本没做记录。
问题的本质是没有一个被各方认可的计量口径。
我们在 AI 网关的计量层做了重构,目标不是把误差降到零,是让每一笔差异都能解释清楚。
计量点从原来的单点改成双向。请求侧在网关接收到请求、完成协议归一化之后立即计算输入 token;响应侧在流式输出结束或非流式响应返回时计算输出 token。两个数字分开记录,不做合并,因为很多模型的输入输出单价不同。
token 计算不再依赖模型返回的用量字段。这是个关键改动。原来网关直接取模型响应里的用量数据,问题是不同模型的统计口径不一致,有的算系统提示词有的不算,有的把特殊标记计入有的不计。我们改成网关自己用对应模型的分词器算一遍,同时也记录模型返回的数字,两者作为独立的两组数据共存,对账时做比对。
异常调用识别单独做了一层:超时失败的、被限流拒绝的、被内容安全拦截的、客户端主动取消的,这几类调用要不要计费、计多少,规则事先约定清楚并写进配置。
分摊这块,每次调用都带上部门、应用、用户三级标签,标签在网关的鉴权环节从令牌里解析,业务侧无感知。月末按标签聚合,生成分摊明细。
对账做成了自动化任务,每天跑一次,把网关计量、模型侧统计、外部账单三方数据拉齐比对,差异超过阈值的自动生成归因报告。
口径统一是最花时间的一块,而且大部分工作不是写代码。我们把十四个部门、六个模型的所有计量相关问题列了一张表,逐条和相关方确认:系统提示词算不算在输入里、多轮对话的历史上下文每轮重复计算还是只算增量、流式输出中途取消已生成的部分算不算、被安全拦截的请求算不算。这张表最后确认了二十三条规则,开了四次会。这四次会开完,后面的技术实现反而顺利了。
流式请求的计量是技术上最棘手的。非流式很简单,响应完整拿到手,分词一算就完事。流式的输出是逐帧过来的,而且客户端可能中途断开。我们的做法是在网关侧边转发边累加:每收到一帧,对增量内容做分词计数,累加到会话的计数器上。客户端断开时,已经生成的部分照常计数,因为算力确实消耗了。会话结束(正常完成、客户端断开、超时中止)时统一落账。
这里有个坑:分词的边界问题。流式输出的帧切分位置和分词的边界不一定对齐,一个 token 可能被切在两帧里。逐帧独立分词会算多。我们改成维护一个待处理缓冲区,每帧到达后把内容追加进去,分词后只消费能确定完整的部分,剩下的尾巴留在缓冲区等下一帧。这样算出来的结果和整段一次性分词完全一致,我们拿一万条真实会话验证过。
异常调用的剔除规则落地时也有争议。被限流拒绝的请求,从技术上说网关连模型都没调,不该计费。但有部门提出"限流是因为我们配额用完了,说明我们确实在用",主张应该记录但不计费。最后的方案是记录三个数字:调用次数、计费 token、非计费 token,让财务和部门自己看,不由系统替他们做判断。这个处理方式后来被证明很聪明,因为它把技术问题和管理问题分开了。
外部 API 的账单差异归因最后也理清了。我们拉齐三方数据后发现,差异主要来自两块:外部服务商的计费周期和我们的自然月不对齐(他们按 UTC,我们按东八区),以及重试请求在我们这边算一次业务调用但在服务商那边是两次计费。前者做了时区对齐,后者在计量里增加了"业务调用次数"和"实际请求次数"两个字段分别记录。
案例片段(已脱敏): 一次自动对账的归因报告节选:
模型 M3 本月网关计量输出 token 4,812,003,模型侧统计 4,795,660,差异 16,343(0.34%)。归因明细:客户端断开会话 47 次,网关计入已生成部分共 15,908 token,模型侧因会话未正常结束未计入;剩余 435 token 差异来自 3 次网关重试后模型侧去重。结论为差异可解释,无需人工介入。 流式分词缓冲区的效果验证:取 10,000 条真实流式会话,逐帧独立分词累加结果与整段一次性分词结果对比,未使用缓冲区时平均偏高 2.7%(最大单条偏高 6.1%),使用缓冲区后两者完全一致,差异为 0。
系统运行三个月后的情况。网关计量与模型侧统计的误差率,从原来百分之三到七的波动收敛到百分之零点五以内,且每一笔差异都能自动归因。与外部服务商账单的对账差异从最高百分之十二降到百分之一以内,剩余部分主要是服务商侧的四舍五入。
自动对账任务每天凌晨跑,覆盖六个模型和三家外部服务商,需要人工介入的异常从每月平均十九次降到两次。月度对账会从原来的两个多小时缩到二十分钟,主要时间花在讨论下月配额而不是争论数字。
配额告警的准确率也上来了。原来因为计量不准,告警要么提前触发要么用超了才报,准确率大概百分之七十。现在稳定在百分之九十八以上,部门可以按告警提前申请追加配额。
分摊争议数从月均十一起降到零到一起。财务那边给的反馈是,现在部门就算有疑问,也是拿着明细来问某一条具体调用,而不是笼统地说数字不对。这个变化比任何指标都重要。以上数据为项目复盘口径,已做脱敏。
计量这类事,技术准确性和各方认可是两回事。我们完全可以做出一个技术上无懈可击的计量系统,但如果口径没有事先达成共识,照样会被质疑。那四次口径确认会,是这个项目里性价比最高的时间投入。
不要信任外部系统返回的用量数字。不同模型、不同服务商的统计口径千差万别,网关自己算一遍才有主动权。同时把对方的数字也记下来,作为对账的另一路输入,两者的差异本身就是有价值的信息。
对账要自动化并且要能归因。只报差异不报原因的对账等于没做,人还是得手工排查。把常见的差异模式固化成归因规则,绝大部分差异系统自己就能解释掉。
有争议的规则不要在系统里替业务做决定。记录足够细的原始数据,把判断权交给使用者。限流拒绝算不算用量这种问题,本质是管理问题不是技术问题,系统提供事实就够了。
流式场景的计量要特别小心边界问题。分词缓冲区那个坑如果没发现,我们会一直多算百分之二点七,而且这个偏差是系统性的,很难被业务方发现,最后就是长期多收部门的钱。这类静默的错误比明显的报错危险得多。
分词器按模型版本管理,模型升级时分词器同步更新,历史数据保留当时的分词器版本号便于回溯。计量数据写入走异步批量,不阻塞主链路,批量间隔一百毫秒或攒够五百条触发。落账采用两阶段,会话开始时预占,结束时结算,防止长会话在统计窗口边界上被漏掉或重复。三级标签在鉴权环节解析,令牌里带部门和应用信息,用户 ID 做哈希后存储。对账任务的三方数据拉取做了失败重试和缺数告警,外部账单通过服务商的用量接口自动拉取。归因规则目前有十一条,覆盖了百分之九十六的差异场景,新出现的差异模式由人工分析后补充为规则。所有计量原始数据保留十八个月,满足审计要求。
上这套东西之前,最好先确认客户内部有没有一个能拍板口径的角色。我们运气不错,客户的信息化主管有这个权限,四次会开完就定了。见过另一个项目,财务、IT、业务三方谁也不愿意认口径,系统做得再准也落不了地,最后不了了之。计量分摊表面上是技术活,实际上七分是组织协调。这话可能不太中听,但确实是我们做下来最真实的感受。