大模型应用
需要把 Linear/任务看板中的开发任务交给隔离编码代理自…
在已有 OpenAI/Codex、Linear(或手动任务源)和 GitHub 凭据的团队中,将任务交给隔离代理自动实现、收集 CI/评审证据并落地 PR,而不是人工监督代理会话。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
需要把 Linear/任务看板中的开发任特定
解决思路
- 安装方式一:把提示词 `Implement Symphony according to the following spec: https://github.com/openai/symphony/blob/main/SPEC.md` 粘贴到 Claude Code、Cursor 或 Codex,让代理实现 Symphony。
- 安装方式二:使用 Elixir 参考实现:`git clone https://github.com/openai/symphony.git`,然后 `cd symphony/elixir`。
- 按 `elixir/README.md` 配置,或让代理执行:`Set up Symphony for my repository based on https://github.com/openai/symphony/blob/main/elixir/README.md`。
- 准备依赖:安装 Elixir + Mix;准备 OpenAI API key(供 Codex agent 使用);若使用 Linear 集成则准备 Linear API key;准备 GitHub token(用于 PR 操作)。
- 导出环境变量:`export OPENAI_API_KEY="sk-..."`、`export LINEAR_API_KEY="lin_api_..."`、`export GITHUB_TOKEN="ghp_..."`、`export SYMPHONY_REPO_PATH="/path/to/repo"`。
- 安装依赖:`cd elixir` 后执行 `mix deps.get`。
- 在 `elixir/config/config.exs` 中配置:`config :symphony, openai_api_key: System.get_env("OPENAI_API_KEY"), linear_api_key: System.get_env("LINEAR_API_KEY"), github_token: System.get_env("GITHUB_TOKEN"), repo_path: System.get_env("SYMPHONY_REPO_PATH", "./"), poll_interval_ms: 30_000, max_concurrent_agents: 3`。
- 运行 Symphony:`mix symphony.start`;开发时可用 `iex -S mix`。
- 确保每个任务获得隔离实现运行:每个任务使用全新 git 分支,代理只在该分支内操作,不同运行之间不共享状态,PR 合并前先收集 proof of work。
- 在 PR 被接受前收集 proof of work:CI/CD 流水线状态、PR 评审反馈、复杂度分析,以及可选的 walkthrough 视频。
- 启动 Symphony supervisor:在 `application.ex` 中使用 children 列表 `[Symphony.Supervisor]`,并调用 `Supervisor.start_link(children, strategy: :one_for_one)`。
- 定义 `Symphony.Task` struct:字段包括 `id`、`title`、`description`、`source`、`status`、`branch`、`pr_url`、`proof_of_work`;`status` 默认 `:pending`,`source` 可为 `:linear` 或 `:manual`,`status` 可为 `:pending | :running | :completed | :failed`。
- 实现 `Symphony.AgentRunner.run(task)`:生成分支名 `branch = "symphony/#{task.id}-#{slugify(task.title)}"`;按顺序执行 `Git.create_branch(branch)`、`Codex.implement(task, branch)`、`GitHub.open_pr(branch, task)`、`ProofOfWork.collect(pr_url)`;成功后把 task 更新为 `status: :completed, pr_url: pr_url, proof_of_work: proof`,失败返回 `{:error, reason}`。
- 实现 `slugify(title)`:将 title 转小写,用正则 `~r/[^a-z0-9]+/` 把非字母数字替换为 `-`,再 `String.trim("-")`。
- 实现 `Symphony.Linear.Poller` GenServer:从配置读取 `@poll_interval`;`init` 调用 `schedule_poll()`;收到 `:poll` 时调用 `Symphony.Linear.Client.fetch_todo_tasks()`;用 `processed_ids` 过滤已处理任务;对每个新任务调用 `Symphony.AgentRunner.run/1`;更新 `processed_ids`;出错时 `Logger.error`;最后 `schedule_poll()`。
- `schedule_poll` 使用 `Process.send_after(self(), :poll, @poll_interval)` 定时轮询。
- 实现 `Symphony.Linear.Client`:GraphQL endpoint 为 `https://api.linear.app/graphql`;查询 `issues(filter: { state: { name: { eq: "Todo" } } }) { nodes { id title description } }`;用 `HTTPoison.post` 发送 `Jason.encode!(%{query: query})`;headers 为 `Authorization: LINEAR_API_KEY` 与 `Content-Type: application/json`;200 时解析 `data.issues.nodes` 并映射为 `Symphony.Task`;否则返回 `{:error, reason}`。
- 实现 `Symphony.ProofOfWork.collect(pr_url)`:依次调用 `wait_for_ci(pr_url)`、`fetch_reviews(pr_url)`、`analyze_complexity(pr_url)`,返回包含 `ci_status`、`reviews`、`complexity`、`collected_at: DateTime.utc_now()` 的 map。
- 实现 `wait_for_ci(pr_url, retries 默认 30)`:若 CI 为 `:success` 则返回;若为 `:pending` 且 `retries > 0`,调用 `Process.sleep(60_000)` 后以 `retries - 1` 重试;其他状态直接返回;错误返回 `{:error, reason}`。`fetch_reviews` 调 `GitHub.get_pr_reviews(pr_url)`;`analyze_complexity` 调 `GitHub.get_pr_diff_complexity(pr_url)`。
- 按 SPEC.md 自定义实现时覆盖五部分:1) Task Source 轮询 Linear/GitHub/Jira 中特定状态的任务;2) Agent Invocation 用任务上下文调用 Codex 或其他代理;3) Isolation 每个 run 使用全新分支,尽量容器化;4) Proof of Work 合并前收集 CI、评审和分析;5) Landing 自动合并或交给工程师批准。
- 实现核心循环:`fetch_new_tasks(state.source)`;筛选 `status == :todo`;对每个任务用 `Task.async` 执行 `create_isolated_branch(task)`、`invoke_agent(task, branch)`、`collect_proof_of_work(branch)`、`present_for_review(task, proof)`;`Process.sleep(state.poll_interval)` 后递归 `symphony_loop`。
- 限制并发代理运行:实现 `Symphony.AgentPool` GenServer,`@max_concurrent 3`;`start_link` 初始状态 `%{running: 0, queue: []}`;`submit` 用 `GenServer.cast`;当 `running < @max_concurrent` 时调用 `spawn_agent(task)` 并把 `running + 1`;否则把任务加入 `queue`;收到 `{:agent_done, _result}` 且 queue 非空时取出 next 并 spawn 下一个;queue 空时把 `running - 1`;`spawn_agent` 中 `spawn` 执行 `Symphony.AgentRunner.run(task)` 并 `send(parent, {:agent_done, result})`。
- 手动注入任务(不使用 Linear 时):在 IEx 或 Mix task 中调用 `Symphony.AgentPool.submit(%Symphony.Task{id: "manual-001", title: "Add rate limiting to API", description: "Implement token bucket rate limiting on /api/v1 endpoints", source: :manual})`。
- 排查 agents 不启动:检查 `OPENAI_API_KEY` 是否已导出。
- 排查 Linear 任务未检测:更新 query filter,使其匹配你的看板 state name。
- 排查 PR 未打开:验证 `GITHUB_TOKEN` 是否有 `repo` scope 且仓库正确。
- 排查 CI 永不完成:增加 `wait_for_ci/2` 中的 `retries`。
- 排查并发运行过多:在配置中设置 `max_concurrent_agents`。
- 排查分支冲突:确保每次 run 的 task ID 唯一。
- 开启调试:在 `config/dev.exs` 中设置 `config :symphony, log_level: :debug`;或运行时执行 `Logger.put_module_level(Symphony.AgentRunner, :debug)` 和 `Logger.put_module_level(Symphony.Linear.Poller, :debug)`。
- 需要完整规范时查阅 `SPEC.md`;需要 Elixir 配置细节时查阅 `elixir/README.md`;需要方法论时查阅 Harness Engineering;许可证为 Apache 2.0 License。
适用边界 · 注意事项
- 不适用于没有 OpenAI API key/Codex、GitHub token,或无法让代理操作仓库与 PR 的团队。
- 不适用于尚未采用 harness engineering、缺少自动化 CI/测试/PR 流程的代码库。
- 不适用于必须人工监督代理会话、不能接受自动开 PR 或自动落地的场景。