DigitalOcean 的 AI 推理路由器是如何构建的

11 阅读18分钟

如今,大多数基于大语言模型的团队都会选定一个模型,然后将它统一应用到每一次请求。他们选择前沿模型,并不是因为每个任务都需要它,而是因为构建一个更智能的基础设施太难、太耗时,而且容易出错。当工具缺位时,阻力最小的路径就是用单一模型,即使这意味着你对大多数任务都在超额付费。

举个例子。如果你是一名开发者,正在使用 Cursor、Claude Code、Open Code 或任何编码智能体,你大概已经感受到这一点了。在一个会话中,你的智能体会做深度的代码库分析、编写新函数、根据测试输出修复 bug、解释方法、搜索文档。这些任务并不相同,但如果你只用一个硬编码的模型,你就得为所有任务都付前沿模型的价格,包括那些根本不需要的。在智能体工作流和多智能体系统中,风险更高。当多个智能体并行运行,各自规划、执行和评估长期任务时,模型选择的一刀切带来的成本会在每一步累加。更要命的是,主流 AI 供应商正在转向按 token 计费,并收紧速率限制,推理成本即将变得更加昂贵。

另一种做法是在应用层编写硬编码的路由逻辑,加上一个借助 LLM 的意图分类器,但这既增加了成本,又会很快变得脆弱不堪。即使你用一个像 Haiku 这样的小模型来压低成本,现在你的每一次推理调用之上,又多了一次路由调用的费用。而且,由于这个模型并非为路由专门构建,准确率会打折扣。随着你的任务类型不断演化、模型不断变化,这套逻辑会以难以察觉的方式崩溃。你陷入了双重征税:分类器的成本,再加上维护那套脆弱的、每次技术栈变动都需要更新的路由代码的成本。你把模型选择变成了一个自己拥有和维护的功能,而这并不是开发者想要的。真正可规模化的,是在基础设施层面进行路由:根据任务的真实需求,自动把每个请求匹配到最合适的模型,同时把成本和延迟等优先级纳入考量,并且不把这些逻辑写进你的代码。

这正是我们构建 DigitalOcean 推理路由器的原因。它读取每个请求,从对话上下文中理解任务,然后从你配置好的模型池中路由到最合适的模型——根据你的需要来优化成本、延迟或质量。只需一行改动("model": "router:software-engineering"),你就可以把它接入,你的智能体就开始自动为每个任务使用合适的模型。

在底层,它由 Plano(github.com/katanemo/plano) 驱动,这是一个开源的 AI 原生代理,最初由 Katanemo(现已被 DigitalOcean收购)开发。负责意图解析的路由模型是一个 30B 的混合专家(MoE)模型,专门针对长上下文窗口中的任务检测进行了微调——在多轮对话的路由准确率上,它超过了 GPT-5.1 和 Claude Sonnet 4.5,并在约 200 毫秒内完成意图解析。一个 4B 的稠密变体模型也可用于对延迟敏感的部署。本文将介绍它是如何工作的:产品、模型、排序引擎,以及底层的基础设施。

DigitalOcean 推理路由器

开始路由的最快方式是使用预设路由器。推理路由器内置了针对常见工作流的预设,如软件工程、通用、写作、知识库与文档智能。

每个预设的模型推荐都基于一套混合评估方法。我们将来自主流排行榜的公开基准信号结合起来,先为每个任务筛选出顶级候选模型,然后通过在精心构建的任务特定数据集上的内部基准测试进行验证。最终推荐由 DigitalOcean 的数据科学团队使用自动化评分和人工评估确认。在某个任务上,当开源模型的准确率能与闭源替代模型相当时,我们推荐开源模型;否则,我们推荐闭源的前沿模型。

预设支持三种选择策略:最优(DigitalOcean 基于此混合评估给出的推荐模型排序)、成本优先(优先最低成本)和速度优先(优先最低延迟)。从推理路由器目录中选一个,几分钟内就能完成配置。

使用预设路由器是任何模型调用的直接替代。在模型字段中将路由器名称加上 router: 前缀:

