# Claude Code 调用方法总结

## 核心调用方式

Hermes 通过 `terminal` 工具调用 Claude Code，有两种模式：

### 模式一：Print Mode（推荐，适合绝大多数任务）

```bash
cat << 'TASK_END' | claude -p print \
  --dangerously-skip-permissions \
  --add-dir ~/.claude/skills/fireworks-tech-graph \
  --add-dir ~/docker/agent-base/src \
  --max-turns 30 \
  2>&1
[这里写任务描述]
TASK_END
```

### 模式二：TMUX 交互模式（适合超长任务）

```bash
tmux new-session -d -s claude-work -x 140 -y 40
tmux send-keys -t claude-work 'claude --permission-mode bypassPermissions' Enter
sleep 8 && tmux capture-pane -t claude-work -p  # 确认已启动后即可发送任务
```

> 用 `--permission-mode bypassPermissions` 可直接跳过信任目录 + bypass 权限确认两步，不需要额外的 sleep + send-keys 模拟交互。

---

## 关键参数说明

| 参数                                    | 作用                                          |
| ------------------------------------- | ------------------------------------------- |
| `--permission-mode bypassPermissions` | 直接设置 bypass 模式，跳过所有交互确认（包括信任目录、bypass 权限提示） |
| `--dangerously-skip-permissions`      | 同上，但通过 CLI 界面内部触发，可能仍需交互确认                  |
| `--add-dir <路径>`                      | 添加可访问目录，可多次使用                               |
| `--max-turns N`                       | 最大迭代次数，建议 20-30                             |
| `--bare`                              | 跳过插件/MCP/CLAUDE.md 加载，最快启动                  |
| `--model <模型>`                        | 指定模型，如 `sonnet`、`opus`                      |
| `--output-format json`                | 结构化 JSON 输出                                 |
| `-p print`                            | 非交互单次执行模式                                   |

---

## 任务文本（stdin）写法

### 基础结构

```
1. 告诉 Claude Code 要做什么
2. 告诉它用哪个 skill
3. 告诉它目标文件输出到哪里
4. 如果需要格式转换（如 SVG → PNG），明确写出转换命令
5. 最后要求它输出"done: 文件路径"
```

### 示例：完整任务文本

```
使用 fireworks-tech-graph 技能，生成 ~/docker/agent-base 项目的 ER 关系图，展示 Session、Message、ToolCall 三个模型及字段关联，Style 用 dark tech。先生成 SVG 保存到 /tmp/agent-base-er.svg，然后用 cairosvg 转换为 PNG 保存到 /tmp/agent-base-er.png，1920px 宽度。完成后输出 "done: /tmp/agent-base-er.png"
```

---

## Skill 加载方法

Claude Code 自动扫描 `--add-dir` 目录下的 `SKILL.md` 和 `.claude/skills/` 目录。

**加载技能只需要：`--add-dir <技能所在目录>`**

```
--add-dir ~/.claude/skills/fireworks-tech-graph
```

SKILL.md 中定义的触发条件（自然语言模式匹配）会在对话中自动激活。

---

## 项目目录设定

```
--add-dir ~/docker/agent-base/src       # 项目源码
--add-dir ~/.claude/skills/fireworks-tech-graph  # 技能
--add-dir /tmp                           # 临时输出目录（如果需要写入）
```

---

## 常见坑点

1. **不写 bypass 参数** → 文件写入被阻塞，任务卡住（优先用 `--permission-mode bypassPermissions`）
2. **命令行参数直接传任务**（`claude -p "任务"`）→ 特殊字符（括号、引号）引发 shell 转义错误
3. **max-turns 太小** → 任务没跑完就超时，建议复杂任务设 25-30
4. **用管道不用参数** → `echo '任务' | claude -p print` 比 `claude -p "任务"` 更可靠
5. **环境变量 `ANTHROPIC_API_KEY`** → Claude Code 需要在 settings.json 或环境变量中配置认证

---

## 认证状态检查

```bash
claude auth status --text
```

---

## 完整模板

### Print Mode

```bash
cat << 'TASK_END' | claude -p print \
  --dangerously-skip-permissions \
  --add-dir ~/.claude/skills/[技能名] \
  --add-dir [项目源码路径] \
  --add-dir /tmp \
  --max-turns 30 \
  2>&1
[具体任务描述]
TASK_END
```

### TMUX 交互模式

```bash
# 创建 session 并直接进入 bypass 模式
tmux new-session -d -s <session-name> -x 140 -y 40
tmux send-keys -t <session-name> 'cd <项目目录> && claude --permission-mode bypassPermissions' Enter
sleep 8 && tmux capture-pane -t <session-name> -p  # 确认 Claude Code 已就绪

# 向 session 发送任务
tmux send-keys -t <session-name> '[任务描述]' Enter

# 查看输出
tmux capture-pane -t <session-name> -p

# 附加交互（可选）
tmux attach -t <session-name>
```

输出后检查 stdout 是否包含 `done: 文件路径`，然后用 `MEDIA:/路径` 将文件发送给用户。

---

## delegate_task vs terminal 调用 Claude Code 的区别

`delegate_task` 工具虽然有 `acp_command` 参数，但它只能控制子 AIAgent 的构造参数，子 AIAgent 仍然是 Hermes 自身的 agent 实例，通过 API 调用 LLM。**只有 provider 为 `copilot-acp` 时**，acp 参数才会真正建立外部 CLI 通道。

**关键区别**：

| | delegate_task | terminal 调用 claude -p |
|--|--------------|------------------------|
| 本质 | Hermes 子 agent（API 调用） | 外部 Claude Code 进程 |
| Skill 感知 | 无 | 能识别 SKILL.md |
| 工具能力 | Hermes 工具集 | Claude Code 自身工具集 |
| 适用场景 | 通用推理任务 | 需要 Claude Code 技能的特定任务 |

**结论**：当任务需要调用 Claude Code 的 skill（如 fireworks-tech-graph）时，应使用 `terminal` 调用 `claude -p`，而非 `delegate_task`。
