
Plano 智能路由配置实战编写高质量routing_preferences偏好描述让 1.5B 路由模型精准分诊【免费下载链接】planoPlano is an AI-native proxy server and data plane for agentic apps. Smart LLM routing, observability, agent orchestration, and guardrails so you stay focused on your agents core logic.项目地址: https://gitcode.com/GitHub_Trending/ar/plano导读Plano 是一个面向 Agent 应用的 AI 原生代理与数据平面其内置的plano_orchestrator_v1路由模型会根据你在配置中声明的routing_preferences描述将每个请求语义化分类到最合适的模型并返回一个有序候选列表供客户端按序回退。本文以routing_preferences的编写规范为核心讲解配置的位置与版本迁移、正反示例、七条编写原则、请求/响应协议并结合仓库源码剖析其底层实现链路最后给出基于planoai trace --where的验证方法。读完本文你将能编写出互斥、具体、可被 LLM 准确理解的路由偏好描述并独立完成一次偏好路由的配置、部署与调试验证。路由偏好是如何参与决策的在 Plano 中plano_orchestrator_v1路由器使用一个1.5B 的偏好对齐preference-alignedLLM对传入请求进行分类分类依据就是你配置的routing_preferences描述。分类完成后路由器会为命中的路由返回一个有序的models列表客户端以models[0]作为主选模型当主选模型返回429限流或5xx服务端错误时依次回退到models[1]、models[2]……因此描述质量直接决定路由准确率描述写得模糊路由模型就会把昂贵任务误分给廉价模型或把简单任务送进大模型造成成本与延迟的双重浪费。从源码看路由决策的核心入口在 model_selection.rsrouter_chat_get_upstream_model将任意上游协议请求统一转换为 OpenAI Chat Completions 形态然后调用orchestrator_service.determine_route(...)完成分类命中路由时取ranked_models.first()作为主模型并返回完整的有序列表未命中时则返回哨兵值none由调用方回退到请求自带的model字段。配置位置v0.4.0 顶层形式与 v0.3.0 内联迁移自v0.4.0起routing_preferences位于配置文件的顶层与model_providers平级且每条偏好拥有自己独立的models: [...]候选池。而 v0.3.0 及更早版本的旧式写法是将偏好内联在每一个model_provider之下Plano 会自动迁移这种旧式配置并给出弃用警告——建议尽快改用下面的顶层形式。底层配置结构定义在 configuration.rspub struct TopLevelRoutingPreference { pub name: String, pub description: String, pub models: VecString, #[serde(default)] pub selection_policy: SelectionPolicy, }即每条偏好包含四个要素路由名name、自然语言描述description、有序候选模型池models以及可选的selection_policy源码中支持cheapest、fastest、none三种偏好none为默认值表示按声明顺序返回、不做重排。需要特别说明models中的每个模型都必须在model_providers中声明否则配置校验无法通过。反面示例模糊且重叠的描述以下配置虽然在语法上合法但路由效果极差version: v0.4.0 model_providers: - model: openai/gpt-4o-mini access_key: $OPENAI_API_KEY default: true - model: openai/gpt-4o access_key: $OPENAI_API_KEY routing_preferences: - name: simple description: easy tasks # Too vague — what is easy? models: - openai/gpt-4o-mini - name: hard description: hard tasks # Too vague — overlaps with easy models: - openai/gpt-4o问题一目了然easy tasks / hard tasks 过于抽象。对 1.5B 路由模型而言easy 与 hard 没有可操作的语义边界分类结果近乎随机两条路由语义重叠。同一句话既可能被分到 simple 也可能被分到 hard路由模型无法稳定复现你的意图两条路由都只有单一模型失去 429/5xx 自动回退的能力。正面示例具体、互斥、带多模型回退正确的写法是用动作动词 具体子任务/同义词描述每条路由让路由模型能像读说明书一样完成分类version: v0.4.0 model_providers: - model: openai/gpt-4o-mini access_key: $OPENAI_API_KEY default: true - model: openai/gpt-4o access_key: $OPENAI_API_KEY - model: anthropic/claude-sonnet-4-5 access_key: $ANTHROPIC_API_KEY routing_preferences: - name: summarization description: Summarizing documents, articles, emails, or meeting transcripts. Extracting key points, generating TL;DR sections, condensing long text. models: - openai/gpt-4o-mini - openai/gpt-4o - name: classification description: Categorizing inputs, sentiment analysis, spam detection, intent classification, labeling structured data fields. models: - openai/gpt-4o-mini - name: translation description: Translating text between languages, localization tasks. models: - openai/gpt-4o-mini - anthropic/claude-sonnet-4-5 - name: code_generation description: Writing new functions, classes, or modules from scratch. Implementing algorithms, boilerplate generation, API integrations. models: - openai/gpt-4o - anthropic/claude-sonnet-4-5 - name: code_review description: Reviewing code for bugs, security vulnerabilities, performance issues. Suggesting refactors, explaining complex code, debugging errors. models: - anthropic/claude-sonnet-4-5 - openai/gpt-4o - name: complex_reasoning description: Multi-step math problems, logical deduction, strategic planning, research synthesis requiring chain-of-thought reasoning. models: - openai/gpt-4o - anthropic/claude-sonnet-4-5这个示例展示了全部关键实践每条路由的语义边界清晰互斥summarization 不会与 code_generation 混淆、描述列出了 35 个具体子任务、按最优先→次优先排列模型池以支持跨供应商自动回退。编写高质量偏好描述的七条原则综合原文档与上述示例编写description时应遵循以下原则使用具体动作动词开头如writing、reviewing、translating、summarizing、classifying、debugging。动作动词给出了任务类型的强信号比形容词hard、easy信息量大得多为每条偏好列出 35 个具体子任务或同义词例如 summarization 的 Extracting key points, generating TL;DR sections, condensing long text用多个等价表述覆盖模型可能的语义联想确保各路由之间的作用域互斥一条请求只应最像某一条路由。若两条描述共用大量词汇如都含 code请明确区分动词generate vs. review vs. explain按最优先到最次优先排列models客户端会在429/5xx时严格按列表顺序回退所以第一个位置放你最想用的模型一条路由下多列模型以获取自动供应商回退如 code_review 同时列出 Claude 与 GPT上游任一供应商限流时无需客户端额外逻辑即可切换这正是响应中models有序列表的用途见下文请求/响应协议models中的每个模型都必须在model_providers中声明这是 Routing API 明确要求的约束也是 v0.4.0 配置校验的一部分用代表性查询实测验证使用planoai trace配合--where过滤器检查每次请求实际命中的路由迭代收敛描述。请求/响应协议routing_preferences在 API 层如何流转routing_preferences不仅可以配置在 YAML 中还可以在单个请求体内内联下发实现配置兜底、请求覆盖的灵活模式。完整的请求与响应格式见 Routing API。请求体是一个标准的 OpenAI Chat Completions 结构唯一的扩展是可选字段routing_preferences该字段在转发上游前会被剥除下游不会看到POST /v1/chat/completions { model: openai/gpt-4o-mini, messages: [ {role: user, content: write a sorting algorithm in Python} ], routing_preferences: [ { name: code generation, description: generating new code snippets, models: [anthropic/claude-sonnet-4-6, openai/gpt-4o, openai/gpt-4o-mini] }, { name: general questions, description: casual conversation and simple queries, models: [openai/gpt-4o-mini] } ] }字段说明字段类型必填说明namestring是路由标识需与路由模型的分类型对应descriptionstring是路由模型用于匹配用户意图的自然语言描述modelsstring[]是有序候选池至少一个条目且必须在model_providers中声明三条使用规则routing_preferences是可选的省略时使用配置文件中的定义请求体内联时会仅对本次请求覆盖配置model字段仍然必填作为无路由命中时的回退模型。响应体则是一个独立的 JSON{ models: [ anthropic/claude-sonnet-4-6, openai/gpt-4o, openai/gpt-4o-mini ], route: code generation, trace_id: 4bf92f3577b34da6a3ce929d0e0e4736 }字段类型说明modelsstring[]排序后的模型列表models[0]为主选429/5xx时依次用models[1]等重试routestring | null命中的路由名null表示未命中客户端应使用原始请求的modeltrace_idstring分布式追踪 ID用于观测对应的客户端使用模式伪代码response plano.routing_decision(request) models response[models] for model in models: try: result call_llm(model, messages) break # success — stop trying except (RateLimitError, ServerError): continue # try next model in the ranked list源码级实现请求内联偏好如何被解析与覆盖在路由决策端点 routing_service.rs 中extract_routing_policy负责从请求体中剥离routing_preferences字段并解析为VecTopLevelRoutingPreference同时返回清洗后的请求体字节流确保下游解析器看不到该字段let routing_preferences json_body .as_object_mut() .and_then(|o| o.remove(routing_preferences)) .and_then(|value| serde_json::from_value::VecTopLevelRoutingPreference(value).ok());随后在routing_decision_inner中判断本次请求是否携带内联偏好与配置中是否有全局偏好共同决定路由是否可覆盖模型选择let routing_can_override_model inline_routing_preferences.is_some() || orchestrator_service.has_routing_preferences();再结合route_on_user_only等会话策略见 configuration.rs 中的Routing结构将内联偏好传入router_chat_get_upstream_model完成最终决策。整个链路印证了原文档的描述请求体偏好的优先级高于配置偏好且仅对本次请求生效。同文件下的单元测试如extract_routing_policy_routing_preferences、extract_routing_policy_preserves_other_fields也验证了字段剥离、JSON 兼容性与默认selection_policy的解析行为可作为阅读源码的入口。实战验证运行偏好路由 Demo 并用planoai trace --where校验仓库提供了开箱即用的偏好路由示例 demos/llm_routing/preference_based_routing其中 config.yaml 定义了 code understanding 与 code generation 两条路由。启动方式cd demos/llm_routing/preference_based_routing ./run_demo.sh # 也可加 --with-ui 同时启动 AnythingLLM 与 Jaeger或手动启动先docker compose up -d启动辅助服务再planoai up config.yaml启动 Plano然后通过 curl 或 AnythingLLMhttp://localhost:3001/发起请求。演示日志中可以看到路由决策记录例如2025-05-31T01:02:19.382716Z INFO brightstaff::router::llm_router: router response: {route: code_generation}, response time: 203ms如需本地自托管路由模型不经托管端点可参考 plano_config_local.yaml先ollama pull hf.co/katanemo/Arch-Router-1.5B.gguf:Q4_K_M再用planoai up plano_config_local.yaml启动并通过overrides.llm_routing_model指向本地模型地址。验证路由决策的推荐方式是 CLI 追踪planoai trace支持--where过滤器keyvalue形式可叠加多个条件实现在 trace_cmd.py 中用代表性查询逐一测试观察每条请求命中的路由名与所选模型据此迭代打磨你的description。例如按路由名过滤出所有命中 code_generation 的追踪检查是否有漏网的代码生成请求被分去了别的路由。常见问题排查速查启动报错顶层routing_preferences不被接受——请确认配置version: v0.4.0及以上低于 v0.4.0 时顶层形式会触发启动错误版本要求见 Routing API 的 Version Requirements 表日志出现弃用警告——说明你仍在使用 v0.3.0 的内联写法偏好写在model_provider下请迁移到顶层形式并把models候选池移入每条偏好内路由始终回退到请求的model字段——响应中route为null说明没有命中任何路由。检查描述是否过于模糊、路由是否互相重叠或请求类型是否真的属于已声明的路由范围models中的模型未生效——检查该模型是否已在model_providers中声明且模型名含供应商前缀如openai/gpt-4o完全一致希望优先低成本/低延迟模型——可在偏好上配置selection_policycheapest/fastest/ 默认none这是源码 configuration.rs 中确认支持的字段。掌握这些原则与工具后你的 Plano 路由配置将能稳定实现按任务难度与类型分诊、按供应商自动回退、按 Trace 持续可观测的完整闭环。【免费下载链接】planoPlano is an AI-native proxy server and data plane for agentic apps. Smart LLM routing, observability, agent orchestration, and guardrails so you stay focused on your agents core logic.项目地址: https://gitcode.com/GitHub_Trending/ar/plano创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考