curl -s https://inference.do-ai.run/v1/chat/completions \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "router:software-engineering",
    "messages": [
      {"role": "user", "content": "Write a Python function to sort a list of dictionaries by key"}
    ]
  }'

响应会告诉你选中的是哪个模型(在 model 字段中),以及匹配到了哪个任务(通过 x-model-router-selected-route 响应头)。如果没有匹配到任何任务,请求会回退到路由器配置的回退模型,按顺序尝试。

当你需要更多控制,或想为自己的用例定制路由时,自定义路由器允许你定义自己的任务。每个任务有一个名称、一段用于意图匹配的自然语言描述、一个符合条件的模型池,以及一种选择策略(成本最低、速度最快或按序排列):

curl -X POST "https://api.digitalocean.com/v2/gen-ai/models/routers" \
  -H "Authorization: Bearer $MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-coding-router",
    "policies": [
      {
        "custom_task": {
          "name": "code-generation",
          "description": "Generate new code, write functions, or create boilerplate"
        },
        "models": ["openai-gpt-5.2", "anthropic-claude-sonnet-4.5"],
        "selection_policy": { "prefer": "fastest" }
      },
      {
        "custom_task": {
          "name": "bug-fixing",
          "description": "Identify and fix errors or bugs in user-supplied code"
        },
        "models": ["openai-gpt-5.2", "glm-5"],
        "selection_policy": { "prefer": "cheapest" }
      }
    ],
    "fallback_models": ["openai-gpt-oss-120b"]
}'

你可以在DigitalOcean的模型Playground中测试路由行为,将路由器与单一模型并排对比,每个请求的成本和延迟差异一目了然。对于系统性评估,Evals 功能允许你用数据集运行路由器,并衡量正确性和完整性,让你在发布到生产环境之前,轻松比较路由器的输出质量与单一模型的差异。

Analyze 仪表板展示了实时流量的聚合指标:总请求数、Token 用量、任务匹配率和回退率。

它是如何工作的:底层的 Plano

当一个请求到达推理路由器时,Plano 内部发生的事情如下:

每一次路由决策都分两个阶段。首先,一个专门构建的小语言模型(SLM)通过将对话与自然语言任务描述进行匹配,来解析用户意图。其次,一个排序引擎利用来自可插拔指标源(包括 DigitalOcean 的定价 API 和 Prometheus)的实时成本和延迟数据,对匹配到的任务的候选模型进行排序。

推理路由架构流程图

在完整代理模式下,Plano 负责处理整个生命周期:分类意图、对模型排序、转发到排名最高的供应商,并将响应流式传回。对 DigitalOcean 的推理路由器而言,这意味着在 DigitalOcean 推理平台上可用的模型之间进行路由。Plano 的开源引擎还支持跨供应商 API(OpenAI、Anthropic、Gemini、Bedrock 等)的格式转换,用于你自带供应商密钥的自托管部署。

在底层,一个推理路由器的配置会转换成一个 Plano 的路由配置。每个任务变成一个具有自然语言描述、模型池和选择策略的路由:

routing_preferences:
  - name: code_generation
    description: generating new code, writing functions, or creating boilerplate
    models:
      - anthropic/claude-sonnet-4-20250514
      - openai/gpt-4o
    selection_policy:
      prefer: fastest
  - name: complex_reasoning
    description: complex reasoning tasks, multi-step analysis, or detailed explanations
    models:
      - openai/gpt-4o
      - openai/gpt-4o-mini
    selection_policy:
      prefer: cheapest

任务描述就是路由模型看到的内容,它们直接以自然语言的形式传入其提示。selection_policy 则指定了排序引擎应该优化哪个指标。

对于长对话,提示会被裁剪以适应模型的 Token 预算,而不会在热路径上运行完整的 tokenizer。系统保留最近的对话轮次,如果最后一条用户消息仍然超出预算,它会采用中间裁剪策略——大致保留开头的 60% 和结尾的 40%,中间用省略号分隔。这样做的理由是:用户倾向于在长消息的开头概述任务,并在结尾给出真正的任务,因此保留两端能比仅保留开头为路由模型提供更强的信号。

推理路由模型的演进

