快速开始
agentrun 用一条命令在沙箱里运行 claude-code、codex、pi 和 dsh,支持 macOS、Linux、Cloud Managed 容器和 docker 容器。这一页带你装好 agentrun,检查环境,在沙箱里运行第一个任务,再把它放进脚本。照着做一遍大约需要五分钟。
安装 agentrun
agentrun 是一个独立的可执行文件,支持 macOS 与 Linux 的 x86_64 与 arm64。从 GitHub Releases 下载与你的系统对应的文件,放进 PATH。把命令里的 linux-x86_64 换成 linux-arm64、macos-arm64 或 macos-x86_64:
VERSION=1.0.1
FILE=agentrun-$VERSION-linux-x86_64
curl -LO https://github.com/yhnocoder/agentrun/releases/download/v$VERSION/$FILE
chmod +x $FILE
mkdir -p ~/.local/bin
mv $FILE ~/.local/bin/agentrun
~/.local/bin 不在 PATH 里时(macOS 默认不在),把下面一行加进 shell 的配置文件(zsh 是 ~/.zshrc,bash 是 ~/.bashrc),再打开一个新的终端:
export PATH="$HOME/.local/bin:$PATH"
在 macOS 上用浏览器下载的文件带有 quarantine 属性,系统会拒绝运行它。放进 ~/.local/bin 之后去掉这个属性:
xattr -d com.apple.quarantine ~/.local/bin/agentrun
装了 cargo-binstall 时,可以用它安装。它从 GitHub Releases 下载与你的系统对应的文件,放进 ~/.cargo/bin,不在本机编译:
cargo binstall agentrun
装了 Rust 工具链时,也可以从 crates.io 下载源码,在本机编译安装:
cargo install agentrun --locked
确认它已经在 PATH 里:
准备运行时
agentrun 负责启动和隔离 agent,agent 本身来自运行时。按各自的文档安装你要用的运行时并登录一次:
| 运行时 | 子命令 | 版本 |
|---|---|---|
| claude-code | agentrun claude-code | >= 2.1.288 |
| codex | agentrun codex | >= 0.159.2 |
pi(npm 包 @earendil-works/pi-coding-agent) | agentrun pi | >= 1.0.1 |
dsh(DeepSeek Harness,npm 包 @deepseek-ai/dsh) | agentrun dsh | >= 0.2.1-rc.2 |
agentrun 在 PATH 里查找运行时,并沿用你已有的登录。用 pi 时,在 pi 的设置里选好默认模型,或者每次用 --model 服务商/模型 指定。
dsh 的 npm 默认标签还是更早的 0.2.0-rc.2,安装时写明版本。装好后的 node_modules 约 860 MB,比其他运行时大得多。dsh 用 DeepSeek 的 API key 登录:把它导出为环境变量 DEEPSEEK_API_KEY。agentrun 不读 ~/.dsh/.env,写在那里的 key 不起作用。
npm install -g @deepseek-ai/dsh@0.2.1-rc.2
export DEEPSEEK_API_KEY=...
在 macOS 上,沙箱由系统提供,不需要另外安装。在 Linux 上,安装 bwrap 与 socat:
# Debian、Ubuntu
sudo apt install bubblewrap socat
# Fedora
sudo dnf install bubblewrap socat
Ubuntu 23.10 及以后的版本默认不允许普通程序创建 user namespace,bwrap 要有自己的 AppArmor profile 才能启动,做法见沙箱与网络。下一步的 agentrun doctor 会告诉你是否需要这一步。
检查环境
运行 agentrun doctor,后面写上你要用的运行时:
每一行是一项检查:运行时能不能找到、版本是否满足上面表里的要求,能不能登录,沙箱能不能启动,网络限制能不能执行。sandbox 一行说明 agentrun 在一个临时目录里试过了:沙箱里的命令能写这个目录,写不了目录以外的地方。全部是 ok 或 skip 就可以继续。出现 fail 时,这一行会写明原因和改法,也可以查常见问题。
运行第一个任务
新建一个目录,放一个小文件:
mkdir hello && cd hello
printf 'def greet(name):\n return "hello " + name\n' > greet.py
让 claude-code 给它写测试:
怎么读这段输出:
- 每行开头的
[main]表示这一行来自主 agent。agent 启动 subagent 时,subagent 的行以它自己的标签开头,例如[explore#1]。 tool行是一次完成的工具调用,text行是 agent 说的话。调用被拒绝时tool行末尾有(denied),执行出错时有(error),例如测试没有通过。- 最后的
[end]行是结果:finished表示正常完成,后面是耗时、送进模型的输入、模型的输出、输入中命中缓存的比例,最后是运行时报告的费用,单位美元。运行时不报告费用时(例如 codex 与 dsh)不显示费用。
这次运行发生在沙箱里:agent 只能写 hello 目录和一个临时目录,它运行的命令不能联网,它也读不到你自己的运行时配置、插件和会话记录。
不加 --format text 时,终端里显示的是动态界面:上方滚动显示同样的行,下方显示正在运行的 subagent 和主 agent 的状态。
换成 pi、codex 或 dsh,只需要换子命令:
agentrun pi --model deepseek/deepseek-flash --prompt "给 greet.py 写一个测试并运行"
agentrun codex --prompt "给 greet.py 写一个测试并运行"
agentrun dsh --prompt "给 greet.py 写一个测试并运行"
在脚本里使用
输出不是终端时,agentrun 默认输出 jsonl:每行一个 JSON 事件,最后一行是 end 事件,里面有结果和 agent 的最后一段话。用退出码判断成败,用 jq 取结果:
#!/bin/sh
agentrun claude-code --prompt "用一句话说明 greet.py 做什么" > run.jsonl
status=$?
if [ "$status" -eq 0 ]; then
jq -r 'select(.type == "end") | .result' run.jsonl
else
jq -r 'select(.type == "end") | "\(.status): \(.detail)"' run.jsonl
exit "$status"
fi
环境有问题时,脚本拿到退出码 2,detail 写明原因。下面是 PATH 里没有 claude 时的输出,第一行是 agentrun 写到标准错误的说明:
退出码的含义:
| 退出码 | 结果 | 你可以怎么做 |
|---|---|---|
| 0 | 正常完成 | 读 result |
| 1 | agent 没有完成,例如模型调用失败 | 看 detail,按需重试 |
| 2 | 启动前就失败,环境或命令有问题 | 先改环境或命令,原样重试不会成功 |
| 3 | 超过 --timeout | 放宽时限或拆小任务 |
| 4 | 超过 --max-turns 或 --max-tokens | 放宽上限或拆小任务 |
| 130、143 | agentrun 被 Ctrl-C 或 SIGTERM 中断 | agent 已经停止,result 是中断前收到的内容 |