# 智能体工作规范

本文记录 VOTX Agent 在本地执行任务时的操作约定，重点覆盖工具选择、文件落点、知识库维护和当前已收口的插件边界。

更新时间：2026-06-12

## 一、工具选择优先级

硬性原则：**能用 Skill 或专用工具完成的，不使用 shell。**

优先级：

```text
专用 Skill/工具 > 文件/知识库/文档类 Skill > 受控基础工具 > shell
```

执行流程：

1. 判断用户请求是否命中某个 Skill。
2. 命中后先读取对应 `SKILL.md`，理解工具、参数、边界和注意事项。
3. 多个 Skill 都可用时，优先使用最专用、语义最明确的工具。
4. 工具失败时先读错误信息和 Skill 文档，再决定是否换工具。
5. shell 只用于没有等价 Skill 的诊断、测试、构建、git 状态查看、进程/环境检查，或专用工具失败后的最小范围排查。

典型选择：

| 任务 | 优先工具/Skill |
|------|----------------|
| 文件读写、目录、搜索、复制、移动 | `file` |
| PDF/Office/HTML 转 Markdown | `markdown_converter` |
| PDF 信息、拆分、合并、旋转、预览、OCR、脱敏 | `pdf_tools` |
| DOCX 创建/读取 | `word_docx` |
| HTTP 请求和网页正文读取 | `network` |
| 本地知识库检索 | `kb_retriever` |
| 普通下载/视频下载 | `download_anything` |
| 时间查询/等待 | `time` |

## 二、默认路径规则

本文面向开源仓库，不写死个人部署路径。真实路径以运行时项目根目录、当前用户和配置文件为准：

```text
项目根目录: <project-root>
临时文件:   <project-root>/tmp
输出文件:   <project-root>/users/<name>/download
上传文件:   <project-root>/users/<name>/history/file
用户知识库: <project-root>/users/<name>/knowledge
全局知识库: <project-root>/knowledge
```

泛化规则：

| 目录 | 用途 |
|------|------|
| `tmp/` | 临时脚本、中间缓存、测试样本，用完清理 |
| `users/<name>/download/` | 智能体生成、导出、下载的默认产物 |
| `users/<name>/history/file/` | 用户上传文件、外部消息附件、用户原始材料 |
| `users/<name>/knowledge/` | 用户私有知识库 |
| `knowledge/` | 全局共享知识库 |

输出规则：

- 用户上传或外部消息附件只进入 `history/file/`。
- 智能体主动生成、导出、下载的可交付文件默认进入 `download/`。
- 临时中间产物只放 `tmp/`，不要污染 `download/` 或 `history/file/`。
- 用户要求加工上传原件时，可以在 `history/file/` 内生成副本；没有明确要求时，新结果仍输出到 `download/`。

## 三、知识库写入和索引维护

知识库双层结构：

```text
users/<name>/knowledge/   # 用户私有，优先
knowledge/                # 全局共享
```

默认规则：

- 查询时用户知识优先，全局知识兜底。
- 写入时默认写用户知识库。
- 只有用户明确说“全局知识库”或给出 `knowledge/` 路径，才写全局。

索引维护是完成条件：

- 用户知识库发生新增、修改、删除、重命名、移动后，必须更新 `users/<name>/knowledge/data_structure.md`。
- 全局知识库发生新增、修改、删除、重命名、移动后，必须更新 `knowledge/data_structure.md`。
- 如果变动发生在有子索引的子目录，也要更新该目录最近的 `data_structure.md`，再更新根索引。
- 索引只记录目录结构、文件用途、格式、来源、更新时间和检索关键词，不复制大段正文。
- 删除或移动知识文件时，索引中旧路径必须同步移除或改名，不能留下失效入口。

二进制知识文件加入知识库时，索引至少写明：

```text
文件类型、主题、来源、建议读取工具、是否已有 Markdown 转换稿
```

## 四、当前插件收口状态

近期插件边界已经调整：

| 旧能力/插件 | 当前归属 |
|-------------|----------|
| `file_search` | 已并入 `file.search_files` |
| `video_download` | 已并入 `download_anything.download_video` |
| `web_content_fetcher` | 已并入 `network.web_read` |

当前重点工具：

| Skill | 主要工具 |
|-------|----------|
| `file` | `read_file`, `read_file_range`, `write_file`, `append_file`, `edit_file`, `list_dir`, `tree_dir`, `stat_file`, `search_files`, `copy_file`, `move_file`, `make_dir`, `delete_file` |
| `download_anything` | `inspect_download_url`, `download_direct_file`, `download_video`, `list_downloads` |
| `network` | `http_get`, `http_post`, `web_read` |
| `tavily_search` | `tavily_search`, `tavily_extract`, `tavily_crawl`, `tavily_map`, `tavily_research` |
| `pdf_tools` | PDF 信息、提取、拆分、合并、旋转、盖字、水印、预览、OCR、脱敏、视觉对比、依赖检查 |

`time.sleep` 的单次上限是 30 分钟，并通过工具 meta 跳过全局 `tool_timeout` 截断。

## 五、沙箱和网络范围

文件操作默认受项目目录和用户目录限制。可通过环境变量按需放开：

```text
VOTX_FILE_OUTSIDE_SANDBOX=1
VOTX_FILE_READ_OUTSIDE_SANDBOX=1
VOTX_FILE_EDIT_OUTSIDE_SANDBOX=1
VOTX_FILE_DELETE_OUTSIDE_SANDBOX=1
VOTX_DOWNLOAD_ANYTHING_OUTSIDE_SANDBOX=1
```

网络请求默认只允许公网地址。需要访问本机或内网时使用工具参数或环境变量明确指定：

```text
network_scope: public / local / private / all
VOTX_NETWORK_SCOPE=public|local|private|all
HTTP_NETWORK_SCOPE=public|local|private|all
NETWORK_SCOPE=public|local|private|all
```

云元数据地址始终应硬拦截，不因 `all` 放开。

## 六、交付前自检

文档或知识库更新后至少检查：

1. 新增/删除/移动的知识文件是否同步更新 `data_structure.md`。
2. 目录路径是否符合 `tmp` / `download` / `history/file` 的用途边界。
3. 文档里的插件名是否仍然存在，避免保留已合并或删除的旧工具名。
4. 涉及代码改动时运行受影响文件的 `py_compile` 或现有测试。
