基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
技术实践2026-09-12 04:35

OpenAI 自托管执行器只向外拨号,所以我们的停止按钮是个队列

dev.to · AI#OpenAI#Agents API#安全架构
Editor brief · 编辑速览

OpenAI Agents API 的自托管模式中,executor 是纯 Outbound WebSocket 客户端,无法被外部主动终止;作者通过维护待处理任务队列实现了可靠的停止机制。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

OpenAI 于 9 月 10 日向公众开放了 Agents API。值得细读的不是概述页面,而是自托管沙箱指南——它描述了当你拒绝 OpenAI 的托管容器时,什么代码会跑在你的硬件上。你在自己的环境里运行 codex exec-server。它"运行 shell 命令、读写文件,并使用本地 MCP 服务器"。它"使用环境 ID 和一个受限 API key 向 API 注册",然后"通过 WebSocket 连接来接收命令并返回结果"。然后还有一句:"所有连接都是外向的。如果连接断开,executor 会重新连接。"

这句话说明了很多。OpenAI 侧不会在你的机器上打开任何入站连接。executor 是一个不断拨回主站的客户端,整套测试框架想在你的机器上执行的每个操作都经由这条连接。每个 session 拥有自己的环境 ID,且需要各自的 executor。executor 持有的 key"仅允许连接环境",文档对此的解释很直白:"agent 生成的代码可以读取 executor 的 key。"

文档没有描述的是如何停止。概述页面走完了四个步骤:创建 session、分配任务、通过流或 webhook 跟踪进度,然后继续下一个任务或给当前任务提供指导。但其中没有 stop 调用。session 被定义为"一个持续运行的 agent 实例,负责处理任务并响应输入"。这个运行在你硬件上的持久化实体如何被告知终结,则留给了监管 executor 的上层来回答。

shell.online 的架构形态完全相同——一个只向外拨号的本地进程——所以 stop 问题同样需要我们自己来回答。今天合并到 main 的 PR #88,把答案放到了看板视图和 session 详情页上,此前这两处都没有这个功能,只在 sessions 列表表里存在。

谁有权限按 Stop

shell.online 的一个 session 是某台机器上的一个进程,它服务自己的本地 socket 并持有一个独立的终端 key。账户服务转发的是一个它无法解密且没有任何路径进入机器的密封 session 密码。要让一台已签入的机器从浏览器端可访问,整台机器要运行一个 daemon。daemon.go 顶部的注释解释了它存在的原因:"shell.online 的其余部分没有常驻进程。" daemon 拒绝启动,除非该机器是通过 shell login --allow-remote-start 签入的,且每台机器只会运行一个 daemon。

在此之前,Stop 只存在于表里。没有任何 stop 按钮,session 页面既没有 stop 也没有 remove——而在手机上,用户实际面对的恰恰是这个页面。PR #88 两处都加上了,但受到与 session-view.ts 中已有的相同两条规则约束:

canStop:你拥有这个 session,且 session 有 device id。满足这两个条件才有资格。被分配到一个 session 使你可以在里面输入内容。成为组织管理员使你可以整理列表。但两者都不能让你杀掉别人笔记本上的进程。服务端注释直接说了:"组织角色永远不应悄然扩展为远程进程管理。"

canRemove:所有者,或组织 owner 或管理员。按钮的 tooltip 载明了规则的其余部分:"从列表中移除。机器本身不受影响。"

Stop 实际做了什么

按下 Stop 向 /api/commands 发送一个 kind 为 kill 的 POST。服务端 app.ts 随后按顺序做了五件事:

检查调用者是否拥有该 session。其他人收到 403:"只有 session 所有者可以停止其进程。"

在请求机器之前先写入"stopped"审计条目。注释写道:"队列即决策;进程是否还活着并收到了它,是关于机器的事实。"

从 session 记录的 device 而非浏览器持有的副本中解析目标机器。如果该设备行被重新登录替换了,它会跟随机器转移到当前持有它的那个设备。

如果 daemon 过去 15 秒(AGENT_ONLINE_MS)没有轮询过,返回 409,说明 stop 无法送达。不为不在监听的机器排队任何命令。

否则将命令入队并返回 202。

接下来是机器侧。daemon 每两秒请求一次 GET /api/agent/commands(agent_loop.go 中的 agentPollInterval)。当它认领一个 kill 时,以子进程方式运行 shell kill <id>。该命令向 session 的本地控制 socket 写入"stop"。session 进程向其进程组发送 SIGTERM,等待两秒,然后发送 SIGKILL。daemon 将完成状态发回服务端,服务端在收到确认后关闭 session 行——而不是等 session 自己报告退出,因为 session 可能在机器解除关联之前就启动了,已经撤销了凭证,永远无法再报告任何事情。

最坏情况下,那是两秒的轮询等待加上 SIGTERM 到 SIGKILL 之间的两秒。session 页面在点击后 1.5 秒重新加载,旁边那个计时器的注释坦言这一行"很快就会跟上"。延迟是单向出站设计的代价。它换来的是 OpenAI executor 同样在买的东西:没有入站端口、没有服务能伸进机器,以及当没有人监听时在源头拒绝 stop——而不是让它永远排在队列里。从按钮到信号的全路径可以在 shell.online 仓库的 app.ts、agent_loop.go 和 session_unix.go 中从头到尾读完。

往下一层看,同样的权衡

Pilot Protocol 以不同的方式回答了可达性这半个问题,因为它处在不同的层面。我们的 IETF 草案及其开源实现为 agent 提供了一个永久虚拟地址和在 A2A、MCP 等应用协议之下的双向信任模型,通过 STUN、NAT 打洞和为对称 NAT 准备的 relay 回退来实现。这个 peer 是否可以访问那个 agent,是由信任关系在数据包送达之前就决定的,而不是由 daemon 轮询的队列来决定。可达性与向进程发送信号的权限是两个独立的事实,而今天的 PR 处理的是第二个。

OpenAI 的 executor 和我们的 daemon 都是只向外拨号然后等待指令的进程。这使得 stop 成为一个消息而非信号,而消息有所有者、有路由、有队列、有延迟。今天的改动只是确保这条消息可以从手机用户正站在的那个页面发送出去。

Original source

本文由 AI 翻译整理,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
幂等性:防止大问题的 API 小概念
下一篇
AI Agent 大规模利用 PaperCut 漏洞攻陷 395 家机构

资讯速览

dev.to · AI · 2026-09-12 04:35

AI 评分 8.0 / 10

相关标签

#OpenAI#Agents API#安全架构

继续阅读

  • AI 搜索引擎如何理解网站:RAG 到引用的技术链路
  • 幂等性:防止大问题的 API 小概念
  • AI Agent 大规模利用 PaperCut 漏洞攻陷 395 家机构
  • Copilot 代码审查新增自动关闭评论与智能提交信息
  • n8n详解流程编排:执行模型、可观测性与生产挑战