# Tool 管理 + Agent 工具授权 + 多模态 OCR 前置治理 设计文档

> 日期: 2026-04-18
> 范围: Neta-monorepo 后端 + 前端 + 数据模型
> 参考: Hermes Agent 工具注册 / toolset / tools config 体系
> 目标: 基于 Hermes 的成熟做法，结合 Neta 当前架构，设计一套真正可落地的 Tool 管理方案

---

## 1. 背景与问题

你当前的真实诉求并不只是“加一个 OCR 功能”，而是:

1. 给 Neta 增加可治理的 Tool 管理能力
2. 让 Agent 可以显式选择允许使用哪些工具
3. 让工具的提示词注入、能力要求、启停状态进入后台管理
4. 为多模态 OCR 这类能力提供稳定落点

这件事之所以必须先做设计，而不是直接上 OCR，是因为 OCR 一旦落地，会立刻依赖以下治理能力:

- 它属于哪个 toolset
- 是否全局可用
- 哪些 Agent 可以使用
- 当前模型是否支持视觉/多模态
- 提示词里怎么引导模型使用它

如果这些不先补齐，OCR 只会成为一个继续硬编码在运行时里的“特殊工具”，后续浏览器、网页抽取、图像理解、文档解析都会重复同样的问题。

---

## 2. 先看 Hermes 是怎么做的

Hermes 的工具管理不是一个单页面，而是一套三层结构。

## 2.1 Hermes 的三层结构

### 第一层: 单工具注册中心

文件:

- `hermes-agent-main/tools/registry.py`

职责:

1. 每个工具文件在模块加载时调用 `registry.register(...)`
2. 注册内容包括:
   - `name`
   - `toolset`
   - `schema`
   - `handler`
   - `check_fn`
   - `requires_env`
   - `is_async`
   - `description`
   - `emoji`
3. 运行时由 `registry.get_definitions()` 和 `registry.dispatch()` 统一取 schema 和执行

关键特点:

- 工具注册中心同时保存“元数据 + 执行 handler”
- `check_fn` 用来判断工具是否真的可用
- 工具并不直接在 UI 层管理，而是在运行时层先统一注册

### 第二层: Toolset 组合层

文件:

- `hermes-agent-main/toolsets.py`

职责:

1. 定义工具分组，如 `web`、`vision`、`browser`、`file`
2. 支持 toolset 组合和递归解析
3. 平台不是勾单个工具，而是勾 toolset

关键特点:

- toolset 是产品管理的最小单位
- toolset 可组合
- 平台默认不是直接选单工具，而是按能力集启用

### 第三层: 配置与 Provider-aware Setup 层

文件:

- `hermes-agent-main/hermes_cli/tools_config.py`

职责:

1. 提供工具配置 UI
2. 不同平台配置不同 toolset
3. 工具启用后，如果需要 API Key，会立即进入 provider 配置流程
4. 配置最终落到 `~/.hermes/config.yaml`

关键特点:

- Hermes 管的重点其实是 `toolset`，不是单个 tool
- 对需要外部依赖的工具，配置 UI 会联动 provider 配置
- 平台维度强于 Agent 维度

---

## 3. Neta 当前现状分析

Hermes 的思路成熟，但 Neta 不能直接照搬。原因是两边的产品中心不同。

## 3.1 Neta 已经有的能力

### 1. 已有轻量工具目录

文件:

- `packages/backend/src/modules/netaclaw/tools/catalog.ts`

当前能力:

- 已能注册 `name + toolset + description`
- 已有 `TOOLSET_DEFAULTS = ['base', 'planning', 'interaction']`
- 已按 `import` 触发注册

这意味着:

- Neta 不是“没有工具系统”
- Neta 缺的是“运行时工具治理 + 后台配置”

### 2. 已有 Tool 可见性体系

文件:

- `packages/backend/src/modules/netaclaw/tools/common.ts`

当前能力:

- 已有 `ToolVisibility = 'internal' | 'tool' | 'skill'`

这说明 Neta 已经考虑了:

- 哪些工具对用户可见
- 哪些工具是运行时内部工具

