👁 140 次阅读
Open WebUI如何实现大规模工具集的搜索与懒加载?
来源:https://github.com/open-webui/open-webui/issues/31642现象描述
Open WebUI 在模型上配置了工具或 MCP 服务器后,会把每个工具的完整 JSON schema 注入到每一次 API 请求的 tools 数组中。这个动作不考虑工具是否与当前对话轮次相关,不考虑用户在聊天界面里是否已经把某个工具关掉,也不考虑模型是否真的会在本次会话中调用它。 Issue 提交者给出了一份按工具数量测量的开销数据:| 配置规模 | 每次请求的额外开销 |
| 中等工具集(约 39 个工具,例如 Jira + Confluence MCP) | 约 25,000 tokens |
| 拉满的工具集(约 128 个工具) | 约 200k tokens |
背景原因
问题根源在于工具注入策略是”全量注入”而非”按需注入”。用户一旦按照 MCP 生态的预期方式接入了多个专用服务器(搜索、数据库、工单、CI/CD、可观测性、代码工具等),工具定义就会挤占真实对话上下文,导致上下文窗口提前触顶、API 费用显著膨胀、提示词信噪比下降从而拖累模型表现。 Issue 描述中提到的唯一当前变通办法,是维护两套并行的模型配置——一套带工具、一套不带。这种做法脆弱、对终端用户造成困惑,也让统一聊天界面的设计初衷落空。 提交者还指出,几乎所有主流 LLM 客户端都已经实现了客户端层的工具搜索/延迟加载,Open WebUI 在这一块存在明显缺口。虽然可以在网关层实现类似能力,但该路径繁琐,且要求用户具备未必拥有的基础设施。期望行为与量化方法
Issue 提出的目标机制是:模型只接收一份轻量级工具清单(名称 + 简短描述)和一个search_tools 元工具,只有当某个工具与当前任务相关时才按需加载其完整 schema。实现路径中包含四项:基于阈值的延迟加载(完整 JSON schema 超过可配置 token/字符阈值的工具被延迟,仅在清单块中显示名称与截断描述)、search_tools 内置工具(类比已有的 view_skill 模式,供模型按关键词检索延迟工具的完整 schema,搜索可用 BM25 或关键词匹配)、始终加载的白名单(管理员或用户可配置的永不被延迟的工具列表,例如 web_search、code_interpreter 等核心内置工具与高频 MCP 工具)、尊重现有 UI 开关(作为基线改进,用户在聊天界面关闭的工具不应被注入 API 请求)。
量化方法可以直接采用上表中的测量口径:按当前配置统计每次请求注入的 tools 数组对应的 token 增量,并与去掉工具后的请求做对比。Issue 中给出的 39 工具约 25k tokens、128 工具约 200k tokens 两个量级,可作为判断是否需要引入延迟加载的参考基线。
解决方案与讨论进展
社区方向上的推进由 taylorwilsdon 发起。据 issue 讨论,他在 2026-09-30 表示已经有一个起点,并给出了对应的 PR:https://github.com/open-webui/open-webui/pull/31651
同一天他补充说会继续投入时间,并先在内部放开验证边界情况是否正常。当 Classic298 询问”你构建的本质上是对 ALL tools 的搜索吗”,taylorwilsdon 在给出的评论中未就该措辞直接作答,只回复自己在同步做压力验证;Classic298 随后表示愿意 review 这个 PR,并称”PR lgtm”。
关于实现层次存在一处明确分歧:
- Classic298 主张应当在 MCP 层和 OpenAPI 层实现,并覆盖所有内置工具;对于自定义 workspace 工具,建议由每个 workspace 工具文件暴露自己的搜索工具(一个文件可能包含 10、20、30 个工具),同时需要一个集中化的方式告诉 AI 它拥有哪些”种类”的工具。
- taylorwilsdon 不否认上述路径可行,但指出几乎所有其他主流客户端都是在客户端层支持的。这意味着从其他客户端迁移到 Open WebUI 的用户会面对截然不同的体验,并且他表示自己正在真实环境中遇到这个问题。他同时提到在 MCP 层实现需要具备修改每一个 MCP 的能力,而其中许多是不可控的远程一方服务(例如 Atlassian Rovo),对这些服务而言目前的替代方案只能是网关层(如 litellm 的 Virtual Tool Search 等),且并非完整存在、往往需要从零自建。他还反问是否有理由把该能力做成可选开关,认为它对受限上下文窗口的本地 LLM 用户是很大的质量提升,也能让企业场景与其它主流客户端能力对齐。
当前处理路径与局限
由于该 issue 仍处于 open 状态,且讨论集中在 PR 的早期验证阶段,目前可确认的处理路径仅有: 1. 跟踪 PR #31651 的进展,该 PR 是当前讨论中唯一被引用的实现起点。 2. 参与该 PR 的 review,Classic298 已在讨论中表态愿意 review,taylorwilsdon 回应表示感谢并说明自己也在同步验证。 3. 在 PR 落地前,仍只能依赖维护并行模型配置的旧办法,而这一办法正是 issue 认为脆弱且会困惑用户的做法。 需要说明的是,PR #31651 的合并状态、代码是否进入主干,在本次讨论中均无明确记录。可核实的方式是直接查询该 PR 的 GitHub 状态。常见错误排查
Issue 与讨论中并未提供报错日志或失败栈,本节只归纳与工具注入过载相关的可观察症状,不引入事实之外的排查步骤:- 上下文窗口提前触顶:Issue 将”上下文窗口提前触顶”列为工具定义挤占对话上下文的表现之一。
- API 费用异常偏高:Issue 将”API 费用显著膨胀”列为工具定义全量注入的后果之一。
- 模型表现下降:Issue 指出提示词信噪比随工具定义挤占真实对话上下文而下降,进而拖累模型表现。
- 工具载荷超限导致工具完全不可用:Issue 明确写到,当 tools 载荷超出模型可处理范围时,会”preventing usage entirely”。
- 工具被用户关闭后仍被注入:Issue 指出注入行为不考虑用户是否在聊天界面中关闭了工具。
实践建议
- 在评估是否需要该功能前,先按 issue 的测量口径统计当前每次请求因 tools 数组产生的 token 增量,对照 39 工具约 25k、128 工具约 200k 的量级判断自身所处区间。
- 若采用多 MCP 服务器组合,注意这属于 issue 认定的高增长场景:搜索、数据库、工单、CI/CD、可观测性、代码工具等叠加后,开销按工具数量累积。
- 在 PR #31651 合入前,不要假设 Open WebUI 已具备客户端层延迟加载;该能力目前仅处于讨论与 PR 阶段,issue 仍为 open。
- 关注实现层次之争的走向:客户端层方案对所有来源工具统一生效,MCP/OpenAPI 层方案则可能要求逐层适配,workspace 工具还需考虑单文件多工具(10 至 30 个)的自暴露搜索方式。
- 若在真实环境中复现了高开销问题,可参照 taylorwilsdon 的做法直接在 issue 中反馈,他明确表示正在真实环境中处理该问题。
FAQ
Q1:这个功能现在可以用了吗? A1:不能。据 issue 讨论,该 issue 状态为 open,唯一被引用的实现起点是 PR #31651,且讨论停留在早期验证与 review 表态阶段。PR 是否合入、是否进入主干,本次材料中没有记录,建议直接查询该 PR 的 GitHub 状态。 Q2:为什么工具关闭了还会被注入? A2:据 issue 描述,注入行为”regardless of whether the user has toggled it off in the chat UI”,即不检查用户在聊天界面中的关闭操作。这是当前实现的已知特性,也是该 issue 要解决的问题之一。 Q3:应该在 MCP 层还是客户端层实现? A3:讨论中存在明确分歧。Classic298 主张在 MCP 层、OpenAPI 层以及所有内置工具上实现,workspace 工具自行暴露搜索工具,并需要集中化的工具”种类”告知机制。taylorwilsdon 则指出几乎所有其他主流客户端都在客户端层支持,从其他客户端迁移的用户会面对不同的体验,且 MCP 层方案需要某种额外能力(该句在摘录中被截断)。截至末条实质评论,双方未在讨论中收敛出统一结论。 Q4:39 个工具和 128 个工具的开销差多少? A4:据 issue 提供的数据,约 39 个工具(Jira + Confluence MCP 为例)每次请求约多 25,000 tokens;约 128 个工具(拉满)每次请求约多 200k tokens。两者相差约 8 倍。 Q5:有没有临时替代方案? A5:Issue 提到的唯一当前变通办法是维护两套并行模型配置,一套带工具、一套不带。Issue 同时指出这一做法脆弱、对终端用户造成困惑,并且违背统一聊天界面的初衷。网关层实现虽然可行,但被 issue 描述为繁琐且要求用户具备未必拥有的基础设施。🔗 相关阅读(你可能还想看)
📄 Outlook 节点创建草稿添加附件为何报 UnableToDeserializePostBody?
📄 Flowise 点击市场或聊天页为何整页白屏?
📄 如何解决 Azure AI Search 向量存储的 $filter 递归深度超限错误?
📄 如何解决 shadcn/ui Sidebar 与 Header 重叠的问题?
📄 Next.js 开发服务器为何会 JavaScript heap out of memory?
📄 Nuxt 偶发 Cannot read properties of undefined 报错是怎么回事
📄 如何解决「Visual Studio Code for ipad」相关的问题?
📄 如何在AutoGen中实现企业级代理治理的加密行动收据(AAR)?
📄 记忆内容未清洗直接注入系统提示词,如何防范间接提示注入?
crewAI LiteAgent 将记忆内容直接拼接到系统提示词,存在间接提示注入风险。社区提出分层防御方案,但 iss