从模型到 Agent:OpenAI 的 Runtime 架构揭秘
TL;DR
OpenAI 公开了其 Agent Runtime 的底层架构:Responses API + Shell Tool + Hosted Containers。这不是简单的功能组合,而是一个完整的安全、可扩展、生产级的 Agent 执行环境。本文深度解析这一架构的设计原理、安全机制和规模化挑战。
📋 本文结构
- 为什么需要 Agent Runtime?
- 架构概览:三层设计
- Responses API:Agent 的神经系统
- Shell Tool:安全的执行边界
- Hosted Containers:隔离与扩展
- 安全模型:纵深防御
- 规模化挑战与解决方案
- 对开发者的启示
为什么需要 Agent Runtime?
大语言模型(LLM)可以生成代码,但生成代码和执行代码是两回事。
从模型到 Agent 的鸿沟
| 能力 | LLM 模型 | 生产级 Agent |
|---|---|---|
| 代码生成 | ✅ 可以生成 | ✅ 可以生成 |
| 代码执行 | ❌ 不能执行 | ✅ 需要执行环境 |
| 文件操作 | ❌ 不能操作 | ✅ 需要读写文件 |
| 工具调用 | ❌ 不能调用 | ✅ 需要调用 API |
| 状态管理 | ❌ 无状态 | ✅ 需要会话状态 |
| 安全隔离 | ❌ 无关 | ✅ 必须隔离 |
核心问题:如何让 AI 安全、可控、可扩展地执行代码?
现有方案的局限
方案 1:本地执行
- 问题:安全风险高,AI 可能执行恶意代码
- 问题:环境不一致,”在我机器上能跑”
- 问题:难以扩展,受限于单机资源
方案 2:云服务器
- 问题:启动慢,不适合交互式场景
- 问题:成本高,需要长期运行
- 问题:资源浪费,大部分时间空闲
方案 3:无服务器函数
- 问题:冷启动延迟
- 问题:状态管理复杂
- 问题:执行时间限制
OpenAI 的解决方案:Hosted Containers——快速启动的隔离执行环境。
架构概览:三层设计
OpenAI 的 Agent Runtime 采用三层架构:
┌─────────────────────────────────────────┐
│ Agent Runtime Stack │
├─────────────────────────────────────────┤
│ Layer 3: Hosted Containers │
│ - 隔离执行环境 │
│ - 资源限制与监控 │
│ - 快速启动/销毁 │
├─────────────────────────────────────────┤
│ Layer 2: Shell Tool │
│ - 命令执行接口 │
│ - 文件系统操作 │
│ - 输出捕获与流式传输 │
├─────────────────────────────────────────┤
│ Layer 1: Responses API │
│ - 结构化输出 │
│ - 工具调用协议 │
│ - 状态与会话管理 │
└─────────────────────────────────────────┘
设计哲学
每一层都有明确的职责边界:
| 层级 | 职责 | 关键设计 |
|---|---|---|
| Responses API | 智能编排 | 让模型决定”做什么” |
| Shell Tool | 执行接口 | 定义”怎么做”的标准 |
| Containers | 资源提供 | 安全、隔离的”在哪里做” |
Responses API:Agent 的神经系统
Responses API 是 Agent 的决策中心——它负责理解任务、规划步骤、调用工具。
核心功能
1. 结构化输出
不是简单的文本生成,而是结构化的行动指令:
{
"reasoning": "需要分析代码库中的依赖漏洞",
"actions": [
{
"tool": "shell",
"command": "find . -name 'requirements.txt'",
"purpose": "定位依赖文件"
},
{
"tool": "shell",
"command": "pip-audit -r requirements.txt",
"purpose": "扫描已知漏洞"
}
]
}
2. 工具调用协议
标准化的工具调用接口:
# 定义可用工具
tools = [
{
"type": "shell",
"description": "执行 shell 命令",
"parameters": {
"command": {"type": "string"},
"timeout": {"type": "integer", "default": 60}
}
},
{
"type": "file",
"description": "读写文件",
"parameters": {
"operation": {"enum": ["read", "write"]},
"path": {"type": "string"},
"content": {"type": "string"} # for write
}
}
]
# 模型决定调用哪个工具
response = responses_api.create(
messages=user_request,
tools=tools,
tool_choice="auto"
)
3. 状态与会话管理
Agent 需要”记忆”之前的操作:
会话 1
├── 步骤 1: 读取文件 A
├── 步骤 2: 修改文件 A
├── 步骤 3: 运行测试
└── 状态:测试通过
会话 2(新会话)
├── 步骤 1: 读取文件 B
...
关键设计:会话隔离 + 持久化状态。
Shell Tool:安全的执行边界
Shell Tool 是 Agent 与执行环境的接口层。它不是一个简单的 os.system(),而是一个受控的执行网关。
功能边界
┌─────────────────────────────────────────┐
│ Shell Tool Interface │
├─────────────────────────────────────────┤
│ 允许的操作: │
│ - 执行 shell 命令 │
│ - 读写文件(指定目录) │
│ - 进程管理(启动、停止、查询) │
│ - 网络请求(受限) │
├─────────────────────────────────────────┤
│ 禁止的操作: │
│ - 访问容器外文件系统 │
│ - 特权命令(sudo, mount等) │
│ - 对外网络连接(除非白名单) │
│ - 资源超限操作 │
└─────────────────────────────────────────┘
安全设计
1. 命令白名单
不是所有命令都能执行:
ALLOWED_COMMANDS = [
"ls", "cat", "grep", "find",
"python", "node", "npm", "pip",
"git", "make", "pytest",
# ...
]
BLOCKED_COMMANDS = [
"sudo", "rm -rf /", "mkfs",
"curl http://evil.com", # 未授权网络
# ...
]
2. 资源限制
RESOURCE_LIMITS = {
"cpu": "1 core", # CPU 限制
"memory": "512MB", # 内存限制
"disk": "1GB", # 磁盘限制
"timeout": 300, # 执行超时(秒)
"network": False # 默认禁用网络
}
3. 输出捕获与流式传输
Agent 需要实时看到执行结果:
# 流式输出
def execute_streaming(command):
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
for line in iter(process.stdout.readline, ''):
yield {"type": "stdout", "data": line}
for line in iter(process.stderr.readline, ''):
yield {"type": "stderr", "data": line}
Hosted Containers:隔离与扩展
Hosted Containers 是 Agent 的执行沙箱——每个 Agent 会话运行在独立的容器中。
容器生命周期
用户请求
↓
调度器分配容器
↓
[冷启动 ~500ms] 或 [热容器复用]
↓
容器执行 Agent 任务
↓
任务完成
↓
[保留 ~5分钟] 或 [立即销毁]
↓
资源回收
冷启动优化
容器启动慢是主要挑战。OpenAI 的解决方案:
1. 预置镜像
常用环境预先构建:
# Python 环境镜像
FROM python:3.11-slim
RUN pip install numpy pandas pytest pip-audit
RUN apt-get update && apt-get install -y git
WORKDIR /workspace
2. 热容器池
预先启动的容器池:
HOT_CONTAINER_POOL = {
"python": [container_1, container_2, ...], # 预热的 Python 环境
"node": [container_3, container_4, ...], # 预热的 Node 环境
# ...
}
# 快速分配
def get_container(env_type):
if HOT_CONTAINER_POOL[env_type]:
return HOT_CONTAINER_POOL[env_type].pop()
else:
return create_new_container(env_type) # 冷启动
3. 分层文件系统
只读基础层 + 可写工作层:
┌─────────────────────────────────────────┐
│ 可写层(工作目录) │
│ - 用户代码 │
│ - 执行结果 │
│ - 临时文件 │
├─────────────────────────────────────────┤
│ 只读层(基础环境) │
│ - Python/Node 运行时 │
│ - 常用库 │
│ - 工具链 │
├─────────────────────────────────────────┤
│ 只读层(操作系统) │
│ - Debian/Ubuntu 基础系统 │
└─────────────────────────────────────────┘
安全隔离
1. 命名空间隔离
# PID 命名空间 - 进程隔离
unshare --pid --fork --mount-proc /bin/bash
# 网络命名空间 - 网络隔离
unshare --net /bin/bash
# 文件系统命名空间 - 文件隔离
chroot /container/rootfs /bin/bash
2. Cgroups 资源限制
# CPU 限制
cgroup_create -g cpu:/agent_123
echo 100000 > /sys/fs/cgroup/cpu/agent_123/cpu.cfs_quota_us
# 内存限制
cgroup_create -g memory:/agent_123
echo 536870912 > /sys/fs/cgroup/memory/agent_123/memory.limit_in_bytes # 512MB
3. Seccomp 系统调用过滤
# 只允许安全的系统调用
ALLOWED_SYSCALLS = [
"read", "write", "open", "close",
"execve", "clone", "exit",
# ... 其他安全调用
]
BLOCKED_SYSCALLS = [
"mount", "umount", "reboot",
"setuid", "setgid", "setreuid",
# ... 危险调用
]
安全模型:纵深防御
OpenAI 的 Agent Runtime 采用纵深防御策略——多层安全措施,即使一层被突破,还有其他层保护。
安全层次
┌─────────────────────────────────────────┐
│ Layer 7: 应用层审计 │
│ - 操作日志记录 │
│ - 异常行为检测 │
├─────────────────────────────────────────┤
│ Layer 6: API 层控制 │
│ - 请求限流 │
│ - 权限验证 │
├─────────────────────────────────────────┤
│ Layer 5: 工具层限制 │
│ - 命令白名单 │
│ - 参数校验 │
├─────────────────────────────────────────┤
│ Layer 4: 容器层隔离 │
│ - 命名空间隔离 │
│ - 文件系统隔离 │
├─────────────────────────────────────────┤
│ Layer 3: 系统层限制 │
│ - Seccomp 过滤 │
│ - Capabilities 限制 │
├─────────────────────────────────────────┤
│ Layer 2: 资源层控制 │
│ - Cgroups 限制 │
│ - 网络隔离 │
├─────────────────────────────────────────┤
│ Layer 1: 基础设施层 │
│ - 虚拟机隔离 │
│ - 物理安全 │
└─────────────────────────────────────────┘
威胁模型与防护
| 威胁 | 防护层级 | 防护措施 |
|---|---|---|
| 恶意代码执行 | L4-L6 | 容器隔离 + 命令白名单 |
| 资源耗尽攻击 | L2, L6 | Cgroups + 请求限流 |
| 数据泄露 | L4, L5 | 文件系统隔离 + 网络限制 |
| 权限提升 | L3, L4 | Seccomp + 命名空间 |
| 供应链攻击 | L7 | 操作审计 + 异常检测 |
规模化挑战与解决方案
Agent Runtime 的规模化面临独特挑战:
挑战 1:冷启动延迟
问题:新容器启动需要 1-5 秒,用户体验差。
解决方案:
- 热容器池(预先启动)
- 镜像优化(只包含必要依赖)
- 懒加载(按需加载大型依赖)
挑战 2:资源成本
问题:每个 Agent 需要独立容器,成本高。
解决方案:
- 容器复用(同一会话的多个请求)
- 自动扩缩容(根据负载调整池大小)
- 休眠机制(空闲容器快速冻结)
挑战 3:状态管理
问题:Agent 需要持久化状态(文件、数据库)。
解决方案:
- 挂载卷(持久化存储)
- 状态快照(定期备份)
- 会话恢复(从快照恢复)
挑战 4:网络隔离与连通
问题:Agent 需要访问特定外部服务,但必须隔离风险。
解决方案:
- 出口代理(控制出站流量)
- 域名白名单(只允许特定域名)
- 内部服务网格(安全的内部通信)
对开发者的启示
OpenAI 的 Agent Runtime 架构对构建 AI-Native 应用的开发者有重要启示:
1. 分层设计的重要性
不要将智能、执行、资源混在一起。清晰的层次边界让系统更易维护、更安全。
2. 安全是架构问题,不是功能问题
纵深防御需要在架构设计的每个层级考虑,不能事后补丁。
3. 性能与安全的权衡
热容器池牺牲了一些资源效率,换取了用户体验。这种权衡需要根据场景调整。
4. 标准化的价值
Responses API 定义了标准化的工具调用协议,让不同 Agent 可以互操作。
结论:Agent 基础设施的成熟
OpenAI 公开的 Agent Runtime 架构标志着一个重要趋势:Agent 基础设施正在成熟。
从简单的 API 调用,到完整的执行环境,再到安全、可扩展、生产级的 Runtime——这是 AI 应用从 demo 走向 production 的关键一步。
对于开发者来说,这意味着:
- 可以更专注于业务逻辑,而非基础设施
- 可以构建更复杂、更强大的 Agent 应用
- 需要在设计时就考虑安全、隔离、可扩展性
Agent 时代的基础设施战争刚刚开始,OpenAI 已经展示了一个可能的蓝图。
参考与延伸阅读
- Equipping the Responses API with a Computer Environment - OpenAI Engineering
- Linux Containers (LXC) - 容器技术基础
- Seccomp BPF - 系统调用过滤
- Cgroups - 资源控制
本文基于 OpenAI Engineering 博客文章分析。
💬 评论
💡 使用 GitHub 账号登录 即可参与讨论