想象一下:一位用户打开你的技术支持聊天窗口,输入:“你们的营业时间是几点?”
在你的后端某个地方,这个五个字的问题被路由到了一个你可能用来调试 Kubernetes 网络故障、解释微服务分布式追踪的高级模型(比如 Claude、OpenAI)。模型在两秒内返回了答案。用户说了句谢谢,关掉了聊天窗口。
你刚刚在一个远小得多、便宜得多的模型同样能回答的问题上,消耗了前沿模型的 token。再把这个场景乘以你的技术客服机器人每天处理的数千个类似查询。
这是开发者在构建 AI 驱动的应用时最常犯、也最昂贵的错误:选一个模型,然后到处用它。不是因为这是正确的架构决策,而是因为这是最简单的。一个 API 密钥、一个端点、一个硬编码在配置文件里的模型名称,你就能上线了。
问题在于,并非所有“提问”生来平等。一个回答真实客户问题的技术支持机器人会处理范围广泛的提问,有的简单到极点,有的极其复杂。一般性的常见问题——比如营业时间、退款政策、账号设置——需要的是快速且便宜的回复,而不是昂贵的推理引擎。账单纠纷需要一定的上下文理解能力和措辞谨慎,因此一个中档模型更加合适。但如果有客户报告说,他们的 GPU 服务器推理工作负载在驱动更新后产生了不一致的输出?这真的需要一个具备深厚技术知识的强大模型。
当你对这三种情况都用同一个模型时,要么在简单的问题上多付了钱,要么在困难查询上推理能力不足。两种结果在生产环境中都不可接受。
更好的做法是按照复杂度进行路由,让模型匹配任务,而不是匹配习惯。将简单查询发送给轻量级模型,将前沿智能留给真正需要它的请求,并让基础设施自动做出这个决策,而不是自己写硬编码或写一堆 if-else 条件。
这正是你将在本教程中会学习到的。从一个真实的 Python 客服机器人示例开始,你将把它连接到 DigitalOcean 的推理路由器,该路由器会根据你一次性配置好的任务定义对每个传入的请求进行分类,并自动匹配合适的模型。你的应用代码里不需要路由逻辑,不需要管理多个大模型的 API 密钥,也不需要在查询模式改变时手工维护那脆弱的 if/else 决策树。
为什么“一个模型包打天下”是设计缺陷
DigitalOcean AI 云平台现在包含了一个推理路由层,帮助应用智能地将 AI 请求发送到不同的模型。推理路由器不再为每个请求使用同一个模型,而是充当应用和多个大语言模型之间的智能流量管理器。
应用 → 推理路由器 → 不同的 AI 模型
由路由器来决定:
- 应该由哪个模型处理请求
- 是优先考虑速度、质量还是成本
- 当某个模型变慢或不可用时,何时回退到另一个模型
例如:
- 简单的常见问题查询 → 较小的低价模型
- 代码生成 → 更强的编码模型
- 长推理任务 → 更大的推理模型
- 视觉任务 → 多模态模型
应用仍然使用单一的 API 端点,而路由器在后台处理复杂性。
AI 智能体通常在单个 AI 流水线中执行不同类型的任务,例如:
- 摘要
- 检索
- 规划
- 代码执行
- 视觉理解
对于智能体的不同步骤,不同的模型可能更合适。路由让智能体可以为每项任务选择最佳模型。
随便找一个过去两年内构建的 AI 驱动应用,你都会在后端发现同样的模式:一个模型,一个端点,每个请求都被同等对待。这能跑,能上线。但它悄无声息地成了代码库中最昂贵的架构决策之一。
要理解原因,你需要深入到每一个具体的“查询/请求”这个层面,去分析“每一条请求本身”发生了什么。
想象一个客服机器人在一天内处理真实的客户流量。它收到的查询,难度分布并不均匀,而是扎堆出现。
其中很大一部分是纯粹的信息检索——“你们接受哪些支付方式?”“我该怎么重置密码?”“哪里可以找到我的发票?”这些问题的确定性答案就在你的文档里。任何具备基本能力的模型都能正确回答。它们不需要推理,不需要多步推断,也不需要领域专业知识。
较小的一部分涉及上下文理解——“我这个月被扣了两次款,而且我上周已经联系过客服了”“我的团队版续费马上就要来了,但我想先降级”。这些需要模型保留上下文、推断意图,并用谨慎的语言回复。一个中档模型就能很好地处理。
还有更小的一部分确实是难题——“我的 Kubernetes pod 在 GPU Droplets 云服务器上扩容推理工作负载后一直崩溃,报 OOMKilled 错误”“我的微调模型在 checkpoint 重载后输出不一致”。这些需要深厚的技术知识、多步推理以及智能地提出澄清性问题的能力。这正是一个前沿模型真正能值回票价的地方。
错误不在于使用前沿模型。错误在于对所有三个层级都用它。
成本
前沿 AI 模型比小型模型贵得多,每次请求的价格常常高出 10 到 50 倍。这对小项目来说可能不算什么,但在生产规模下,成本会迅速攀升。在智能体 AI 系统中,摘要、记忆搜索和工具调用等额外任务也会消耗 token,如果默认将所有内容都路由经过昂贵的前沿模型,会进一步推高总体推理成本。
代码逻辑
最自然的第一反应是写路由逻辑:
if "billing" in query.lower():
model = "mid-tier-model"
elif any(word in query.lower() for word in ["kubernetes","gpu", "pod", "error", "crash"]):
model = "frontier-model"
else:
model = "cheap-model"
这乍看起来似乎不错,但很容易失效。当用户用不同的方式表述问题、使用其他语言,或者提出看似简单实则复杂的问题时,基于关键词的路由就会力不从心。而且它还需要随着用户查询的变化不断手动更新。
生产级路由真正需要什么
要让路由在查询级别可靠地工作,需要四样关键词匹配无法提供的东西。
第一,它需要语义理解。分类器需要能够区分“我有一个关于账单的问题”和“我的部署正在为我没有使用的资源计费”。一个是简单的常见问题,另一个是技术与账单混合的问题,需要一个更有能力的模型来处理。
第二,它需要是任务感知,而不仅仅是查询感知。同一个用户会话可能在三个轮次内从一个简单的入门问题转变为一个复杂的故障排除问题。路由决策需要按请求做出,而不是按会话,基于此刻实际在问什么。
第三,它需要回退行为。如果选中的模型触发速率限制或返回服务器错误,系统应该自动尝试下一个模型,而不是向用户显示失败。
第四,它需要可观测性。你需要知道哪个模型服务了哪个请求,以及为什么——既是为了调试路由错误,也是为了理解生产环境中真实的成本分布。
自己动手构建这四样东西是一项重大的工程投入和苦活。DigitalOcean 的推理路由器通过配置而非代码提供了许多这些能力,这也正是本文接下来要讲的内容。
DigitalOcean 推理路由器是如何工作的
在深入代码之前,理解当你的应用发送请求时会发生什么会很有帮助。一旦看清楚了,这个概念其实很简单。
一个端点,多个模型
起点是端点本身:
https://inference.do-ai.run/v1
这是一个固定、稳定的 URL,永远不会变。它的背后是 DigitalOcean 的整个模型目录,包含超过 70 个模型,涵盖了 Llama 3.3 70B、DeepSeek 和 Qwen 等选项,以及来自 OpenAI 和 Anthropic 的前沿模型。
❗️注:新注册DigitalOcean的用户,如需使用Claude、OpenAI模型,需联系卓普云(aidroplet.com)申请权限。
路由器就在这一切的前面。你的应用不再自己决定调用哪个模型,而是将每个请求都发送到同一个端点,把 model 字段设为 "router:你的路由器名称",平台会处理剩下的一切。

