Agent Infra - Cloud Agents V2
Agent Skills
- 为 Agent 附加领域专业知识
- Skills 为 Agent 附加领域专业知识
- 一个 Skill 是一组结构化的指令和流程,让 Agent 在特定任务上表现得更专业、更可靠
架构概览
1 | flowchart TB |
| 层次 | 组件 | 特性 | 耦合关系 |
|---|---|---|---|
| 静态 | Agent | 可复用、版本化、不可变快照 | Session 创建时锁定,后续修改不影响已运行实例 |
| 静态 | Environment | 容器模板、依赖声明 | Session 创建时绑定,容器启动时热安装依赖 |
| 静态 | Skill | 版本化知识模块 | 可选绑定到 Agent,支持动态跟随或钉住版本 |
| 动态 | Session | 独立运行实例、/data 沙箱隔离 | 消费 Agent 快照 + Environment 实例 |
| 运行时 | 权限策略 | 工具调用控制 | 在 Agent 的 tools.configs 中配置 |
端点总表
| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/api/v1/cloud/skills |
创建 Skill(含首个版本) |
GET |
/api/v1/cloud/skills |
列出 Skills |
GET |
/api/v1/cloud/skills/{skill_id} |
获取 Skill |
PUT |
/api/v1/cloud/skills/{skill_id} |
更新 Skill ⚠️ 已废弃 |
DELETE |
/api/v1/cloud/skills/{skill_id} |
删除 Skill |
POST |
/api/v1/cloud/skills/{skill_id}/versions |
创建 Skill 版本 |
GET |
/api/v1/cloud/skills/{skill_id}/versions |
列表 Skill 版本 |
GET |
/api/v1/cloud/skills/{skill_id}/versions/{version} |
获取 Skill 版本 |
GET |
/api/v1/cloud/skills/{skill_id}/versions/{version}/content |
下载 Skill 版本内容 |
DELETE |
/api/v1/cloud/skills/{skill_id}/versions/{version} |
删除 Skill 版本 |
版本化模型
Skill 采用「skill 壳 + 不可变版本快照」两层模型:
Skill 壳:承载
id、display_title、source、metadata等与内容无关的属性,以及指向最新版本的latest_version。Skill 版本(version):每个版本是一份不可变的完整内容快照。版本号是创建时刻的 epoch 微秒字符串(如
"1759178010641129"),由服务端生成,不可指定。更新内容 = 通过
POST /skills/{skill_id}/versions追加一个新版本;旧版本保持不变,可单独获取、下载和删除。删除最新版本后,
latest_version自动回退到次新版本;所有版本删光时为null。Skill 的
name(来自SKILL.mdfrontmatter)在所有版本间必须保持一致,创建后不可更改。
PUT /api/v1/cloud/skills/{skill_id}已废弃。内容更新请改用 创建 Skill 版本。
Skill 的作用
| 作用 | 描述 |
|---|---|
| 注入专业知识 | 让通用 Agent 具备特定领域能力(如代码审查、文档生成) |
| 标准化流程 | 确保 Agent 按统一步骤执行,输出一致 |
| 可复用 | 一次创建,多个 Agent 共享 |
Skill 文件结构
Skill 以 .zip 文件(或裸文件树 multipart 上传)提交,必须有唯一的顶级目录,且目录名等于 SKILL.md 中的 name:
1 | my-skill/ |
SKILL.md 是核心文件,使用 YAML frontmatter + Markdown 格式:
1 |
|
创建 Skill
1 | POST https://api.qoder.com/api/v1/cloud/skills |
curl 示例
先打包 Skill 目录(保留顶级目录)
1 | $ zip -r my-skill.zip my-skill/ |
上传
1 | $ curl -s -X POST https://api.qoder.com/api/v1/cloud/skills \ |
latest_version由服务端生成,是创建时刻的 epoch 微秒字符串- SKILL.md frontmatter 中的
version(如1.0.0)仅作信息标记用途,并非服务端版本号
关联到 Agent
- 通过 Agent 的
skills字段将 Skill 绑定到 Agent - 绑定元素可携带可选的
version字段:省略或传"latest"表示动态跟随最新版本;传数字时间戳表示钉住该版本(写入时会校验该版本真实存在,否则返回 400)
1 | $ curl -s -X POST https://api.qoder.com/api/v1/cloud/agents/agent_00mqky5ogkt1cpm84o7r \ |
版本管理
为已有 Skill 追加新版本:
1 | $ curl -s -X POST https://api.qoder.com/api/v1/cloud/skills/skill_00mqyyqaxvdohy1fqx8c/versions \ |
- 未钉版的绑定始终使用最新版本
- 钉住数字版本的绑定固定使用该版本内容
获取 Skill 详情
1 | $ curl -s https://api.qoder.com/api/v1/cloud/skills \ |
Skill 编写建议
| 建议 | 描述 |
|---|---|
| 明确触发条件 | 在 description 中写清楚何时应使用此 Skill |
| 步骤具体 | Steps 中写精确操作,而非模糊描述 |
| 记录陷阱 | Pitfalls 帮助 Agent 避免常见错误 |
| 提供验证 | 告诉 Agent 如何确认任务完成 |
常见问题
Q:Skill 和 Agent system 提示词有什么区别?
A:system 是 Agent 的通用指令,对所有任务生效。Skill 是按需激活的专业模块,Agent 根据任务内容决定是否使用。
Q:一个 Agent 可以关联多少个 Skills?
A:无硬性限制,但建议控制在 10 个以内以确保 Agent 行为可预测。
Q:Skills 功能何时全面开放?
A:当前处于 M2 门控阶段,预计后续版本全量开放。可联系我们申请提前开通。
Q:zip 文件大小有限制吗?
A:压缩包不超过 50 MB,且解压后总大小同样不超过 50 MB。
权限策略
- 控制工具调用是允许、询问还是拒绝
- 权限策略控制 Agent 想调用工具时会发生什么
- 内置工具和 MCP 工具会被评估为
allow、ask或deny - client-side 自定义工具始终暂停,由你的应用执行后回传结果
运行时行为
工具调用进入事件流时,会投影为:
| 事件 | 含义 | 关键字段 |
|---|---|---|
agent.tool_use |
内置工具调用 | id, name, input, evaluated_permission |
agent.mcp_tool_use |
MCP 工具调用 | id, name, input, mcp_server_name, evaluated_permission |
agent.custom_tool_use |
Client-side 自定义工具请求 | id, name, input |
evaluated_permission 可能为:
| 值 | 行为 |
|---|---|
allow |
平台直接执行工具 |
ask |
当前 turn 暂停,等待 user.tool_confirmation |
deny |
平台向 Agent 返回被拒绝的工具结果 |
1 | flowchart TB |
- 自定义工具不支持
permission_policy - 它们由客户端执行,并通过
user.custom_tool_result回复
在 Agent 中配置权限
内置工具和 MCP 工具的权限配置写在 Agent 的 tools 数组里:
1 | { |
| 位置 | 作用范围 | 说明 |
|---|---|---|
tools[].configs[].permission_policy |
一个具名工具 | 单工具权限覆盖。内置工具的 name 使用 Read 等内置工具名;MCP 工具的 name 使用该 MCP server 暴露的原始工具名 |
tools[].configs[].enabled |
一个具名工具 | 设为 false 时会禁用并拒绝该工具。如果同时使用 enabled_tools 白名单,不要把已禁用工具放进白名单 |
permission_policy.type 可选值:
| 值 | 运行时结果 |
|---|---|
always_allow |
evaluated_permission: "allow" |
always_ask |
evaluated_permission: "ask",当前 turn 等待 user.tool_confirmation |
always_deny |
evaluated_permission: "deny" |
Pending Action 流程
当工具调用需要人工或客户端输入时:
- 事件流先发送
agent.tool_use或agent.custom_tool_use - 事件流再发送
session.status_idle,其中stop_reason.type为"requires_action" stop_reason.event_ids列出需要响应的事件 ID- 客户端向
POST /api/v1/cloud/sessions/{session_id}/events发送响应事件 - Agent 继续同一个 turn
1 | { |
Pending action 不会自动超时。它会一直保持 pending,直到客户端解决,或 session/turn 被取消。
确认工具调用
- 使用
agent.tool_use事件的id作为tool_use_id - 这里传的是
evt_...事件 ID,不是模型供应商内部的 tool-use ID
批准
1 | curl -X POST https://api.qoder.com/api/v1/cloud/sessions/sess_abc123/events \ |
拒绝
1 | curl -X POST https://api.qoder.com/api/v1/cloud/sessions/sess_abc123/events \ |
完成自定义工具
- 自定义工具通过 Agent 的
type: "custom"配置,详见 Agent 工具配置 - 当 Agent 请求自定义工具时,你的应用执行该工具,然后使用
agent.custom_tool_use事件 ID 回传
1 | curl -X POST https://api.qoder.com/api/v1/cloud/sessions/sess_abc123/events \ |
content 可以是字符串、单个 text block 或 text block 数组。返回事件会以 content block 结构保存。
常见问题
Q:一个 turn 可以有多个待响应操作吗?
A:可以。stop_reason.event_ids 可能包含多个事件 ID,需要逐个响应。
Q:pending action 会超时吗?
A:不会。它会保持 pending,直到被解决,或 session/turn 被取消。
Q:自定义工具能使用 permission_policy 吗?
A:不能。自定义工具是 client-side 工具,是否执行或拒绝由客户端负责。
云端环境
- 选择 Agent 运行的容器、网络与依赖
- Environment 定义 Session 使用的运行环境,包括环境类型、预装依赖、启动脚本和 metadata
- 你可以使用默认托管环境,也可以为特定任务创建预装工具的环境或接入自托管执行环境
环境是什么
Environment 是 Session 的基础设施层:
| 项 | 描述 |
|---|---|
| 环境类型 | cloud 表示云端托管容器,self_hosted 表示自托管执行环境 |
| 依赖包 | 预装系统包、Python 包、Node.js 包 |
| 启动脚本 | 容器准备阶段、依赖安装完成后执行的用户脚本 |
每个 Session 启动时会基于指定的 Environment 模板创建独立的运行实例。
字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
string | - | 系统生成,env_ 前缀 |
type |
string | - | 固定为 "environment" |
name |
string | 是 | 环境名称 |
description |
string | 否 | 描述信息,默认 "" |
config |
object | 否 | 环境配置;省略时默认为 {"type":"cloud"} |
config.type |
string | config 存在时是 | 环境类型:"cloud" 或 "self_hosted" |
config.packages |
object | 否 | cloud 环境的预装依赖包配置 |
config.setup_script |
string | 否 | sandbox 准备阶段执行的 shell 脚本(最大 64 KB) |
metadata |
object | 否 | 自定义 key/value metadata |
archived_at |
string|null | - | 归档时间(ISO 8601),未归档时为 null |
created_at |
string | - | 创建时间 |
updated_at |
string | - | 最后更新时间 |
Config 类型
config.type可以是"cloud"或"self_hosted"self_hosted的 config 可以只包含类型,也可以包含setup_script:
1 | {"type": "self_hosted"} |
- Self-hosted Environment 不会启动托管云端容器
- 外部 worker 通过 Work API poll、ack、heartbeat 和 stop 该 Environment 下的 Session work
self_hostedconfig 仅支持type和可选的setup_scriptcloud的 config 可以包含packages和setup_script
预装依赖
通过 config.packages 指定容器启动时预装的依赖:
1 | { |
| 包管理器 | 字段 | 说明 |
|---|---|---|
| apt | packages.apt |
Debian/Ubuntu 系统包 |
| pip | packages.pip |
Python 包 |
| npm | packages.npm |
Node.js 包 |
预装依赖会增加环境初始化时间。只添加确实需要的包,其余可在 Session 运行时按需安装。
启动脚本
config.setup_script是一段在 sandbox 准备阶段、packages安装完成之后执行的 shell 脚本,使用/bin/bash -lc解释器运行- 常用于克隆代码、写配置文件、warmup 缓存等无法用
packages表达的初始化步骤
| 约束 | 值 |
|---|---|
| 类型 | string |
| 最大长度 | 64 KB |
| 解释器 | /bin/bash -lc |
| 超时 | 10 分钟 |
| 执行时机 | sandbox 准备阶段,packages 安装完成之后 |
创建一个会自动 clone 项目并预装依赖的环境
1 | curl -s -X POST https://api.qoder.com/api/v1/cloud/environments \ |
- 执行成功后会在沙箱内写入完成标记,本次 sandbox 内不会重复执行;沙箱被回收重建后会再次执行
- 脚本以非零状态退出会导致 Session 启动失败,错误响应中会带上 exit code 和 stderr 摘要
创建环境
创建一个数据科学专用环境
1 | curl -s -X POST https://api.qoder.com/api/v1/cloud/environments \ |
成功返回 200 OK:
1 | { |
查询环境
列出所有环境
1 | curl -s https://api.qoder.com/api/v1/cloud/environments \ |
获取单个环境详情
1 | curl -s https://api.qoder.com/api/v1/cloud/environments/env_ds456 \ |
更新环境
为已有环境添加新的依赖包
1 | curl -s -X POST https://api.qoder.com/api/v1/cloud/environments/env_ds456 \ |
- 更新环境不会影响已运行的 Session
- 新配置仅对后续创建的 Session 生效
环境选型建议
| 场景 | 推荐配置 |
|---|---|
| 通用开发 | default 环境,无需额外配置 |
| 数据分析 | 预装 pandas/numpy,并验证依赖源连通性 |
| 前端开发 | 预装 Node.js 生态工具,并验证 npm registry 连通性 |
| CI/CD 集成 | 预装所需 CLI,并在目标环境中验证依赖服务连通性 |
常见问题
Q: 环境创建后需要等待多久才能使用?
A: 环境创建后可立即用于创建 Session。实际的容器初始化(包括安装依赖)发生在 Session 启动时。
Q: 预装包的版本可以指定吗?
A: pip 和 npm 包支持版本指定,如 "pandas==2.1.0" 或 "[email protected]"。apt 包使用系统源的默认版本。
Q: 一个账号最多能创建多少个环境?
A: 无硬性限制,但建议按实际需求创建,避免管理混乱。建议通过命名规范分类。
容器参考
- 容器类型、网络策略和预装包参考
- 托管
cloudEnvironment 中可供 Agent 使用的容器环境。self_hostedEnvironment 的操作系统、工具和资源由自托管运行环境决定。 - 在托管环境中,可以稳定依赖以下行为:
- Agent 工具默认从
/data运行 config.packages支持安装 apt、pip 和 npm 依赖config.setup_script在依赖安装完成后执行- 容器文件系统是临时工作区,重要产物需要保存到外部存储
- Agent 工具默认从
运行时与操作系统
- 托管环境的标准镜像当前基于 Ubuntu 22.04 LTS
- CPU 架构、内核和容器引擎可能因运行环境而异
- 在 Session 中运行以下命令可以查看实际环境:
1 | cat /etc/os-release |
需要运行原生二进制时,请在 Session 中检测实际架构,或同时提供所需架构的构建产物。
当前标准镜像中的工具
- 当前标准镜像包含常用系统工具,例如
git、curl、wget、jq、vim、ssh、make、cmake、gcc、ripgrep、tar和unzip。 - 当前标准镜像还包含以下主要语言运行时:
| 运行时 | 当前主版本 |
|---|---|
| Python | 3.12 |
| Node.js | 20 |
| Go | 1.22 |
| Java | 21 |
| Ruby | 3.3 |
| PHP | 8.3 |
| Rust | stable |
预装工具及其补丁版本会随镜像升级而变化。任务依赖精确版本时,请在 Environment 中显式安装或固定版本,并在 Session 中检查:
1 | python --version |
工作目录
Agent 工具的默认工作目录是:
1 | /data |
- 托管环境中
WORK_DIR的值为/data,Bash 等工具未指定目录时也从/data执行 - 建议将仓库和工作文件放在
/data/workspace/等子目录中
上传文件和仓库资源时,请通过各资源的 mount_path 指定挂载位置;参见 文件上传与挂载。
安装额外软件
托管 cloud Environment 支持通过 config.packages 安装以下三类依赖:
| 字段 | 执行方式 |
|---|---|
apt |
apt-get install 系统包 |
pip |
pip install Python 包 |
npm |
npm install -g Node.js 包 |
1 | { |
- 如果初始化逻辑不能用
packages表达,可以使用config.setup_script - 脚本在依赖安装之后通过
/bin/bash -lc从/data执行,最大 64 KB,超时时间为 10 分钟
资源与超时
- 可用 CPU、内存、磁盘和执行超时取决于实际运行环境和服务配置
- 不要让任务依赖固定的资源规格
- 如果任务存在最低资源要求,请先在目标环境中验证
- 内存或磁盘耗尽时,进程可能被终止或写入失败
- 长任务还应考虑单个工具调用和单次 Turn 的超时
文件持久化
Turn(对话轮次):一次完整的交互循环 —
user.message→ Agent 思考执行 →agent.message→idle
同一容器内,前一个 Turn 写入的文件,下一个 Turn 可继续读取修改
- 同一个运行实例存续期间,文件通常会在 Turn 之间保留
- 容器临时存储在连续 24 小时未活跃后可能被回收
- 回收后再次唤醒 Session 时,平台会重新初始化容器并按需重新准备 Environment 与挂载资源;未保存到外部存储的文件可能丢失
- Session 归档或结束后,不应再依赖其容器文件继续存在
- 容器文件系统是临时工作区
- 需要长期保留的产物请通过 Files API、Git 仓库或其他外部存储保存
- 重要代码修改应及时 commit 并 push
1 | flowchart LR |
关键原则:容器文件系统是临时工作区,不是长期存储,所有重要数据应在产生时立即同步到外部存储
执行用户与环境变量
- 执行用户以及
HOME、USER、SHELL和LANG的值可能因运行环境或自定义镜像而异 - 不要让脚本依赖特定 UID,也不要假设系统目录始终可写
需要确认时,在 Session 中运行:
1 | id |
Session 的 environment_variables 以及关联 Vault 中的环境变量凭证会在工具调用时注入。不要在日志或任务输出中打印密钥。
IP 地址
- Cloud Agents 使用固定 IP 地址池发起 MCP 工具调用的出站连接
- 你可以将这些地址加入防火墙白名单,使 MCP Server 能正常接收来自 Cloud Agents 的流量
- 这些地址专用于 MCP 出站流量,不与沙箱公网出口网段复用,变更前会提前通知
出站 IP 地址(MCP)
Agent 调用 MCP 工具连接外部服务器时使用的固定出口 IP 网段:
1 | 8.216.144.48/28 |
防火墙配置
- 将上述 CIDR 加入你服务器的入站白名单,即可允许 Cloud Agents 的 MCP 调用到达
- 以上 IP 范围仅适用于 MCP 工具调用出口,不适用于沙箱容器的公网出口
FAQ
Q:这些 IP 会变吗?
A:不会在无预告情况下变更。如果新增或轮换 IP 段,我们会提前公告,留出足够时间供你更新防火墙规则。
Q:沙箱的出站连接也来自这些 IP 吗?
A:不是。沙箱公网出口使用另外的 IP 池。本页列出的地址专用于平台代 Agent 发起的 MCP 工具调用。