这是比 Hermes 更贴近前端对话 UI 的一层。

### 3. 已有 Skill 系统

当前 Skill 本质是:

- 提示词能力包
- 通过 `read_skill/read_skill_file/skill_manage` 辅助使用

不是工具执行引擎。

所以 OCR 不适合先做成 Skill 本体，这个判断仍然成立。

### 4. 已有模型通道系统

文件:

- `packages/backend/src/modules/netaclaw/service/model_channel.ts`
- `packages/backend/src/modules/netaclaw/entity/model_channel.ts`

当前能力:

- 已有 channel
- 已有 model 列表
- 已有 `capability` 字段

这比 Hermes 的 env/config 模式更强，因为 Neta 已经把模型配置结构化进数据库了。

## 3.2 Neta 当前真正缺的能力

### 1. 运行时工具实例还是硬编码的

文件:

- `packages/backend/src/modules/netaclaw/service/agent_executor.ts`

当前:

```typescript
private readonly defaultTools: AnyAgentTool[] = [
  bashTool, readFileTool, writeFileTool, listDirTool, patchTool, clarifyTool
];
```

问题:

- 后台配置无法控制这里
- 新工具只能继续改代码
- Tool catalog 和实际执行源没有完全打通

### 2. Agent 没有工具授权字段

文件:

- `packages/backend/src/modules/netaclaw/entity/agent.ts`

当前 Agent 只有:

- `skills`
- `modelConfig`
- `config`

没有:

- `tools`
- `toolsets`
- `tool policy`

### 3. Prompt Builder 只知道 toolset，不知道 Tool 配置

文件:

- `packages/backend/src/modules/netaclaw/runtime/prompt_builder.ts`

当前 `collectAvailableToolNames()` 是按默认 toolset 和条件拼工具名，不知道:

- 工具是否被后台禁用
- Agent 是否勾选
- 当前模型是否支持
- 某个工具是否有专属 Prompt Hint 覆写

### 4. 前端没有 Tool 管理页，也没有 Agent 工具选择

当前前端只有:

- Agent 管理
- Skill 管理
- 模型管理

没有:

- Tool 管理
- Agent 工具配置

---

## 4. 设计结论: Hermes 哪些要学，哪些不能照搬

## 4.1 要学习的部分

### 1. 学 Hermes 的“三层拆分”

要拆成:

1. 代码注册层
2. Toolset 组织层
3. 配置治理层

Neta 现在已经有前两层雏形，重点要补第三层，并把三层串起来。

### 2. 学 Hermes 的“toolset 先行”

不要一上来只做“Agent 勾选单工具”。

真正可扩展的模型是:

- 先管理 toolset
- 再允许细粒度控制单工具

因为未来 OCR 不会是唯一工具，后面还会有:

- vision
- browser
- web
- document
- data extraction

### 3. 学 Hermes 的“可用性检查”

Hermes 每个工具可绑定 `check_fn`。

Neta 也应该引入类似概念，但不必完全复刻函数式注册。Neta 更适合做成:

- `requiredCapability`
- `requiredConfig`
- `sceneConstraint`

由运行时统一判断。

### 4. 学 Hermes 的“启用工具时同步配置依赖”

Hermes 开某些 toolset 时会进入 provider 配置流程。

Neta 不需要 CLI 式交互，但要在后台 UI 上体现:

- 这个工具依赖什么
- 模型是否满足
- 是否需要辅助模型

## 4.2 不能直接照搬的部分

### 1. 不能照搬“平台级配置优先”

Hermes 的核心入口是 CLI / Telegram / Discord 等平台，所以它以“平台启用哪些 toolset”为中心。

Neta 的核心入口是“数据库中配置的 Agent”。

所以 Neta 应以:

- 系统全局 Tool 配置
- Agent 级 Tool 授权

为中心，而不是平台级。

### 2. 不能照搬“注册中心同时持有 handler”

Hermes 的 registry 直接持有 handler。

Neta 当前内置工具有静态工具，也有工厂工具:

- memory 工具需要 provider
- skill 工具需要 skillLoader
- crew 工具需要运行时上下文

所以 Neta 不适合把所有 handler 都塞进统一 registry。

