104 lines
6.2 KiB
Markdown
104 lines
6.2 KiB
Markdown
---
|
||
name: run-command-guide
|
||
description: run_command 工具使用指南。介绍前台与后台模式、后台模式的等待方式(command_id + sleep(wait_runcommand_id))、互斥参数约束以及常见坑与示例。
|
||
---
|
||
|
||
# run_command 使用指南
|
||
|
||
## 核心原则
|
||
|
||
- `run_command` 是 **一次性执行** 的终端命令,适合查询文件信息(`ls`、`file`、`grep -n`)、触发 CLI 工具、做简单的数据转换或运行非交互脚本。它**不能**用于启动交互式程序(如 `python` REPL、`vim`、`top`)。
|
||
- 每次调用必须提供 `timeout`(单位秒,必须大于 0),系统会在超时后强制打断命令并返回当前输出。
|
||
- 输出内容有字符数限制(默认 10000 字符),超过时会被截断或遭拒,因此尽量控制命令输出量,必要时拆分多个命令或保存到文件再读取。
|
||
- 如果需要持续交互、长时间运行、反复检查进度,优先使用 `terminal_session`/`terminal_input`;`run_command` 用于“一次性”场景。
|
||
|
||
## 执行模式:前台 vs 后台
|
||
|
||
### 前台模式(默认,`run_in_background=false`)
|
||
|
||
- timeout 上限 30 秒。命令在工具完成前会阻塞整个模型线程,返回后即可马上读取 `output`、`return_code` 等字段。
|
||
- 适合“快照式”场景:查看目录、检查某个文件、运行一条短命令并立刻需要结果。
|
||
- 要求命令在 30 秒内完成,否则会中断并返回 `status: "timeout"`。
|
||
|
||
### 后台模式(`run_in_background=true`)
|
||
|
||
- timeout 最长 3600 秒。命令在后台继续执行,工具会等约 5 秒收集当前输出并返回,然后 **立即释放控制权**,让你继续处理其他任务。
|
||
- 返回值里会包含 `command_id`,`status` 可能是 `running_background`。你会拿到已经产生的输出片段,但最终结果要靠系统通知或手动等待。
|
||
- 成功或失败完成后,系统会自动发送一条 `system` 消息(内容类似 `后台命令已完成(completed)`,并附带 `command_id`、`command`、`output` 摘要)通知你。不要再依赖 `wait_sub_agent`/手动轮询。
|
||
- 适合长时间任务(大规模日志分析、编译/安装、数据处理),或者你想发起命令后继续进行其他工作。
|
||
- 返回的 `command_id` 需要保留,用于后续通过 `sleep(wait_runcommand_id=...)` 等待结果或根据通知定位输出。
|
||
|
||
## 等待后台命令完成:command_id + sleep(wait_runcommand_id)
|
||
|
||
1. 调用后台命令后记录 `command_id`(形如 `cmd_<时间戳>_<8位hash>`);
|
||
2. 当你确实需要知道最终输出/返回码时,调用 `sleep(wait_runcommand_id=command_id)`;
|
||
3. `sleep` 工具会阻塞直到命令完成,返回值的 `result` 字段就是后台命令的最终 payload,`success`/`return_code` 等都可以直接使用;
|
||
4. `sleep` 默认会验证该 `command_id` 是否属于当前对话;跨会话调用会报错。
|
||
|
||
注意:即使你不调用 `sleep`,后台命令完成后也会有系统通知,只要收到消息就可以去交叉检查输出或 `sleep` 结果。
|
||
|
||
## `sleep` 工具的互斥参数规则
|
||
|
||
- `sleep` 工具支持三种等待方式:`seconds`(纯等待)、`wait_sub_agent_ids`(等待子智能体)、`wait_runcommand_id`(等待后台 `run_command`)。
|
||
- **只能选择其中一个等待参数**,否则会报错 “sleep 的等待参数互斥”;
|
||
- 如果你需要短暂停顿而非等待任务完成,传 `seconds` 并可选填 `reason`;
|
||
- 需要等待后台命令完成时仅填写 `wait_runcommand_id`,其余两个参数必须为 `null`/不传。
|
||
- `wait_runcommand_id` 返回:
|
||
```
|
||
{
|
||
"success": true,
|
||
"mode": "wait_runcommand_id",
|
||
"command_id": "...",
|
||
"result": {...}, # 与 run_command 结果结构一致
|
||
"message": "后台 run_command 等待完成"
|
||
}
|
||
```
|
||
|
||
## 常见坑与注意事项
|
||
|
||
1. **忘记设置 `timeout` 或给值 ≤ 0**:前台/后台都会立即报错。后台模式还有限制(>0 且 ≤3600)。
|
||
2. **误以为后台模式会自动输出最终结果**:后台只返回 `running_background` 的片段,必须通过系统通知或 `sleep(wait_runcommand_id=...)` 才能拿到完整状态。
|
||
3. **没有保存 `command_id` 即失去追踪**:`command_id` 是等待、复查、排错的唯一标识符,出错后可直接用它查询后台管理器。
|
||
4. **在 wait/run_command 之间同时传多个 `sleep` 参数**:会被客户端拒绝,报错明确指出互斥约束。
|
||
5. **命令输出过大(超过 10000 字符)**:会被截断并提示降低输出量,可考虑写入文件再用 `read_file` 读取,或分步执行。
|
||
6. **尝试运行交互式程序**:`run_command` 明确禁止,命令会在 `_validate_command` 阶段失败。
|
||
7. **后台命令属于别的对话**:`sleep(wait_runcommand_id=...)` 会报 “该后台命令不属于当前对话”,只能在原 conversation 中等待。
|
||
8. **误以为 `sleep` 会自动拼接 system message**:`sleep` 只是等待,系统通知仍旧按背景轮询插入,你收到 `system` 消息即可确认状态。
|
||
|
||
## 示例
|
||
|
||
### 前台快速查询
|
||
|
||
```python
|
||
run_command(command="ls -a docs | head", timeout=5)
|
||
# 立即得到输出和 return_code
|
||
```
|
||
|
||
### 后台安装并等待
|
||
|
||
```python
|
||
# 发起后台安装
|
||
bg = run_command(
|
||
command="python -m pip install -r requirements.txt",
|
||
timeout=600,
|
||
run_in_background=True
|
||
)
|
||
command_id = bg.get("command_id")
|
||
|
||
# 可先去做别的事情,或立即等待最终状态
|
||
sleep(wait_runcommand_id=command_id, reason="等待 pip 安装完成")
|
||
# 返回 result["result"]["output"], return_code 等最终内容
|
||
```
|
||
|
||
### 结合系统通知与 sleep
|
||
|
||
- 系统会插入类似 `后台命令已完成(completed)` 的 `system` 消息,包含 `command_id`。
|
||
- 如果你优先希望第一时间处理输出,可以在收到消息后再 `sleep(wait_runcommand_id=command_id)` 来确认成功状态(即使已有通知,也可再次 `sleep` 获得 `result` 结构)。
|
||
|
||
## 总结
|
||
|
||
- 前台模式适用于“立刻需要结果”的单步命令,后台模式适合“发起后继续干别的”的长任务。
|
||
- 后台结果需要 `command_id + sleep(wait_runcommand_id=...)` 或系统通知来确认最终状态。
|
||
- `sleep` 的等待参数互斥,务必只传一个。
|
||
- 避免交互式命令、超出字符/超时限制,必要时将输出先写到文件再读。
|