news 2026/9/24 14:53:42

IronClaw 渐进式工具披露:tool_search 命名空间目录头的设计与实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
IronClaw 渐进式工具披露:tool_search 命名空间目录头的设计与实现

IronClaw 渐进式工具披露:tool_search 命名空间目录头的设计与实现

【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址: https://gitcode.com/gh_mirrors/iro/ironclaw

导读

本文围绕 IronClaw Agent OS 中tool_search桥接工具的命名空间目录头(namespace catalog header)展开,深入剖析这条被注入到系统提示词(system prompt)中的一行模板如何被源码渲染为「工具总数 + 授权命名空间 + 代表性工具名」的结构化索引。你将理解 IronClaw 渐进式工具披露(progressive tool disclosure)为何需要它、它如何受字节预算与安全描述(safe-description)约束,以及tool_search → tool_describe → tool_call完整发现链路在 crates/loop/ironclaw_loop_host 中的真实实现与测试验证。

目录头模板:一行文本承载的发现协议

IronClaw 将tool_search桥接工具的描述文本同时用作「常驻目录索引」——模型每次看到的可见工具列表只是实际能力的精选子集,更多工具按需加载,而tool_search的描述必须告诉模型:当前到底还有多少工具、分布在哪几个授权命名空间、以及搜索结果以何种形式返回。

该模板位于 crates/loop/ironclaw_loop_host/prompts/tool_search_namespace_header.md,全文如下:

These {{total_tools}} tools are available on demand across {{namespace_count}} authorized namespaces. Search results include complete schemas when schema_complete=true; otherwise use tool_describe. Never report a capability unavailable before searching. Namespaces:

这行模板定义了四条关键语义,全部被下游实现逐一落实:

模板要素语义对应实现
{{total_tools}}按需可发现的工具总数渲染时被替换为各命名空间工具数之和
{{namespace_count}}授权命名空间数量渲染时被替换为BTreeMap去重后的命名空间数
schema_complete=true搜索结果已含完整 schema,可直接调用;否则须先tool_describe见 tool_disclosure.rs 的CatalogSearchResult
Never report a capability unavailable before searching模型在搜索之前不得断言能力不可用见 tool_disclosure_protocol.md 的强制步骤 1

模板末尾的Namespaces:是命名空间列表的锚点,随后的每一行以- namespace (count)形式列出语义命名空间及其工具数,再由Representative tools (fair namespace rounds):引出代表性工具名。

源码注入与占位符渲染

模板通过include_str!在编译期嵌入二进制,与空目录描述一并成为两个常量(tool_disclosure.rs 第 20-21 行):

const EMPTY_CATALOG_DESCRIPTION: &str = include_str!("../prompts/tool_search_empty_catalog.md"); const NAMESPACE_CATALOG_HEADER: &str = include_str!("../prompts/tool_search_namespace_header.md");

渲染入口是catalog_index_tool_search_description_for_mode(tool_disclosure.rs 第 696-756 行),核心流程如下:

  1. 若当前披露模式不含命名空间摘要(includes_namespace_summaries()为假),则退化为纯字母序索引;
  2. 通过catalog.discoverable_namespaces(policy)获取经过授权策略过滤的命名空间分组;
  3. 若没有任何可发现工具,直接返回 tool_search_empty_catalog.md 的内容("No additional tools are available on demand. Tools already listed are available and do not need to be searched.");
  4. 否则执行占位符替换:
let mut description = NAMESPACE_CATALOG_HEADER .trim_end() .replace("{{total_tools}}", &total.to_string()) .replace("{{namespace_count}}", &namespaces.len().to_string());
  1. 依次追加每个命名空间条目\n- {namespace} ({count}),当累计长度超出预算时以\n- additional authorized namespaces exist; use tool_search截断收尾;
  2. 再以「公平轮次」(fair rounds)逐命名空间轮流取一个代表性工具名写入Representative tools (fair namespace rounds):之后,直到预算耗尽或全部列出;若仍有剩余,追加\n…and N more — use tool_search(query="<service or action>")引导模型继续搜索。

字节预算:为什么索引只写名字不写描述

