176 lines
9.0 KiB
Markdown
176 lines
9.0 KiB
Markdown
---
|
||
title: 工具系统
|
||
created: 2026-04-13
|
||
updated: 2026-05-15
|
||
type: entity
|
||
tags: [tool, agent, runtime, backend]
|
||
sources: [packages/backend/src/modules/netaclaw/tools/, packages/backend/src/modules/netaclaw/tools/operations/, packages/backend/src/modules/netaclaw/service/tool_resolver.ts, packages/backend/src/modules/netaclaw/service/tool_registry.ts, packages/backend/src/modules/netaclaw/subagent/worker_tools.ts, packages/backend/src/modules/netaclaw/gateway/tool_risk.ts]
|
||
---
|
||
|
||
# 工具系统
|
||
|
||
工具系统是 Agent 可调用能力的实现层。当前 NetaClaw 工具架构分为五层:
|
||
|
||
```text
|
||
工具实现
|
||
-> Tool Operations
|
||
-> Tool Catalog
|
||
-> Tool Governance / Resolver
|
||
-> Tool Manifest / Runtime Policy
|
||
```
|
||
|
||
其中工具实现层关注参数语义和结果格式,[[tool-operations]] 关注底层文件/进程/搜索后端,[[tool-governance]] 关注“是否允许、如何投影、如何被前端理解”,[[tool-runtime-policy]] 关注“在主进程或子进程里怎么安全执行”。
|
||
|
||
## 工具接口
|
||
|
||
运行时工具一般具备:
|
||
|
||
```typescript
|
||
interface AnyAgentTool {
|
||
name: string;
|
||
description: string;
|
||
inputSchema: object;
|
||
execute: (args: unknown) => Promise<string | Record<string, unknown>>;
|
||
}
|
||
```
|
||
|
||
模型输出 `tool_use` 后,`runAgent` 会从 resolver 提供的工具集合中查找并执行对应工具。当前工具执行结果除了传统字符串结果,还可能携带结构化 `rawResult`,供 WebSocket 和前端渲染层展示文本、JSON、图片等不同结果形态。
|
||
|
||
## 内置工具分组
|
||
|
||
| 分组 | 工具 | 说明 |
|
||
| --- | --- | --- |
|
||
| 文件/搜索 | `read_file`、`write_file`、`list_dir`、`find_files`、`grep` | workspace 文件读写与检索 |
|
||
| Shell | `bash` | 命令执行,受 policy 控制 |
|
||
| 编辑 | `edit`、`patch` | 精确编辑与补丁应用 |
|
||
| Skill | `read_skill`、`read_skill_file`、`skill_manage`、`execute_skill` | 技能读取、管理和 compute-entry 执行 |
|
||
| Memory | `memory_save`、`memory_recall` | 长期记忆写入与检索 |
|
||
| AIGC | `text_to_image`、`image_to_image` | 文生图、图生图和图片结果持久化,详见 [[image-generation-tools]] |
|
||
| 委派 | `delegate_task`、`delegate_parallel` | 子 Agent 委派,详见 [[subagent-session]] |
|
||
| 微信桌面 | `weixin_send_text` | 通过 [[desktop-op-module]] 在 PC 微信目标群发送文本 |
|
||
| MySQL 问数 | `mysql_list_sources`、`mysql_schema`、`mysql_table_sample`、`mysql_query` | 授权 MySQL 数据源的只读 schema、样例和 SQL 查询 |
|
||
| 交互 | `clarify`、`escalate` | 澄清与升级 |
|
||
| Todo | `todo` | 会话级任务状态 |
|
||
|
||
## 主 Agent 执行
|
||
|
||
主 Agent 的工具调用链路:
|
||
|
||
```text
|
||
LLM 输出 tool_use
|
||
-> runAgent 解析工具名和参数
|
||
-> ToolResolver 提供可执行工具 Map
|
||
-> tool.execute(args)
|
||
-> 产生 tool_result
|
||
-> 写入 session tree message entry
|
||
-> WebSocket 推送 tool_call/tool_result
|
||
```
|
||
|
||
2026-05-02 后,Gateway 会在真正执行 bash 前调用 `gateway/tool_risk.ts` 做风险检测。命中 `rm`、`del`、`rd`、`rmdir`、`drop table`、`git reset --hard`、`git clean -f`、`git push --force` 等模式时,会先推送 `tool_confirmation_request`,等待前端返回 `tool_confirmation_response`;用户拒绝则该工具调用不会执行。
|
||
|
||
## Operations 注入
|
||
|
||
文件、搜索、编辑和 bash 类工具现在通过 [[tool-operations]] 访问底层系统能力:
|
||
|
||
- `read_file`、`write_file`、`list_dir` 使用 `FileOperations`。
|
||
- `edit`、`patch` 使用 `FileOperations` 和写队列。
|
||
- `find_files`、`grep` 使用 `SearchOperations`。
|
||
- `bash` 使用 `ProcessOperations`。
|
||
|
||
`tool_resolver.ts` 在构造工具列表时注入 `operations?: ToolOperations`;未提供时使用 `getDefaultOperations()` 的本地实现。这让测试可以用 mock operations,也为后续远程 workspace / 沙箱后端留出替换点。
|
||
|
||
## 子 Agent 执行
|
||
|
||
子 Agent worker 不会默认拥有所有工具。工具按 manifest 和 runtime policy 分为:
|
||
|
||
- 本地 worker 工具:适合只读、低风险、可在子进程直接执行。
|
||
- 主进程代理工具:需要父进程执行,例如写文件、技能管理、记忆写入。
|
||
- 禁用工具:当前策略下不允许执行。
|
||
|
||
详见 [[tool-runtime-policy]]。
|
||
|
||
主进程与子进程之间的边界已经进一步明确:
|
||
|
||
- 子 Agent 使用的不是“主 Agent 全量工具复制品”,而是 resolver 结合 `allowedToolNames`、workspace roots、shell/readonly 策略、manifest 路由之后裁剪出的工具集。
|
||
- `delegate_task` / `delegate_parallel` 会把 `toolRuntimeRoutes` 一并带入子 Agent 批次与回放数据,前端据此显示当前任务到底是 `worker-local`、`main-process-proxy` 还是 `disabled`。
|
||
- 某个工具能否进入子 Agent,不只看它是否启用,还要看它的 `effectiveSubagentAllowed`、`workerRoutingHint` 和运行时 blocked reason。
|
||
|
||
## Catalog 与治理
|
||
|
||
`Tool Catalog` 提供工具静态 schema 和基础元数据。`Tool Governance` 把 catalog 同步到 DB,支持全局启停、核心工具、Agent 局部覆盖和 Prompt Hint。
|
||
|
||
这意味着工具实现文件不应直接决定最终可见性;最终口径以 resolver 输出为准。
|
||
|
||
当前 resolver 的核心输出已经不只是工具名:
|
||
|
||
- `toolNames`: 最终允许进入 prompt / runtime 的工具集合。
|
||
- `toolPromptHints`: Prompt Builder 消费的行为提示。
|
||
- `toolManifest`: 子进程安全执行需要的 manifest。
|
||
- `toolRuntimeRoutes`: 每个工具在当前会话/Agent 下的实际运行路由。
|
||
- `disabledReasons`: 被过滤工具的解释。
|
||
|
||
因此“工具有没有生效”不能只查内置文件是否存在,必须看 resolver 的最终投影。
|
||
|
||
## 过程事件
|
||
|
||
2026-05-07 后,长耗时工具和 compute-entry Skill 可以通过 [[runtime-process-events]] 输出阶段进度。工具执行链路会为一次调用分配 `operationId`,过程事件可以被 WebSocket 流式推送,也可以采样写入 session metadata,并把完整 JSONL 日志落到 dataDir。
|
||
|
||
这条链路主要服务:
|
||
|
||
- [[vehicle-damage-skill]] 的抽帧、检测、定位和复核过程。
|
||
- `execute_skill` 对 compute-entry 子进程过程事件的桥接。
|
||
- 前端对话页的 `tool-process-timeline.vue` 历史回放。
|
||
|
||
## weixin_send_text
|
||
|
||
2026-05-14 新增的 `weixin_send_text` 属于 `weixin_desktop` toolset,是 weixin-db 群聊自动回复的发送工具。
|
||
|
||
执行要点:
|
||
|
||
- `channelId` 优先从 `_netaRuntime.bizContext.channelId` 读取,其次才接受显式参数。
|
||
- `modelChannelId` 来自 `_netaRuntime.currentAgent.modelChannelId`,即桌面操作 Agent 自己的模型渠道。
|
||
- 只允许在 channel 的 `config.weixinReply.enabled=true` 时执行。
|
||
- 支持 `suffix`、`zero-width`、`none` 三种水印策略。
|
||
- 创建 `DesktopTask(appId="weixin", actionType="send-text")` 后调用 `DesktopOpService.runAndWait()`,默认最多等待 60 秒。
|
||
|
||
这类工具应配置为子 Agent 可用且强制走主进程代理,因为真正的键鼠和窗口操作必须留在主进程控制边界内。
|
||
|
||
## MySQL 问数工具
|
||
|
||
2026-05-15 新增的 `mysql` toolset 提供只读智能问数后端能力:
|
||
|
||
- `mysql_list_sources`:列出当前 Agent 授权的数据源摘要,不返回 host、用户名、密码或连接串。
|
||
- `mysql_schema`:读取授权表的字段、索引、主键、外键和脱敏标记。
|
||
- `mysql_table_sample`:读取授权表的少量未脱敏字段样例,用于判断字段含义和 JOIN key。
|
||
- `mysql_query`:执行经过 guard 校验的只读 `SELECT`,支持授权表范围内的显式 JOIN,并写入查询审计。
|
||
|
||
MySQL 工具在子 Agent manifest 中统一走 `main-process-proxy`。数据库连接、密钥解密、SQL guard、脱敏列拒绝、行数限制和审计都留在主进程服务侧,worker 只看到工具 manifest 与代理路由。
|
||
|
||
这组工具的完整配置面和服务端安全边界见 [[mysql-data-source]]。其中几个容易误判的实现细节是:`mysql_schema` 会拆开读取 `information_schema.TABLES` 与 `information_schema.COLUMNS`,避免把 `TABLE_COMMENT` 当作字段元数据;`mysql_table_sample` 用小写映射做权限校验但保留原始列名执行,兼容 `tenantId` 这类驼峰列;`mysql_query` 允许单个末尾分号并在执行前规范化,但真实多语句仍会被 guard 拒绝。
|
||
|
||
## 前端渲染
|
||
|
||
前端工具展示不直接硬编码每个工具的 UI。当前实现是:
|
||
|
||
- 工具调用渲染通过 `renderer-registry.ts` 注册。
|
||
- `runtime-policy.ts` 负责把后端路由状态投影成页面展示。
|
||
- 工具管理页和 Agent 编辑页都消费后端 `runtimeDiagnostic` projection。
|
||
- 对话页除了一般工具调用卡片,还会结合 `tool_call_started` / `tool_result_streamed` / `tool_call_completed` 事件展示运行中状态。
|
||
|
||
这可避免工具新增后只写后端、前端看不到或文案不一致。
|
||
|
||
## 相关页面
|
||
|
||
- [[tool-governance]]
|
||
- [[tool-runtime-policy]]
|
||
- [[tool-operations]]
|
||
- [[tool-catalog]]
|
||
- [[mysql-data-source]]
|
||
- [[image-generation-tools]]
|
||
- [[runtime-process-events]]
|
||
- [[desktop-op-module]]
|
||
- [[agent-runtime]]
|
||
- [[subagent-session]]
|
||
- [[frontend-architecture]]
|
||
- [[prompt-builder]]
|