OpenSandbox × Qwen Code:在沙箱容器中运行 Qwen Code CLI 的 OpenAI 兼容端点实战指南
【免费下载链接】OpenSandboxSecure, Fast, and Extensible Sandbox runtime for AI agents.项目地址: https://gitcode.com/GitHub_Trending/ope/OpenSandbox
本文基于 OpenSandbox 仓库中的官方示例文档与配套源码,讲解如何在 OpenSandbox 容器中通过 OpenAI 兼容端点运行 Qwen Code(阿里 Qwen 系列的编码 CLI 工具)。读完本文,你将掌握:如何启动本地 OpenSandbox server、如何配置模型提供方(BASE_URL / MODEL_NAME / API_KEY),以及示例脚本examples/qwen-code/main.py是如何完成沙箱创建、写入 Qwen Code 项目配置、安装 CLI 并以 headless 模式执行推理任务的完整链路。
一、场景说明
Qwen Code 是一个命令行编码智能体。本示例把 Qwen Code 放进 OpenSandbox 容器内运行:CLI 本身运行在隔离的沙箱里,而模型推理走外部的 OpenAI 兼容 API(示例默认指向 DashScope 的compatible-mode端点,模型为qwen3-coder-plus)。这样既让 LLM 的"手脚"(终端命令、文件操作)被限制在沙箱内,又保留了自定义模型接入的灵活性——API Key 只通过环境变量注入,不落盘、不进仓库。
对应的官方文档为 docs/examples/qwen-code.md,示例代码位于 examples/qwen-code/main.py,入口说明见 examples/qwen-code/README.md。
二、第一步:启动本地 OpenSandbox Server(Docker 运行时)
1. 预拉取 code-interpreter 镜像
code-interpreter 镜像自带 Node.js 运行环境,Qwen Code 是 Node 编写的 CLI,因此可以直接在容器内用npm安装:
docker pull sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/code-interpreter:v1.1.0 # use docker hub # docker pull opensandbox/code-interpreter:v1.1.02. 安装并启动 server
uv pip install opensandbox-server opensandbox-server init-config ~/.sandbox.toml --example docker opensandbox-serverinit-config子命令用于从打包的示例配置生成一份 TOML 配置文件。查看 server/opensandbox_server/cli.py 中init-config的参数定义可知:- 第一个可选参数是目标路径,默认为
~/.sandbox.toml; --example支持docker、docker-zh、k8s、k8s-zh四种打包示例(分别对应 Docker / Kubernetes 运行时的中英文配置);不带--example时会渲染一份带占位符的完整骨架,所有字段都需用户显式填写;--force允许覆盖已存在的配置文件;文件已存在且未加--force时会抛出FileExistsError。
- 第一个可选参数是目标路径,默认为
- 打包示例配置模板位于 server/opensandbox_server/examples/ 目录,
init-config通过 Python 资源加载机制复制该模板。 - 执行
opensandbox-server(不带子命令)即启动服务,标准输出日志会直接打印在终端,便于本地观察沙箱创建、命令执行等生命周期事件。
三、第二步:创建并访问 Qwen 沙箱
在另外的终端中准备 Python 环境与模型提供方变量:
# Install OpenSandbox package uv pip install opensandbox # Export provider settings export API_KEY=your-api-key export BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 export MODEL_NAME=qwen3-coder-plus # Run the example uv run python examples/qwen-code/main.py脚本的运行行为(与 examples/qwen-code/README.md 及文档描述一致):
- 创建沙箱时通过
env={"API_KEY": qwen_api_key}把模型 API Key 注入容器环境变量; - 在沙箱内写入项目级配置
/tmp/qwen-code-example/.qwen/settings.json; - 运行时执行
npm install -g @qwen-code/qwen-code@latest安装 Qwen Code CLI; - 以 headless 模式运行
qwen -p "Compute 1+1 and reply with only the final number."; - 打印执行日志后调用
sandbox.kill()销毁沙箱。
整个流程中 API Key 仅经由API_KEY环境变量传递,不会写入仓库或配置文件。
四、示例脚本源码解读:一次完整的沙箱编排
examples/qwen-code/main.py 只有百余行,但它完整演示了 OpenSandbox Python SDK 的核心编排模式,值得逐段拆解。
1. 读取环境变量并构建连接配置
domain = os.getenv("SANDBOX_DOMAIN", "localhost:8080") api_key = os.getenv("SANDBOX_API_KEY") qwen_api_key = _required_env("API_KEY") # API_KEY 必填,缺失直接抛 RuntimeError qwen_base_url = os.getenv("BASE_URL", "https://dashscope.aliyuncs.com/compatible-mode/v1") qwen_model_name = os.getenv("MODEL_NAME", "qwen3-coder-plus") image = os.getenv( "SANDBOX_IMAGE", "sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/code-interpreter:v1.1.0", ) config = ConnectionConfig( domain=domain, api_key=api_key, request_timeout=timedelta(seconds=60), )ConnectionConfig是 SDK 中管理 API 连接的配置模型,定义在 sdks/sandbox/python/src/opensandbox/config/connection.py,结合源码可以看清楚示例中各参数的含义与默认行为:
| 字段 | 示例取值 / SDK 默认值 | 说明 |
|---|---|---|
domain | localhost:8080 | 沙箱管理服务地址;未设置时回退读环境变量OPEN_SANDBOX_DOMAIN,再回退到localhost:8080(见 connection.py#L122) |
api_key | 示例中可为None | 本地 server 不强制鉴权;也可从环境变量OPEN_SANDBOX_API_KEY兜底读取(见 connection.py#L190-L198) |
request_timeout | 示例设为 60s;SDK 默认 30s | 管理 API 的 HTTP 请求超时,必须为正值(有 validator 校验,见 connection.py#L183-L188) |
protocol | http | 只接受http/https,domain若自带 scheme 则覆盖该字段 |
retry_policy | 默认RetryPolicy() | 非流式请求默认走重试包装的RetryAsyncTransport;如需快速失败可传RetryPolicy.disabled() |
use_server_proxy | False | 当客户端无法直连沙箱内的 execd 时,可让 sandbox server 代为转发进程级请求 |
从源码结构看,get_base_url()最终拼出形如http://localhost:8080/v1的管理 API 地址,说明客户端与 server 之间走的是统一的v1REST 接口层(见 connection.py#L204-L212)。
2. 创建沙箱并注入 API Key
sandbox = await Sandbox.create( image, connection_config=config, env={"API_KEY": qwen_api_key}, ) async with sandbox: ... await sandbox.kill()Sandbox.create(见 sdks/sandbox/python/src/opensandbox/sandbox.py)以镜像名 + 连接配置创建沙箱,env参数把API_KEY直接注入容器环境——这就是"密钥只走环境变量"的实现点;async with sandbox提供上下文管理,退出时资源可被安全清理;示例末尾显式await sandbox.kill()销毁沙箱,保证不留驻。
3. 写入 Qwen Code 项目配置
await sandbox.files.create_directories( [ WriteEntry(path=QWEN_PROJECT_DIR, mode=755), WriteEntry(path=QWEN_SETTINGS_DIR, mode=755), ] ) await sandbox.files.write_file(QWEN_SETTINGS_PATH, _build_qwen_settings(...), mode=644)脚本先在沙箱内创建/tmp/qwen-code-example及其下的.qwen目录(权限 755),再写入settings.json(权限 644)。WriteEntry是 SDK 的文件系统写入模型,定义于 sdks/sandbox/python/src/opensandbox/models/filesystem.py。
_build_qwen_settings()(main.py#L37-L59)生成的配置结构如下,它把BASE_URL与MODEL_NAME两个环境变量翻译成了 Qwen Code 的模型提供方声明:
{ "modelProviders": { "openai": [ { "id": "<MODEL_NAME>", "name": "<MODEL_NAME>", "baseUrl": "<BASE_URL>", "description": "Qwen Code via OpenAI-compatible API in OpenSandbox", "envKey": "API_KEY" } ] }, "security": { "auth": { "selectedType": "openai" } }, "model": { "name": "<MODEL_NAME>" } }几个关键设计点:
baseUrl指向 OpenAI 兼容端点(默认https://dashscope.aliyuncs.com/compatible-mode/v1),因此任何提供 OpenAI 兼容接口的服务(自建 vLLM、其他厂商网关等)都可以通过修改BASE_URL接入,无需改动脚本逻辑;envKey字段声明该提供方从环境变量API_KEY读取密钥,与前面Sandbox.create(env=...)的注入一一对应;security.auth.selectedType = "openai"选择 OpenAI 兼容认证通道,model.name指定最终使用的模型(默认qwen3-coder-plus)。
4. 安装并 headless 运行 Qwen Code
install_exec = await sandbox.commands.run( "npm install -g @qwen-code/qwen-code@latest" ) await _print_execution_logs(install_exec) run_exec = await sandbox.commands.run( 'cd /tmp/qwen-code-example && qwen -p "Compute 1+1 and reply with only the final number."' ) await _print_execution_logs(run_exec)- 沙箱内的 execd 组件负责命令执行,
sandbox.commands.run返回的执行结果对象带有logs.stdout/logs.stderr/error字段;_print_execution_logs(main.py#L62-L68)逐行打印,便于在本地终端直接观察沙箱内 CLI 的输出; qwen -p "<prompt>"是 Qwen Code 的 headless(无交互)模式:给定一次性提示词,完成推理后直接返回最终答复,适合脚本化编排——这正是"LLM Agent 跑在沙箱里、由 SDK 从外部驱动"的典型形态。
五、环境变量速查表
以下变量表完整继承自官方文档,并与 examples/qwen-code/main.py 中的读取逻辑一一对应:
| 变量 | 默认值 | 说明 |
|---|---|---|
SANDBOX_DOMAIN | localhost:8080 | 沙箱服务地址 |
SANDBOX_API_KEY | (本地可留空) | 若 server 开启了鉴权则必填;SDK 侧还会回退读取OPEN_SANDBOX_API_KEY |
SANDBOX_IMAGE | sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/code-interpreter:v1.1.0 | 使用的沙箱镜像 |
API_KEY | (必填,无默认) | Qwen Code 所用的 OpenAI 兼容模型提供方的 API Key |
BASE_URL | https://dashscope.aliyuncs.com/compatible-mode/v1 | OpenAI 兼容端点地址 |
MODEL_NAME | qwen3-coder-plus | Qwen Code 使用的模型名 |
注意API_KEY与SANDBOX_API_KEY是两个不同维度的密钥:前者是模型提供方(DashScope 等)的 Key,注入到沙箱内部;后者是 OpenSandbox server 自身的访问凭证,作用于宿主机侧 SDK 与管理 API 的通信。本地运行 docker 示例时后者通常不需要,但接入启用鉴权的部署时两者要分别配置。
六、可验证的实现依据与延伸阅读
本文所有结论均可在仓库中直接对照源码核验:
- 官方文档:docs/examples/qwen-code.md
- 示例脚本:examples/qwen-code/main.py(连接配置
L82-L86、沙箱创建L88-L92、写配置L95-L105、安装与运行L107-L117) - Python SDK 连接配置模型:sdks/sandbox/python/src/opensandbox/config/connection.py
Sandbox.create入口:sdks/sandbox/python/src/opensandbox/sandbox.py- 文件系统写入模型
WriteEntry:sdks/sandbox/python/src/opensandbox/models/filesystem.py - server 侧
init-config子命令实现:server/opensandbox_server/cli.py
适用前提与限制:示例面向 Docker 运行时的本地 server(localhost:8080);code-interpreter:v1.1.0镜像需可访问对应镜像仓库;Qwen Code 的npm install -g与模型请求发生在沙箱内部,因此沙箱需要可达 npm registry 与BASE_URL所指端点的网络。若你的部署启用了出站策略或凭据注入,可参考 docs/examples/index.md 中列出的其他 Agent 类示例(Claude Code、Gemini CLI、Codex CLI 等)了解同类编排模式。
【免费下载链接】OpenSandboxSecure, Fast, and Extensible Sandbox runtime for AI agents.项目地址: https://gitcode.com/GitHub_Trending/ope/OpenSandbox
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考