源码注释(tool_disclosure.rs 第 672-687 行)明确解释了这一设计约束:

  • tool_search的描述会被校验为能力安全描述(safe-description),存在4096 字节硬上限和敏感内容黑名单;超出即导致整轮对话在提示词阶段直接失败;
  • 因此索引只携带工具名字——若写入工具描述,既会撑爆字节预算,也可能携带被黑名单拦截的子串;
  • 代码层设置了更保守的内部预算BUDGET_BYTES = 3800,另预留TAIL_NOTE_RESERVE = 96字节给「…and N more」尾部提示,确保永不触顶。

测试 index_description_stays_under_the_model_safe_cap_for_a_large_catalog 用 300 个长名工具构造超大目录,断言最终描述长度<= 4096且包含more — use tool_search尾部提示,防止回归。

命名空间如何划分:从 capability id 到语义分组

命名空间分组定义在 tool_disclosure.rs 第 319-422 行。DiscoveryNamespace枚举包含 12 个第一方意图分组加一个扩展组:

agentscodingdataextensionsmemorymessagingobservabilityschedulingsettingsskillssystemweb,以及按扩展 id 命名的Extension(String)

discovery_namespace的映射规则:

  • capability id 以builtin.开头 → 走builtin_discovery_namespace二次映射;
  • ironclaw.memory.开头 →Memory;以ironclaw.开头 →System
  • 其余视为扩展工具,取点号前一段作为扩展 id 命名空间。

内置工具的语义映射(builtin_discovery_namespace)示例:read_file/write_file/list_dir/glob/grep/apply_patch/shellcodinghttpwebextension_*/ironhub_*extensionsskill_*skillstrigger_*schedulingoutbound_*/notification_*messagingtrace_commons.*observabilityadmin_*/operator_config_*settingsspawn_subagentagentsjsondata;其余落入system

分组结果经BTreeMap按命名空间名与工具名双重排序,保证索引文本确定性与缓存稳定性——同一 surface 版本与同一授权策略下,每次生成的描述字节完全一致。

谁被索引、谁被排除:核心工具与桥接工具

并非所有工具都会进入命名空间索引。CapabilityCatalog::new构建目录时(tool_disclosure.rs 第 146-176 行):

  • 桥接工具(tool_search/tool_describe/tool_call,即is_bridge_name)与桥接 capability id 被排除出目录;
  • 剩余条目按is_core_tool_definition或配置档位固定(profile pins)判定为Core层,否则为Discoverable层;
  • Discoverable层的工具会进入命名空间摘要——因为Core工具(如read_fileshellmemory_searchextension_installtrigger_createoutbound_deliver等,见 CORE_TOOL_NAMES 第 29-77 行)的完整 schema 已在可见列表里直接给出,无需重复索引。

测试 tool_search_description_summarizes_namespace_and_representative_tool 验证:索引必须包含可发现工具google-calendar__list_events、必须出现授权命名空间计数fixture (1)、且不得重复列出已直出 schema 的核心工具read_file

授权策略:索引与结果同口径收窄

命名空间索引与tool_search结果、tool_describe一样,都受CapabilitySurfacePolicy过滤。discoverable_namespaces(policy)只统计policy.permits_capability_id允许的条目;测试 tool_search_description_is_narrowed_by_policy 用allow_only策略验证:允许列表内的github__list_issues仍会出现在索引中,而未被允许的google-calendar__list_events名字绝不泄漏进索引——否则收窄后的 profile 会通过tool_search自己的描述旁路绕过结果过滤,直接读到全部工具名。

模式开关:REBORN_TOOL_DISCLOSURE 环境变量

命名空间摘要是否启用由披露模式决定,定义在 crates/loop/ironclaw_loop_host/src/tool_disclosure_mode.rs,通过环境变量REBORN_TOOL_DISCLOSURE配置:

取值模式命名空间摘要完整签名配置档位固定
offOff
compactCompact
signaturesSignatures
namespaces(默认)Namespaces
bridgedBridged

默认值为Namespaces(生产臂);未设置或空值沿用默认;识别不了的值与显式off失败关闭Off(回滚路径);非 UTF-8 取值同样回退到Off并在 debug 级记录日志。测试 tool_disclosure_mode_defaults_namespaces_with_off_kill_switch 覆盖了全部取值的大小写、非法值与开关语义。

完整发现协议:从「看不见」到「调起来」

