做LLM应用落地的人,迟早要面对同一个尴尬:模型池越来越大,但真正能在自己业务里稳定可控的没几个。我这次想聊的是Not Diamond——一个在请求层面做LLM路由的选择器。它做的事其实很聚焦:把多条用户请求发给它,它根据请求特征、候选模型和你的偏好,自动挑出最适合的那个模型来应答。
标题里的llm90,是我之前在一组模拟项目里做的路由对比实验代号,那段时间围绕Not Diamond做了一轮完整的选型评估。如果你也在纠结“同一批请求到底该用哪个模型”“怎么在质量和成本之间自动取平衡”,这篇应该能帮到你。我会把整个案例的解析思路、接入细节、踩坑记录都拆开来讲,尽量还原我当时实际操作的过程,而不是只给结论。
1. 为什么我会盯上Not Diamond这个路由选择器
1.1 单模型策略的成本陷阱
先说说痛点。
我手上有个长期维护的智能问答项目,说白了就是一套RAG加多Agent的任务分发。早先为了效果好,所有用户请求无脑走当时最强的模型。效果确实稳,但账单相当吓人——每天近百万token的请求,全用旗舰模型,一个月的推理成本高得离谱。
后来我尝试换便宜模型,质量又撑不住。用户问“帮我总结这段合同风险”,便宜模型给出的答案经常漏掉关键条款,反而更费人力去校验。那时候我意识到一个核心问题:不同请求对模型能力的需求差异极大,而单模型策略只适合“求稳”或“求省”,没法同时在两头上岸。
1.2 路由选择不是“规则匹配”,而是在线决策
当时我也想过自己做一套分流逻辑,比如按关键词、按问题长度、按意图分类来路由。结果发现规则一多就崩:你根本写不完所有边界情况。
举个例子,用户问“我的订单什么时候能到”,看起来是个简单查询,但如果附带了“如果延迟了怎么赔偿”这种隐含诉求,它其实是个多轮推理问题。关键词规则根本区分不出来。
Not Diamond的思路不一样。它把路由当成一次实时决策:请求进来之后,由路由层预估每个候选模型的表现,再结合你期待的“质量、成本、延迟”权重,动态选一个。它不是靠写死规则,而是靠模型对语义和任务难度的理解去做判断。
1.3 它适合谁,不适合谁
这半年试下来,我的感觉是:Not Diamond最适合那些调用量大、请求类型杂、既有质量要求又在意成本控制的应用。典型的就是客服问答、Agent工具调用、RAG管道的上游分发、内容分类这类场景。
不太适合的场景也有。如果你业务里只有一种固定任务,比如只做摘要,那直接用调好的单一模型就够了,没必要引入一层调度;如果是离线批量处理,对延迟不敏感,那也可以慢慢算,不用实时路由。
2. 核心机制拆解:NDLite、偏好微调与动态权衡
2.1 请求级别的路由判定
我们要理解一个关键差异:Not Diamond路由的粒度是“请求级”,不是“对话级”。
也就是说,同一个session里的每一条用户消息,都可能被路由到不同模型。这听起来有点反直觉,因为大部分基于会话的应用都希望保持模型一致。但实际效果反而是优点:对话过程中,有些轮次只需要确认信息,有些轮次需要强推理,让每一条消息各找各的最优模型,整体体验是上升的。
我一开始很担心换模型会导致回答风格漂移。后来发现,只要系统提示词和上下文是一致的,用户在多数场景下感知不到背后的模型切换,反而会觉得“回答质量一直在线”。
2.2 NDLite:轻量模型只做“分诊”
Not Diamond在官方机制里提到一个核心组件叫NDLite,我的理解是:一个在云端跑的小模型,专门负责为每个请求做“分诊”。
它不负责生成内容,只负责判断“这个请求应该找谁”。可以类比成一个技术团队里的需求分诊人:不写代码,但很清楚哪些需求该派给前端、哪些该派给后端、哪些需要架构师介入。
NDLite的好处是轻量。路由决策本身的延迟很小,官方给的数据通常不到50毫秒级别的增量,我在实际批量压测中感受也差不多。这对在线场景很重要——如果路由层就要花几百毫秒,那还不如直接用最强模型。
2.3 偏好微调:让路由器长在你的数据上
这算是Not Diamond比较核心的一个功能:偏好微调。
默认情况下,它靠通用能力做路由。但它还支持用你自己的偏好数据去校准路由策略。简单说,你把一批请求的“好回答”和“差回答”喂给它,它学会区分在你业务里什么样的模型输出是好的,以后路由就更贴合你的场景。
我实际使用下来,这个校准太重要了。通用路由再聪明,也不懂你业务里“好”的定义。举个例子,我们团队希望代码生成类请求优先准确率、风格统一;而问答类请求优先语气友好。这些偏好如果不显式告诉路由器,光靠模型能力打分是不够的。
2.4 质量、成本、延迟的三角关系
Not Diamond有一个很直观的配置概念,就是tradeoff参数。你可以在一次请求里指定一个列表,比如质量优先、成本优先、延迟优先。路由器会按这个优先级顺序去选模型。
这背后其实是一个多目标优化问题。我测试后的体感是:如果质量排第一位,它倾向于选择更强的模型;如果你明确把成本放前面,它会更多考虑低价模型;只有当两者接近时才考虑延迟排序。
这个设计比“一键均衡”要实用得多,因为不同业务阶段的诉求完全不同。我们在上线初期偏质量,稳定后就开始偏成本,这种调整在路由层改一行配置就行。
3. 集成实操:从初始化到偏好校准一条线
3.1 安装与初始化
先说环境。我用的是Python SDK,安装很直接:
pip install notdiamond然后初始化客户端,需要到控制台创建项目拿到API Key:
from notdiamond import NDClient client = NDClient(api_key="你的_API_KEY")这里有个小坑:API Key有权限范围,创建时要注意勾选“路由调用”的权限。我第一次只勾了管理权限,结果调用时报401,排查了半天。
3.2 构造第一次路由请求
基本调用长这样:
messages = [ {"role": "system", "content": "你是智能客服助手,回答简洁准确。"}, {"role": "user", "content": "用户要退款,但订单已发货,怎么处理?"} ] response = client.chat.completions.create( model=["gpt-4o", "claude-3-5-sonnet", "llama-3-70b"], messages=messages, max_models=3, tradeoff=["quality", "cost"], )model参数传的是候选模型列表。这里的意思不是你一次性调用三个模型,而是让路由器从这三个里面挑一个来生成回答。
我测试时发现一个容易误解的地方:max_models不是“最多调用几个模型”,而是路由器在决策时会考虑的候选模型数量上限。如果给3,它就从列表里选最优的一个;如果给1,那跟指定单个模型就没什么区别了。
3.3 关键参数怎么填
tradeoff参数是我觉得最值得细说的。它不是单选,而是按优先级排序的列表。
取一个实际场景:客服机器人在线请求,延迟不能太离谱,但质量也不能差太多。我一般这么配:
tradeoff=["quality", "latency", "cost"]如果只是内部日志分析这类任务,不实时,我就会配成:
tradeoff=["cost", "quality"]注意:别一次六个参数全塞进去。路由器的优化空间是有限维度,你给得太杂,它反而难以取舍。清晰的三项优先级比五项模糊参数要有效得多。
3.4 怎么知道最终调了哪个模型
刚接入的时候我一直在找“到底路由到谁了”的日志。其实SDK的返回对象里就带:
print(response.model) print(response.provider) print(response.finish_reason)response.model就是实际生成回答的模型名,response.provider是服务提供方。这两个字段我强烈建议写到日志里,不仅方便排查,还能长期积累“路由分布”数据。
我跑了一周后发现,在这三个候选模型里,gpt-4o占了差不多一半的调用量,剩下的一半由另外两个模型分配。这个分布如果和你的预期差太多,就该检查是不是tradeoff配错了。
3.5 偏好数据收集与校准流程
偏好微调是我认为最值得花时间的环节。它的思路是准备一组对比数据:同一请求,哪个回答更好,哪个回答更差。
数据格式大致是这样的:
| 请求文本 | 更好的回答 | 更差的回答 |
|---|---|---|
| “这个产品支持导出哪些格式?” | 回答A(简洁枚举) | 回答B(啰嗦但齐全) |
| “帮我把这封邮件写成正式英文” | 回答C(正式得体) | 回答D(太口语化) |
数据准备好之后,调用校准接口。我当时用的是通过SDK传preference_id的方式,把一组正负例数据关联到某个校准任务上。路由器会基于这些对比重新校准自己的路由策略。
这里提醒一下:校准不是一次性的。业务需求会变,用户提问方式也会变,我建议每两周做一轮增量校准,把最近积累的bad case沉淀成新的偏好数据。
4. 一组真实跑过的对比数据与成本测算
4.1 测试集设计和指标定义
我在模拟项目里准备了一套500条的真实脱敏请求,混合了简单问答、复杂推理、多轮对话、代码生成和日志摘要五类任务。
质量评估采用人工打分加自动判题结合的方式:人工看语义完整性、准确性和格式合规性,自动判题用来校验硬性要求。成本按token单价估算,延迟统计从发出请求到拿到完整响应的时间。
4.2 单一模型与路由方案的对比
我拿三套方案做了横向对比:
| 方案 | 质量分 | 千次调用成本 | 平均延迟 |
|---|---|---|---|
| 全部走gpt-4o | 92.4 | 4.8元 | 1.2秒 |
| 全部走llama-3-70b | 78.1 | 0.6元 | 1.8秒 |
| ND路由+三个候选 | 90.2 | 1.5元 | 1.3秒 |
这个结果很能说明问题:ND路由比“全便宜模型”质量高了12分,比“全贵模型”成本省了约68%,代价是质量分只降了2分左右。
我在后续调整tradeoff为成本优先之后,千次调用成本降到了0.9元,质量分掉到87.5。这套配置适合做大规模初审场景,不适合直接面对终端用户。
4.3 延迟增量到底有多大
路由器本身有判断开销。我压测下来,路由决策的耗时增量通常在30到80毫秒之间,具体看网络和候选模型数量。
这个增量在交互式应用里基本可以接受。真正影响延迟感知的其实还是目标模型本身的生成速度,以及多轮上下文变长之后的处理时间。
我建议在接入路由前,先统计一下你当前模型调用的平均延迟。如果本身就是1.5秒以上,那路由层那几十毫秒可以忽略;如果你的应用要求首字延迟小于500毫秒,那就需要多考虑网络节点位置,必要时开更近的区域接入点。
4.4 路由器不是银弹
说了这么多好处,也得讲点边界。
第一,如果你业务核心是强指令任务且只用一个模型就能稳定解决,路由不会带来太大收益。第二,如果你的请求量很小,一个月才几万调用,引入路由省下的钱可能还不如你花在调试上的时间成本。第三,偏好校准需要持续投入,不是配一次就一劳永逸。
用一句话总结我的经验:路由适合“量大、类杂、有取舍空间”的业务。它是在已有的模型选择里做乘法,而不是在模型能力上做加法。
5. 常见问题与排查心得
5.1 配置层面的坑
认证失败我遇到过好几次。第一次是API Key权限没勾全,换了新Key也报错,后来进控制台重新生成才解决。第二次是模型名称写错,候选列表里写了一个不存在的模型名,路由器整个请求直接报错。
排查这类问题我总结了一个流程:先用官方示例请求跑通,再逐步加自己的参数。千万别一开始就上复杂配置,不然你分不清是参数错还是网络错。
5.2 路由效果不稳定的调试思路
有段时间我发现路由结果波动很大,同样的请求,上午路由到gpt-4o,下午路由到llama-3-70b。后来排查发现,问题不是路由器抽风,而是我的tradeoff里同时放了质量和成本,路由器在不同时间点对“最优解”的判断产生了摇摆。
调试思路是先固定tradeoff,比如只测质量优先,跑几天看分布;再只测成本优先,看分布变化。最后再切换组合,这样你能很清楚地看到每个参数的影响,而不是黑盒状态。
还有一次路由后返回的内容特别差,查了日志才发现是候选模型里有一个服务的响应超时,路由器启用降级策略,换到了备用模型。这不算是bug,但提醒我要在日志里把路由原因也打出来,不能只看最终模型。
5.3 问题速查表
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 401认证失败 | API Key权限不足 | 重新生成Key并勾选路由权限 |
| 模型名报错 | 候选列表含不存在模型 | 核对控制台上的准确模型ID |
| 同一请求路由结果反复变化 | tradeoff权重太均衡 | 明确优先级,减少优化目标数量 |
| 响应质量突然下滑 | 某个候选模型超时降级 | 检查服务状态,调整候选模型池 |
| 日志里看不到路由原因 | 未记录返回元数据 | 将response.model和provider写入日志 |
踩过这些坑之后,我的一个核心心得是:路由器不是一个可以“配完就不管”的组件。它需要你像养推荐系统一样,持续观察分布、持续校准偏好、持续维护候选模型池。如果你没有这个运维预期,那它带给你的麻烦可能比省下的钱还多。
我个人在实际操作中的体会是:Not Diamond这类路由选择器的价值,不在于取代最强模型,而在于让中等模型在合适的请求上发挥出接近最强的效果。它的隐藏收益其实很可观的——质量稳定、成本可控,同时能把团队从“人工挑模型、写规则分流”里解放出来。如果你现在还在靠手工维护一张“什么请求用什么模型”的映射表,我觉得可以认真考虑测一下路由方案,先小流量跑一两周,看看分布和质量是不是符合你的预期。
最后再分享一个小技巧:每次校准偏好数据时,把那些“人工排查过、确认答案有硬伤”的bad case单独建一个集合,持续积累,等量足够后再统一训练。这个集合比随便采样的反馈数据有用得多,因为路由器的本质是在边缘上做取舍,只有真正暴露过问题的数据才能帮它避开将来的大坑。