
Weave Router 的 dispatch 执行边界完全指南plan walk、retry/failover 与 attempt 事件流如何运作【免费下载链接】routerModel router for agentic systems. Routes every prompt to the right model in 50ms. Cut costs 40-70% with just an endpoint change.项目地址: https://gitcode.com/GitHub_Trending/router101/routerWeave Router是面向 agentic systems 的模型路由器它在 50ms 内把每个 prompt 路由到最合适的模型仅更换一个 endpoint 就能降低 40–70% 的推理成本。而支撑这一能力的最后一公里就是 internal/dispatch/ 包——它是策略解析出的执行计划plan与各家 provider 适配器之间的唯一执行边界拿着计划逐个走完候选目标、应用统一的 retry/failover 规则、发出有序可审计的 attempt 事件流。dispatch 是什么计划与上游之间唯一的边界很多路由系统里该调哪个上游、失败了怎么办散落在各个业务包里。Weave Router 的做法是把这一切收拢到dispatch功能包只依赖抽象的inference.Executor契约只有 dispatch 包会真正解引用providers.Client去发起上游 I/O。这条规则不是口头约定而是有机器检查兜底的——架构基线清单在 docs/INFERENCE_BOUNDARY.md 中冻结了每一个 provider 调用点make inference-boundary会拒绝任何新增的越界调用。执行边界由四个部件组成部件文件职责Executorexecutor.go走 plan 的目标序列应用重试/故障转移规则发出 attempt 事件Clients注册表clients.go启动时冻结的只读 provider 客户端注册表Transport/AttemptFuncexecutor.go#L13-L52单次 attempt 的传输适配器声明是否已提交、如何重置、如何准备凭证AttemptSinkexecutor.go#L54-L65按序接收 attempt 事件落盘失败不得阻塞分派plan walkExecutor 如何一步步走完目标序列Executor.Run是整条流水线的核心executor.go#L160-L307。它的走法非常确定取目标序列plan.SelectedTarget()排第一随后依次是plan.AlternativeTargets()策略声明的备选目标预算裁剪若plan.Budget().MaxAttempts 0且目标数超出上限序列会被截断——预算约束的是含同目标重试在内的总 attempt 数逐个目标推进每个目标先向Clients注册表取客户端。若该 provider 在本部署中未配置则记录一个skipped事件原因provider_not_configured并继续走下一个目标而不是直接失败成功即返回任何一个 attempt 成功Result会带上ServedTarget、FallbackUsed是否用了备选目标和ResponseCommitted并立即结束 walk。注册表本身在 clients.go 中定义NewClients在启动时拷贝provider 映射之后调用方再修改自己的 map 也不会影响 dispatch 行为映射到 nil 客户端的名字算已注册可用于资格判断但永远不可分派。retry 与 failover同一目标的两种救火方式这是 dispatch 最有价值的部分——它把重试和故障转移严格分开且规则集中在一处同目标重试same-binding retry只有同时满足以下条件才会在原地重试错误是瞬时的providers.IsRetryable计划里只有一个目标单目标计划没有别的路可走重试次数未超上限MaxSameBindingRetries 2重试墙钟预算未耗尽sameBindingRetryBudget 10s防止挂死的上游把每次请求都拖满超时见 executor.go#L67-L75。退避采用指数策略基础 250ms每次重试翻倍250ms → 500ms。退避睡眠通过sleepWithContext尊重 context 取消。跨目标故障转移failover多目标计划中当错误可重试、上游模型不存在model-not-found或上游账单被阻断billing-blocked且尚未有任何响应字节提交给客户端时才 failover 到下一个目标executor.go#L292-L304。两个特殊开关由Transport声明用于覆盖默认规则Committed响应已开始流式写给客户端后重试被永久禁止——再发一次请求对用户毫无意义。此时记录committed失败原因并终止Terminal报告即使错误类别允许重试也必须立即结束例如凭证租约拿不到Bound操作必须留在当前目标例如调用方绑定的凭证在提供服务——瞬时错误可以原地重试但绝不 failover。失败原因是有界的机器词汇每个失败 attempt 都会映射到一个有限的失败原因常量executor.go#L77-L89事件里永远不携带上游响应体内容失败原因含义provider_not_configured该 provider 在本部署未配置target_mismatch准备出的 wire 请求与计划目标不一致见下节upstream_status/upstream_model_not_found/upstream_billing_blocked上游 HTTP 状态类错误transport/canceled/committed/prepare/attempt_budget_exhausted传输、取消、已提交、准备阶段失败、预算耗尽attempt 事件流每次上游尝试的完整审计线每一次 attempt无论成功、失败、跳过还是中止都会按序写入一个AttemptEvent契约见 telemetry.go#L59-L77定位信息ProvenancePurpose、PolicyID、registry/policy 修订号RequestIDOperationIDOperationID的意义同一个请求可能有多次推理操作主回合 handover 摘要它保证不同操作的 attempt 序号永不碰撞结果信息AttemptIndex、目标Target、Outcomeserved/failed/skipped/aborted四种之一、有界的FailureReason、UpstreamStatusCode、Latency。Sink接口只有一条纪律落盘失败绝不能阻塞分派主流程。事件与请求摘要共享同一份 Provenance因此事后可以把这次尝试用了哪个策略版本跨全部数据源对齐复盘。防线如何保证发给上游的确实是计划指定的模型dispatch 还内置了一道 I/O 前检查GuardTarget包装任意 provider 客户端在请求真正上线前校验 wire 请求体中的model字段必须等于计划目标的 catalog ID 或 upstream IDtarget.go。不一致则返回ErrTargetMismatch请求根本不会发出executor 收到后以target_mismatch原因终止操作——这是策略说用 A 模型、代码却发了 B 模型这类事故的硬防线。Buffered 适配器摘要类辅助调用的标准姿势像 handover 摘要、标题生成这类非流式辅助推理通过dispatch.Buffered接入buffered.goPrepare为某个 attempt 的目标构建 wire 请求Consume解析完整响应。整个响应先被捕获、再交给调用方读取天然适配 executor 的Committed/Reset语义。快速导航继续深入执行核心internal/dispatch/executor.goRun方法即全部 walk/retry/failover 逻辑执行契约internal/inference/executor.goResolvedPlan、Executor接口事件与结果类型internal/inference/telemetry.go、internal/inference/outcome.go调用点冻结清单docs/INFERENCE_BOUNDARY.md行为回归测试internal/dispatch/executor_test.go 与 internal/proxy/baseline_failover_integration_test.go一句话总结Weave Router 的 dispatch 把选谁、试几次、失败怎么办、留下什么记录这四件事从散落各处的业务代码中抽离出来变成一条确定、有界、全程留痕的执行边界——这正是它能把路由决策压进 50ms 并稳定交付的原因。【免费下载链接】routerModel router for agentic systems. Routes every prompt to the right model in 50ms. Cut costs 40-70% with just an endpoint change.项目地址: https://gitcode.com/GitHub_Trending/router101/router创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考