当一个请求进来时会发生什么
当你的应用向路由器发送一条消息时,在响应返回之前,有三件事按顺序发生。
首先,路由器读取你的请求——系统消息、用户消息以及任何对话历史——并将它通过一个分类器运行。分类器将请求与你构建路由器时配置的任务定义进行比对。每个任务都有一个名称和一个描述,这些描述充当路由信号。一个关于崩溃的 Kubernetes pod 的请求会匹配 technical_troubleshooting 任务。一个关于支付方式的问题会匹配 general_faq 任务。
其次,一旦分类器选定了一个任务,路由器就从该任务的模型池中选择一个模型。每个任务最多可以有三个模型,你通过一个选择策略来控制路由器如何在它们之间选择:
- 成本效率——优先选择池中最便宜的模型,按 token 成本衡量
- 速度优化——根据 DigitalOcean 基础设施上的首 token 时间(TTFT)选择最快的模型
- 手动排序——按照你构建任务时指定的顺序选择
- 最优——适用于预配置任务,使用 DigitalOcean 自己的基准测试为该任务类型选择最佳模型
第三,路由器将请求发送到选中的模型,并将响应流式传回给你的应用。响应看起来与任何标准的聊天补全响应完全一样——相同的格式,相同的字段,只是多了一个 model 字段,告诉你具体选中了哪个模型。你不需要猜测或单独记录它;它会自动包含在每个响应中返回。
当出现问题时会发生什么
对于那些不匹配你定义的任何任务的请求——比如模糊的查询、边缘情况,或者分类器不够有把握的任何内容——路由器会回退到你在创建路由器时指定的回退模型。这意味着你的应用总能得到响应,即使在查询模式超出你预期的情况下也不例外。
将整个会话保持在一个模型上
如果你正在构建一个多轮对话,有一个行为值得了解:默认情况下,每个请求都是独立路由的。对话中的第一条消息可能会发给一个模型,第二条可能会发给另一个模型——如果分类器对它们的解读不同的话。
对于大多数客服机器人的用例来说,这完全没问题。但如果你需要整个对话保持在同一个模型上——比如为了缓存一致性,或者为了保持跨轮次的推理连续性——那么也有办法。DigitalOcean 提供了一个 X-Model-Affinity 请求头。在你的第一个请求中将它设置为一个唯一的会话标识符,之后每个使用相同值的请求都会跳过路由,直接固定到第一个调用选中的模型上。当会话被锁定时,响应中会包含一个 "pinned": true 字段。
这个请求头目前在大多数客户端库中还没有原生暴露,所以实现它需要在端点前面加一个小型代理层。对于一个直接的客服机器人来说,这是可选的;按请求的回退机制已经能处理可靠性问题,而且对于大多数查询类型,跨轮次的质量差异微乎其微。
模型亲和性有助于在智能体、工具调用和长对话等多步 AI 工作流中,为整个会话保持分配给同一个模型。这能提升响应一致性,并防止会话中途切换不同模型所引发的问题。它还能实现 KV 缓存复用——重复的对话历史可以直接复用,无需重新计算,从而大幅降低延迟、GPU 工作负载和输入 token 成本。通过发送一个 X-Model-Affinity 会话 ID,路由器选择一次模型,然后在后续请求中复用它,同时提升性能和成本效率。
设置推理路由器并开始使用
在写一行代码之前,你需要先在控制面板中配置好一个路由器。这是一次性设置。完成后,你的应用只需按名称引用它,平台会处理其他一切。
第 1 步:导航到推理路由器
在 DigitalOcean 控制面板中,点击左侧边栏的 INFERENCE,选择 Inference Router。你会进入一个页面,有两个选项:使用预设路由器立即开始,或者从头构建一个自定义路由器。
第 2 步:选择你的起点
如果你想要一键设置,点击 Getting Started 标签中的 See Default Routers。DigitalOcean 提供了针对常见模式优化的预配置路由器——写作与内容开发、软件工程和文档智能。这些可以立即使用,一旦选中就会出现在 My Routers 标签下。
对于一个拥有不同复杂度层级的客服机器人,自定义路由器能给你更多控制力。点击右上角的 Create Router 继续。
第 3 步:命名并描述你的路由器
在 Create a Router 页面,先填写两个字段:
- Name——选一个稳定且描述性强的名称,比如 support-bot-router。你将在代码中直接以 router:support-bot-router 的格式引用它,所以避免使用空格或特殊字符。
- Description——这个字段比你看起来更重要。它充当路由提示,为分类器提供路由器用途的上下文。要具体一些:像“一个为云基础设施产品处理通用常见问题、账单问询和深度技术故障排除的支持助手”这样的描述,会比泛泛的描述给分类器提供好得多的信号。
如果你想了解创建推理路由器的分步流程,欢迎查阅文档“在控制面板中创建推理路由器”。
第 4 步:定义你的任务
这是你将查询复杂度映射到模型层级的地方。在 Router Tasks 区域,你有两个选项。
使用预配置任务是更快的路径。从下拉菜单中点击 Add Task 打开 Add Tasks 面板。DigitalOcean 为摘要、代码生成、缺陷修复和文本提取等提供了经过基准测试的任务。在添加任何任务之前,可以点击旁边的 + 查看它的描述、模型池和选择策略。对于客服机器人,寻找与常见问题处理、技术推理以及文档或账单上下文相关的任务。选定后,点击 Save。
使用自定义任务可以让你完全控制模型选择和路由策略。

