Symphony 如何实现每个 Issue 独立工作区隔离?AI 智能体自主执行环境设计深度剖析
【免费下载链接】symphonySymphony turns project work into isolated, autonomous implementation runs, allowing teams to manage work instead of supervising coding agents.项目地址: https://gitcode.com/gh_mirrors/symphony7/symphony
Symphony 是一款将项目任务(Issue)转化为隔离、自主实施运行的 AI 智能体编排工具:它为每个 Issue 创建独立工作区隔离环境,让多个编码智能体并行执行而互不干扰。工程师只需管理工作,而不用监督每一个智能体。本文带你完整剖析 Symphony 的独立工作区隔离机制、安全防线与生命周期管理。
为什么每个 Issue 需要一个独立工作区?
🤔 想象这样的场景:你让 10 个 AI 智能体同时处理 10 个 Issue。如果它们共享同一个代码目录,会发生什么?
- 智能体 A 正在重构的文件,被智能体 B 改坏了
- 一个 Issue 的脏构建产物污染了另一个 Issue 的测试
- 两个智能体对同一个依赖版本各改各的,互相冲突
Symphony 的答案是:一个 Issue = 一个专属目录。每个智能体在自己的"房间"里工作,房间之间完全隔离,互不可见。这就是 SPEC.md 中定义的核心运行模型之一。
隔离目录是如何创建的?核心流程拆解
工作区的全部创建逻辑集中在 workspace.ex 模块中,入口是create_for_issue/2函数。它的工作流程可以概括为 4 步:
- 生成防冲突的目录名:通过
workspace_key函数,把 Issue 标识符(如MT-725)清洗成安全文件名。若标识符包含特殊字符(比如AB/12和AB-12清洗后可能撞名),Symphony 会自动追加一段 16 位的 SHA-256 短哈希,保证目录名永不冲突; - 拼接并规范化路径:在配置的工作区根目录下拼出完整路径,再经过 path_safety.ex 的
canonicalize处理,逐级解析软链接,得到真实的规范路径; - 创建目录:若目录已存在则复用,若是普通文件则先清除再重建;
- 运行
after_create钩子:这是"开箱即用"的关键——你可以在钩子里执行git clone,让全新工作区自动获得完整代码副本。若钩子失败,Symphony 会清理掉这个半成品目录,避免残留垃圾。
配置上只需在 WORKFLOW.md 中声明工作区根目录即可:
workspace: root: ~/code/symphony-workspaces hooks: after_create: | git clone --depth 1 https://example.com/your-org/your-repo.git .未配置时,根目录默认为系统临时目录下的symphony_workspaces(见 schema.ex 中的workspace.root默认值)。
安全防线:三重机制防止智能体"越界"
隔离不只是"各占一个目录",Symphony 还从三层保证了智能体无法逃出自己的工作区:
第一层:路径校验。validate_workspace_path会强制检查工作区必须位于根目录之内,且不能等于根目录本身;若发现软链接指向根目录之外,会直接以"符号链接逃逸"为由拒绝。
第二层:Codex 线程沙箱。Codex 的thread_sandbox默认值为workspace-write,即智能体只能对自己工作区有写权限,其他路径只读。
第三层:逐回合沙箱策略。turn_sandbox_policy默认为workspaceWrite类型,且writableRoots精确锁定到当前 Issue 的工作区——即使智能体在同一台机器上,它也被物理性地限制在自己的"房间"里,连读别的 Issue 工作区都做不到。
横向扩展:SSH Worker 上的远程工作区
单机不够用时,Symphony 支持把工作区创建到远程机器上。在 agent_runner.ex 中,每次运行会先选择一个 worker 主机(本地或配置的worker.ssh_hosts之一),然后:
- 本地执行:直接在根目录下
mkdir创建; - 远程执行:通过 SSH 下发一段脚本,在远端完成目录创建,并用一个特殊标记行回传"是否新建 + 真实路径",Symphony 解析后继续后续流程。
所有 SSH 操作都带超时保护,超时即终止,防止远端卡死拖垮整个编排器。配合agent.max_concurrent_agents与worker.max_concurrent_agents_per_host,你可以精确控制每台机器上的并发智能体数量。
完整生命周期:从创建到自动清理
工作区不是"建完就不管了",它围绕 Issue 的状态走完整生命周期,四个钩子覆盖每个关键节点:
| 钩子 | 触发时机 | 典型用途 |
|---|---|---|
after_create | 工作区首次创建后 | git clone拉取代码、安装依赖 |
before_run | 智能体启动前 | 环境检查、预热构建缓存 |
after_run | 智能体运行结束后 | 上传产物、备份日志 |
before_remove | 目录删除前 | 归档 diff、提取统计数据 |
其中after_create失败会阻断本次运行并清理现场;其余钩子失败只记录告警,不影响主流程。
清理环节由 orchestrator.ex 负责:当被认领的 Issue 进入终态(Done、Closed、Cancelled等),编排器会调用remove_recorded,只删除运行时记录的那个精确路径,且删除前仍要再次通过路径安全校验——即使记录被篡改指向别处,也不会误删。启动时还会做一次"终态工作区清扫",清掉上次异常退出遗留的目录。
快速上手:三步配置你的隔离环境
🚀 想在自己的项目里体验这套机制?
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/symphony7/symphony,进入elixir/目录; - 准备工作流文件:把仓库中的 WORKFLOW.md 拷到你的代码库,修改
workspace.root指向一个专用目录,并在hooks.after_create里写上你的git clone命令; - 启动 Symphony:按 elixir/README.md 说明用
mise安装依赖后执行./bin/symphony ./WORKFLOW.md,可选加--port启动 Web 面板实时观察各智能体的工作区状态。
小结
Symphony 的"每 Issue 独立工作区"设计,本质上是一套面向并行的智能体隔离方案:
- ✅一 Issue 一目录:防冲突、可追溯,目录名自带哈希防撞
- ✅纵深安全:路径规范化 + 沙箱策略双保险,智能体无法越界
- ✅钩子化生命周期:创建、运行、清理全程可定制
- ✅弹性扩展:本地与 SSH 远程工作区统一抽象,天然支持水平扩容
理解了这套机制,你就能把"监督智能体"升级为"管理工作"——这正是 Symphony 想要带来的工作方式变化。
【免费下载链接】symphonySymphony turns project work into isolated, autonomous implementation runs, allowing teams to manage work instead of supervising coding agents.项目地址: https://gitcode.com/gh_mirrors/symphony7/symphony
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考