路由服务在设计上就是模型无关的。架构本身不关心哪个模型来解析意图,只要它返回一个 JSON 路由决策即可。但模型的选择对准确率、延迟以及可能的路由类型至关重要。我们经历了两代模型的迭代。

V1:Arch-Router——基石

我们的第一个路由模型 Arch-Router 是一个 1.5B 的生成式语言模型,专门为单路由分类做了微调。给定一个对话和一组路由描述,它返回 {"route": "code_generation"},如果没有匹配则返回 {"route": "other"}

我们在论文 Arch-Router: Aligning LLM Routing with Human Preferences 中发布了方法论和评估。

关键结果:Arch-Router 在路由准确率上超过了我们测试的每一个前沿模型,且延迟仅为它们的一小部分:

模型延迟 (毫秒)整体准确率
Arch-Router51 ± 1293.17%
Claude 3.7 Sonnet1450 ± 38592.79%
GPT-4o836 ± 23989.74%
Gemini 2.0 Flash581 ± 10185.63%
GPT-4o-mini737 ± 16482.79%

51 毫秒内达到 93.17% 的准确率——比 Claude 快 28 倍,比 Gemini Flash 快 10 倍——证明了一个专为此目的构建的小模型可以在不牺牲质量的前提下,取代前沿模型来承担路由任务。这验证了核心的设计决策:你完全可以把一个真实的模型放在请求路径上,以基础设施级别的速度来运行。

V2:Plano-Orchestrator

Arch-Router 验证了这条路径,但生产环境的工作负载促使我们走得更远。真实的对话是杂乱无章的。用户会发送模糊的追问("对纽约也这样做"),会在对话中途切换话题,或者发送完全不需要路由的消息。我们需要一个在这些模式上泛化能力更强的模型。

Plano-Orchestrator 就是今天驱动 DigitalOcean 推理路由器的路由模型。它使用同样的生成式方法——将路由描述放在提示中,输出 JSON。但它在更丰富的对话数据上进行训练,涵盖了上下文相关的路由、多轮对话流程处理(追问、澄清、纠正)以及负面案例检测(识别何时不需要专门路由)。其结果是,一个在多样化路由场景中泛化能力明显更强的模型。

该模型在 Plano-Orchestrator 集合中提供了两种尺寸:一个用于低延迟部署的 4B 稠密模型,和一个用于更高准确率的 30B-A3B MoE 模型,每种都有 FP8 量化变体。我们在 605 组多轮对话中的 1,958 条用户消息上,使用超过 130 个不同的智能体进行了评估:

模型通用编码长上下文平均性能
Plano-Orchestrator-30B-A3B88.8783.5186.8187.84
GPT-5.189.7177.5481.2886.93
Claude Sonnet 4.588.5374.3985.5386.11
Plano-Orchestrator-4B87.4171.2384.2684.68
Gemini 2.5 Flash84.4266.3282.1381.51
Claude Haiku 4.581.9972.6385.5381.05
Gemini 2.5 Pro83.3867.0281.2880.75
GPT-581.6470.1863.4077.78
GPT-5 mini70.1061.4058.7267.47

30B-A3B MoE 模型以 87.84% 的平均性能领先,超越了 GPT-5.1(86.93%)和 Claude Sonnet 4.5(86.11%)。4B 稠密模型得分 84.68%,以极低的推理成本与前沿模型相竞争。

编码类别显示出最大的差距:Plano-Orchestrator-30B-A3B 得分 83.51%,对比 GPT-5.1 的 77.54% 和 Claude Sonnet 4.5 的 74.39%。这正是专有训练回报最高的地方。编码查询包含模糊的意图("修复这个"、"让它更快"、"再试一次"),需要对话上下文才能正确路由,而一个专门在路由模式上训练的模型比被提示进行分类的通用模型处理得更好。

以下展示了路由模型如何融入完整的代理请求路径:

完整代理请求路径图

在不同路由模型之间切换是配置变更,而不是代码变更。排序引擎、指标源和传输层全都是模型无关的。我们将在后续文章中完整介绍从 Arch-Router 到 Plano-Orchestrator 的模型演进。

排序引擎:实时的成本和延迟数据