Neta 更适合:

- `catalog.ts` 管 schema 元数据
- `tool_resolver.ts` 管运行时实例组装

### 3. 不能照搬 config.yaml 模式

Hermes 的配置落在文件。

Neta 已经有:

- DB Agent
- DB Model Channel
- Admin 前端

因此 Tool 配置必须进入数据库和后台页面，而不是文件。

---

## 5. 面向 Neta 的最优方案

综合 Hermes 的成熟做法和 Neta 当前项目结构，Neta 的最优方案应是:

### 方案核心

1. 保留现有 `catalog.ts` 作为代码注册层
2. 扩展 `catalog.ts` 元数据，补齐 toolset / capability / core 属性
3. 新增 DB Tool 配置表，承接全局治理
4. Agent 新增 `toolsets + tools` 配置
5. 新增运行时 Tool Resolver，统一生成最终工具实例
6. Prompt Builder 从静态 toolset 推断，升级为“读取 Tool Resolver 结果”

这才是适合 Neta 的版本，而不是直接复刻 Hermes。

---

## 6. 总体架构设计

分成 5 层。

### 第 1 层: 代码注册层

现有文件:

- `packages/backend/src/modules/netaclaw/tools/catalog.ts`

职责:

- 注册 Tool 元数据
- 不负责运行时 handler

建议扩展:

```typescript
export interface ToolSchema {
  name: string;
  toolset: string;
  description: string;
  visibility?: 'internal' | 'tool' | 'skill';
  capability?: 'text' | 'vision' | 'multimodal';
  isCore?: boolean;
  canDisable?: boolean;
  supportsPromptHint?: boolean;
}
```

说明:

- `visibility` 与当前 `common.ts` 对齐
- `capability` 为多模态 OCR 预留
- `isCore/canDisable` 用于后台保护
- `supportsPromptHint` 用于限定哪些工具能做专属提示词覆写
- 上述字段中，`visibility/capability/isCore/canDisable/supportsPromptHint` 的真相源应为代码注册层
- DB 仅同步镜像用于展示、筛选和治理判断，不应允许后台直接改写这些运行时语义字段

### 第 2 层: Toolset 管理层

继续保留当前 toolset 体系，但要正式化。

当前已有:

- `base`
- `planning`
- `interaction`
- `memory`
- `skill`
- `crew`

建议新增:

- `vision`
- `document`

不要一开始就分太细，但要给 OCR 留出明确归属。

### 第 3 层: 全局 Tool 治理层

新增数据库表 `netaclaw_tool`。

这个表承接:

- 全局启用/禁用
- 展示名称
- 排序
- Prompt Hint 覆写

不承接:

- `capability` 覆写
- `visibility` 覆写
- `toolset` 覆写

原因:

- 这些字段属于代码注册层的运行时真相
- 若允许后台改写，会导致 resolver、prompt、实际 handler 能力产生漂移

### 第 4 层: Agent 工具授权层

Agent 上新增两个维度:

- `toolsets`
- `tools`

原因:

- 只做 `tools` 太细，配置成本高
- 只做 `toolsets` 又不够灵活

所以需要“toolset 粗授权 + tool 细覆盖”的混合方案。

### 第 5 层: 运行时解析层

新增 `tool_resolver.ts`，统一计算:

- 当前 Agent 最终可用工具实例
- 当前 Prompt 最终可见工具名
- 被过滤工具和原因

---

## 7. 数据模型设计

## 7.1 新增表 `netaclaw_tool`

| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | int | PK, auto | 主键 |
| name | varchar(100) | unique | Tool 名称，对应代码注册名 |
| label | varchar(200) | nullable | 展示名 |
| toolset | varchar(50) | indexed | 所属 toolset |
| description | text | nullable | 展示描述 |
| visibility | varchar(20) | nullable | internal/tool/skill |
| capability | varchar(20) | nullable | text/vision/multimodal |
| status | int | indexed, default 1 | 0=禁用 1=启用 |
| isCore | int | default 0 | 是否核心工具 |
| canDisable | int | default 1 | 是否允许后台关闭 |
| promptHint | text | nullable | Tool 专属提示词覆写 |
| sort | int | default 0 | 排序 |
| extra | json | nullable | 预留字段 |
| createTime | datetime | auto | 创建时间 |
| updateTime | datetime | auto | 更新时间 |
| deleteTime | datetime | nullable | 软删除 |

