claw-code 源码详细分析:Route / Bootstrap / Tool-Pool——把提示词映射到「可执行面」的分层策略

张开发
2026/5/16 17:25:40 15 分钟阅读
claw-code 源码详细分析:Route / Bootstrap / Tool-Pool——把提示词映射到「可执行面」的分层策略
涉及源码src/runtime.py、src/tool_pool.py、src/command_graph.py、src/bootstrap_graph.py、src/main.py辅读src/setup.py、src/context.py、src/query_engine.py。1. 「可执行面」指什么在 Harness 语境里可执行面不是单指「调了哪个 API」而是在某一信任级别与策略下系统承认可以接线的命令名、工具名及其执行入口的集合再加上把自然语言提示词prompt落到该集合上的映射结果。claw-code 把这件事拆成几层互不替代的能力层次代表 API / CLI是否依赖用户 prompt回答的问题静态能力面工具池assemble_tool_pool/tool-pool否当前策略下最多能给模型/用户暴露哪些工具静态能力面命令图build_command_graph/command-graph否命令清单在builtin / plugin-like / skill-like上如何分段启动叙事引导图build_bootstrap_graph/bootstrap-graph否与上游对齐时运行时阶段在文档上如何排序提示词条件映射route_prompt/route是这句 prompt像在点名哪些命令/工具条目会话级编排bootstrap_session/bootstrap是在真实上下文 setup 路由 shim 引擎 落盘下一整轮可观测地长什么样下面按从静到动说明实现并标出分层策略的用意与边界。2. Tool-Pool策略约束下的「工具可执行面」# 28:37:src/tool_pool.pydefassemble_tool_pool(simple_mode:boolFalse,include_mcp:boolTrue,permission_context:ToolPermissionContext|NoneNone,)-ToolPool:returnToolPool(toolsget_tools(simple_modesimple_mode,include_mcpinclude_mcp,permission_contextpermission_context),simple_modesimple_mode,include_mcpinclude_mcp,)# 16:25:src/tool_pool.pydefas_markdown(self)-str:lines[# Tool Pool,,fSimple mode:{self.simple_mode},fInclude MCP:{self.include_mcp},fTool count:{len(self.tools)},]lines.extend(f-{tool.name}—{tool.source_hint}fortoolinself.tools[:15])return\n.join(lines)策略输入simple_mode只保留BashTool/FileReadTool/FileEditTool、include_mcp、permission_contextdeny_tool/deny_prefix。输出当前允许出现在「池」里的PortingModule子集 Markdown 报告默认只列前 15 条。分层含义这是产品/安全策略下的「能力上限」——回答「系统打算让 agent 看见多少工具」不读用户这句 prompt。CLI 里tools子命令可走同一套get_tools过滤tool-pool则是固定默认参数的报表入口# 113:115:src/main.pyifargs.commandtool-pool:print(assemble_tool_pool().as_markdown())return03. Command-Graph命令侧的「分段可执行面」# 29:34:src/command_graph.pydefbuild_command_graph()-CommandGraph:commandsget_commands()builtinstuple(moduleformoduleincommandsifpluginnotinmodule.source_hint.lower()andskillsnotinmodule.source_hint.lower())plugin_liketuple(moduleformoduleincommandsifplugininmodule.source_hint.lower())skill_liketuple(moduleformoduleincommandsifskillsinmodule.source_hint.lower())returnCommandGraph(builtinsbuiltins,plugin_likeplugin_like,skill_likeskill_like)策略输入get_commands的include_plugin_commands/include_skill_commandsCLIcommands可关插件/技能。输出三段计数 可flattened()拼回列表。分层含义与 Tool-Pool 对称——命令宇宙在来源维度builtin vs 插件 vs 技能上长什么样同样与当前 prompt 无关用于架构评审与 parity 对照。4. Bootstrap-Graph阶段叙事不是bootstrap_session的逐行调用栈# 16:27:src/bootstrap_graph.pydefbuild_bootstrap_graph()-BootstrapGraph:returnBootstrapGraph(stages(top-level prefetch side effects,warning handler and environment guards,CLI parser and pre-action trust gate,setup() commands/agents parallel load,deferred init after trust,mode routing: local / remote / ssh / teleport / direct-connect / deep-link,query engine submit loop,))性质文档化/对齐用的阶段列表描述完整产品里从预取到 submit loop 的意图顺序不等于Pythonbootstrap_session里函数调用顺序的 1:1 映射。价值评审时把Tool-Pool / Route / QueryEngine放在同一幅「运行时故事」里避免只见树木不见森林。5. Route唯一「prompt → 候选符号」层# 90:107:src/runtime.pydefroute_prompt(self,prompt:str,limit:int5)-list[RoutedMatch]:tokens{token.lower()fortokeninprompt.replace(/, ).replace(-, ).split()iftoken}by_kind{command:self._collect_matches(tokens,PORTED_COMMANDS,command),tool:self._collect_matches(tokens,PORTED_TOOLS,tool),}...returnselected[:limit]输入用户字符串 limit。输出带kind/name/source_hint/score的有序候选列表。关键分层点与result/08.md一致路由扫的是全量PORTED_COMMANDS/PORTED_TOOLS不应用 Tool-Pool 的simple_mode、MCP 开关或permission_context。因此Tool-Pool描述的是策略收缩后的能力面Route描述的是在完整镜像面上这句 prompt 的文本相关性两者故意解耦移植期可同时观察「若全开镜像会路由到哪」与「若收紧池子模型本该看见什么」产品期则需在更上层用同一 policy 过滤路由结果或只把池内名字喂给模型以对齐。6. Bootstrapbootstrap_session把各层粘成「一轮可观测会话」bootstrap_session是动态层的总编排在已有 prompt的前提下依次叠环境上下文、setup、路由、shim、权限推断、QueryEngine、持久化。# 109:152:src/runtime.pydefbootstrap_session(self,prompt:str,limit:int5)-RuntimeSession:contextbuild_port_context()setup_reportrun_setup(trustedTrue)setupsetup_report.setup historyHistoryLog()engineQueryEnginePort.from_workspace()history.add(context,fpython_files{context.python_file_count}, archive_available{context.archive_available})history.add(registry,fcommands{len(PORTED_COMMANDS)}, tools{len(PORTED_TOOLS)})matchesself.route_prompt(prompt,limitlimit)registrybuild_execution_registry()command_execstuple(registry.command(match.name).execute(prompt)formatchinmatchesifmatch.kindcommandandregistry.command(match.name))tool_execstuple(registry.tool(match.name).execute(prompt)formatchinmatchesifmatch.kindtoolandregistry.tool(match.name))denialstuple(self._infer_permission_denials(matches))stream_eventstuple(engine.stream_submit_message(...))turn_resultengine.submit_message(...)persisted_session_pathengine.persist_session()...returnRuntimeSession(...)分层在代码里的体现环境层build_port_context()—— 源码树、测试、资源、归档是否在盘context.py。启动层run_setup(trustedTrue)—— Python/平台、预取、延迟初始化setup.pyWorkspaceSetup.startup_steps()明文列出加载镜像 command/tool 快照等步骤。清单规模层history 记录PORTED_*数量全宇宙大小与 Tool-Pool 子集对照。路由层route_prompt→matches。可执行 shim 层ExecutionRegistry对匹配到的名字执行仍不读 Tool-Pool 过滤。策略/审计层_infer_permission_denials。会话语义层QueryEnginePort流式 submit_message→TurnResult。持久化层persist_session。RuntimeSession.as_markdown()把上述块按章节输出便于人类做一次「分层验收」# 39:85:src/runtime.pydefas_markdown(self)-str:lines[# Runtime Session,...## Context,render_context(self.context),...## Routed Matches,...## Command Execution,...## Tool Execution,...## Stream Events,...## Turn Result,self.turn_result.output,...self.history.as_markdown(),]7. 分层关系示意图提示词驱动静态能力面无 prompt策略子集builtin/plugin/skill全量 PORTED_* 打分未自动接入command-graphtool-poolbootstrap-graph 叙事route_promptbootstrap_session当前允许的工具集合命令分段RoutedMatch 列表QueryEnginePort persist虚线表示本仓库尚未把 Tool-Pool 的过滤结果自动喂给route_prompt这是阅读与演进时最需要注意的接缝。8. CLI 上的「策略组合」速查命令分层角色command-graph静态命令分段tool-pool默认策略下的工具池报告tools --simple-mode --no-mcp --deny-prefix ...自定义策略下的池与tool-pool默认不同route prompt仅路由无 setup/shim/引擎bootstrap prompt全栈编排 Markdown 报告bootstrap-graph阶段叙事对照用9. 小结分层策略在工程上的收益Tool-Pool / Command-Graph把策略与分段从 prompt 中剥离便于配置 diff、安全评审、与模型 context 对齐。Route把自然语言 → 符号候选隔离成单一函数便于换算法embedding、学习排序而不动 setup。Bootstrap把「这一轮故事里每一层长什么样」固化为RuntimeSession Markdown便于移植回归与 PR 审查。有意识的不连接路由用全量镜像、池用过滤子集迫使贡献者显式决定产品最终用哪一面驱动模型——这是避免隐式魔法的一种粗糙但诚实的设计。

更多文章