组件开发 · 第 1 篇 / 共 3 篇 —— 机制
组件系统
组件就是一个继承 BaseCell 的 Python 类,丢进 components/ 目录,3 秒内被扫描、加载、包装成工具,LLM 就能直接调用。不注册、不改配置、不重启。
从文件到工具:完整链路
每一层都有独立的职责,任何一步失败都会记录在加载错误里,可用 component.info() 查到。
components/foo.py
│ discover_components() 扫描目录,AST 提取 BaseCell 子类
│ _instantiate_component() 动态 import + 实例化 + on_load()
│ register_cell() 写入内存注册表 _cell_registry
│ register_to_config() 追加到 settings.yaml enabled_components
│ CellToolAdapter 包装成 BaseTool(含 JSON Schema)
│ ComponentToolRegistry 线程安全注册表,version++
↓
AgentLoop 每轮对话 get_all_tools() → LLM 看到 foo
↓
execute_with_context() → _cmd_xxx() → Dict 返回三层注册表
同一个组件在三个地方留痕,用途不同。
| 层 | 位置 | 作用 |
|---|---|---|
| 内存注册表 | _cell_registry | 运行时真实可用的组件实例,热重载直接改这里 |
| 配置清单 | settings.yaml | 持久化启用列表,由系统自动维护,手改会被覆盖 |
| 工具注册表 | ComponentToolRegistry | 线程安全的工具视图,带 version 计数,AgentLoop 每轮对话重新读取 |
核心特性
| 特性 | 说明 |
|---|---|
| 自动发现 | 扫描目录并用 AST 提取 BaseCell 子类,无需装饰器或注册代码 |
| 热插拔 | ComponentWatcher 每 3 秒对比文件 mtime,新增/修改/删除都会触发增量重载 |
| 工具包装 | CellToolAdapter 把组件包装成 BaseTool,自动生成 function calling 定义 |
| 沙箱隔离 | 默认在子进程执行,崩溃或死循环不会拖垮主进程;超时 120 秒 |
| 免沙箱白名单 | 可信组件可加入白名单在主进程直接执行,改完立即热重载 |
| 保留名保护 | shell / memory / file 为系统保留工具名,组件不能覆盖 |
工具定义怎么生成
没有手写 schema,全部从代码推导。这也是写组件时唯一需要讲究的地方。
- 方法签名决定参数名、类型和必填项(无默认值 = 必填)
- docstring 的 Args: 段决定参数描述,解析不到就退化为参数名本身
- 类型注解 int/float/bool/list/dict 分别映射为 integer/number/boolean/array/object
- 类 docstring 超过 400 字符会被截断,并自动补上命令列表和 help 提示
# 单命令:参数平铺,无 command 字段
def _cmd_ping(self) -> Dict: ...
# 多命令:command 变成 enum,其余参数全部合并到同一层
# 所以不同命令不要用同名但不同类型的参数
def _cmd_get(self, key: str) -> Dict: ...
def _cmd_set(self, key: str, value: str) -> Dict: ...命令推断兜底
LLM 偶尔忘记传 command 字段。适配器会按「参数命中覆盖度」给每个子命令打分,必填参数权重更高,选得分最高的那个执行;显式传了 command 就完全按传入值走。
保留工具名
以下三个名字属于内置工具,组件注册同名会被拒绝,cell_name 请避开。
shell— ShellToolmemory— MemoryToolfile— FileTool
沙箱与白名单
非白名单组件一律进子进程。子进程常驻并复用,但空闲会被回收。
| 参数 | 值 |
|---|---|
| 单次命令超时 | 120 s |
| 空闲进程回收 | 300 s |
| 心跳间隔 | 30 s |
| 自定义白名单文件 | config/sandbox.yaml |
内置免沙箱组件(硬编码,不可移除):component、scheduler、skill_manager、skill_installer、sub_agent、web_fetch、web_search、qq_files、telegram_files、feishu_files、weixin_files。
白名单的具体操作(查看、加入、移出)放在第 2 篇,这里只讲模型本身。
内置组件
随发行版自带,源码就在 components/ 下,可以直接读、直接改。
| 组件 | 功能 |
|---|---|
component | 组件生成、列出、重载、沙箱白名单、缓存清理 |
scheduler | 定时任务:间隔 / 每日 / 每周 |
skill_manager / skill_installer | Skill 包的索引查询与安装卸载 |
sub_agent | 并行子 Agent 编排,独立工具与人格 |
web_fetch / web_search | 浏览器抓取与多引擎搜索 |
qq_files / telegram_files / feishu_files / weixin_files | 各 IM 通道的文件收发 |
常见故障
| 现象 | 处理 |
|---|---|
| 组件不出现在工具列表 | component.info(name) 看加载错误;多半是 import 报错或没继承 BaseCell |
| 改了代码没生效 | 顶层 .py 改 mtime 会自动重载;包组件内部改动 watcher 不监控,需 component.reload() |
