一个跑在Apps Script里的线索分类任务,每个月要处理60000次调用,每次大约800个输入token和60个输出token。之前一直用旗舰模型跑,因为代码里接的就是它。按claude-opus-5的公开列表价算,一个月成本330美元。换成gemini-2.5-flash-lite,同样的调用量,一个月6.24美元。
Prompt没改,表格没改,这个任务本身的准确率也没有可感知的变化——变的只是哪个模型在回答问题。从330美元到6.24美元,意味着同一个调用点可以触达多个提供商,而不是被某一个模型的价格绑死。
![]()
三个提供商,三个不同的坑
通常的说法是这事很简单,因为在Apps Script里三个模型长得一样:都是UrlFetchApp.fetch()打一个REST端点,prompt放body里,key放header里。传输层确实一样,但代码层有三个具体差异,而且每个差异的失败方式都是静默的,不报错。
第一个差异是系统提示词放哪。Gemini把它作为顶层的systemInstruction对象;OpenAI把它作为messages数组开头一条role为"system"的消息;Claude把它作为顶层的system字符串,而messages里的system消息是另一个功能,规则完全不同。把Gemini格式的请求体发给OpenAI,系统提示词会悄悄消失——没有报错,只是模型无视了你确信自己发出去的指令。
第二个差异是key放哪。Gemini读x-goog-api-key,OpenAI读Authorization: Bearer,Claude读x-api-key,而且Claude还额外要求一个anthropic-version头,另外两家没有对应物。
第三个差异是输出上限是否必填。Gemini的generationConfig.maxOutputTokens和OpenAI的max_completion_tokens都是可选的,Claude的max_tokens是必填的——一个把输出上限当可选参数的helper,对两家没问题,对第三家直接返回400。
一个注册表管住路由和价格
作者最终用一个对象同时保存路由词汇和价格,这样一条路由永远不会指向成本函数不认识的模型。这个MODELS对象是价格变动时唯一需要编辑的地方,里面记录了模型ID、提供商和每百万token的公开列表价(2026年9月读取,做商业测算前需要重新核对)。
任务到模型的映射函数pickModel返回的是模型ID而不是"便宜"之类的标签,这样路由用的字符串和MODELS的键是同一个,不会出现对不上号的情况。classify和tag任务走gemini-2.5-flash-lite,extract走gpt-5.6-luna,reply走claude-haiku-4-5。
这个路由器的核心价值不在于选哪个模型,而在于把"哪个模型"变成了一个可配置的变量。价格变动时改一个对象,任务分配变化时改一个函数,调用代码本身不需要动。对于跑在Apps Script里的自动化任务,这种解耦意味着成本优化不再需要重写业务逻辑。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.