资讯动态

智能LLM路由实战:按难度分模型,API账单狂省70%

发布时间:2026/10/18 20:18:34 来源:尧图企业网站定制
做AI应用这么久我头一回被一张API账单吓到4660元。看了一下明细我那个跑了两年的智能问答服务一个月费用直接翻了快三倍。仔细研究之后发现原因不复杂——我把所有请求都默认发给了旗舰模型。哪怕用户只是问了一句“你们周末上班吗”底层也要调用一次最贵的大模型来走完整个思维链。这就是我这篇内容想讲的核心怎么用智能LLM路由把请求按任务难度分给不同档位的模型在不明显影响回答质量的前提下硬生生把成本砍掉七成。这篇东西适合被大模型API账单折磨过的开发者、正在做Agent或客服机器人的团队以及所有想优化LLM调用成本又没有头绪的人。我不讲虚的全是我自己调账单、改架构、踩坑之后沉淀下来的实操记录。1. 账单爆炸的第一现场4660元都花在哪了1.1 账单明细扒开之后发现每个请求都在“高射炮打蚊子”先说背景。我这边维护的是一个偏向知识库问答和客服辅助的小系统总共就三个核心入口用户提问系统做语义匹配并生成回答后台会自动对每轮对话做摘要和打标每天还有一批工单需要自动分类和情感分析。之前这套系统一直用一家海外模型服务商的旗舰档模型一个月也就是一千多元。上个月因为给系统加了一轮复杂推理功能比如“结合用户历史订单和当前会话推断用户真实意图”我顺手把调度逻辑里的模型版本全部升级了。结果月底账单一看4660元。我把账单拉出来和用量曲线对了一下发现一个很扎心的事实有接近40%的请求输入输出都很短问的问题也非常简单比如“退款什么时候到账”“发票去哪开”。这些请求完全不需要旗舰模型的推理能力但因为我改了全局默认配置它们全走了最贵的通道。一整个月大量预算都烧在这种“高射炮打蚊子”的事情上。真正触目惊心的是输出token费用。我算了一笔账账单里的支出大头根本不是调用次数而是生成内容的价格。旗舰模型每百万输出token的价格是轻量模型的六倍以上而我的系统里有大量任务根本不需要那么长的输出。用户问一句“你们几点下班”模型却用八百字回答了一段官方客服话术。你说这钱花得冤不冤。1.2 把费用结构拆开你的钱其实花在三个地方我在复盘的时候做了个简单归类所有费用基本可以划成三条线。第一条线是输入token。只要你给模型发了消息不管它回不回答这部分的钱就已经产生了。有些人喜欢把一大段上下文、工具返回结果、系统提示词全部堆进去一个请求输入上万token是常事。问题在于默认旗舰模型处理输入的价格是轻量模型的五六倍。同样的上下文换一个模型档位成本差距非常明显。第二条线是输出token这是最能撕裂预算的部分。旗舰模型的单次回答质量确实高但它往往会把原本一句话能说完的事情扩写成一段话经常还带着“首先/其次/最后”这种结构。我在核查日志时发现每次客服问答的平均输出token接近400但其中真正有用的信息大概只有一半。这一半多的浪费乘以每天的调用量费用就非常可观了。第三条线比较隐蔽是重试和误调用。系统遇到超时或格式错误时会自动重试一次重试就是两到三次的费用。更麻烦的是有些请求明明应该走快捷回复或者知识库直接命中却被设计成了必须调用大模型。这一部分纯属架构设计问题因为你根本没有给非LLM路径留出位置。1.3 真正的问题不是用量涨了而是模型档位选错了我花了很长时间说服自己“是因为功能复杂度上来了所以成本高很正常”。但把日志按任务类型拆开之后我发现用量其实只涨了不到30%费用却涨了接近200%。这背后只有一个变量在起作用所有请求都从“默认中等模型”被切到了“默认旗舰模型”。换句话说我花了一笔钱买了一堆我用不上的推理能力。到这里问题已经很清楚不是要把用量砍掉而是要在模型选择上做文章。让简单任务走便宜模型复杂任务才走贵模型必要时加一点级联兜底。这其实就是“智能LLM路由”这个思路最朴素也最核心的出发点。别急着上什么玄乎的算法先把流量分对档位省下的钱立刻就能看到。2. 智能LLM路由设计先画任务分镜再谈省钱2.1 先把任务分档有些活儿根本不需要大模型做路由之前我先给自己定了个规矩别追求一步到位先盘点业务场景把任务分清楚。我按“必须上模型的等级”把系统里的任务划分为四个档位。第一档是“不碰模型”。关键词匹配能解决的、知识库里有精准答案的、模板话术能覆盖的一律不走大模型调用。比如“退款到账时间是多久”后台规则库里有现成答案直接返回就行。这一档看着不起眼但至少能拦住10%~15%的请求。只要拦住了这些请求的边际成本就是零。第二档是“轻量模型档”。任务特征是信息抽取、分类、改写、标签生成不需要多步推理对格式要求不高。比如给用户投诉自动打“物流/质量/售后”标签或者把一段客服对话压缩成两句摘要。这类任务轻量模型做得又快又便宜偶尔出错也完全能接受。第三档是“中等模型档”。任务特征是单轮推理、带少量上下文、需要结构化输出。比如“根据退换货政策判断这笔订单是否支持七天无理由”它需要模型理解政策条文但不需要跨多个数据源来回折腾。这个档位的模型速度和成本都比较均衡是主力档位。第四档才是“旗舰模型档”。我把复杂多跳推理、跨轮工具调用、生成式文本润色、矛盾信息判断这类任务归到这里。比如“结合用户三个月内的消费记录和上个月的投诉工单分析他的满意度趋势”这种任务信息分散、逻辑链条长才值得动用旗舰模型。这个分档表一旦建好路由问题就变成了分类问题每个请求进来先判断它属于哪个档位然后走对应的模型。听起来很简单但难点在于判断本身要快、要准、要便宜。如果你判断一个请求需要先调用一次大模型那省下来的钱就全被判断成本吃掉了所以判断要尽量用规则和轻量级语义手段完成。2.2 三种路由策略的取舍硬规则、语义路由、级联路由我在设计路由策略的时候没有直接选最流行的方案而是从稳定性和可控性出发做了三级递进。第一级是硬规则路由也是目前我用的主要手段。它基于关键词、接口类型、上下文长度、是否带工具调用等信号直接判定档位。比如请求带图片直接进旗舰档请求长度超过8000 token直接进中档以上用户问题命中“退款/发票/退货”这一类业务词且没有复杂句式直接进轻量档。硬规则最大的好处是零额外成本、执行快、完全可解释出了问题你知道为什么走了这条路。第二级是语义路由。当硬规则判断不了比如用户问的是“东西还没到但是上面显示签收了”这既涉及物流又涉及售后关键词也不好抓。这时我会用一个非常小的分类模型让它输出这个请求更偏向哪个业务域、需不需要多轮推理。这个小分类模型本身很便宜一次调用可以控制在几十token的输出量级。第三级是级联路由也叫“先便宜后贵”策略。请求先丢给轻量模型如果轻量模型返回的置信度低、格式不合法或业务关键字段缺失就把整个请求升级到上一档模型重新跑一遍。我在客服场景里把这种策略用得最多实测下来大约70%的请求在轻量模型这一层就能正常结束剩下30%升级到中等或旗舰总成本依然远低于全部走旗舰。选型时我放弃了“把路由判断交给大模型”的做法原因是成本不可控。你让大模型去当调度器等于每个请求多套了一层全量推理这笔额外开销通常比你省下来的还要多。用来做路由判断的模型必须足够便宜、响应足够快否则不如老老实实用规则。2.3 路由决策时的四个关键输入少了哪一个都会失控路由层不能只凭一句话就拍板我在实践里总结了四个必须收集的输入信号。第一个是任务类型或接口入口。这最简单也最实用。调用方来自哪个模块是问答、摘要、分类还是工单分析可以直接决定默认档位。我在代码里给每个模块都加了一个任务标记路由层拿到标记后优先参考它准确率非常高。第二个是输入长度和模态。上下文越长模型性价比越差但也往往意味着任务越复杂。输入超过6000 token时轻量模型的注意力可能已经不够用了强行走轻量会频繁出现漏信息。图像或文件类请求直接锁定旗舰档没法商量。第三个是输出格式要求。如果下游需要严格的JSON结构还要保证字段完整那么轻量模型容易翻车。这种请求要么走中等模型要么走级联先叫轻量跑一遍校验失败再升级。相比一次性上旗舰这种带兜底的方案长期算下来更划算。第四个是延迟预算。用户等在聊天窗口前超过五秒就烦躁后台离线任务跑十分钟也没关系。延迟敏感的请求我会优先选择速度快的轻量或中等模型必要时牺牲一点复杂推理换取体验。延迟不敏感的批量任务则可以直接走更便宜的大上下文模型。路由逻辑做完之后我还做了一件事给每一类请求都加了“成本标签”。每次请求结束把模型档位、输入输出token数、花费金额、是否触发升级全部写进日志。这一步一开始看起来麻烦但后面所有优化决策都离不开它。没有这笔账你根本不知道路由层到底省了多少钱、哪里又漏了钱。3. 路由层落地实现一套可以跑起来的方案3.1 先把模型接入层抽象好别让路由代码绑死在一家厂商上很多人做路由的时候容易忽略一个前置问题你的业务代码是不是已经和某个模型SDK深度绑定了如果到处都在直接调用厂商SDK路由层想要接管就得把所有地方都改一遍特别痛苦。我的做法是加了一层适配器接口核心就一个方法chat(messages, params)返回文本或结构化结果。至于背后调的是哪个厂商、哪个模型、哪个版本对业务代码完全透明。路由层只需要在收到请求后决定把请求交给哪个适配器实例即可。class ModelAdapter: def chat(self, messages, temperature0.3, max_tokens1000): raise NotImplementedError class LightModelAdapter(ModelAdapter): def chat(self, messages, temperature0.3, max_tokens1000): # 这里接入你选定的轻量模型API pass class HeavyModelAdapter(ModelAdapter): def chat(self, messages, temperature0.3, max_tokens1000): # 这里接入旗舰模型API并开启更完善的重试和超时控制 pass抽象这层还有个额外好处如果你想换掉某家模型供应商或者临时接一个新的模型来对比效果只需要新增一个适配器类。路由表的配置完全不用动。这也让我在上线路由层时可以用少量流量先做灰度确认稳定后再全量切换整个过程的改动面被压到了最小。3.2 决策引擎核心代码硬规则优先分类模型兜底路由决策引擎我写成了一个独立的类输入是一个请求对象输出是一个模型档位。整个流程走三关先跑短路口再跑硬规则最后才是语义分类和默认档位。class LLMRouter: def __init__(self, default_modelmid): self.default_model default_model # 关键词到档位的映射表 self.rules [ ([退货, 退款, 发票], light), ([报告, 对比分析, 深层次, 为什么], heavy), ] async def route(self, task_type, text, input_length, has_image): # 第一关图片直接进旗舰 if has_image: return heavy # 第二关根据任务入口判断 if task_type in (kbcategory, quick_chat): return light if task_type complex_analysis: return heavy # 第三关关键词规则 for keywords, target in self.rules: if any(k in text for k in keywords): return target # 第四关语义分类用一个轻量分类模型判断 return await self.semantic_route(text)注意我在这里刻意把“默认档位”设为中等而不是轻量也不是旗舰。这样做的考虑是当一个请求无法被规则分类时说明有点复杂但又不至于要动用旗舰中等档位是出错概率和成本之间的平衡点。如果你设置成默认轻量频繁升级会产生额外延迟设置成默认旗舰又容易让规则失去意义。我前面提到会用一个轻量分类模型来做兜底判断。下面是它的简化逻辑核心输出可以控制得非常短比如只返回“light/mid/heavy”三个词之一token开销极小async def semantic_route(self, text): prompt f判断下面请求需要哪一个档位的模型。 如果只需要简单分类、抽取、改写回答 light 如果需要带一点推理和上下文判断回答 mid 如果必须多步推理、处理冲突信息回答 heavy。 请求内容{text[:500]} 直接返回档位英文单词 result await light_adapter.chat([{role: user, content: prompt}], max_tokens10) return result.strip().lower()这个分类调用的成本你可忽略不计因为它的输出只有几个词输入也被我截断到了500字以内。而它带来的收益是能把硬规则漏掉的复杂请求准确分流到更合适的档位减少“该走重模型的走轻模型”导致的重试消耗。3.3 止损链路重试、升级、人工复核三层防线缺一不可路由层上线前我还加了一套止损机制。当时想的是省成本可以但不能以牺牲核心业务为代价。如果轻量模型把关键信息说错了用户投诉和后续纠错成本可能比省下的API费用还要贵。第一道防线是格式校验。轻量模型返回的内容只要不符合约定的JSON结构或缺少必要字段直接视为无效触发一次升级调用。这个过程在用户无感知的情况下完成用户最终拿到的一定是格式正确的结果。第二道防线是置信度阈值。部分模型接口直接返回置信度分数有些没有。我的做法是让路由层对特定任务额外要求一个score字段。比如情感分类的输出是“negative, score0.82”如果得分低于0.6就说明轻量模型自己都很犹豫值得用中等模型再跑一次。第三道防线是人工复核队列。每天抽取不超过5%的轻量模型结果推到后台由人工简单看一眼确认回答质量没有滑坡。别小看这个动作它不只用于质检还能反向校准你的路由规则。比如连续三天发现某类问题的升级率很高那就应该把这类问题直接固定到中等档位而不是让用户每次等升级重跑。下面这段代码是升级链路的简化实现。核心思路是每个任务携带一个max_attempts逐级尝试直到成功async def call_with_escalation(router, request): current_level await router.route(request.task_type, request.text, request.input_length, request.has_image) levels [light, mid, heavy] attempt 0 while attempt len(levels) - levels.index(current_level): model levels[levels.index(current_level) attempt] result await get_adapter(model).chat(request.messages) if validate(result): return result, model attempt 1 return result, heavy这里有个经验不要把重试次数设为无限。灯枯油尽时给用户一个兜底回答也比无限升级强不然一个坏请求可能烧掉四倍的钱还拖延响应时间。我的系统中任何请求最多升级两次再失败就走预设模板。4. 成本与质量双验证从4660元到1500元的实操记录4.1 一张成本核算表告诉你“省70%”是怎么算出来的我要强调一下省70%这种数字在不同业务形态下差异很大关键要看你的任务分布。所以我不直接空口说而是给你一张可以套用自家数据的核算表。我假设你用三个模型档位旗舰、中等、轻量平均每次请求输入1500 token输出400 token每月的请求量是3万次。价格我按公开常见的量级折算成人民币来举例旗舰模型输入60元/百万token输出200元/百万token中等模型输入25元/百万token输出80元/百万token轻量模型输入10元/百万token输出30元/百万token如果全部请求都走旗舰3万次请求的费用大约是输入费用 2700元输出费用 2400元合计 5100元。这跟我那张4660元的账单比较接近。加了路由之后我按实际日志里的流量比例来算60%请求走轻量30%走中等10%走旗舰。结果非常直观档位请求占比输入费用输出费用小计轻量60%270元216元486元中等30%338元288元626元旗舰10%270元240元510元合计100%878元744元1622元从5100元降到1622元降幅约68%再把一些短请求接入缓存和规则短路最后的账单大约在1500元上下。这正好对应我开头说的“狂省70%”。注意我没有把轻量模型的任务成功率当作100%账面上省下来的钱已经包含了一部分升级重跑的成本。4.2 质量指标不能只盯着账单我同时盯这三个数据省钱的代价绝对不能是回答质量崩塌。我给自己定了三条硬指标每周复盘一次。第一条是任务成功率。指的是请求最终是否返回了可用结果且通过格式和基础校验。全线旗舰时这个指标是99.6%切到路由之后因为有升级兜底最终成功率仍然保持在99.1%左右。差距很小却省下了大半费用。第二条是“升级率”。也就是有多少请求从轻量或中等被升级到了更高档位。如果某一类任务的升级率超过25%就说明初始档位定低了需要调整路由规则如果低于3%说明档位给高了可以往下压一档。我用升级率来做路由规则的持续调优比凭感觉改参数靠谱得多。第三条是用户侧体验指标。客服场景里是“是否最终解决”知识库场景里是“回答相关性评分”。这里没有统一公式必须和具体业务挂钩。我的经验是每调整一次路由策略至少要灰度三到五天对比这一条体验指标有没有下降。只有体验指标平稳省钱才有意义。4.3 哪些业务场景最适合先上路由哪些暂时别动不是所有应用都适合立刻上智能LLM路由。我梳理了一下适合与不适合的情况给你一个参照系。适合的场景通常满足两个条件任务类型差异大、单次调用成本占比高。首先是客服问答和知识库RAG简单问题占大头复杂问题只是少数天然适合分档。其次是内容安全审核、文本分类、情感分析、信息抽取这类流水线任务输出格式固定评估容易。再次是批量离线处理比如每天定期把一堆工单做摘要这种场景对延迟不敏感就算分错了重跑一遍也不影响用户体验。不适合的场景也值得说。如果你做的是长篇小说写作或代码生成输出的连贯性和创造力极其重要贸然把一部分请求切到轻量模型可能省了钱但毁掉产品核心体验。还有极少数硬核推理任务比如数学证明、复杂代码调试这类任务对模型能力极其敏感路由层的升级和重试机制反而可能引入更多不确定性我建议直接全程旗舰。不管适合还是不适合我都建议你先接好日志统计再做切换。没有数据支撑你根本不知道哪类请求在烧钱哪类请求本来就不该走大模型。5. 这三个月踩过的坑常见问题与排查实录5.1 最隐蔽的问题模型跳档之后回答风格不一致上线路由第一周我自己都没发现用户先发现了。有人反馈“同一个问题上午回答很简洁下午突然变得特别啰嗦完全像两个人”。我一查日志上午的请求走了轻量模型下午因为触发了升级链路最终由旗舰模型回答。这个问题的根源是档位切换后没有做出口风格的一致性控制。同一个路由层不同模型给出的答案长度、语气、标点习惯都不一样用户会立刻感知到。我的处理方法有两步。第一所有档位在系统提示词里都强制注入同一段“语气规范”把回答风格约束在相近范围内。第二路由层记录每个会话使用的档位同一个会话内尽量维持同一个档位不出现“轻量开场、旗舰续答”这种割裂情况。实在需要升级时也会在回复结构上做统一比如固定“结论依据补充说明”的段落结构。5.2 Prompt缓存命中率暴跌问题出在路由前缀第二个坑把我折腾了挺久。某家模型服务商支持Prompt缓存第一次调用后相同前缀的内容第二次调用费用能下降很多。但我上了路由之后发现缓存命中率几乎归零省下的钱又被缓存损失吃掉了一部分。排查后发现原因很蠢我在不同档位的请求里拼接了不同的路由指令前缀。这就导致同一用户的同一段会话每分钟生成的新前缀都不一样缓存完全失效。解决办法是固定缓存前缀。我把系统提示词、用户画像、品牌知识等静态内容固定为统一前缀而且把这个前缀放在消息数组的头部只有靠后的动态问题部分变化。这样一来相同前缀就能被不同请求共同命中缓存费用立刻降了下来日后的调用成本又多省了一截。5.3 日均请求不到一千次就别费劲折腾路由了我也给朋友的建议踩过反面教材。当时有个项目一天就几百次请求全走旗舰也就几百块但我兴致勃勃给他搭了一整套路由规则、语义分类、升级链路。最后发现路由层本身的开发和维护成本远超省下的API费用。优化成本这件事是有门槛的。我的经验是月API账单低于两千元或者日请求量长期低于一千次优先做两件事就够了一是把所有同类型简单任务锁定到轻量模型二是把重复静态内容做成缓存。这两步能覆盖80%的浪费不需要做完整的智能路由。等请求量真的大到每月大几千元账单时再上本文这套系统式路由投入产出比才明显。5.4 千万别让大模型去做路由调度等于双重收费最后这个坑比较反直觉。我曾经尝试让一个中等模型来当“调度员”替每个请求决定应该走哪个档位的模型。想法很美但实际跑起来之后账单反而更高了。原因非常直接每进来一个请求都要多花一次中等模型的完整调用来完成“调度判断”这个判断本身不仅耗输入还有不短的输出。如果你的原始请求是轻量档这个调度费用甚至可能比任务本身还贵如果你的原始请求是旗舰档等于你额外支付了一次“咨询费”让中间商再薅一层羊毛。所以我的建议很明确路由决策层一定要保持轻量。能用规则就规则实在不行用极小模型输出长度控制在50token以内坚决不要用旗舰或中等模型做大规模调度。路由层越厚越容易出现“为了省钱而花更多钱”的怪圈。最后分享一点点个人体会。做了这轮优化之后我最大的感受是智能LLM路由的本质不是让你学会更多花哨算法而是让你重新审视每一个请求是不是真的需要那么贵的算力。先把账单拆明白再把任务分清楚最后才轮到技术方案。路由层的代码可以写得很简单但日志和核算一定不能省。用数据说话你才能既保住体验又把每一分钱花在刀刃上。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