补充约束:

- `toolset/visibility/capability/isCore/canDisable` 为代码镜像字段，只读
- 后台仅允许修改 `label/description/status/promptHint/sort/extra`

## 7.2 扩展 `netaclaw_agent`

V1 在 Agent 表新增 2 个字段:

| 字段 | 类型 | 说明 |
|------|------|------|
| toolsets | json | Agent 启用的 toolset 列表 |
| tools | json | Agent 额外精细化工具配置 |

建议结构:

```json
{
  "disabled": ["clarify"]
}
```

说明:

- `toolsets` 用于粗粒度启用能力集
- V1 的 `tools` 仅保留 `disabled`
- `tools.enabled` 暂不进入首版，避免 UI、运行时和数据模型过早复杂化
- 若后续确有“跨 toolset 单工具白名单”诉求，再增补 `tools.enabled`

最终解析优先级:

1. 从 `toolsets` 展开默认工具
2. 应用 `tools.disabled`

为什么这样设计:

- 更接近 Hermes 的 toolset 思路
- 又能满足 Neta 首版足够实用的精细控制

## 7.3 模型能力约束

当前 `model_channel.models` 已有 `capability` 字段，但需统一语义。

标准值:

- `text`
- `vision`
- `multimodal`

统一规则:

| Tool capability | 模型 capability | 满足 |
|------|------|------|
| text | text/vision/multimodal | 是 |
| vision | vision/multimodal | 是 |
| multimodal | multimodal | 是 |
| vision | text | 否 |
| multimodal | text/vision | 否 |

补充要求:

- `model_channel.ts` 必须提供统一的模型能力解析接口
- `resolveForAgent()` 或等价运行时接口必须显式返回 `capability`
- REST / WS / Crew 不允许各自重复推导能力，必须复用同一链路

---

## 8. 后端设计

## 8.1 新增文件

| 文件 | 路径 | 说明 |
|------|------|------|
| Entity | `packages/backend/src/modules/netaclaw/entity/tool.ts` | Tool 配置实体 |
| Service | `packages/backend/src/modules/netaclaw/service/tool_registry.ts` | Tool 元数据同步服务 |
| Service | `packages/backend/src/modules/netaclaw/service/tool_resolver.ts` | Tool 运行时解析服务 |
| Controller | `packages/backend/src/modules/netaclaw/controller/admin/tool.ts` | Tool 管理接口 |

## 8.2 Tool Registry Service

职责:

1. 从 `catalog.ts` 读取所有注册工具
2. 将元数据同步到 `netaclaw_tool`
3. 返回后台使用的 Tool 列表

与 Hermes 的区别:

- Hermes registry 直接管 handler
- Neta 的 `tool_registry.ts` 只管治理元数据

这是因为 Neta 有大量运行时工厂工具，不能直接复刻 Hermes 的 handler 注册模型。

同步策略:

- 服务启动时执行一次幂等自动同步，保证首屏与运行时不会因空库失真
- `/admin/netaclaw/tool/sync` 仅作为人工刷新与补录入口
- catalog 中已删除的工具默认不物理删除 DB 记录，而是标记为“已脱离代码注册”

## 8.3 Tool Resolver Service

这是本方案最关键的新增层。

职责:

1. 根据 Agent 配置展开 toolset
2. 合并全局 Tool 配置
3. 过滤不可用工具
4. 组装最终 Tool 实例
5. 生成 Prompt Builder 使用的工具名列表
6. 向 skill context 构建过程暴露最终可用工具名，避免 skill 指导信息与运行时注入脱节

接口建议:

