# 工具参考

zhi 提供 **7 个内置工具**，供代理在对话和技能执行过程中调用。每个工具有风险等级，决定是否需要用户确认。

## 风险等级

| 等级 | `approve` 模式下的行为 | `auto` 模式下的行为 |
|------|----------------------|-------------------|
| **低** | 无需确认 | 无需确认 |
| **高** | 需要确认 | 无需确认 |
| **始终** | 始终需要确认 | 始终需要确认 |

---

## file_read

读取文本文件的内容。

| 属性 | 值 |
|------|-----|
| 风险等级 | 低 |
| 确认 | 从不 |

### 参数

| 名称 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `path` | string | 是 | 文件的相对路径 |

### 约束

- **仅限相对路径** -- 绝对路径会被拒绝
- **最大文件大小**：100KB（超出部分截断并警告）
- **禁止路径遍历** -- `..` 路径段被阻止
- **禁止二进制文件** -- 包含空字节的文件被拒绝
- **编码**：UTF-8，回退 Latin-1

### 示例

```
file_read(path="reports/q4-summary.md")
```

---

## file_write

将新文件写入输出目录（`zhi-output/`）。

| 属性 | 值 |
|------|-----|
| 风险等级 | 高 |
| 确认 | 仅在 `approve` 模式下 |

### 参数

| 名称 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `path` | string | 是 | 输出目录内的相对路径 |
| `content` | string/object | 是 | 文件内容（格式取决于扩展名） |

### 支持的格式

| 扩展名 | 内容类型 | 说明 |
|--------|---------|------|
| `.md`、`.txt` | 纯文本字符串 | 直接写入 |
| `.json` | 任意 JSON 值 | 2 空格缩进美化输出 |
| `.csv` | `{"headers": [...], "rows": [[...]]}` | 标准 CSV，正确转义 |
| `.xlsx` | `{"sheets": [{"name": "...", "headers": [...], "rows": [[...]]}]}` | 多工作表 Excel |
| `.docx` | `{"content": "markdown 字符串"}` | Markdown 转 Word 文档 |

### 约束

- **禁止覆盖** -- 已存在的文件不能被覆盖
- **禁止绝对路径** -- 必须是 `zhi-output/` 内的相对路径
- **禁止路径遍历** -- `..` 路径段被阻止
- **禁止符号链接逃逸** -- 解析后的路径必须在输出目录内
- **输出上限**：50KB（每次工具响应）

!!! tip "完整格式支持"
    `.xlsx` 和 `.docx` 输出已包含在默认安装中，无需额外安装。

### 示例

```
file_write(path="summary.md", content="# 报告摘要\n\n主要发现...")
```

---

## file_list

列出目录内容及元数据。

| 属性 | 值 |
|------|-----|
| 风险等级 | 低 |
| 确认 | 从不 |

### 参数

| 名称 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `path` | string | 否 | `.` | 要列出的相对路径 |
| `max_depth` | integer | 否 | 2 | 递归深度（范围：1-10） |

### 输出格式

每个条目显示：

```
[f] filename.txt                           1.2KB  2026-02-20 14:30
[d] subdirectory/                              -  2026-02-19 09:15
```

- `[f]` = 文件，`[d]` = 目录
- 大小以可读格式显示（B、KB、MB、GB）
- 修改日期为 UTC 时间

### 示例

```
file_list(path="data", max_depth=3)
```

---

## ocr

使用智谱 OCR API 从图片和 PDF 中提取文本。

| 属性 | 值 |
|------|-----|
| 风险等级 | 低 |
| 确认 | 从不 |

### 参数

| 名称 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `path` | string | 是 | 图片或 PDF 文件的路径 |

### 支持的格式

`PDF`、`PNG`、`JPG`、`JPEG`、`GIF`、`WEBP`

### 约束

- **最大文件大小**：20MB
- **输出上限**：50KB（超出部分截断）
- 允许绝对路径（与 `file_read` 不同）

### 示例

```
ocr(path="scanned-invoice.pdf")
```

---

## shell

执行带安全检查的 shell 命令。