从下拉菜单中点击 Add Custom Task,为每个任务填写以下内容:
- 名称和描述——精确并使用以名词为中心的语言。当任务名称直接反映其意图、且描述之间重叠最小时,分类器的表现更好。例如:
| 任务 | 推荐 | 避免 |
|---|---|---|
| 名称 | technical_troubleshooting | hard_stuff |
| 描述 | “诊断基础设施故障、Kubernetes 错误、GPU 内存问题和 API 调试。” | “任何技术性或复杂的东西” |
- 选择策略——从三种中选择一种:Cost Efficiency、Speed Optimization 和 Manual Ranking。
- 模型池——每个任务最多选择三个模型,按照你希望路由器尝试它们的顺序排列。对于客服机器人,一个实用的初始设置看起来像这样:配置好每个任务后点击 Save。
第 5 步:设置回退模型
回退模型处理不匹配任何已定义任务的请求——模糊的查询、边缘情况,或者分类器不够有把握的任何内容。在 Fallback Models 区域,点击 Add Fallback Models,选择一个或两个可靠的通用模型,然后按偏好拖拽排序。像 Llama 3.3 70B 这样的中档模型是一个安全的回退选择——能力足以处理大多数边缘情况,又无需前沿模型的价格。
第 6 步:创建路由器
点击 Create Router。创建完成后,路由器会出现在 My Routers 标签中。从此刻起,你的应用只需一行代码引用它:
"model": "router:support-bot-router"
无需其他代码改动。路由器已经就绪,现在你发送的每个请求都会被自动分类和分发。