知道正确的任务只是问题的一半。在一个任务中,你可能有三款候选模型。哪款最好,取决于你此刻要优化成本还是延迟。静态排序不够,因为模型定价会变、延迟随负载波动、速率限制影响可用性。

排序引擎持续从外部源拉取成本和延迟数据。对于推理路由器,成本数据默认来自 DigitalOcean Gen AI 定价 API;延迟数据来自 Prometheus。该接口可扩展到其他源。这很重要,因为模型性能不是静态的,供应商延迟在一天之内会根据流量模式波动 2 到 3 倍。一个凌晨 2 点时最快的模型,到了下午 2 点往往最慢。实时排序能捕捉到这些变化;静态配置则不能。

排序算法很直接:

  1. 从内存缓存中读取最新的成本和延迟快照。
  2. 根据任务的选择策略:
    • 成本优先:按成本升序排列候选模型。没有成本数据的模型被排到最后。
    • 速度优先:按延迟升序排列候选模型。没有延迟数据的模型被排到最后。
    • 手动排序:完全按照你指定的顺序返回——不做重排。这让你在需要确定性排序时完全掌控模型优先级。
  3. 对于任何缺失指标数据的模型,记录一条告警(在启动时和每次请求时都记录),以便在指标暂时缺失时尽早发现配置错误,而不会硬性失败。

最终结果是一个有序列表,位于列表顶部的模型最符合当前策略,而没有数据的模型仍然可以作为回退,但不会被优先选择。model_aliases 映射弥合了指标源和路由配置之间的命名差异——例如,定价目录中使用的 openai-gpt-4o 就能清晰地映射到你任务定义中的 openai/gpt-4o

Plano 在启动时验证完整的指标配置。对于不匹配的选择策略、重复的源、供应商中缺失的模型,它会给出具体的错误信息并终止运行,而不是静默地回退到默认排序。

底层技术:Envoy、WASM 与异步 Rust

路由服务运行在 Plano 的三层架构内部。

Plano 三层架构图

Envoy 负责处理 TLS、连接池、重试、熔断以及 HTTP/2 多路复用。对路由来说,其线程模型尤为重要:每个 CPU 核心一个事件循环工作线程,每个连接固定在一个工作线程上,在热路径中不存在锁竞争。对于流式传输 LLM 响应,即长连接、分块的 HTTP 连接,这种模式无需协调开销就能自然扩展。

llm_gateway.wasm 过滤器 在 Envoy 的进程内部运行,而不是作为边车或独立服务。它以线速处理不同供应商(OpenAI、Anthropic、Gemini、Mistral、Groq、DeepSeek、xAI、Bedrock)间的格式转换,零网络跳转。WASM 沙箱施加了严格的约束:无标准网络库、无 tokio、无异步运行时,所有依赖必须兼容 no_std。格式转换层由我们的 Rust 库 hermesllm 驱动,专门用于 LLM API 抽象。添加一个新的供应商,意味着只需实现 ProviderRequestProviderResponse 这两个特性,路由器和网关本身无需任何改动。

Brightstaff 是一个原生二进制文件,与 Envoy 并行运行,负责处理路由逻辑,包括意图解析、模型排序和 OTEL 链路追踪。它为每个请求使用一个轻量级的异步任务,而非每个请求一个线程,因此能够在适中的硬件上并发处理数千个路由决策。对于处于流式传输 LLM 响应热路径的代理而言,可预测的尾部延迟至关重要。路由层中垃圾回收器的暂停,会以 Token 交付卡顿的形式向上传播。Brightstaff 使用 Rust 编写,从根本上消除了这类问题:没有垃圾回收器,没有 "Stop the World" 式暂停,内存回收是确定性的。指标缓存采用了一个针对读操作优化的并发数据结构。每个请求都会读取它,但写入只在刷新间隔时发生,因此实际中的竞争几乎为零。

开始使用

在 DigitalOcean 上:从路由器目录创建一个推理路由器——挑选一个预设,或通过 API 或 UI 构建自定义路由器。无需管理 GPU,无需维护基础设施。只需在任何兼容 OpenAI 的 API 调用中将 "model" 设置为 "router:your-router-name" 即可使用。

