ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Symphony 入门:用 WORKFLOW.md 把 Linear 任务变成自主编码 Agent 的调度器

Symphony 入门:用 WORKFLOW.md 把 Linear 任务变成自主编码 Agent 的调度器 1. 从 Linear 工单到自主编码 AgentSymphony 调度器到底解决什么问题如果你已经在用 Linear 管理开发任务大概率经历过这样的循环看板上躺着一堆 Todo你手动挑一个打开编辑器把 issue 描述复制给 Codex 或 Claude Code等它跑完再手动改状态、提 PR。任务一多光是「派活」这件事就消耗掉大量注意力。Symphony 想做的事情很直接把「派活」这一步自动化。它是一个长跑型调度服务定期轮询 Linear 看板上的可执行任务为每个 issue 创建独立 workspace在里面启动 Codex Agent 执行Agent 完成后自动提交 PR 并回写 Linear 状态。你只需要把任务放进看板剩下的调度、隔离、执行、跟进由 Symphony 接管。适合谁用三类人值得关注一是团队已经用 Linear 做任务管理想让常规开发任务自动流转二是想研究多 Agent 并发调度的工程实践三是愿意自己调整 prompt 策略和沙箱边界把 Agent 当成「按工单交付的团队成员」而不是「一次性脚本」。核心检索词先明确Symphony 是 OpenAI 开源的多 Agent 任务调度服务WORKFLOW.md 是它的编排契约文件Linear 是任务输入源Codex 是执行层。这四个词串起来就是本文要跑通的最小闭环。我试过把几个常规重构任务丢进去跑整体感受是Symphony 本身不做代码修改它只做调度和看板读取具体怎么改 ticket、怎么发评论、怎么提 PR全部写在 WORKFLOW.md 的 prompt 模板里由 Codex Agent 自己执行。这个设计意味着——你的 prompt 质量直接决定 Agent 的产出质量。Symphony 用 Elixir/OTP 编写参考实现包含 Orchestrator调度器、Issue Tracker ClientLinear 适配、Workspace Managerper-issue 目录、Agent RunnerCodex app-server四个核心组件。它解决的核心问题是把 issue 执行变成可重复的 daemon 流程在每个 issue 独立的 workspace 中隔离 Agent 执行团队把 Agent prompt 规则版本化在 WORKFLOW.md 里并提供足够多的可观测性来同时运营多个并发 Agent。需要提前说明的是Symphony 目前是低层次的工程预览版主要供在受信环境中测试使用。它本身不做 sandbox 控制依赖 Codex 加操作系统层面的安全机制。部署前需要确认 Linear API Key 的权限范围、Codex app-server 的审批策略、workspace 目录的隔离是否充分。2. 前置准备Linear API Key、Codex 环境与 WORKFLOW.md 编排契约在跑通最小调度闭环之前需要把三样东西准备好Linear 侧的 API Key 和自定义状态、Codex 侧的 app-server 环境、以及仓库根目录的 WORKFLOW.md 文件。这一章把每一步拆开讲清楚。2.1 申请 Linear Personal API Key进入 Linear 的 Settings → Security access → Personal API keys创建一个新的 key。创建后立刻复制保存页面刷新后就看不到了。设置环境变量export LINEAR_API_KEYlin_api_***这个 key 会被 Symphony 用来轮询看板、读取 issue 详情、回写状态。权限范围建议只给必要的项目读写权限不要用管理员级别的 key。2.2 配置 Linear 自定义状态Symphony 的参考实现依赖几个非标准的 Linear 状态需要在 Team Settings → Workflow 中手动创建状态名作用ReworkAgent 自评未通过需要重做Human Review等待人工审核Merging准备合入这三个状态是 Symphony 调度逻辑的锚点。如果缺失Agent 完成任务后无法正确流转issue 会卡在中间态。创建时注意状态类型要选对Rework 和 Human Review 属于 Started 类别Merging 也归入 Started。2.3 准备 Codex app-server 环境Symphony 通过codex app-server命令启动 Agent。确认本地 Codex CLI 已安装且能正常运行codex --version codex app-server --help如果 Codex 需要走统一的 API 网关来管理多模型账号和用量可以在环境变量里配置 Base URL 和 Key。比如用 TaoToken 作为统一接入层时Codex 的配置可以写成# ~/.codex/config.toml model gpt-5 model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY然后在 shell 里导出 keyexport TAOTOKEN_API_KEYsk-***这样 Codex app-server 启动时会自动读取这个 provider 配置。如果你同时跑多个 Agent统一网关的好处是 Key 轮换和用量统计都在一处管理不用每个 Agent 单独配账号。2.4 编写 WORKFLOW.mdWORKFLOW.md 是 Symphony 的编排契约用 YAML front matter 配置运行时Markdown body 作为 Codex Agent 的 prompt 模板。在仓库根目录创建这个文件最小可用配置如下--- tracker: kind: linear project_slug: your-project-slug api_key: $LINEAR_API_KEY workspace: root: ~/code/workspaces hooks: after_create: | git clone gitgithub.com:your-org/your-repo.git . cd your-repo npm install agent: max_concurrent_agents: 5 max_turns: 20 codex: command: codex app-server approval_policy: on-request thread_sandbox: workspace-write --- You are working on a Linear issue {{ issue.identifier }}. Title: {{ issue.title }} Body: {{ issue.description }} Follow the repository conventions in README.md and CONTRIBUTING.md. When done, commit your changes, push a branch, and open a PR. Update the Linear issue status to Human Review.关键配置项对照字段作用建议值tracker.kind看板类型lineartracker.project_slugLinear 项目标识从项目 URL 提取workspace.rootworkspace 根目录~/code/workspaceshooks.after_create创建 workspace 后执行git clone 装依赖agent.max_concurrent_agents最大并发 Agent 数从 3 开始试agent.max_turns单次会话最大轮次20codex.approval_policy审批策略on-requestcodex.thread_sandbox沙箱模式workspace-writeproject_slug的获取方式在 Linear 里右键项目 → 复制 URLURL 中类似linear.app/your-org/project/your-project-slug的最后一段就是 slug。环境变量支持$VAR形式会被自动替换。~会自动展开为 home 目录。所以api_key: $LINEAR_API_KEY和root: ~/code/workspaces都能正常工作。hooks.after_create支持任意 shell 命令常用于 git clone 拉代码、装依赖、创建配置文件。注意这个 hook 在每个 issue 的 workspace 创建后执行一次所以 clone 的是完整仓库副本Agent 在里面改代码不会影响主仓库。3. 可复制配置WORKFLOW.md 完整片段与 Linear 触发设置这一章给出可以直接复制粘贴的完整配置包括 WORKFLOW.md 的进阶版本、Linear 侧的触发条件设置、以及 Codex 的 provider 配置。目标是让你复制完就能启动。3.1 完整 WORKFLOW.md 配置--- tracker: kind: linear project_slug: agent-sandbox api_key: $LINEAR_API_KEY active_states: - Todo - Rework terminal_states: - Done - Closed - Cancelled - Duplicate workspace: root: $SYMPHONY_WORKSPACE_ROOT hooks: after_create: | git clone gitgithub.com:your-org/your-repo.git . cd your-repo npm ci cp .env.example .env before_run: | git fetch origin git checkout main git pull --ff-only agent: max_concurrent_agents: 5 max_turns: 20 retry: max_attempts: 3 backoff: exponential codex: command: $CODEX_BIN --config model\gpt-5\ app-server approval_policy: on-request thread_sandbox: workspace-write --- You are an autonomous coding agent working on a Linear issue. Issue: {{ issue.identifier }} Title: {{ issue.title }} Description: {{ issue.description }} ## Your task 1. Read the issue description carefully. 2. Explore the repository to understand the codebase. 3. Implement the changes described in the issue. 4. Run the test suite and fix any failures. 5. Commit with a descriptive message referencing {{ issue.identifier }}. 6. Push a branch named symphony/{{ issue.identifier }}. 7. Open a pull request against main. 8. Update the Linear issue status to Human Review. ## Constraints - Do not modify files outside the repository root. - Do not install global packages. - If you need clarification, set the issue status to Rework and explain why.这个配置比最小版本多了几个关键点active_states明确哪些状态的任务会被派发terminal_states定义终态进入这些状态后 Symphony 会停止 Agent 并清理 workspacebefore_runhook 在每次 Agent 运行前同步主分支retry配置瞬时失败的重试策略。3.2 Linear 侧触发设置Linear 不需要额外安装插件Symphony 通过 API 轮询读取。但有几个设置需要确认第一项目 slug 要和 WORKFLOW.md 里的project_slug一致。第二issue 的初始状态要是Todo或在active_states列表里。第三issue 描述要足够具体因为 Agent 完全依赖描述来理解任务。一个适合 Agent 执行的 issue 描述模板## 背景 用户反馈登录页在移动端布局错乱。 ## 期望行为 登录表单在 375px 宽度下应该垂直排列按钮占满宽度。 ## 验收标准 - [ ] 375px 宽度下表单垂直排列 - [ ] 按钮宽度 100% - [ ] 现有测试全部通过 - [ ] 新增一个移动端布局的测试用例 ## 相关文件 - src/pages/Login.tsx - src/styles/login.css描述越结构化Agent 的产出越可控。模糊的「优化一下登录页」会让 Agent 自由发挥结果往往不是你想要的。3.3 Codex provider 配置如果 Codex 需要走统一网关在~/.codex/config.toml里配置model gpt-5 model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api responses三件套要写全Base URL 指向https://taotoken.net/apiKey 通过环境变量TAOTOKEN_API_KEY注入Model ID 在model字段指定。这样 Codex app-server 启动时会用这个 provider 发请求。3.4 启动 Symphonygit clone https://github.com/openai/symphony cd symphony/elixir mise trust mise install mise exec -- mix setup mise exec -- mix build mise exec -- ./bin/symphony /path/to/your/WORKFLOW.md --port 4000--port 4000会启动 Phoenix LiveView Dashboard可以在浏览器里实时观察所有活跃 run。--logs-root可以指定日志目录默认是./log。启动后服务会开始轮询 Linear按 WORKFLOW.md 的策略派发任务。你可以在 Dashboard 的/api/v1/state端点看到当前调度状态的 JSON。4. 验证请求一次任务从创建到 Agent 回写的完整闭环配置就绪后需要跑一次完整闭环来验证调度器工作正常。这一章用一个具体任务演示从 Linear 创建 issue 到 Agent 提交 PR 的全过程。4.1 创建测试 issue在 Linear 的agent-sandbox项目里创建一个新 issue标题Add health check endpoint to API server状态Todo描述## 背景 API server 需要一个健康检查端点供负载均衡器探活。 ## 期望行为 GET /health 返回 200body 为 {status:ok}。 ## 验收标准 - [ ] GET /health 返回 200 - [ ] body 为 {status:ok} - [ ] 新增测试用例 - [ ] 现有测试全部通过 ## 相关文件 - src/server.ts - src/routes/创建后不要手动改状态让 Symphony 自己发现。4.2 观察 Symphony 派发在终端里看 Symphony 的日志输出或者打开 Dashboardcurl http://localhost:4000/api/v1/state | jq你会看到类似这样的状态{ active_runs: [ { issue_identifier: AGENT-42, status: running, workspace: /home/user/code/workspaces/AGENT-42, started_at: 2025-01-15T10:23:45Z } ], blocked: [], completed: [] }Symphony 的轮询节奏会先发现这个 Todo issue然后创建 workspace 目录执行after_createhook 克隆仓库再启动 Codex app-server 执行 prompt 模板。4.3 查看 Agent 执行过程进入 workspace 目录可以看到 Agent 的工作现场cd ~/code/workspaces/AGENT-42 git log --oneline -5 git branch -aAgent 会在里面创建分支、修改文件、跑测试、提交。如果配置了--portDashboard 的 LiveView 页面会实时显示 Agent 的每一轮对话和工具调用。4.4 验证回写结果Agent 完成后会做三件事提交 PR、更新 Linear issue 状态为Human Review、在 issue 里留评论。回到 Linear 看板你应该看到issue 状态从Todo变成Human Reviewissue 里有一条评论包含 PR 链接GitHub 上有一个新 PR分支名类似symphony/AGENT-42PR 的内容应该包含/health端点的实现和对应的测试用例。如果一切正常这个最小调度闭环就跑通了。4.5 人工审核与合入在 Linear 里审核 Agent 的产出。如果满意把状态改成Merging然后手动合入 PR。如果不满意把状态改成ReworkSymphony 会重新派发这个 issueAgent 会在同一个 workspace 里继续修改。当 issue 进入Done、Closed、Cancelled、Duplicate这些终态时Symphony 会自动停止该 issue 的 Agent 并清理 workspace。5. 常见报错排查401、local proxy failed、reading choices 与 OAuth跑通过程中大概率会遇到几个典型报错。这一章按报错信息对照排查每个都给出具体原因和修复方式。5.1 401 Unauthorized{error:Unauthorized,message:Invalid API key}原因通常是LINEAR_API_KEY没设置或设置错了。检查echo $LINEAR_API_KEY如果为空重新导出。如果 key 正确但仍然 401检查 WORKFLOW.md 里的api_key字段是否写成了$LINEAR_API_KEY带美元符号才会被环境变量替换。另外确认 key 没有过期Linear 的 Personal API Key 可以设置过期时间。如果是 Codex 侧的 401检查TAOTOKEN_API_KEY是否正确导出以及~/.codex/config.toml里的env_key字段名是否和实际环境变量名一致。5.2 local proxy failedError: local proxy failed to connect这个报错通常出现在 Codex app-server 启动阶段。原因是 Codex 尝试连接的 API 端点不可达。排查步骤第一确认base_url配置正确。如果走统一网关应该是https://taotoken.net/api不要多加路径后缀。第二确认网络能访问该端点curl -I https://taotoken.net/api第三检查~/.codex/config.toml里的wire_api字段。有些 provider 需要responses有些需要chat配置错了会导致连接失败。5.3 reading choices 相关报错Error reading choices: unexpected end of JSON input这个报错说明 Codex 收到了 API 响应但响应格式不符合预期。常见原因是wire_api配置和实际 API 不匹配。如果用的是 responses 风格的 APIwire_api要设为responses如果是 chat completions 风格设为chat。另一个可能原因是模型 ID 写错了。检查model字段是否和 provider 支持的模型名一致。比如gpt-5和gpt-5-codex是不同的模型 ID写错会导致响应异常。5.4 OAuth 相关报错Error: OAuth token expired如果 Codex 配置的是 OAuth 认证而不是 API Keytoken 过期会报这个错。解决方式是重新走 OAuth 流程或者改用 API Key 认证。在~/.codex/config.toml里把env_key指向一个有效的 API Key 环境变量避免 OAuth 过期问题。5.5 Agent 卡在 blocked 状态如果 Dashboard 显示某个 issue 处于blocked说明 Codex 报告需要操作员输入或审批确认。检查codex.approval_policy设置策略行为untrusted所有操作都需要审批on-failure失败时审批on-requestAgent 主动请求时审批never从不审批reject拒绝所有审批请求如果不想被频繁打断可以设为on-request或never。但never意味着 Agent 可以自由执行所有操作需要确保沙箱隔离充分。重启 orchestrator 后blocked map 会被清空issue 可以重新成为派发候选。5.6 workspace 创建失败Error: failed to create workspace: directory existsSymphony 为每个 issue 创建独立目录如果目录已存在会报错。手动清理rm -rf ~/code/workspaces/AGENT-42然后重启 Symphony。注意清理前确认里面没有未提交的改动。6. 把调度器接入你的工作流从最小闭环到多 Agent 并发跑通最小闭环后下一步是把它接入日常开发流程。这一章讲几个实用技巧和扩展方向。6.1 从单任务到多 Agent 并发max_concurrent_agents控制同时运行的 Agent 数量。建议从 3 开始观察系统资源占用和 API 速率限制再逐步调高。每个 Agent 是一个独立的 Codex app-server 进程会消耗内存和 API 配额。并发跑多个 Agent 时Dashboard 的价值就体现出来了。/api/v1/state返回所有活跃 run 的状态/api/v1/issue_identifier返回单个 issue 的详情/api/v1/refresh可以手动触发刷新。6.2 prompt 模板的迭代WORKFLOW.md 的 Markdown body 是 Agent 的 prompt 模板支持{{ issue.identifier }}、{{ issue.title }}、{{ issue.description }}这些变量。你可以根据团队规范不断迭代这个模板。几个实用技巧在模板里明确要求 Agent 跑测试、要求提交信息引用 issue 编号、要求 PR 描述包含变更摘要。这些约束会显著提升产出质量。6.3 自定义 Hook 的用法hooks.after_create和hooks.before_run支持任意 shell 命令。除了 git clone 和装依赖还可以用来复制环境配置文件启动本地数据库或缓存服务拉取最新的主分支代码运行代码生成脚本注意 hook 里的命令失败会导致 workspace 创建失败所以命令要幂等且容错。6.4 安全边界Symphony 本身不做 sandbox 控制依赖 Codex 和操作系统层面的安全机制。部署前确认Linear API Key 的权限范围最小化Codex 的thread_sandbox设为workspace-write而不是danger-full-accessworkspace 目录和主仓库隔离Git 仓库的访问控制到位approval_policy设为never时 Agent 可以自由执行命令只建议在受信环境中使用。6.5 用统一网关管理多 Agent 的模型账号当并发 Agent 数量上去后模型账号管理会变成一件麻烦事。每个 Agent 都要配 Key用量分散在各个账号里成本不好统计。用 TaoToken 这类统一网关可以把 Base URL、Key、Model ID 三件套集中管理Codex 配置里只写一个 providerKey 轮换和用量统计都在网关侧完成。配置方式就是前面 3.3 节给的~/.codex/config.toml片段把base_url指向https://taotoken.net/apienv_key指向统一的环境变量。这样多个 Agent 共享一套接入配置新增 Agent 时不用重复配账号。如果你想让多个 Agent 共享一套 API Key或者想统一管理 Claude、GPT、Gemini 等多模型的用量和计费可以看看 TaoToken 的 Coding Plan它把模型账号管理、API Key 轮换、用量统计这些基础设施一次性解决。Symphony 跑多 Agent 任务时配套用它来管模型账号团队成本会更可控。需要自己管理 Key 的话可以在控制台创建和管理 API Key想先验证模型连通性可以直接在模型对话里试一条请求接入细节参考接入文档。
返回列表