构建客服机器人:代码详解
路由器配置好后,实现起来就很直接了。整个机器人可以放进一个 Python 文件,除了标准库之外你唯一需要的库就是 requests。
前置条件
在运行代码之前,请确保完成以下前置条件:
- 一个已开通推理产品权限的 DigitalOcean 账户
- 一个在 Inference → Manage → Model Access Keys 下创建的 sk-do-… 格式的模型访问密钥
- 在 Inference → Inference Router 下创建的一个具有唯一名称的推理路由器
- Python 3.8 以上版本,并使用 pip install requests 安装 requests 库
设置客户端
import requests
import json
url = "https://inference.do-ai.run/v1/chat/completions"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer doo_v1_xxx",
}
这里有两点值得注意。第一,下面的端点是一个固定、稳定的 URL,无论 DigitalOcean 侧选择了哪个模型或路由器,它永远不会改变。这意味着你可以在控制面板中更换模型、重构路由器池或者添加新的任务类型,而无需改动一行应用代码。
https://inference.do-ai.run/v1
第二,Authorization 请求头遵循标准的 Bearer token 格式,使得这个端点可以无缝替换任何兼容 OpenAI 的客户端。如果你已经有一个调用 api.openai.com 的应用,切换到推理路由器只需要改两行:基础 URL 和密钥。
核心函数
def ask_support_bot(question):
print(f"\n{'='*60}")
print(f"客户查询:{question}")
print(f"{'='*60}")
data = {
"model": "router:support-bot-router",
"messages": [
{
"role": "system",
"content": "你是一个乐于助人的客户支持助手。请清晰、简洁地回答账单问题、技术问题和通用常见问题。",
},
{
"role": "user",
"content": question,
}
],
"stream": True,
}
model 字段正是路由发生的地方。你传递的不是一个具体的模型别名——比如 llama3.3-70b-instruct,而是 router:你的路由器名称。这告诉推理引擎将这个请求通过你的路由器分类器运行,而不是直接发送给某个模型。路由器会读取完整的负载:系统消息、用户消息以及任何先前的对话上下文,然后将其与你配置的任务定义进行匹配。
这里的系统消息起到双重作用:它给模型赋予了角色设定,同时也为路由器在对模糊查询进行分类时提供了额外的上下文。当一个表述模糊的账单问题(比如“我的账户有点问题”)在系统提示表明这是支持上下文的场景下,就更容易被正确分类。
stream: True 启用了 Server-Sent Events(SSE),因此响应会以一系列数据块的形式到达,而不是单个负载。对于一个客服机器人来说,这对感知上的响应速度很重要;用户会看到答案立即开始出现,而不是等待整个响应生成完毕。
读取流并捕获模型信息
response = requests.post(url, headers=headers, json=data, stream=True)
model_logged = False
for line in response.iter_lines():
if line:
decoded = line.decode("utf-8")
if decoded == "data: [DONE]":
break
if decoded.startswith("data: "):
try:
chunk = json.loads(decoded[6:])
if not model_logged:
model_name = chunk.get("model", "unknown")
print(f"路由器选中的模型:{model_name}\n")
print("回复:")
model_logged = True
content = chunk["choices"][0]["delta"].get("content", "")
if content:
print(content, end="", flush=True)
except json.JSONDecodeError:
print("无法解析的行:", decoded)
print()
流中的每一行都遵循 SSE 格式:data: json_payload。decoded[6:] 这个切片在解析之前先去掉 data: 前缀——这是大多数流式实现容易出错的一步,直接把原始行传给 json.loads 会因为那个前缀而每次都失败。
model_logged 标志是一个虽小但重要的细节。流中的每个数据块都带有 model 字段,告诉你路由器为这个请求实际选中了哪个模型。由于这个值在单个响应的所有数据块中都是相同的,你只需要在第一个数据块中读取一次,而不需要在每次迭代时重复打印。
内容提取使用了 .get("content", "") 而不是直接按键访问,因为流中的第一个和最后一个数据块通常携带一个空的 delta——第一个表示响应的开始,最后一个在 [DONE] 标记到达之前表示完成。如果没有 .get() 提供默认值,那些空的 delta 就会抛出 KeyError。
运行三个测试查询
# 简单常见问题 —— 预期使用轻量级模型
ask_support_bot("你们的客服支持时间是几点?")
# 账单问题 —— 预期使用中档模型
ask_support_bot("我这个月的订阅被扣了两次款。你能解释一下为什么吗?")
# 复杂的技术故障排除 —— 预期使用前沿模型
ask_support_bot("我的 Kubernetes pod 在 GPU Droplets 上扩容推理工作负载后一直崩溃,报 OOMKilled 错误。我该如何诊断和修复这个问题?")
这三个查询是特意选择的,覆盖了你的路由器应该处理的完整复杂度范围。依次运行它们,是验证路由是否按预期工作的最快方式。
正确的输出看起来像这样:
============================================================
客户查询:你们的客服支持时间是几点?
============================================================
路由器选中的模型:gemma-4-31B-it
回复:
我是一个 AI 助手,全天候 24/7 随时为你解答问题和提供支持。你可以随时联系我!
不过,如果你需要与人工客服代表沟通,通常的客服支持时间一般是周一至周五的工作时间(通常是当地时间上午 9 点到下午 5 点),但这会因公司而异。
针对你所问的服务的具体支持时间,我建议:
- 查看公司网站底部或"联系我们"页面
- 在你的账户控制面板中查找支持时间
- 检查你收到的任何欢迎邮件
现在有什么具体的事情我可以帮你处理吗?
============================================================
客户查询:我这个月的订阅被扣了两次款。你能解释一下为什么吗?
============================================================
路由器选中的模型:anthropic-claude-4.1-opus
回复:
很抱歉你的订阅出现了重复扣款。这当然是不应该发生的,我理解你的担忧。
以下是这种情况最常见的原因:
**可能的原因:**
- 一笔待处理扣款与实际扣款同时出现(待处理扣款通常在 3-5 个工作日内自动撤销)
- 由于最近的套餐变更或升级导致账单周期重叠
- 我们的计费系统出现技术错误
**你应该做什么:**
1. 检查其中一笔是否显示为"待处理"——如果是,它会自动消失
2. 审查你的账户,看看是否有最近的订阅变更或升级
3. 如果两笔都已完全入账,你有权获得退款
**如何快速解决:**
- 我建议你直接联系我们的账单团队,提供你的账户详情和显示这两笔扣款的银行对账单
- 他们可以调查你的具体情况并立即处理退款
- 大多数退款会在 5-7 个工作日内到账
你需要我帮你查找你的账户信息,或者告诉你如何联系我们的账单团队吗?
============================================================
客户查询:我的 Kubernetes pod 在 GPU Droplets 上扩容推理工作负载后一直崩溃,报 OOMKilled 错误。我该如何诊断和修复这个问题?
============================================================
路由器选中的模型:anthropic-claude-opus-4.7
回复:
# 诊断和修复 GPU Droplets 上的 OOMKilled 错误
OOMKilled 意味着你的 pod 超出了其内存限制。以下是诊断和解决的方法:
## 1. 确认原因
```bash
# 检查 pod 状态和退出代码(137 = OOMKilled)
kubectl describe pod <pod-name>
# 查找 "Last State: Terminated, Reason: OOMKilled"
kubectl get events --sort-by=.metadata.creationTimestamp
```
## 2. 识别是哪种内存耗尽
GPU 工作负载需要考虑**两种**内存类型:
- **系统内存(RAM)**——由 Kubernetes `resources.limits.memory` 管控
- **GPU 显存(VRAM)**——不受 K8s 管理;用 `nvidia-smi` 检查
```bash
# 在 pod 内检查 GPU 内存
kubectl exec -it <pod-name> -- nvidia-smi
# 检查系统内存使用
kubectl top pod <pod-name>
```
如果 `nvidia-smi` 显示显存接近 100%,你就遇到了 GPU 内存问题(通常表现为 CUDA OOM,但也可能导致进程被杀死)。
## 3. 常见修复方案
### A. 增加内存限制
```yaml
resources:
requests:
memory: "16Gi"
nvidia.com/gpu: 1
limits:
memory: "32Gi"
nvidia.com/gpu: 1
```
### B. 减少每个 Pod 的工作负载
- 降低推理的**批量大小**
- 减少**最大序列长度** / **最大 token 数**
- 限制**并发请求数**(例如 vLLM 中的 `--max-num-seqs`)
### C. 使用内存高效的推理方式
- 启用**量化**(INT8、FP8、AWQ、GPTQ)
- 使用**分页注意力**(vLLM、TGI)
- 启用**张量并行**将模型拆分到多个 GPU 上
### D. 水平扩展而非垂直扩展
通过增加更多 pod 来扩展(HPA),而不是把更多东西塞进一个 pod:
```bash
kubectl autoscale deployment <name> --min=2 --max=10 --cpu-percent=70
```
### E. 检查内存泄漏
如果内存随时间持续增长,你的服务框架可能存在泄漏。用 livenessProbe 定期重启 pod,或者检查框架版本。
## 4. 选择合适规格的 GPU Droplet
如果你确实已经超出了当前节点的能力,考虑更大的 DigitalOcean GPU Droplet(例如从单卡 H100 迁移到 8 卡 H100 节点),以获得更多的显存和系统内存余量。
## 5. 后续监控
启用 DigitalOcean 监控,或部署 **Prometheus + DCGM Exporter** 来跟踪 GPU/系统内存趋势,并在 pod 崩溃之前设置告警。
---
需要针对具体配置的帮助吗?如果你能分享你的 pod YAML 以及你正在运行的模型/框架(例如 vLLM、TGI、Triton),我可以给出更具针对性的建议。
关键要观察的是模型名称在不同查询之间发生了变化。如果是像常见问题这样简单的查询,路由器会命中一个轻量级模型,而真正复杂的故障排除问题则被路由到 Claude Sonnet 或更复杂的模型。
测试路由器性能
- 路由器可以直接在 Playground 中与另一个模型或路由器进行对比测试。
- Playground 以对比模式打开,支持并排测试。
- 输入一个提示来进行对比:
- 回复质量
- 成本差异
- 端到端延迟
- 选中的模型
- 路由器匹配到的任务
- 也可以通过信息图标查看路由器配置。

