oh-my-claudecode 委托强制器(Delegation Enforcer):Task/Agent 调用模型参数自动注入机制全解析 oh-my-claudecode 委托强制器Delegation EnforcerTask/Agent 调用模型参数自动注入机制全解析【免费下载链接】oh-my-claudecodeTeams-first Multi-agent orchestration for Claude Code项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-claudecode本文以 docs/DELEGATION-ENFORCER.md 为骨架结合 oh-my-claudecode 仓库源码系统讲解委托强制器Delegation Enforcer如何解决 Claude Code 不会自动应用 Agent 定义中默认模型的痛点——通过 pre-tool-use 钩子自动为Task/Agent调用注入model参数同时始终保留显式指定的模型。读完本文你将掌握它的设计动机、工作流程、核心 API、Agent 模型映射关系、调试手段与底层实现原理并能在自己的多 Agent 编排代码中直接复用它。一、问题背景为什么需要 Delegation EnforcerClaude Code 原生行为中Agent 定义里配置的默认模型并不会被自动应用到实际委托调用上。即使某个 Agent如executor在其AgentConfig中已经声明了model: sonnet当你调用Task工具或Agent工具发起子代理任务时仍必须在每一次调用上手动写出model参数。这种手工重复带来三类明显副作用见 docs/DELEGATION-ENFORCER.md 的 Problem 一节委托代码冗长每次Task调用都要重复携带模型参数样板代码膨胀遗漏导致模型回退一旦某次调用忘记写model子代理就会悄悄继承父级模型的参数与你预期的模型档位不一致模型使用不一致同一类 Agent 散落在代码库各处不同调用点可能写上不同的模型难以统一治理。在 oh-my-claudecode 的编排体系里Agent 数量众多且被划分为多档high/medium/low手工维护每个调用的模型参数几乎必然出错。这正是委托强制器要解决的工程问题。二、解决方案作为中间件的自动注入Delegation Enforcer 是一层中间件核心职责一句话概括当一次委托调用没有显式指定model时根据 Agent 定义自动注入该 Agent 的默认模型当调用已显式指定模型时则一律保留、绝不覆盖。需要说明的是官方文档与源码注释见 实现文件 顶部注释描述的均是这套缺失则注入、显式则保留的语义。此外从源码看它还会在注入前完成 Agent 类型规范化、模型别名解析、模型 ID 归一化等一系列工作详情见下文第五节。1. pre-tool-use 钩子拦截强制器以 pre-tool-use 钩子的形态运行在每次工具调用发生前截获Task与Agent调用并改写其输入。文档给出的前后对比清晰展示了效果// 强制之前未携带 model Task( subagent_typeoh-my-claudecode:executor, promptImplement feature X ) // 强制之后自动 Task( subagent_typeoh-my-claudecode:executor, modelsonnet, // ← 自动注入 promptImplement feature X )2. 从 Agent 定义读取默认模型每个 Agent 在其定义对象中声明默认模型。例如executor的定义可在 src/agents/executor.ts 中看到完整声明export const executorAgent: AgentConfig { name: executor, description: Focused task executor. Execute tasks directly. NEVER delegate or spawn other agents. Same discipline as OMC, no delegation., prompt: loadAgentPrompt(executor), model: sonnet, // ← 默认模型 defaultModel: sonnet, // ← 注入时实际参考的模型来源 };强制器通过getAgentDefinitions()读取这份注册表src/agents/definitions.ts当调用缺失model时查表注入。3. 显式模型永远被保留当一次委托显式指定了模型强制器直接放行并保留该值即便它与 Agent 默认模型不同// 显式模型永远不会被覆盖 Task( subagent_typeoh-my-claudecode:executor, modelhaiku, // ← 显式使用 haiku 而非默认的 sonnet promptQuick lookup )这一安全优先的设计保证了迁移零成本老代码即便仍手写模型也不会被破坏。三、核心 API 详解文档列出的 API 在源码中均有真实对应实现见 src/features/delegation-enforcer.ts下文按文档描述 源码细节的方式逐一展开。enforceModel(agentInput: AgentInput): EnforcementResult对单次委托调用强制执行模型参数。这是整个模块的核心函数内部执行顺序从源码推断大致为规范化subagent_type→ 校验 Agent 是否存在 → 处理 forceInherit / 显式模型 / 别名映射 / 默认模型注入 → 返回结果对象。import { enforceModel } from oh-my-claudecode; const input { description: Implement feature, prompt: Add validation, subagent_type: executor }; const result enforceModel(input); console.log(result.modifiedInput.model); // sonnet console.log(result.injected); // true返回的EnforcementResult结构定义于 src/features/delegation-enforcer.ts包含五个字段字段类型含义originalInputAgentInput原始输入未被修改modifiedInputAgentInput已注入/改写模型的输入可直接发给 SDKinjectedboolean本次是否为自动注入false表示显式指定或走 inherit 路径modelstring最终生效的模型可能是注入结果、归一化结果或inheritwarning?string调试警告信息仅当OMC_DEBUGtrue时存在入参AgentInput的完整字段还包括resume?、run_in_background?等可选属性model?为可选。测试对各类场景显式保留、缺失注入、未知类型抛错等都有覆盖见 src/tests/delegation-enforcer.test.ts。getModelForAgent(agentType: string): ModelType查询某 Agent 类型的默认模型。源码实现会先剥离可选的oh-my-claudecode:前缀并做别名规范化再查表最终对标准 Anthropic 模型 ID 做归一化处理。import { getModelForAgent } from oh-my-claudecode; getModelForAgent(executor); // sonnet getModelForAgent(executor-low); // haiku getModelForAgent(executor-high); // opusisAgentCall(toolName: string, toolInput: unknown): boolean判定一次工具调用是否为代理委托调用。源码的实现要点是工具名大小写不敏感地匹配agent或task且toolInput必须是同时含subagent_type、prompt、description三个字符串字段的对象——缺少任一结构即判定为假因此也天然作为 TypeScript 类型守卫type guard使用。import { isAgentCall } from oh-my-claudecode; isAgentCall(Task, { subagent_type: executor, prompt: ..., description: ... }); // true isAgentCall(Bash, { command: ls }); // false源码中对非法输入null、undefined、字符串、缺字段对象的判定都有单测佐证确保非委托工具不会被误伤。钩子集成强制器自动挂接到 pre-tool-use 流程。模块内processPreToolUse(toolName, toolInput)是对钩子形态的封装先isAgentCall判定命中才enforceModel返回{ modifiedInput, warning }。在 SDK 侧可直接构造钩子输入后走统一钩子入口import { processHook } from oh-my-claudecode; const hookInput { toolName: Task, toolInput: { description: Test, prompt: Test, subagent_type: executor } }; const result await processHook(pre-tool-use, hookInput); console.log(result.modifiedInput.model); // sonnet在完整的 Claude Code 插件运行时中钩子路由在 src/hooks/bridge.ts 的processHook分发逻辑中以case pre-tool-use: return processPreToolUse(input);的方式接入说明这是一条真实生效的调用链而非仅停留在文档层面。四、Agent 模型映射表文档给出了一张核心映射表标明各 Agent 类型默认模型与适用场景。它在源码 Agent 注册表src/agents/definitions.ts 及各 Agent 单文件中逐一有据可查Agent 类型默认模型适用场景architectopus复杂分析、调试architect-mediumsonnet标准分析architect-lowhaiku快速问答executorsonnet标准实现executor-highopus复杂重构executor-lowhaiku简单改动explorehaiku快速代码检索designersonnetUI 实现designer-highopus复杂 UI 架构designer-lowhaiku简单样式document-specialistsonnet文档查找writerhaiku文档撰写visionsonnet图像分析planneropus战略规划criticopus方案评审analystopus规划前分析qa-testersonnetCLI 测试scientistsonnet数据分析scientist-highopus复杂研究说明与补充源码佐证文档是较早对档位变体-low/-high/-medium后缀的约定式描述当前仓库的 Agent 注册表中executor、debugger、verifier、test-engineer、security-reviewer、designer、qa-tester、scientist、tracer、git-master、document-specialist、explore等声明的默认模型均为sonnet而architect、planner、critic、analyst、code-reviewer、code-simplifier等声明为opuswriter为haiku。这一规划/评审用 opus、实现/检索用 sonnet/haiku的分层与文档中的映射思路一致。同时 src/tests/delegation-enforcer.test.ts 的 works with all agents 用例验证了architect→opus、executor→sonnet、explore→haiku、debugger→sonnet、code-reviewer→opus等映射结果可直接作为回归基准。五、调试模式OMC_DEBUG开启调试日志即可看到模型何时被自动注入export OMC_DEBUGtrue开启后注入发生时会出现类似警告[OMC] Auto-injecting model: sonnet for executor重要提示警告仅在OMC_DEBUGtrue时显示。未设置该标志时强制过程完全静默进行。这一点在源码中由process.env.OMC_DEBUG true的严格判断保证单测也验证了无标志时warning为undefined、设true时出现Auto-injecting model、设false时不出现三种情形。此外若注入的模型经过别名重映射或 ID 归一化警告中还会追加(aliased from ...)或(normalized from ...)提示便于追踪最终模型的确切来源。六、实战用法对比Before / After / Override文档提供了三组可直接照搬的委托写法是理解本功能收益的最直观材料。改造前手工模式每次委托都必须显式写出对应档位的模型// 每次委托都需要显式模型 Task( subagent_typeoh-my-claudecode:executor, modelsonnet, promptImplement X ) Task( subagent_typeoh-my-claudecode:executor-low, modelhaiku, promptQuick lookup )改造后自动模式模型自动从 Agent 定义注入调用点只表达委派给谁、做什么// 模型自动从定义注入 Task( subagent_typeoh-my-claudecode:executor, promptImplement X ) Task( subagent_typeoh-my-claudecode:executor-low, promptQuick lookup )需要时显式覆盖简单任务临时降档、复杂任务临时升档均直接写model覆盖默认值// 为简单 executor 任务使用 haiku Task( subagent_typeoh-my-claudecode:executor, modelhaiku, // 覆盖默认 sonnet promptFind definition of X )仓库内还有一份可直接运行的演示脚本 examples/delegation-enforcer-demo.ts覆盖了无显式模型→自动注入有显式模型→保留多档位 Agent 模型查询pre-tool-use 集成调试模式警告五个示例运行命令npx tsx examples/delegation-enforcer-demo.ts七、实现细节与纵深原理文档在 Implementation Details 一节描述的是概念化流程而真实源码在遵循该主线的同时还包含了若干文档未展开的防御性处理一一说明如下。7.1 标准执行流程文档所列钩子处理步骤1 接收调用 → 2 判断是否Task/Agent→ 3 检查model缺失 → 4 查 Agent 定义 → 5 注入默认模型 → 6 返回修改后输入在 enforceModel 实现 中顺序成立但实际代码在注入默认模型前还插入了多个优先级分支。7.2 模型别名与 forceInherit 分支源码新增事实从 src/features/delegation-enforcer.ts 的enforceModel实现可以归纳出完整的决策顺序Agent 存在性校验最先执行subagent_type先被canonicalizeSubagentType规范化——剥离可选的oh-my-claudecode:前缀、将历史别名如build-fixer→debugger、quality-reviewer→code-reviewer见 src/features/delegation-routing/types.ts 的DEPRECATED_ROLE_ALIASES重写为规范名。若 Agent 不存在直接抛Unknown agent type若该标识符其实是内置 Skilloh-my-claudecode:命名空间同时被 Skill 占用错误信息会提示应改用Skill工具并给出规范 Skill 名避免用户误用相近名 Agent 顶替issue #3667有专门单测覆盖。forceInherit 优先当路由配置routing.forceInherit为真非 Claude 供应商如 CC Switch、LiteLLM 会被配置加载器自动开启issue #1201强制器剥除模型参数返回model: inherit让子代理继承用户配置的模型而不是注入供应商无法识别的sonnet/opus/haiku。显式模型分支调用带model时保留但会先经normalizeToCcAlias归一化——完整 ID 如claude-sonnet-5会被折叠为sonnet因为完整 ID 在 Bedrock/Vertex 上会触发 400 错误issue #1415而供应商专有 ID如us.anthropic.claude-sonnet-4-6-v1:0则原样保留。单测覆盖了这两类情形。别名重映射注入默认模型前若配置了modelAliasesOMC_MODEL_ALIAS_HAIKU/SONNET/OPUS/FABLE等环境变量issue #1211、#3726会先把 Agent 档位映射到别名别名解析为inherit时同样不注入任何模型。优先级为显式参数 forceInherit modelAliases Agent 默认值。注入并归一化最终把解析出的模型归一化为 Claude Code 支持的别名后写入modifiedInput。7.3 错误处理未知 Agent 类型抛Unknown agent type: agent (from 原标识)命中 Skill 标识符时附加 Skill 工具引导且采用精确匹配、绝不做模糊替代。无默认模型的 Agent抛No default model defined for agent: agent。非委托工具/结构非法输入原样透传、不做改动processPreToolUse与isAgentCall双重保证。7.4 性能设计每次enforceModel从 Agent 定义构建 O(1) 的哈希表查询全程同步、无异步操作仅命中Task/Agent才产生开销。补充事实配置读取是有缓存的——模块用CONFIG_ENV_KEYS中全部相关环境变量的组合值作为缓存键任何影响配置的环境变量变更都会使键失效并重新加载src/features/delegation-enforcer.ts 顶部的 config cache 说明避免高频委托时的重复磁盘读。7.5 配置项速查以下环境变量直接影响强制器的行为完整列表见源码中的CONFIG_ENV_KEYS数组环境变量作用OMC_DEBUGtrue时输出自动注入警告OMC_ROUTING_FORCE_INHERITtrue时强制继承、不注入模型显式开关OMC_ROUTING_ENABLED/OMC_ROUTING_DEFAULT_TIER路由能力总开关与默认档位OMC_MODEL_ALIAS_HAIKU/SONNET/OPUS/FABLE将对应档位重映射到其他模型或inheritOMC_MODEL_HIGH/MEDIUM/LOW档位模型解析影响buildDefaultConfigANTHROPIC_BASE_URL/CLAUDE_MODEL等触发非 Claude 供应商探测自动开启 forceInheritBedrock/Vertex 系列CLAUDE_CODE_USE_BEDROCK、CLAUDE_CODE_BEDROCK_*_MODEL等解析出供应商专有模型 ID注入时原样保留八、测试与运行运行针对强制器的全部单元测试npm test -- delegation-enforcer测试覆盖的核心断言包括见 src/tests/delegation-enforcer.test.ts显式模型别名与完整 ID被保留并归一化injected为false缺失模型时从定义注入sonnet等默认值injected为true不带oh-my-claudecode:前缀、以及历史别名build-fixer都能正确解析未知 Agent、Skill 标识符附带 Skill 引导正确抛错OMC_DEBUG严格区分true/false/未设置三种状态isAgentCall对非委托工具与畸形输入返回falseforceInherit、modelAliases、Bedrock/Vertex 专有 ID 等分支均有专项用例。运行交互式演示上文第六节已列示例npx tsx examples/delegation-enforcer-demo.ts此外src/tests/delegation-enforcer-integration.test.ts、src/tests/routing-force-inherit.test.ts 与 src/tests/bedrock-model-routing.test.ts 从集成、继承路由与 Bedrock 模型路由等维度对同一套逻辑做了交叉验证。九、收益总结与迁移说明收益原文档五点结合源码可得到更完整的落地图景代码更干净委托调用不再需要每个调用点手写模型一致性每个 Agent 始终使用其定义档位的正确模型安全显式模型永远被保留绝不静默覆盖透明OMC_DEBUGtrue可观测每次注入及其来源含别名/归一化溯源零配置直接复用既有 Agent 定义无需额外注册兼容异构供应商非 Claude 供应商/网关自动切换为 inherit 语义规避供应商无法识别 Claude 档位名导致的错误源码层面的额外收益。迁移无需任何迁移步骤。既有显式写模型的代码继续正常工作新代码可省略model参数无任何破坏性变更。十、延伸阅读Agent 定义总览完整 Agent 注册表与各 Agent 的模型/工具配置注原文档链接以该文件为相对锚点实际仓库的 Agent 入口与类型定义见 src/agents/index.ts 与 src/agents/definitions.tsFeatures 参考模型路由model routing与委托分类delegation categories的功能说明委托路由类型与别名表DEPRECATED_ROLE_ALIASES与角色→子代理默认映射的权威定义GETTING-STARTED 快速上手从安装到首个会话的完整流程便于在真实环境中体验上述机制【免费下载链接】oh-my-claudecodeTeams-first Multi-agent orchestration for Claude Code项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-claudecode创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考