```typescript
interface ResolveToolParams {
  agent: NetaClawAgentEntity | null;
  modelCapability?: 'text' | 'vision' | 'multimodal';
  memoryEnabled?: boolean;
  hasSkills?: boolean;
  crewRole?: 'master' | 'sub';
}

interface ResolveToolResult {
  tools: AnyAgentTool[];
  toolNames: string[];
  builtinToolNames: string[];
  toolPromptHints: Record<string, string>;
  disabledReasons: Array<{
    name: string;
    reason:
      | 'globally_disabled'
      | 'agent_toolset_not_enabled'
      | 'agent_tool_disabled'
      | 'capability_mismatch'
      | 'scene_filtered';
  }>;
}
```

### 8.3.1 解析流程

```text
catalog 全量工具
  -> 根据 agent.toolsets 展开
  -> 去掉 agent.tools.disabled
  -> 过滤全局 status=0
  -> 过滤 capability 不满足
  -> 过滤 scene 不满足
  -> 输出 tools + toolNames + builtinToolNames + toolPromptHints
```

### 8.3.2 为什么必须有这一层

没有 `tool_resolver.ts`，Neta 会继续出现:

1. catalog 是一套
2. prompt 是一套
3. executor 是一套
4. 后台页面又是一套

这四套来源会很快失真。

`tool_resolver.ts` 的价值，就是把它们收敛成单一事实来源。

## 8.4 Tool 管理接口

| 端点 | 方法 | 功能 |
|------|------|------|
| `/admin/netaclaw/tool/page` | POST | Tool 分页查询 |
| `/admin/netaclaw/tool/info` | GET | Tool 详情 |
| `/admin/netaclaw/tool/update` | POST | 更新 Tool 配置 |
| `/admin/netaclaw/tool/all` | GET | 获取全部 Tool 列表 |
| `/admin/netaclaw/tool/sync` | POST | 同步 catalog 到 DB |
| `/admin/netaclaw/tool/forAgent` | GET | 获取 Agent 配置可选工具 |

限制:

- 不开放 handler 编辑
- 不开放 schema 编辑
- 核心不可禁用工具由后端兜底校验

## 8.5 Prompt Builder 改造

当前 `prompt_builder.ts` 的问题是静态。

改造方向:

### 从:

```typescript
collectAvailableToolNames({
  memoryEnabled,
  hasSkills,
  crewRole,
})
```

### 改为:

```typescript
const resolved = await toolResolver.resolve(...);
const toolNames = resolved.toolNames;
```

并支持 Tool Prompt Hint 注入:

```typescript
getToolBehaviorGuidance(toolNames, promptHints)
```

其中 `promptHints` 来自 `netaclaw_tool.promptHint`。

同时需要补一处现有耦合:

- `buildSkillContext()` 当前仍依赖硬编码 builtin tool names
- 改造后必须消费 resolver 产出的 `builtinToolNames`
- 否则工具治理生效后，skill prompt 仍会引用已被禁用的工具

---

## 9. 前端设计

## 9.1 菜单结构

在 `Skill 管理` 上方新增:

- `Tool 管理`

路由:

```typescript
{ path: '/agent/tools', meta: { label: 'Tool 管理' } }
```

## 9.2 Tool 管理页设计

文件建议:

- `packages/frontend/src/modules/agent/views/tools.vue`

页面结构:

### 顶部筛选栏

- 搜索
- toolset 筛选
- capability 筛选
- status 筛选
- 同步工具按钮

### 列表区

字段:

- Tool 名称
- 展示名
- toolset
- capability
- visibility
- 核心标签
- 启用状态
- Prompt Hint 状态
- 操作

### 编辑抽屉

可编辑:

- label
- description
- status
- promptHint
- sort

只读:

- name
- toolset
- capability
- visibility
- isCore
- canDisable

## 9.3 Agent 编辑页改造

当前 `agent-edit.vue` 只有 Skill 配置，没有 Tool 配置。

新增一个平级 Tab:

- `工具配置`

不要放到高级设置，理由:

1. Tool 是一等能力
2. 后续 OCR 就在这里开关
3. 这是 Agent 可用能力的核心组成部分

### 9.3.1 UI 结构

建议分成两部分:

#### 第一部分: Toolset 配置

- 多选 `base/planning/interaction/memory/skill/crew/vision/document`

#### 第二部分: Tool 精细控制