| 属性 | 值 |
|------|-----|
| 风险等级 | **始终**（即使在 `auto` 模式下也需要确认） |
| 确认 | 始终 |

### 参数

| 名称 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `command` | string | 是 | - | 要执行的 shell 命令 |
| `timeout` | integer | 否 | 30 | 超时时间（秒，范围：1-300） |

### 安全层级

#### 封锁（灾难性命令）

这些模式始终被拒绝 -- 无法确认执行：

| 模式 | 原因 |
|------|------|
| `rm -rf /` | 销毁根文件系统 |
| `rm -rf ~` | 销毁主目录 |
| `mkfs /dev/` | 格式化磁盘设备 |
| `:(){ :\|:& };:` | Fork 炸弹 |
| `dd if=/dev/zero of=/dev/` | 覆写磁盘设备 |

同时封锁：`eval`、`bash -c`、`sh -c`、`/bin/rm`、`/usr/bin/rm`（防止绕过）。

#### 警告（破坏性命令）

这些命令在确认前会触发额外的破坏性警告：

`rm`、`del`、`rmdir`、`mv`、`chmod`、`chown`、`mkfs`、`dd`、`shred`、`truncate`、`sed -i`、`git reset --hard`、`git clean`

#### 允许

所有其他命令需要标准确认。

### 约束

- **输出上限**：100KB（超出部分截断）
- **进程管理**：超时时终止整个进程组（不仅仅是父进程）
- **平台支持**：Unix 使用 `start_new_session`，Windows 使用 `CREATE_NEW_PROCESS_GROUP`

### 示例

```
shell(command="wc -l *.csv", timeout=10)
```

---

## web_fetch

获取网页的文本内容。

| 属性 | 值 |
|------|-----|
| 风险等级 | 低 |
| 确认 | 从不 |

### 参数

| 名称 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `url` | string | 是 | 要获取的 URL（必须以 `http://` 或 `https://` 开头） |

### SSRF 防护

以下目标被阻止，防止服务器端请求伪造：

| 类别 | 被阻止的目标 |
|------|-------------|
| 主机名 | `localhost`、`metadata.google.internal`、`metadata` |
| IP 范围 | 私有地址：`10.0.0.0/8`、`172.16.0.0/12`、`192.168.0.0/16` |
| 特殊地址 | 回环地址（`127.0.0.1`）、链路本地（`169.254.x.x`）、保留范围 |

### 约束

- **协议**：仅支持 HTTP 和 HTTPS
- **输出上限**：50KB
- **超时**：30 秒
- **重定向**：自动跟随重定向
- **HTML 处理**：HTML 转换为纯文本（脚本和样式被移除）
- **User-Agent**：`zhi-cli/1.0`

### 示例

```
web_fetch(url="https://example.com/api/data")
```

---

## skill_create

通过生成 YAML 配置文件创建新技能。

| 属性 | 值 |
|------|-----|
| 风险等级 | 高 |
| 确认 | 仅在 `approve` 模式下 |

### 参数

| 名称 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `name` | string | 是 | - | 技能名称（字母数字、连字符、下划线） |
| `description` | string | 是 | - | 人类可读的描述 |
| `system_prompt` | string | 是 | - | 技能的系统提示 |
| `tools` | array[string] | 是 | - | 技能可使用的工具名称列表 |
| `model` | string | 否 | `glm-4-flash` | 技能执行的模型 |
| `max_turns` | integer | 否 | 15 | 最大代理循环轮次（限制为 1-50） |

### 验证规则

- **名称模式**：必须匹配 `^[a-zA-Z0-9][a-zA-Z0-9_-]*$`
- **名称长度**：最长 64 个字符
- **禁止路径分隔符**：`/`、`\` 和 `..` 被拒绝
- **禁止重复**：不能创建与已存在技能同名的技能
- **工具验证**：列出的所有工具必须存在于注册表中

### 示例

```
skill_create(
  name="summarize-chinese",
  description="用中文总结文档",
  system_prompt="你是一个中文摘要助手...",
  tools=["file_read", "file_write"]
)
```