目录头只是发现链路的入口。配套的 tool_disclosure_protocol.md 定义了模型侧完整行为协议:

  1. 当可见工具列表中出现tool_search,说明列表只是精选子集;需要某项能力但没看到匹配工具时,先调用tool_search(query="<service or action>"),它返回带schema_complete标记的排序匹配结果;
  2. 结果schema_complete=true时按返回的parametersschema 直接调用;为false、标记缺失或结果有歧义时,先调用tool_describe(name="<tool>")取完整 schema;
  3. 通过tool_call(name="<tool>", arguments="{\"field\":\"value\"}")执行(arguments为字符串编码的 JSON 对象);已知精确名字后也可直接以该名字调用,审批、策略、钩子与安全机制走完全相同的路径;
  4. 只有当tool_search返回无相关结果后,才能向用户声明能力不可用。

tool_searchtool_describetool_call三个桥接工具的 schema 定义位于 tool_disclosure.rs 第 558-625 行:tool_search接受query(必填)与limit(默认 10、最小 1);tool_describe接受nametool_call接受namearguments。此外tool_disclosure.rs还实现了宽容名称解析——模型无论传点号形式的 capability id(google-calendar.list_events)、__编码的线缆名(google-calendar__list_events)还是裸名,都能解析到同一目录条目(测试见 provider_name_matcher_resolves_non_builtin_dotted_and_encoded_forms)。

容量控制:何时触发按需披露

最后,目录头的存在与否取决于DisclosureCaps与阈值判定(tool_disclosure.rs 第 540-556 行)。默认上限为max_tokens = 12_000max_tools = 32defer_threshold_tokens在配置了上下文上限时取min(max_tokens, ctx_limit / 10)select_active_set_for_mode在有效工具 schema 总 token 数不超阈值工具数不超上限时直出全部定义(deferred: false);否则只直出核心工具与桥接工具,其余全部按需延迟,tool_search的描述随之变成命名空间目录头(deferred: true)。

小结

tool_search_namespace_header.md这行模板是 IronClaw 渐进式工具披露在提示词面的「门面」:它把{{total_tools}}{{namespace_count}}两个占位符渲染成受字节预算约束的命名空间索引,用「公平轮次」给出代表性工具名,再用schema_complete与「先搜索再下结论」两条纪律约束模型行为。它的每一次替换、截断与过滤,都能在 tool_disclosure.rs、tool_disclosure_mode.rs 及对应测试中找到精确的源码依据——理解这条链路,也就理解了 IronClaw 如何在上下文预算内让模型「看得见但不背全量 schema」地调用成百上千个工具。

【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址: https://gitcode.com/gh_mirrors/iro/ironclaw

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 14:53:24

PyCaret 平台运维指南:备份、升级、可观测性与弹性扩展实战

【免费下载链接】pycaret Open-source, low-code AutoML platform for Python. PyCaret 4.0: sklearn-native engine React control plane. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/py/pycaret 点击查看 免费下载 PyCaret 4.0 的 sklearn 原生引擎之上构建了完…

作者头像 李华
网站建设 2026/9/24 14:52:35

2026年软著申请全流程详解(附材料清单)

## 一、申请条件软件著作权申请的门槛并不高&#xff0c;个人和企业都可以申请。只要你有独立开发完成的软件作品&#xff0c;就可以申请软著登记。具体来说&#xff0c;软件必须是开发者独立开发完成的&#xff0c;要有固定的表达形式&#xff0c;也就是要有可运行的代码和相应…

作者头像 李华
网站建设 2026/9/24 14:51:42

AI应用开发:从单模型调用到多智能体系统,2026年完整实战指南

开篇&#xff1a;2026年&#xff0c;AI应用开发早已不是“套API”那么简单 三年前&#xff0c;你写一个AI应用&#xff0c;可能只需要三行代码&#xff1a;导入OpenAI SDK、填好API Key、调用chat.completions接口&#xff0c;再把返回结果打印到前端页面&#xff0c;一个“AI聊…

作者头像 李华
网站建设 2026/9/24 14:49:26

你装的AI编程助手,可能已被接管

一个 40 位的分支名&#xff0c;让四款最火的 AI 编程助手在没人点击任何东西的情况下&#xff0c;执行了攻击者的代码一、先说最反直觉的一点&#xff1a;这次你不需要点任何东西 2026 年 5 月&#xff0c;安全公司 AIR Security 的研究员在实验室里做了一件听起来很无聊的事&…

作者头像 李华