分析路由器性能
Analyze 标签提供了所有路由器或单个路由器的聚合指标,包括:
- 总请求数——已处理的请求总数
- 总 Token 用量——输入和输出 token 用量之和
- 模型匹配率——成功匹配到已配置路由器任务的请求百分比
- 回退率——在没有任何任务匹配时路由到回退模型的请求百分比


测试路由器准确性
- 在 Playground 中,选择 Router Evaluation 来评估路由质量。
- 上传一个数据集,使用 LLM-as-a-Judge 评分来运行评估。
评估结果包括:
- 完整性——回复覆盖提示的全面程度
- 正确性——准确性及幻觉检测
- Token 用量——每个请求的 token 总消耗
- 延迟——平均和 P95 响应时间
常见问题
什么是 DigitalOcean 推理路由器?
DigitalOcean 推理路由器是一个路由层,可以根据查询类型、成本、延迟和模型能力等因素,智能地将 AI 请求发送到最合适的模型。它让应用能通过单一端点使用多个模型,而无需手动管理模型选择。
路由器如何决定使用哪个模型?
路由器分析传入的查询,并将其与配置好的任务进行匹配。每个任务包含一个合格模型池和一个选择策略,例如:
- 最低成本
- 最低延迟
- 最佳综合性能
然后路由器动态地选择最合适的模型。
推理路由器中的任务是什么?
任务是工作负载或查询类型的类别。例如:
- 客户支持
- 摘要
- 编码辅助
- 技术故障排除
- 翻译
- 推理
每个任务可以有不同的路由规则和模型池。
什么是模型池?
模型池是分配给一个任务的一组模型。路由器根据路由策略和模型可用性,从池中选择最佳模型。
可以创建自定义路由规则吗?
可以。开发者可以创建自定义任务,定义自己的模型池,并手动控制模型优先级和回退顺序。
如果一个模型失败或不可用,会发生什么?
如果选中的模型出现以下情况,路由器会自动使用回退模型:
- 超时
- 返回错误
- 过载
- 触发速率限制
这确保了更高的可靠性和不间断的 AI 响应。
什么是模型亲和性?
模型亲和性让同一个会话或对话保持分配给同一个模型。这能改进:
- 响应一致性
- 工具调用稳定性
- KV 缓存复用
- 延迟
- Token 成本效率
这对 AI 智能体和长时间运行的对话特别有用。
什么是 KV 缓存复用?
当重复的对话历史被发送到同一个模型时,KV 缓存允许模型复用先前计算好的注意力状态。这减少了重新计算,降低了延迟,并减少了 token 处理成本。
路由器可以在部署前测试吗?
可以。Playground 允许开发者通过评估以下维度,将路由器与模型或其他路由器进行对比:
- 回复质量
- 成本
- 延迟
- 选中的模型
- 匹配到的路由任务
推理路由有哪些实际用例?
推理路由可用于:
- AI 客服机器人
- 多模型 AI 助手
- RAG 系统
- AI 智能体
- 编码副驾
- 企业 AI 平台
- 成本优化管道
- 大规模推理系统
结语
构建一个 AI 驱动的应用,并不意味着要对所有事情都用最强大的模型。它意味着为每项任务使用正确的模型。当你对每个查询都一视同仁时,你并不是在提高质量,你只是在增加成本。
DigitalOcean 的推理路由器用一个简单的想法解决了这个问题:一次性定义好你的任务,设置好模型池,然后让基础设施自动做出路由决策。你的代码里不需要 if/else 逻辑,不需要管理多个 API 密钥,也不需要每次想尝试一个不同模型时都重新部署。
随着应用从原型走向生产级系统,推理路由正在成为现代 AI 基础设施的重要组成部分。路由器不再依赖一个模型处理所有请求,而是自动在成本、速度、可靠性和模型能力之间取得平衡。
从简单开始。挑选两三个任务,分配模型池,然后把它放在真实流量上运行。观察响应中的 model 字段,看看路由在真实场景中的表现。几天之后,在控制面板中检查你的 token 消耗。有了像 DigitalOcean AI 平台这样的工具,开发者可以简化多模型编排,将更多精力放在构建 AI 体验上,而不是管理复杂的路由逻辑。