数据截至 (上游 commit 7803d562546a)
工具从哪来:四来源聚合与调用路由
30 秒导读: LangBot 的本地 Agent 每一轮都要拿到"我现在能用哪些工具",还要在模型说"调用 exec"时把这次调用送到真正干活的代码。这两件事全归
ToolManager管:它把四个来源不同的工具聚合成一份清单,再按工具名把每次调用路由回对应来源执行。本章讲这套聚合与路由,不讲工具循环本身(见 03-local-agent-loop)和 Box 沙箱内部实现(见 05-extensibility-and-surfaces)。
1. 这是什么(零基础也能懂)
一句话定义: ToolManager 是一个工具中枢——把散落在四个不同子系统里的工具,收拢成一份 LLM 看得懂的统一清单,并在调用发生时把它送回该去的地方。
它解决什么问题。 一个 Agent 能用的"工具"其实来路很杂:
- 有的是 LangBot 内建、跑在沙箱里的
exec/read/write(自带的手脚); - 有的来自用户装的插件;
- 有的来自 LangBot 作为客户端连出去的外部 MCP 服务器;
- 还有一类是"制作技能"用的
activate/register_skill。
模型不关心这些区别——它只想要一份"函数列表",然后说"我要调这个函数、参数是这些"。ToolManager 就站在中间抹平来源差异:对上游(模型)给一份统一清单,对下游(各子系统)按来源分发。
一句话直觉: 把它想成公司总机。四个部门(native/plugin/mcp/skill)各有自己的电话,但对外只公布一个总机号码;来电(一次工具调用)报上分机名,总机负责转接到正确的部门。
一个容易混淆点,先说清楚(重要)。 本章的 mcp.py 是 LangBot 作为 MCP 客户端,连接出去用的外部工具服务器("我去调别人的工具")。这和 05 章里 LangBot 自己对外暴露的 /mcp 服务器("别人来调我的能力")方向完全相反。仓库自己的 AGENTS.md 也专门提醒过别把这两者搞混。本章只讲"连出去"的那一侧。
2. 顶层全景(它大概怎么转)
ToolManager(pkg/provider/tools/toolmgr.py