自托管:路由引擎已作为 Plano 开源。路由模型运行在 vLLM 上——Arch-Router(1.5B 量化版)可以装在单张 NVIDIA L4 上;更大的 Plano-Orchestrator 模型则运行在 NVIDIA L40S 上。演示仓库包含用于自托管的 Kubernetes 资源清单、Docker Compose 文件以及 Plano 配置。

我们的收获

在生产环境中构建和运营这一系统,让我们收获了以下几点并非显而易见的经验:

专有模型在路由上胜过通用模型——前提是你有训练数据

我们的第一个路由模型(Arch-Router, 1.5B)在路由准确率上击败了 Claude 3.7 Sonnet,延迟降低了 28 倍。直觉是,路由是一项窄而精的定义明确的任务——模型不需要生成散文或处理工具调用。它需要阅读对话,将其与路由描述比对,然后输出一个 JSON 对象。这比前沿模型所具备的能力范围小得多,一个专用模型只要有代表性的训练数据,就能以高准确率覆盖它。当我们扩展到 Plano-Orchestrator 时,这一原则依然成立:这种针对特定任务的方法在更广泛的路由场景中持续优于通用模型。

路由描述是一种新的提示工程

路由模型被训练来将用户提示匹配到用户定义的任务上——你配置中的自然语言描述就是接口。这意味着,路由质量在很大程度上取决于你如何编写这些描述。"处理代码"会匹配所有东西;"为数据处理管道编写 Python 函数"则会漏掉"帮我调试这段 JavaScript"。找到恰当的特异性——足以捕获真实流量,又精确到能在不同路由间做区分——就是将提示工程应用到了基础设施配置。团队在设置路由器时通常不会预见到这一点,但在实践中,大多数路由准确率问题都源于此。这也是推理路由器会附带预设路由器的原因。这是经过基准测试、能直接用于常见工作流的任务描述。

实时指标排序比静态配置更有用,因为模型性能会漂移

供应商延迟在一天之内会根据流量模式波动 2 到 3 倍。一个凌晨 2 点时"最快"的模型,到了下午 2 点往往最慢。我们的实现为每个指标源在后台运行一个循环,按可配置的间隔拉取最新数据,并更新内部线程安全的缓存。读取在刷新期间是非阻塞的,因此对正在进行的路由决策没有延迟影响。

WASM 沙箱约束产生更干净的代码

这特指运行在 Envoy 内部的 llm_gateway.wasm 过滤器——而不是 Brightstaff,后者作为原生二进制运行。WASM 沙箱剥夺了你通常会依赖的工具:没有网络栈、没有异步运行时、没有系统调用。剩下的是一种回调驱动的架构:代理控制所有 I/O,你的过滤器代码只处理逻辑。这种约束在开发过程中很痛苦,但它产生的过滤器体积小(个位数 MB)、确定性强且易于审计。你可以仅从源码就追踪每一次外部交互。它还提供了强大的隔离保证:一个 WASM 过滤器中的 bug 无法使代理崩溃,也无法在其沙箱之外泄漏内存。

我们接下来探索的方向

推理路由器是 DigitalOcean 为构建智能体 AI 的生产基础设施所做更广泛努力的一部分。在接下来的一篇文章中,我们将介绍从 Arch-RouterPlano-Orchestrator 的模型演进,我们如何在不同规模上训练专用路由模型,以及我们在多样化路由场景中关于泛化性的心得。

我们同时也在投资研究相关的问题。我们的论文 Signals: Trajectory Sampling and Triage for Agentic Interactions 探讨了智能体系统的可观测性——如何在生产环境中识别有价值的智能体轨迹,而无需审查每一次交互。

注:论文地址是arxiv.org/abs/2604.00…

路由引擎已作为 Plano 的一部分开源。可以在 DigitalOcean 上试用推理路由器,或使用演示自托管运行 Plano。如遇到任何疑问,或需要了解产品详情,可联系卓普云(aidroplet.com)。

注:推理路由器由 DigitalOcean AI推理云团队的多位成员共同构建,包括 Tyler Gillam、Alex Malynovsky、Ram Parthasarathy、Prasad Prabhu、Nirmal Chander Srinivasan 以及许多其他人。