ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

gsd-2 动态模型路由实战指南:capability-aware 两阶段选型、预算压力与扩展 Hook 全解析

gsd-2 动态模型路由实战指南:capability-aware 两阶段选型、预算压力与扩展 Hook 全解析 人工智能AI Agent代码智能体Agent 编排CLIAI 应用【免费下载链接】gsd-2A powerful meta-prompting, context engineering and spec-driven development system that enables agents to work for long periods of time autonomously without losing track of the big picture项目地址https://gitcode.com/gh_mirrors/gs/gsd-2点击查看免费下载导读动态模型路由Dynamic Model Routing是 gsd-2 自动模式下的成本控制核心它为每个派发的工作单元自动挑选够用且最便宜的模型把昂贵模型如 Opus 级留给真正需要深度推理的复杂任务官方文档给出的典型收益是在有成本上限的套餐下减少 20-50% 的 token 消耗。本文以 docs/zh-CN/user-docs/dynamic-model-routing.md 为骨架结合仓库中gsd扩展的实际实现model-router.ts、complexity-classifier.ts、auto-model-selection.ts完整讲解 tier 分类、capability scoring、预算压力降级、用户覆盖、verbose 日志与before_model_select扩展 Hook 的配置与原理让你既能直接上手配置也能理解每一步决策背后的源码逻辑。动态路由引入于 v2.19.0capability scoring 引入于 v2.52.0。下文描述以当前仓库实现为准。一、工作原理只允许降级不允许升级自动模式派发的每个工作单元unit都会经过一个两阶段流水线阶段 1复杂度分类Complexity Classification——先把工作划分到某个 tierlight/standard/heavy。这一步是纯启发式规则不涉及 LLM 调用耗时通常低于 1ms。阶段 2能力评分Capability Scoring——在符合该 tier 的候选模型里根据模型能力与 task 需求的匹配程度排序打分选出最合适的模型v2.52.0 起。核心规则是只允许降级不允许升级用户在偏好设置中配置的 model 始终是上限router 不会把它升级到比你配置更强的模型。这个约束在源码中有明确体现——resolveModelForComplexity() 通过tierOrdinal(requestedTier) tierOrdinal(configuredTier)判断当请求的 tier 不低于用户配置的 model tier 时直接返回配置的 primary model不做任何降级。默认 tier 与模型级别的对应关系如下Tier典型工作默认模型级别Lightslice completion、UAT、hooksHaiku 级Standardresearch、planning、execution、milestone completionSonnet 级Heavyreplan、roadmap reassessment、复杂 executionOpus 级需要说明的是源码中的UNIT_TYPE_TIERS映射见 complexity-classifier.ts比文档表格更精细complete-slice在 v2.52 版本中默认为Standard而非 Light避免把携带大量内联上下文的 slice completion 路由到最便宜模型见代码注释 #4520plan-*默认即为Heavy规划需要最强的配置模型动态路由不会把 Opus 降下去。二、启用方式与完整配置动态路由默认关闭需要在偏好设置中开启--- version: 1 dynamic_routing: enabled: true ---完整配置项如下全部选项及默认值dynamic_routing: enabled: true tier_models: # 可选为每个 tier 显式指定 model light: claude-haiku-4-5 standard: claude-sonnet-4-6 heavy: claude-opus-4-6 escalate_on_failure: true # task 失败时提升 tier默认true budget_pressure: true # 接近预算上限时自动降级默认true cross_provider: true # 可跨 provider 选择 model默认true hooks: true # 是否对 post-unit hooks 也应用路由默认true capability_routing: true # 在 tier 内启用 capability scoring默认true配置项在源码中对应的结构体是 DynamicRoutingConfig。这里有几个值得注意的细节enabled默认为关闭但一旦开启defaultRoutingConfig()model-router.ts中其余特性capability_routing、escalate_on_failure、budget_pressure、cross_provider、hooks全部默认开启。源码中还有一个文档未展开的选项allow_flat_rate_providers对包月制 provider如 claude-code、GitHub Copilot默认不启用路由保留 #3453 的绕过逻辑因为订阅下每次请求成本相同只有当你想在包月订阅内按任务选择模型比如 research 用 haiku、architecture 用 opus时才开启#4386。tier_models支持 provider 前缀匹配配置anthropic/claude-sonnet-4-6这类带前缀的 ID 时router 会剥离前缀后与可用模型列表做 bare ID 匹配见 getEligibleModels()。三、各配置项深度解析3.1tier_models显式覆盖各 tier 的模型如果省略tier_modelsrouter 会使用内置的 capability mapping。当前仓库维护了一张远超文档列举范围的 tier 映射表MODEL_CAPABILITY_TIERmodel-router.ts文档列出的代表性模型为Lightclaude-haiku-4-5、gpt-4o-mini、gemini-2.0-flashStandardclaude-sonnet-4-6、gpt-4o、gemini-2.5-proHeavyclaude-opus-4-6、gpt-4.5-preview、gemini-2.5-pro从源码结构看实际映射中还包括claude-3-5-haiku-latest、gpt-4.1-mini、gemini-flash-2.0lightclaude-3-5-sonnet-latest、gpt-4.1、deepseek-chatstandardo1、o3、gpt-4-turbo、claude-3-opus-latest等heavy。未知模型的容错策略未在映射表中的模型默认按standard处理getModelTier()返回 standard而resolveModelForComplexity()会先检查用户配置的 model 是否在已知映射中——如果不是则直接尊重用户的显式选择、不做任何降级#2192避免基于猜测静默忽略用户配置。3.2escalate_on_failure失败后自动升级 tier当 task 在某个 tier 上失败时router 会在重试时提升到下一层Light → Standard → Heavy。这样可以避免便宜模型在其实需要更强推理能力的工作上浪费重试次数。源码实现是 escalateTier() 的线性升级链在 auto-model-selection.ts 中重试上下文retryContext.isRetry携带上一次的 tier升级后 UI 会主动通知Tier escalation: light → standard (retry after failure)#3962模型变化必须可见。还有一个值得注意的细节若已处于 heavy最高 tier升级函数返回null此时会保留上一次已升级的 tier而不是让新一次的复杂度分类把模型静默降回更低的 tier#4973。3.3budget_pressure预算压力驱动的自动降级当预算接近上限时router 会逐步降低 tier。分类器classifyUnitComplexity()会接收当前预算使用比例0.0-1.0并在 applyBudgetPressure() 中按如下梯度降级已使用预算影响 50%不调整50-75%Standard → Light75-90%更激进地降级除 heavy 外全部 → Light 90%几乎所有工作都 → Light连 Heavy 也降级到 Standard注意最后一个区间源码实现中当budgetPct 0.9时heavy 也会被降到 standardeverything except replan-slice gets cheapest model比文档描述只有 Heavy 保持在 Standard更精确地反映了代码行为。降级发生时ClassificationResult.downgraded置为truereason 会追加(budget pressure: 87%)之类的说明。3.4cross_provider跨 provider 选最便宜开启后router 可以从你的主 provider 之外选择 model。它使用内置成本表按每 1K input tokens 的近似美元价格见MODEL_COST_PER_1K_INPUTmodel-router.ts在每个 tier 里找到最便宜的 model。要求目标 provider 已经正确配置。getEligibleModels()在未显式指定tier_models时会按 tier 过滤可用模型并按成本升序排序因此eligible[0]就是该 tier 内最便宜的模型。关闭cross_provider时cross_provider: falsefindModelForTier()会把搜索范围限制在同 provider仅保留claude-*前缀的模型见 model-router.ts。另一个连带行为配置的 primary model 不可用例如配置了 Anthropic 模型却在非 Anthropic provider 上运行时router 会寻找同 tier 的跨 provider 等价模型并把它插入 fallback 链首位保证路由在跨 provider 场景下依然可用。3.5capability_routingtier 内的能力评分开关开启后默认truerouter 会通过 capability scoring 在某个 tier 内选出最适合的 model而不是永远只选最便宜的那个。设为false可恢复到纯 cheapest-in-tier 行为dynamic_routing: enabled: true capability_routing: false # 关闭评分改用 tier 内最便宜的 model在 resolveModelForComplexity() 中评分路径有两个前提条件capability_routing ! false且该 tier 的 eligible 模型数 1且提供了unitType。因此当 tier 内只有一个候选模型时即便评分开启也会退化为 tier-only 路径。四、Capability Profiles7 维能力画像每个 model 都有一个内置的capability profile它是一个 7 维评分0-100表示该 model 在不同 task 类型下的能力强弱维度含义coding代码生成和实现准确性debugging诊断与修复错误的能力research信息综合与主题探索能力reasoning多步逻辑推理能力speed延迟与吞吐可视为能力深度的反向维度longContext处理大代码库和长文档的能力instruction精确遵循结构化指令的能力文档说明目前 9 个 models 带有内置 profileclaude-opus-4-6、claude-sonnet-4-6、claude-haiku-4-5、gpt-4o、gpt-4o-mini、gemini-2.5-pro、gemini-2.0-flash、deepseek-chat、o3。而当前仓库源码中的MODEL_CAPABILITY_PROFILES表model-router.ts已经扩展到 30 个模型覆盖 Anthropicopus/sonnet/haiku 各代、OpenAI GPT 全系含 gpt-4o/4.1、gpt-5 系列、o 系列推理模型、Google Gemini 以及 DeepSeek。例如claude-opus-4-6coding 95 / reasoning 95 / speed 30深度优先、速度慢claude-haiku-4-5coding 60 / speed 95速度快、能力适中o3reasoning 92 / speed 25推理极强但吞吐低gemini-2.5-prolongContext 90 / research 85长上下文与信息综合见长没有内置 profile 的 models 会收到全维度均为 50 的默认分数。这是一个冷启动策略未知模型可以参与竞争但不会凭空占优对应 scoreEligibleModels() 中{ coding: 50, ... }的兜底 profile。从用户角度看这类模型的路由行为和 capability scoring 引入前保持一致。重要声明这些 profiles 是启发式排序不是 benchmark。它们表达的是大致的相对优势而不是经过严格验证的 benchmark 结果源码注释中也标注了如 gpt-5.5 的评分参考 OpenAI 官方 2026-04-23 公布的 eval 增量。如果你很了解某个 model可通过下面的用户覆盖项修正这些分值。五、评分方式加权平均与动态需求向量tier 内的路由流程如下classify complexity tier ↓ filter eligible models for tier ↓ fire before_model_select hook (optional override) ↓ capability score eligible models ↓ select winner (or first eligible if scoring is disabled)评分公式各能力维度的加权平均score Σ(weight × capability) / Σ(weights)这正是 scoreModel() 的实现遍历需求向量的每个维度累加weight × capability再除以总权重若需求向量为空则返回中性分 50。Task requirements 是动态的不同 unit types 对维度的权重不同源码中的BASE_REQUIREMENTSmodel-router.tsUnit Type核心维度execute-taskcoding (0.9)、instruction (0.7)、speed (0.3)research-milestone/research-sliceresearch (0.9)、longContext (0.7)、reasoning (0.5)plan-milestone/plan-slicereasoning (0.9)、coding (0.5)replan-slicereasoning (0.9)、debugging (0.6)、coding (0.5)complete-sliceinstruction (0.8)、speed (0.7)run-uatinstruction (0.7)、speed (0.8)reassess-roadmapreasoning (0.9)、research (0.5)discuss-milestonereasoning (0.6)、instruction (0.7)对于execute-taskcomputeTaskRequirements() 还会进一步根据 task metadata 微调需求带有docs、config、readme、comment、typo、rename等 tag提高 instruction 权重instruction: 0.9、speed: 0.7、coding 降为 0.3包含concurrency、compatibility等复杂度关键词提高 debugging 和 reasoning 权重各 0.9 / 0.8包含migration、architecture等关键词提高 reasoning 和 coding 权重0.9 / 0.8文件数较多≥6或估计行数较大≥500提高 coding 和 reasoning 权重0.9 / 0.7平分时的决策当两个 models 的得分相差不超过 2 分时优先选择更便宜的那个如果成本也相同则按 model ID 字典序打破平局确定性结果。这条规则在 scoreEligibleModels() 的排序器里逐字实现Math.abs(scoreDiff) 2时按分数降序否则按成本升序成本相同按localeCompare字典序。六、用户覆盖用modelOverrides修正内置画像如果你对某个 model 的能力认知比内置 profile 更准确可以通过models配置里的modelOverrides修正{ providers: { anthropic: { modelOverrides: { claude-sonnet-4-6: { capabilities: { debugging: 90, research: 85 } } } } } }这些覆盖会与内置默认值进行深度合并你只需覆盖指定维度未指定的维度仍保留内置值。源码中 loadCapabilityOverrides() 负责从偏好配置提取覆盖项scoreEligibleModels()对带覆盖的模型执行{ ...builtin, ...override }浅层合并维度级别即深合并。典型用法如果你发现某个 model 在某一类工作上持续优于内置 profile就覆盖对应维度把 router 更积极地引导到该 model。例如上面把 claude-sonnet-4-6 的 debugging 提到 90、research 提到 85 后它在 replan 与 research 类单元上的评分会显著上升从而更频繁地被选中。七、详细输出verbose 模式下的决策日志开启 verbose mode 时router 会把自己的路由决策打印出来。如果使用了 capability scoring日志会包含完整评分拆分Dynamic routing [S]: claude-sonnet-4-6 (capability-scored) — claude-sonnet-4-6: 82.3, gpt-4o: 78.1, deepseek-chat: 72.0如果只使用了 tier 级路由例如评分被禁用、只有一个符合条件的 model或命中了路由守卫Dynamic routing [S]: claude-sonnet-4-6 (standard complexity, multiple steps)路由决策中的selectionMethod字段会说明采用了哪种路径对应 RoutingDecision 接口的selectionMethodcapability-scored使用 capability scoring 选出了最终 modeltier-only使用了 tier 内最便宜的 model或显式固定值此外在评分路径下RoutingDecision还会携带capabilityScores每个候选模型的得分表与taskRequirements本次使用的需求向量方便调试而wasDowngraded为 true 时auto-model-selection.ts 会无条件向用户发送 UI 通知#3962模型被降级必须可见而不仅仅在 verbose 日志里通知文本会包含 tier 标签L / S / H与完整评分拆分。八、扩展 Hookbefore_model_select扩展可以通过before_model_selecthook 拦截并覆盖 model 选择。Hook 触发时机在tier 过滤之后已知符合条件的 models但在capability scoring 之前尚未计算分数。Hook 可以完全接管选择也可以返回undefined让 scoring 按默认逻辑继续。这在源码 auto-model-selection.ts 中实现先计算 eligible 列表再emitBeforeModelSelect(...)若返回了modelId则直接构造 hook 覆盖的 routingResult 并跳过整个 capability scoring。注册处理器pi.on(before_model_select, async (event) { const { unitType, unitId, classification, taskMetadata, eligibleModels, phaseConfig } event; // 自定义路由策略research 一律优先用 gemini if (unitType.startsWith(research-)) { const gemini eligibleModels.find(id id.includes(gemini)); if (gemini) return { modelId: gemini }; } // 返回 undefined让 capability scoring 继续 return undefined; });事件负载字段类型说明unitTypestring当前派发单元类型例如execute-taskunitIdstring此次单元派发的唯一标识符classification{ tier, reason, downgraded }复杂度分类结果taskMetadataRecordstring, unknown \| undefined从单元 plan 中提取出的 task 元数据eligibleModelsstring[]符合该 tier 的 modelsphaseConfig{ primary, fallbacks } \| undefined用户为该 phase 配置的 model返回值{ modelId: string }表示覆盖默认选择返回undefined表示交给 capability scoring。第一个覆盖者生效如果多个扩展都注册了处理器第一个返回非undefined的处理器获胜后续处理器不会再被调用。另注意hooks配置项控制的是 post-unit hooks 是否也应用路由而before_model_select属于扩展 APIADR-004 / D-03 的实现两者是独立机制若routingConfig.hooks false则该 hook 不会触发见 auto-model-selection.ts。九、复杂度分类纯启发式规则工作单元通过纯启发式规则分类不涉及 LLM 调用耗时通常低于 1mscomplexity-classifier.ts 全程只做正则匹配与文件读取。9.1 Unit Type 默认值Unit Type默认 Tierrun-uatLighthook/*Lightresearch-*、discuss-*Standardcomplete-sliceStandardv2.52 从 Light 上调避免大内联上下文打到最便宜模型见 #4520execute-taskStandard可被 task 分析升级plan-*、replan-slice、reassess-roadmapHeavycomplete-milestoneStandardinstruction 0.8 / reasoning 0.59.2 Task Plan 分析对于execute-task单元分类器会分析 task plan读取{milestone}/slices/{slice}/tasks/{task}-PLAN.md见 extractTaskMetadata()信号简单 → Light复杂 → HeavyStep 数量≤ 3≥ 8文件数≤ 3Light 还要求 ≤1 且非新文件≥ 6描述长度 500 chars 2000 chars代码块数—≥ 5复杂度关键词无≥ 2 个依赖数—≥ 3源码中的实际阈值与文档表格略有出入以源码为准dependencyCount 3、fileCount 6、estimatedLines 500、codeBlockCount 5、complexityKeywords 2直接判 Heavy1 个复杂度关键词判 Standard单文件非新建文件的修改判 Light。复杂度关键词research、investigate、refactor、migrate、integrate、complex、architect、redesign、security、performance、concurrent、parallel、distributed、backward compat。源码正则还会从 plan 内容中自动检测migration、architecture、security、performance、concurrency、compatibility等信号并填充到complexityKeywords。此外plan-*单元还有专门的 plan 复杂度分析milestone 级规划直接判 Heavyslice 级规划若其RESEARCH.md超过 200 行也会上调到 Heavy。9.3 自适应学习路由历史.gsd/routing-history.json源码中定义为HISTORY_FILE routing-history.json见 routing-history.ts会按 unit type 和 tier 记录成功 / 失败情况。如果某种模式下某个 tier 的失败率超过 20%未来相似分类会自动上调一个 tier。用户反馈over/under/ok通过/gsd:rate-unit记录的权重是自动结果的2 倍源码FEEDBACK_WEIGHT 2rating: over模型能力过剩→ 反馈让该 tier 降级倾向rating: under模型能力不足→ 反馈让该 tier 升级倾向反馈数组上限 200 条超出后裁剪最旧的。自适应调整逻辑在 classifyUnitComplexity() 中仅当getAdaptiveTierAdjustment()返回的 tier 高于当前分类时才会采用只升不降并在 reason 中标注(adaptive: high failure rate at standard)。十、与 Token Profile 的关系动态路由和 token profile 是互补的Token profilesbudget/balanced/quality控制阶段跳过和上下文压缩Dynamic routing控制每个工作单元在对应 phase 内的 model 选择两者同时开启时token profile 负责给出基础模型集phase 配置的 primary fallbacksdynamic routing 再在这些基础之上做进一步优化。budgettoken profile dynamic routing 组合能带来最大的成本节省token profile 通过压缩上下文和跳过阶段削减 token 总量动态路由则通过降价模型削减单价两者叠加效果最显著。十一、成本表Router 内置了一张常见 models 的成本表源码中为每 1K input tokens 的近似美元价格model-router.ts用于跨 provider 成本比较。文档给出的成本单位为每百万 tokensinput / outputModelInputOutputclaude-haiku-4-5$0.80$4.00claude-sonnet-4-6$3.00$15.00claude-opus-4-6$15.00$75.00gpt-4o-mini$0.15$0.60gpt-4o$2.50$10.00gemini-2.0-flash$0.10$0.40源码成本表还覆盖了gpt-4.1、gpt-5系列、o4-mini、deepseek-chat等更多模型并且对未知模型采用成本兜底值 999getModelCost()model-router.ts——即未知成本按昂贵处理避免把任务路由给成本未知的便宜模型。这张成本表仅用于比较实际计费仍然来自你所使用的 provider。结语从配置到源码的完整决策链动态模型路由的价值在于把每一分 token 预算花在刀刃上light/standard/heavy 三级分类 capability scoring 的组合让 slice completion、UAT 这类轻量工作稳定落在 Haiku 级模型上而 replan、roadmap reassessment 这类重推理工作保留 Opus 级质量预算压力与失败升级两条自适应通道又保证了成本失控时自动收敛、质量不足时自动提升。若要进一步定制modelOverrides修正画像、before_model_selectHook 接管选型、/gsd:rate-unit反馈驱动自适应学习三层手段覆盖了从个人经验到团队策略的全部诉求。相关测试用例可参见 capability-router.test.ts、model-router.test.ts、dynamic-routing-default.test.ts 与 guided-flow-dynamic-routing.test.ts可作为进一步理解路由边界行为的入口。赞分享人工智能AI Agent代码智能体Agent 编排CLIAI 应用【免费下载链接】gsd-2A powerful meta-prompting, context engineering and spec-driven development system that enables agents to work for long periods of time autonomously without losing track of the big picture项目地址https://gitcode.com/gh_mirrors/gs/gsd-2点击查看免费下载相关推荐gsd-core 动态模型路由Dynamic Routing与失败分层升级实战指南gsd core 动态模型路由Dynamic Routing与失败分层升级实战指南 导读 本文围绕 gsd core 的 dynamic_routing 配Ghidra 免费逆向工具入门指南6 步把二进制程序读成可读代码Ghidra 免费逆向工具入门指南6 步把二进制程序读成可读代码 拿到一个不知名来源的 exe想弄清它到底干了什么却从没装过专业分析工具Ghidra 是逆向工程网络安全gsd-2 扩展开发指南模型与 Provider 管理Model Provider Managementgsd 2 扩展开发指南模型与 Provider 管理Model Provider Management 本文面向 gsd 2pi coding a人工智能AI Agent代码智能体Agent 编排CLIAI 应用上一篇IoT-For-Beginners 实战在 Raspberry Pi 上接入 Grove GPS Air530 传感器并读取 NMEA 定位数据下一篇Unreleased创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表