- 左侧当前 toolset 展开的工具
- 右侧已禁用覆盖

每个 Tool 展示:

- label
- toolset tag
- capability tag
- core tag
- 简介

### 9.3.2 交互规则

- toolset 勾选后，默认带出该组工具
- 可对单个工具做禁用覆盖
- V1 不支持“额外加开不在当前 toolset 内的工具”
- 这样可以确保授权心智、UI 和 resolver 优先级保持简单一致

这是对 Hermes“toolset 优先”的本地化改造。

原因:

- 完全照 Hermes 只配 toolset，不够细
- 完全只配 tool，不利于规模扩展

混合模式是最适合 Neta 的。

## 9.4 Prompt 预览增强

Agent 编辑页已有 prompt 预览，应扩展返回:

- 最终生效 toolNames
- 被过滤 tools 和原因
- tool prompt hint 来源

这对 OCR 非常重要，因为视觉工具最容易因 capability 不满足而消失。

---

## 10. 对 OCR / 多模态能力的直接影响

本设计不是直接实现 OCR，但要明确它如何承接 OCR。

后续 OCR 方案建议:

### Tool 归属

- `vision_ocr` 属于 `vision` 或 `document` toolset

### capability

- `vision_ocr.capability = 'vision'`

### Agent 体验

- Tool 管理页中可全局启用/禁用
- Agent 编辑页中可勾选
- 若当前模型不支持视觉，则显示不可用原因

### Prompt 注入

可通过 `promptHint` 告诉模型:

- 什么时候优先用 OCR
- OCR 适合抽文字，不适合复杂推理
- 识别后需要继续结构化处理时如何组合其他工具

这就是为什么必须先做 Tool 治理，再做 OCR。

---

## 11. 与现有 Neta 代码的具体衔接点

## 11.1 `tools/catalog.ts`

从当前的轻量结构:

```typescript
interface ToolSchema {
  name: string;
  toolset: string;
  description: string;
}
```

扩展成带治理元数据的结构。

## 11.2 `tools/common.ts`

当前已有 `visibility`，这是很好的基础。

建议:

- catalog 的 `visibility` 与 common.ts 保持同一枚举
- 运行时由 resolver 统一读取
- DB 中的 `visibility` 仅作为镜像字段供后台查询，不作为独立真相源

## 11.3 `service/agent_executor.ts`

这里是必须动的关键文件。

当前 `defaultTools` 硬编码必须下沉到 `tool_resolver.ts`。

否则任何 Tool 管理页面都是伪配置。

同时还要一起改:

- `buildSkillContext()` 的 `builtinToolNames` 输入
- 不能继续保留当前硬编码列表

## 11.4 `entity/agent.ts`

新增:

- `toolsets`
- `tools`

以支持 Hermes 式 toolset 思路和 Neta 式单 Agent 精细控制的结合。

## 11.5 `runtime/prompt_builder.ts`

从“根据几个布尔值猜工具列表”，升级为“读取 resolver 结果”。

---

## 12. 兼容性策略

## 12.1 老 Agent

老 Agent 没有 `toolsets/tools` 时:

- 默认视为启用 `TOOLSET_DEFAULTS`
- 保存后写入明确配置

## 12.2 老 Tool

老 Tool 首次同步到 DB 时:

- label = name
- status = 1
- capability = text
- promptHint = null

其中:

- `capability/visibility/toolset` 来自 catalog 镜像
- 不是后台运营配置

## 12.3 老 Prompt

如果没有 DB 配置的 promptHint，就继续使用代码默认 guidance。

---

## 13. 风险与控制

## 13.1 风险: 设计过重

控制:

- 不做 handler 可视化管理
- 不做 schema 可视化编辑
- 不做 plugin marketplace
- 第一版只做内置工具治理

## 13.2 风险: 页面做完但运行时不生效

控制:

- `tool_resolver.ts` 作为单一事实来源
- `agent_executor.ts` / `gateway/server.ts` 全部接入 resolver

## 13.3 风险: capability 配置不统一

控制:

- capability 枚举统一
- `model_channel.ts` 统一返回模型 capability
- resolver 中集中判断
- 后台不允许编辑 tool capability

