MoonshotAI / MoonshotAI/kimi-code
dynamic tool select:按协议接入 API 原生 tool search(anthropic `defer_loading` / OpenAI Responses `tool_search`)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
你希望看到什么功能?
问题
dynamic tool select(双重门控:模型capabilities dynamically_loaded_tools + [experimental] tool-select = true)目前只在 Kimi 私有协议下完整生效:
- 已加载的动态工具被标记 deferred,从请求顶层
tools[]剥离,schema 通过 Kimi 私有的消息级工具声明(messages[].tools)投递; - anthropic / openai / google-genai 协议的适配层全部跳过这类消息,导致已加载工具的 schema 从未到达模型——模型只能拿到
<tools_added>公告文本里的工具名。
实测结果(真实会话数据):
- GLM-5.3-flash(anthropic 协议)、kimi-k3(anthropic 协议): 无限循环调用 select_tools(每次返回 Already available)并穿插无效probe,直到用户中断;
- deepseek / qwen / gemini:凭工具名盲调,首次调用几乎必被参数校验拒绝(
Invalid args ... must have required property ...),再从上报的报错反学要求的字段后重试,每轮浪费一次失败调用; - 对照组(kimi 私有协议):加载后首调即精确成功,含嵌套 filters 参数,全程 0 次参数错误。
关联:#3090(k3 served catalog 未声明 dynamically_loaded_tools,门控在 k3 上根本不打开)。#3090 解决的是"门控不打开",本 issue 解决的是"门控打开后 schema 送不到"——两者都修好,k3 与第三方模型才能真正用上 progressive disclosure。
为什么急需解决
- k3 响应慢且服务器经常过载,实际工作流被迫是:k3 完成规划后,执行阶段切到第三方模型,或委派给 secondary model 的 subagent 执行;
- 这些承接执行的第三方模型(GLM / deepseek / qwen 等)全部走 anthropic / openai 协议——正好全部踩在"schema 不投递"的缺陷上,tool select 对它们形同虚设;
- 大型项目挂载的 MCP 众多,动辄几十上百个工具:全量 schema 常驻上下文不可接受(贵、慢、稀释注意力),而盲调失败重试在本就紧张的执行窗口里更是纯浪费。对这个场景,可用的 tool search 是刚需,不是优化。
为什么不能用"并入顶层 tools[]"修复
最直接的修法是加载后把工具并入顶层 tools[]。但 tools 块位于请求最前端,任何变化都会使前缀 prompt cache 失效:实测 GLM(anthropic 协议)加载第二批 MCP 工具后,下一请求 cache read 占比从约 99% 掉到约 37%,一到两个请求后才恢复。每加载一批工具掉一次缓存,这个方案不可接受。
建议
按 provider 协议桥接各 API 原生的 tool search 机制:
- anthropic 格式:桥接 tool-search beta——工具自第一个请求起以
defer_loading: true恒定置于顶层tools[](字节稳定),发现结果以tool_reference块追加进对话尾部,由服务端展开为完整定义。官方明确 "The prefix is untouched, so prompt caching is preserved"。GLM 的 anthropic 端点已实测接受该 beta; deepseek 系列模型在 Claude Code 中实测支持 tool search。 - OpenAI Responses 格式:桥接
tool_search——deferred 工具不进顶层tools[],发现结果作为tool_search_output追加到 input 末尾;官方明确该特性 "designed to preserve the model's cache"(Codex CLI 即采用 client-executed 模式 + 本地 BM25)。 - openai chat completions、google-genai 是否有通用的tool search能力需要探明, 如果不支持, 请维持全量 inline 或明确禁用 tool select,不做"加载后并入顶层"的折中。
默认k3配置请求(#3090)
请在 k3 系列的 served model catalog 的默认capabilities配置里添加 dynamically_loaded_tools。否则需要 使用 override config 覆写默认给定的capabilities, 对普通人不友好。
门控与回退
- 仍由现有双门控控制:模型能力
dynamically_loaded_tools+[experimental] tool-select; - 按 provider definition 显式白名单标记支持原生机制的端点;未标记端点回退到全量 inline 或禁用 tool select,不允许静默劣化;
- kimi 私有协议保持现有消息级声明路径,行为零变化。
验收标准
- anthropic / openai-responses 协议下,工具加载不引起顶层
tools[]任何字节变化,prompt cache 全程不中断; - 加载后模型首次调用即参数正确:无 Invalid args、无 select_tools 循环;
- k3 系列默认配置声明
dynamically_loaded_tools,flag 打开即生效; - 不支持原生机制的端点行为明确且可观测;
- kimi 协议行为零变化。
补充信息
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No files or tests are named. Start by tracing the existing dynamic tool select implementation, provider adapter layers, provider definitions, and the k3 served model catalog; compare the Kimi message-level path with the Anthropic and OpenAI Responses paths. Done means native tool search preserves top-level tool bytes and cache behavior, unsupported endpoints have an explicit fallback, k3 advertises the capability, and Kimi behavior is unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend, cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100