Agent Sandbox 里的 Sourcegraph Amp CLI
在 GitHub 查看 ↗amp
Agent Sandbox 里的 Sourcegraph Amp CLI。镜像钉住 @ampcode/cli,在端口 9000 上提供命名命令。
做什么
安装 Amp CLI(命令名 amp),并注册四个命令:
| 命令 | 实际执行 |
|---|---|
amp_version |
amp version |
amp_setup_check |
amp version,然后写入下面的设置文件 |
amp_execute |
amp --dangerously-allow-all --no-color --no-notifications --no-ide -x <prompt> |
amp |
amp_execute 的旧名字。参数相同。 |
stream_json 为 true 时,amp_execute 加上 --stream-json。HTTP 响应是进程退出后的完整标准输出,不是实时流。
amp_execute 在启动 CLI 之前检查 AMP_API_KEY。变量缺失或只有空白时,命令返回的错误里写明 AMP_API_KEY,并说明 CLI 自己会进入设备登录并等待。2026-10-15 实测:不带密钥执行 amp -x 会打印设备登录 URL 并一直等待。这个命令不会走那条路径。
Amp 不接受 DashScope 密钥、ABX_LLM_API_KEY 或 OpenAI 兼容的 base URL。令牌是 Amp 自己的访问令牌,在 ampcode.com 设置 创建。
--dangerously-allow-all 是 0.0.1792022479-ge66e24 这个二进制接受的标志。该版本的 amp --help 选项列表里没有它。帮助文本里写的是设置项 amp.dangerouslyAllowAll。amp_execute 会传这个标志,amp_setup_check 会写入这个设置项。
技术栈
- 基础镜像
fc-e2b-registry.<region>.cr.aliyuncs.com/runtime/base:<tag>。abx template deploy把<region>换成ALIBABA_CLOUD_REGION_ID或cn-hangzhou,把<tag>换成ABX_BASE_IMAGE_TAG或v0.0.49。 - 基础镜像里的 Node.js 20,只用来跑
npm。amp二进制是同版本可选包@ampcode/cli-linux-x64里的 glibc ELF。 @ampcode/cli@0.0.1792022479-ge66e24,来自 2026-10-15 的npm view @ampcode/cli version。目录里原来的 pin 是0.0.1791964847-g13f24a。基础镜像把 npm 源设成registry.npmmirror.com,该源对这个版本的@ampcode/cli-linux-x64返回 404,所以 Dockerfile 从https://registry.npmjs.org安装。构建时会跑amp version,原生二进制没解出来时构建失败。agent-sandbox-server来自 python-sdk 提交61c43e0be65a1f57aa09186d578e7b399e48429b(PR #21)。这个发行包不在 PyPI 上。- git 和 ripgrep。
- 工作目录
/home/user/app。运行用户user。平台用start_cmd启动进程。Dockerfile 没有CMD或ENTRYPOINT。
解决的问题
generation 2 沙箱可以在没有 TUI 的情况下运行钉死版本的 Amp CLI;不带密钥就能报告版本和设置文件;AMP_API_KEY 缺失时拒绝执行,而不是堵在设备登录上。
快速开始(CLI)
在本仓库检出目录,环境里放好极速版凭证:
abx template deploy ./amp -y --generation 2 \
--start-cmd 'agent-sandbox-server serve --port 9000 --commands /home/user/app/commands.py' \
--ready-cmd 'agent-sandbox-server healthcheck --port 9000'
abx create --template <template-id> -y
abx run <sandbox-id> amp_version
abx run <sandbox-id> amp_setup_check
template.yaml 里已经写了 generation、start_cmd 和 ready_cmd。真正跑一轮需要 Amp 访问令牌。在创建时传入,不要写进镜像:
abx create --template <template-id> -y --env AMP_API_KEY=<amp-access-token>
abx run <sandbox-id> amp_execute --arg prompt='Reply with exactly: ABX_E2E_OK'
stream_json 是布尔值,用 --json-args 传递:
abx run <sandbox-id> amp_execute --json-args '{"prompt":"Reply with exactly: ABX_E2E_OK","stream_json":true}'
用完后删掉沙箱和模板:
abx kill <sandbox-id> -y
abx template delete <template-id> -y
python3 scripts/express_e2e.py amp 会用唯一别名部署,通过 abx run 和 Python SDK 跑 smoke 里的 amp_version 和 amp_setup_check,只在通过后写证据,并删除这次创建的沙箱和模板。
快速开始(Python SDK)
客户端的 PyPI 名称是 agent-sandbox-client(python3 -m pip install agent-sandbox-client)。导入名仍是 agent_sandbox。pip install agent-sandbox 是另一个无关项目。
import asyncio
from agent_sandbox import Sandbox
async def main() -> None:
sb = await Sandbox.create(template="<template-id>", timeout=300)
try:
print(await sb.run("amp_version"))
print(await sb.run("amp_setup_check"))
# AMP_API_KEY 是 Amp 访问令牌,不是 DashScope 密钥。
# print(await sb.run("amp_execute", prompt="Reply with exactly: ABX_E2E_OK"))
finally:
await sb.kill()
asyncio.run(main())
需要 amp_execute 时在创建时带上密钥:
sb = await Sandbox.create(
template="<template-id>",
timeout=300,
envs={"AMP_API_KEY": "<amp-access-token>"},
)
text = await sb.run("amp_execute", prompt="Reply with exactly: ABX_E2E_OK", stream_json=False)
await sb.run(...) 返回该命令的 result。sb.commands.run 跑的是 shell,不是这些命名命令。python-sdk 0.3.0 上 Sandbox.create_sync 会抛 TypeError(python-sdk#22),请用 await Sandbox.create。
命令参考
| 命令 | 参数 | 返回 | 说明 |
|---|---|---|---|
amp_version |
无 | 字符串 | amp version 的第一个字段,例如 0.0.1792022479-ge66e24。 |
amp_setup_check |
无 | 对象 | installed、package、version、api_key_set、settings_path、dangerously_allow_all、updates_mode。 |
amp_execute |
prompt 字符串,必填。stream_json 布尔,可选,默认 false。 |
字符串 | amp -x 的标准输出。stream_json 为 true 时加上 --stream-json。 |
amp |
与 amp_execute 相同 |
字符串 | 旧命令名。 |
POST /commands/amp_execute,请求体 {"prompt":"hi"},CLI 退出码为 0 时响应 {"result":"<stdout>"}。缺少 prompt 是 HTTP 400。缺少 AMP_API_KEY、找不到二进制,或 amp 非零退出,是 HTTP 500,响应体含 error 和 type。api_key_set 只是布尔值,不返回密钥。RuntimeError 文本在密钥非空时会把密钥打成 ***。
amp_setup_check 写入下面的 JSON(合并进已有对象):
{
"amp.dangerouslyAllowAll": true,
"amp.updates.mode": "disabled",
"amp.notifications.enabled": false
}
路径优先用 AMP_SETTINGS_FILE;设置了 WORKSPACE 时用 $WORKSPACE/.e2e_amp/settings.json;HOME 为 /home/user 时用 /home/user/.config/amp/settings.json。镜像里设置了 AMP_SETTINGS_FILE=/home/user/.config/amp/settings.json。
配置
| 名称 | 必填 | 默认 | 用途 |
|---|---|---|---|
AMP_API_KEY |
amp_execute 需要 |
空 | Amp 访问令牌。不是 DashScope 或 OpenAI 密钥。template.yaml 里的值是空字符串。 |
AMP_URL |
否 | https://ampcode.com/ |
Amp 服务地址。这是 CLI 自己的默认值,镜像不覆盖它。 |
AMP_SETTINGS_FILE |
否 | 镜像内为 /home/user/.config/amp/settings.json |
amp_setup_check 写入的设置文件。 |
AMP_LOG_FILE |
否 | 镜像内为 /home/user/.cache/amp/logs/cli.log |
CLI 日志路径。 |
ABX_SERVER_TOKEN |
否 | 空 | 沙箱内设置之后,客户端发送 Authorization: Bearer。 |
ABX_SERVER_PORT |
否 | 9000 |
本地执行 python3 commands.py 时 start() 监听的端口。 |
密钥放在 abx create --env 或 Sandbox.create(envs=...)。不要写进镜像或日志。
在镜像外启动 commands.py 之前请设置 AMP_SETTINGS_FILE 或 WORKSPACE。否则当 HOME 不是 /home/user 时,进程会在当前目录写 .e2e_amp/settings.json。
资源
| 资源 | 值 |
|---|---|
| cpu | 2 vCPU |
| memory | 2048 MB |
| 端口 | 9000 |
| 磁盘 | 平台 rootfs,极速版大约 10G |
带工具的真实 agent 回合没有测过内存。不需要密钥的命令(amp_version、amp_setup_check)在这个规格下可以跑。amp 二进制大约 130 MB。
已验证
| 提供方 | 日期(UTC) | 模板版本 | SDK | 通过的内容 |
|---|---|---|---|---|
| alicloud-express | 2026-10-15 | 1.1.0 | 0.3.0 | L2。python3 scripts/express_e2e.py amp 以 generation 2 部署到 READY,并用 abx run 和 Sandbox.run 跑了 amp_version 与 amp_setup_check。 |
L1:对本 Dockerfile 做 docker build 时,amp version 打印了 0.0.1792022479-ge66e24,并安装了 python-sdk 提交 61c43e0be65a1f57aa09186d578e7b399e48429b 的 agent-sandbox-server。
L0:e2e_test.py 在 PATH 上有 amp 时通过(版本和设置文件),没有 amp 时也通过(错误写明找不到 CLI)。python3 scripts/run_local_e2e.py 里这个目录通过了。
没有跑 L3。这个环境没有 AMP_API_KEY。没有把 DashScope 或 OpenAI 兼容密钥交给 Amp。
二次开发
版本钉在 Dockerfile 的 AMP_CLI_VERSION(@ampcode/cli@0.0.1792022479-ge66e24)和 template.yaml 里 amp_version 的 smoke 期望值。跑过 npm view @ampcode/cli version 之后,同时改这两处,以及 e2e_test.py 里的 PINNED_VERSION,再跑一次 amp version,让 smoke 字符串等于输出的第一个字段。
amp_execute 用参数数组调用 CLI。不要把 prompt 拼进 shell 字符串。AMP_API_KEY 检查必须放在 subprocess 之前,避免缺密钥时堵在设备登录。
要加命令,再注册一个用参数数组调用 amp 的 @command。start() 只放在 if __name__ == "__main__" 下面。
贡献
见 CONTRIBUTING.md 和 docs/template-spec.zh-CN.md。设计说明在 docs/design/amp.md。
问题反馈
| 主题 | 仓库 |
|---|---|
| 本模板、规范、检查器 | awesome-templates |
Python SDK 或 agent-sandbox-server |
python-sdk,标题前缀 [templates] |
abx CLI |
agent-sandbox,标题前缀 [templates] |
许可证
Apache-2.0,与本仓库相同。见 LICENSE。