## 13.4 风险: toolset 和 tool 配置冲突

控制:

优先级固定为:

1. 全局禁用
2. agent toolsets 展开
3. agent tools.disabled 剔除
4. capability 过滤

V1 收敛策略:

- 首版不引入 `tools.enabled`
- 先用 `toolsets + disabled` 完成 80% 场景
- 降低实现复杂度与解释成本

## 13.5 风险: Tool 管理与 Skill 上下文失真

控制:

- resolver 输出 `builtinToolNames`
- `buildSkillContext()` 改为消费 resolver 输出
- previewPrompt 也返回同一结果，保证前后端解释一致

---

## 14. 文件变更清单

| 操作 | 位置 | 文件 |
|------|------|------|
| 新增 | backend | `src/modules/netaclaw/entity/tool.ts` |
| 新增 | backend | `src/modules/netaclaw/service/tool_registry.ts` |
| 新增 | backend | `src/modules/netaclaw/service/tool_resolver.ts` |
| 新增 | backend | `src/modules/netaclaw/controller/admin/tool.ts` |
| 修改 | backend | `src/modules/netaclaw/tools/catalog.ts` |
| 修改 | backend | `src/modules/netaclaw/tools/common.ts` |
| 修改 | backend | `src/modules/netaclaw/entity/agent.ts` |
| 修改 | backend | `src/modules/netaclaw/service/agent_executor.ts` |
| 修改 | backend | `src/modules/netaclaw/gateway/server.ts` |
| 修改 | backend | `src/modules/netaclaw/runtime/prompt_builder.ts` |
| 修改 | backend | `src/modules/netaclaw/runtime/prompt_guidance.ts` |
| 修改 | backend | `src/modules/netaclaw/service/crew_orchestrator.ts` |
| 修改 | backend | `src/modules/netaclaw/service/crew_delegate.ts` |
| 修改 | backend | `src/entities.ts` |
| 新增 | frontend | `src/modules/agent/views/tools.vue` |
| 修改 | frontend | `src/modules/agent/config.ts` |
| 修改 | frontend | `src/modules/agent/views/agent-edit.vue` |

---

## 15. 分阶段落地建议

### Phase 1: 对齐 Hermes 的核心治理思想

1. 扩展 catalog 元数据
2. 新增 `netaclaw_tool`
3. 做 catalog -> DB 同步
4. 后台 Tool 管理页

### Phase 2: 打通 Neta 运行时

1. Agent 新增 `toolsets/tools`
2. 新增 `tool_resolver.ts`
3. `agent_executor.ts` / `gateway/server.ts` 全部改接 resolver
4. `buildSkillContext()` 改成吃 resolver 结果
5. Prompt Builder 改成吃 resolver 结果

### Phase 3: 为 OCR 接入做准备

1. 新增 `vision/document` toolset
2. 能力约束与 UI 提示
3. Tool Prompt Hint 覆写

### Phase 4: 接入 OCR

1. 新增 `vision_ocr`
2. 绑定 capability=vision
3. Agent 勾选可用
4. 后续再考虑 Skill 工作流封装

---

## 16. 最终结论

参考 Hermes 之后，结论比之前更明确:

1. 你这个需求的第一优先级确实不是先做 OCR，而是先做 Tool 管理
2. 但不能只做“一个页面”，而是要补齐:
   - 代码注册层
   - toolset 组织层
   - 全局治理层
   - Agent 授权层
   - 运行时解析层
3. Hermes 的核心经验要吸收:
   - toolset 优先
   - 统一注册
   - 可用性检查
   - 配置与能力联动
4. 但不能直接照搬 Hermes:
   - Hermes 是平台中心
   - Neta 是 Agent 中心
   - Hermes 是文件配置
   - Neta 应该走数据库 + 后台配置

因此，适合 Neta 的最终设计不是“单纯的工具管理页”，也不是“直接每个 Agent 勾单工具”，而是:

**全局 Tool 治理 + Agent toolset 授权 + 单工具精细覆盖 + 运行时统一解析**

这套设计完成后，多模态 OCR 才有一个真正稳固的落点。
