最近被低价 API 中转站折腾得有点累,也顺手做了一个 OpenRouter 网关
事情起因很普通。
我平时会用 API 接 Cursor 、Grok Builder, Claude Code 、Codex 等工具。之前找过一些价格看起来很便宜的中转服务,刚开始没觉得有什么问题,但用一段时间后,偶尔会发生一种很奇怪的情况:
明明客户端选的还是同一个模型,模型表现却突然断崖式下降。
具体表现包括:
- 前面刚交代过的上下文,几轮之后就忘了;
- 重构代码时漏文件、改错调用关系;
- 工具调用格式突然变得不稳定;
- 长对话越到后面,回答越像只看到了最后几条消息;
- 同一个模型昨天还能处理的任务,今天突然开始反复犯低级错误。
一开始我以为是模型本身有波动,或者客户端更新后改变了系统提示词。后来我分别检查了客户端请求、流式响应和 Token 使用情况,又用官方渠道对相同任务做了几组对照,才发现问题未必出在模型本身。
有些中转服务可能会缩短上下文、改写请求参数、压缩历史消息,或者将请求路由到成本更低的模型和渠道。客户端显示的模型名称没有变化,实际收到的服务却可能已经不是一回事。
当然,仅凭某一次回答质量下降,不能证明服务商一定替换了模型。模型输出本身存在随机性,供应商也可能调整推理配置。
真正让我放弃一些中转服务的,是多次对照后差异依然明显,而且请求路由、用量统计和扣费方式都无法核验。出了问题,只能得到一句“模型最近有波动”,用户几乎没有办法继续追查。
试过几家以后,我发现常见的问题大致有以下几类。
一、模型名称没变,实际路由却不透明
面板上选择的是一个模型,但请求最终经过了哪个上游、使用了哪个版本、有没有发生自动降级、上下文是否被裁剪,用户通常看不到。
有些平台甚至会在主渠道失败后,静默切换到便宜模型。请求不会报错,客户端也能继续收到内容,但回答质量、上下文长度和工具调用能力已经发生变化。
便宜本身不是问题。平台使用混合渠道、负载均衡或者备用模型,只要提前说清楚,也可以是一种合理的产品方案。
问题在于:页面按高价模型展示和扣费,后台却在用户不知情的情况下换成另一套东西。
二、“美元当人民币”的价格错觉
有一种很常见的宣传方式,是把官方价格里的美元数字直接换成人民币数字。
假设官方价格是 3 美元,平台页面写成 3 元人民币,然后宣传自己是“官方价格的低至一折”或者“美元当人民币”。
第一眼看上去确实非常便宜,但这只是入口价格。后面往往还会叠加:
- 模型倍率;
- 分组倍率;
- 渠道倍率;
- 输入和输出的不同倍率;
- 缓存 Token 倍率;
- 充值兑换比例;
- 高峰期或特殊线路倍率。
比如页面显示 1 元,结算时先乘模型倍率,再乘渠道倍率。最后到底相当于官方价格的几折,不能看首页标价,必须把所有系数乘完才能知道。
“美元当人民币”也不是天然有问题。如果平台真的按这个比例结算,并且把补贴范围、限额和持续时间写清楚,那就是正常促销。
真正容易误导人的,是只突出最便宜的换算口径,却把决定实际价格的倍率放在后台、文档角落,甚至在使用过程中调整。
三、用“积分”模糊真实成本
积分是另一个很容易让人失去价格感知的设计。
充值 100 元,到账可能显示成:
- 100 积分;
- 1,000 积分;
- 100,000 点额度;
- 100 美元余额;
- 700 元“模型额度”。
数字变大以后,余额看起来很多,但用户很难立刻判断一次请求到底花了多少钱。
有的平台还会同时存在多套换算关系:
人民币先兑换成积分,积分再按照模型倍率扣除;赠送积分和充值积分的有效期不同;不同渠道使用不同积分价格;活动结束后兑换比例又会变化。
这时即使后台显示“本次消耗 23,000 积分”,用户也很难直接回答三个问题:
- 这次请求实际花了多少人民币?
- 相同用量走官方渠道需要多少钱?
- 所谓的低价,算完全部倍率后还剩多少?
我现在判断价格是否透明,会直接尝试把一次请求还原成人民币成本:
实际成本 = 充值金额 ÷ 实际获得的可用额度 × 本次扣除额度
如果中间还有模型倍率、渠道倍率和积分兑换,就继续全部展开。只要无法通过账单复算,我就不会把面板上的“单价”当成真实价格。
四、平台统计的 Token 很难复核
有些平台显示的 Token 数量,与客户端估算或上游返回的 usage 差异很大。
这里同样不能看到差异就认定平台在多扣费。不同模型采用的分词器不同,系统提示词、工具定义、图片输入、缓存 Token 和推理 Token ,也可能造成统计口径差异。
但一个相对透明的平台,至少应该说明:
- 计费依据是客户端估算还是上游 usage ;
- 系统提示词和工具定义是否计费;
- 缓存命中、缓存写入分别怎么计算;
- 推理 Token 是否包含在账单中;
- 最终费用经过了哪些倍率。
如果平台只能展示一个最终扣费数字,却无法解释它是怎么计算出来的,那么单价再低也很难真正比较。
五、SSE 流式连接不稳定
代码生成到一半 SSE 断开,对普通聊天来说,可能只是重新问一次;但对编辑器和 Agent 工具来说会比较麻烦。
工具调用可能只返回了一半,客户端不知道应该重试还是继续。有时模型已经执行了一部分文件修改,但后续说明和检查没有返回,最后留下一个改到一半的项目。
偶尔断流很正常,网络、上游服务和客户端都可能出问题。真正影响使用的是频繁断开,而且平台没有合理的超时、连接释放和错误反馈机制。
怎么初步判断中转站有没有偷偷换模型?
很多人会问,能不能直接探测出中转站背后到底是什么模型。
答案是:可以通过客户端和对照测试发现不少异常,但通常无法只凭几段回答,百分之百证明背后就是某一个具体模型。
比较实用的方式,是选择自己熟悉的客户端,例如 Claude Code 、Codex 、Cherry Studio 或其他能够查看请求与响应信息的工具,准备一组固定测试,再分别通过官方渠道和中转渠道运行。
我一般会观察以下几个方面。
- 上下文长度
准备一段足够长、带有多个细节标记的上下文,在后续问题中随机询问前面的信息。
如果页面宣称支持很长的上下文,但达到某个长度后,前文开始稳定消失,就需要怀疑平台是否裁剪了消息、限制了请求体,或者路由到了上下文更短的模型。
- 工具调用能力
给模型提供固定的工具定义,测试它能否持续按照要求生成正确的调用格式、参数类型和调用顺序。
不同模型在工具选择、参数约束和并行调用上的表现往往有差异。某个渠道如果突然从稳定调用变成频繁输出错误 JSON ,通常值得进一步检查。
- 固定代码任务
准备一个不涉及实时信息的小型代码仓库,设计几组可重复的任务,例如跨文件重命名、调用链修改、测试修复和约束条件较多的重构。
不要只比较回答措辞,而要比较:
- 是否读取了必要文件;
- 是否遗漏调用点;
- 能否遵守项目约束;
- 是否正确使用工具;
- 修改后测试能否通过;
- 多轮之后是否仍然记得最初目标。
代码任务比“你是什么模型”更有参考价值。直接询问模型身份通常不可靠,因为模型可能复述系统提示词中的名称,也可能根本不知道实际路由。
- 响应元数据
如果客户端允许,可以查看响应中的模型字段、usage 、请求标识、供应商信息和错误格式。
一些转发服务会重写这些字段,所以它们不能单独作为证据。但如果模型字段、Token 统计、上下文上限、错误格式和官方渠道同时存在明显差异,通常能找到一些线索。
- 多次重复对照
同一个提示至少运行多次,并尽量保持温度、工具、上下文和其他参数一致。
单次回答变差可能只是随机波动;如果中转渠道持续在上下文、代码能力、工具调用和响应特征上表现出另一类模型的特征,才更值得怀疑。
很多不透明的中转服务,单独看某一项都可以解释,但放在一起往往会露出马脚:
页面写着大上下文,实际长对话很早就遗忘;响应里显示高价模型,工具调用能力却长期不匹配;后台 Token 消耗异常,账单又无法还原;同样的任务切到官方渠道后,成功率马上恢复。
这些现象不能直接当成“实锤”,但足以作为停止充值、要求平台解释或者更换渠道的理由。
最后还是回到了 OpenRouter
折腾一圈后,我还是回到了 OpenRouter 。
原因并不复杂:模型比较全,价格和上游信息相对容易核对,也能通过返回信息检查实际路由。它当然也不是绝对完美,但至少很多信息有机会复核。
不过,我在国内网络环境下使用时,偶尔会碰到连接和流式传输不稳定的问题。同时,我和几个朋友还有共享额度、密钥隔离和防止异常消耗的需求。
于是花了两天写了一个很薄的 OpenRouter 网关。
它没有做模型聚合,也没有自己采购所谓的低价渠道。上游只有 OpenRouter ,网关主要处理以下几件事。
- 请求尽量原样转发
网关不修改请求正文里的模型名称、消息内容、上下文和生成参数,也不做自动模型降级。
鉴权、Host 以及逐跳传输 Header 会按照代理协议正常处理。如果宣称所有 Header 一个字节都不改,反而不太符合实际。
- 保留可以复核的用量信息
计费以 OpenRouter 返回的用量和成本信息为依据,不再增加一套积分体系,也不叠加模型倍率和渠道倍率。
每次请求可以记录模型、时间、Token 使用量、上游请求标识和费用,方便使用者自行对账。余额直接对应实际成本,不需要先把积分换成美元,再把美元乘倍率换回人民币。
- 优化 SSE 转发
流式响应不会先缓存完整内容再一次性返回,而是在读取到上游事件后及时向客户端转发。
同时关闭可能影响实时性的代理缓冲,设置连接、首字节和空闲超时,并在客户端主动断开时释放上游连接,避免生成任务已经结束,后台请求却还在继续消耗额度。
目前测试过 Codex 、Claude Code 、OpenClaw 、Cherry Studio 等客户端。
我不太想宣传“保证永不断流”。更准确的说法是:在我当前的线路和测试环境下,长连接比直接访问稳定,暂时没有发现明显的协议兼容问题。以后如果线路或上游环境变化,仍然可能遇到故障。
- 给共享使用增加一层限制
每个人使用独立的访问密钥,可以分别设置额度、并发数和速率限制。
这样不需要把 OpenRouter 主密钥直接发给所有人。某个密钥泄露时可以单独吊销,也能限制单日消耗,避免脚本失控或者密钥被盗后一次性刷完全部余额。
这个项目要解决的不是“怎样比官方更便宜”,而是:
怎样在保留 OpenRouter 模型、路由和计费逻辑的前提下,让网络访问、多人共享和费用核对更省心。
我也不想把它包装成一个“绝对可信”的中转站。
任何经过第三方服务器的 API 请求,本质上都增加了一层信任成本。比起相信“无损”“纯净”“不掺水”这些宣传词,更实际的判断标准是看它是否允许用户核验:
- 模型名称和生成参数有没有被修改;
- Token 使用量能否与上游响应对应;
- 是否保留可追踪的上游请求标识;
- 路由失败时会不会静默更换模型;
- 充值金额、余额和实际费用能否直接换算;
- 是否存在积分、模型和渠道等多重倍率;
- 日志记录哪些内容、保存多久;
- 能否限制密钥权限并单独查看账单。
如果数据特别敏感,最稳妥的选择仍然是直接使用模型官方 API ,或者自行部署一个足够薄、代码可审查的网关。
我做这个项目,主要是因为自己和身边的人确实有需求。它更适合已经决定使用 OpenRouter ,但希望改善国内连接、共享额度和账单管理的人。
如果后续有人感兴趣,我可以再整理一篇技术说明,把请求转发、SSE 、超时处理、用量核对、限流机制,以及如何设计一组相对可靠的模型对照测试分别写清楚。
也欢迎大家分享自己遇到过的计费套路和探测方法,但最好附上可复现的测试过程。与其争论某个平台“良不良心”,不如看它能不能让用户把模型、用量和每一笔钱核对清楚。