TODO: 这是另一个优秀的项目,借鉴他的设计优点,改进ccloop:
AI Dispatcher
一个轻量的 GitHub Issue 驱动 worker。
它负责拿任务、启动 AI、把结果回写到 GitHub。
它解决什么问题
把这段流程自动化:
Issue -> AI 执行 -> PR 或报告 / paused / stuck
适合单仓库或少量仓库、仍然保留人工 review 的场景。
当前模型
ai-todo:待处理
ai-running:已有 worker 正在处理
ai-blocked:依赖未满足,暂不启动 worker
ai-paused:中断但有进展,仍由原 worker 续做
ai-review:PR 已创建,等待人工 review
ai-stuck:没形成稳定结果,需要人工处理
任务归属和抢占历史写到 issue comments 里,业务状态只放在 labels 上。
任务类型用额外 label 表示:
ai-task:code:代码任务,默认类型,完成后必须创建 PR
ai-task:test:测试 / E2E 验证任务,不改代码,不创建 PR,完成后回写测试报告
ai-task:investigate:调查分析任务,不改代码,不创建 PR,完成后回写调查报告
ai-task:maintain:维护任务,不启动 AI;由 dispatcher 同步已有 PR 分支
如果不加任务类型 label,按 ai-task:code 处理。
ai-paused:已经形成了可续做的分支进度,默认由原 owner 继续
ai-blocked:dispatcher 只做只读检查,不 claim、不切分支、不启动 AI
ai-stuck:这一轮没有形成可靠续做点,需要人工判断是否重开
ai-review:如果有人在 issue 里继续追问,原 owner 会自动续做并更新原 PR
claim 方式
当前用的是“comment 事件流 + 状态标签”:
worker 看到 ai-todo、属于自己的 ai-paused,或属于自己的 ai-review 追问
先 append 一条 machine-readable claim comment
回读 issue comments
按 comment 顺序确定胜者
胜者把 issue 切到 ai-running
loser 写 abandon comment 并退出
这不是原子锁,但比节点优先级和节点标签都更干净。
如果 issue 声明了依赖,claim 前会先做 dependency preflight:
部署需要什么
最小运行集是 3 个文件:
ai-dispatcher.sh
/.env
/.ai-dispatcher-policy.env
如果想省事初始化 worker,再加:
init-worker.sh
旧的 install.sh 仍可用,但新项目优先用 init-worker.sh,它会一次性处理 state dir、.env、项目 policy、GitHub labels、.claude-account 和 cron。
./init-worker.sh
--repo owner/repo
--workdir /path/to/project
--worker-id worker-a
--claude-account account-a
--base-branch main
常用参数:
--instance name:多实例并存时指定 state dir 后缀,默认用 repo 名
--state-dir path:显式指定 state dir
--worker-cmd cmd:默认优先使用 ~/.local/bin/claude-account,否则用 claude
--clone-url url:workdir 不存在时自动 clone
--no-cron:只生成配置,不安装定时任务
--dry-run:只打印计划,不写文件、不访问 GitHub
如果是接管已有 worker,一定要传原来的 --state-dir 或匹配的 --instance,否则会创建一个新的并行实例。
运行配置
/.env
WORKER_ID=worker-a
CLAUDE_CMD=claude
REPO=owner/repo
WORKDIR=/path/to/project
MAX_TURNS=200
可选:私有仓库附件下载优先使用本实例 token;未设置时回退到 gh auth token
GH_TOKEN=
可选:引用 issue 上下文默认先用 LLM 生成摘要,失败才降级机械摘要
REFERENCE_SUMMARY_MODE=llm
如果本机跑 Codex,可以把 CLAUDE_CMD 指到 codex-worker.sh。
WORKER_ID=worker-b
CLAUDE_CMD=/path/to/dispatcher/codex-worker.sh
REPO=owner/repo
WORKDIR=/path/to/project
MAX_TURNS=200
默认 state-dir 是 ~/.ai-dispatcher。如果一台机器要并行监控多个仓库,就给每个实例单独目录,例如:
~/.ai-dispatcher-project-a
~/.ai-dispatcher-project-b
对应 cron 里用 AI_DISPATCHER_STATE_DIR=/path/to/state-dir 区分实例。
Claude 账号并发
dispatcher 会按 Claude 账号做全局并发控制:同一个 .claude-account 同时只允许一个 worker 领取并执行 Claude 任务;拿不到账号锁时,本轮直接跳过,不改 issue label。不同 Claude 账号可以并行。
默认锁目录是 ~/.ai-dispatcher-account-locks。如果项目使用 Codex worker,或任务类型是 ai-task:maintain,不会占用 Claude 账号锁。必要时可在实例 .env 中设置:
CLAUDE_ACCOUNT_LOCK_ENABLED=true
CLAUDE_ACCOUNT_LOCK_DIR="$HOME/.ai-dispatcher-account-locks"
项目策略
项目根目录放 .ai-dispatcher-policy.env,常用字段:
BASE_BRANCH=main
TEST_COMMAND="npm test"
可选:维护任务同步 PR 后运行;留空则只同步并 push,不做本地验证
MAINTENANCE_TEST_COMMAND="npm test"
COMMIT_GUIDANCE="commit message 简洁说明改了什么"
PR_TITLE_GUIDANCE="PR title 格式:fix/feat/refactor: 简短描述 (#ISSUE)"
PR_BODY_GUIDANCE="PR body 包含改动摘要和测试结果"
可以从 policy.example.env 复制。
规则边界
dispatcher 代码只处理通用调度能力:claim、续做、状态流转、报告回写、附件提取、多实例运行。
仓库或业务特有规则不要写死进 dispatcher,优先放到项目根目录的 .ai-dispatcher-policy.env,必要时再通过 PROMPT_APPEND_FILE 补充长规则。
生产调查、只读约束、脱敏要求、某类 issue 的优先调查路径,默认都属于项目规则,不属于通用调度层。
如果一条规则只对某个仓库成立,就应放在该仓库的 policy / prompt 文件里;只有跨项目稳定复用后,才考虑上升到 dispatcher 本身。
报告渲染约束
报告型任务可以使用 Mermaid 辅助说明流程、依赖、状态流转或系统边界。dispatcher 会在回写 issue 前做轻量预检,目标是提前拦截 GitHub 常见渲染失败,而不是替 Mermaid 做完整语法解析。
建议写法:
flowchart TD
A["输入"]
B["处理「引用」"]
C["输出"]
A --> B --> C
Loading
注意:
节点 ID 只用英文、数字、下划线。
节点文字优先写成 A["文字"]。
节点文字和边标签里不要使用 ASCII 双引号;需要引用时用中文引号「」。
不要把整份报告包在 ```markdown 里;只有真正的 Mermaid、代码或日志片段才用 fenced block。
需求收敛
需求明确、验收标准清楚、一次 PR 能收完的任务,直接用 ai-task:code。
目标不清楚、范围偏大、实现路径不止一种、需要先调查现状的任务,先用 ai-task:investigate。
最稳的默认流程是:先收敛,再执行。不要让 AI 一边猜需求、一边改代码。
AI 可以给出拆分建议,但默认不自动创建多个子 issue;先由人工确认,再决定是否拆票。
如果调查报告包含可解析的后续 issue 候选,可以在原 issue 评论回复确认指令,由 dispatcher 创建。
如果一条规则只是在“需求不清楚时先调查、先收敛”,这仍然属于项目规则或工作流约定,不需要改 dispatcher 代码。
任务类型
Issue 写法规则
写 issue 时,只写“任务意图”和“验收标准”。不要重复写 worker 已经默认知道的执行命令。
默认不用写:
不用写“先 checkout / 拉 main / 新建分支 / 提交 / 开 PR”。
不用写“不要提交 token / 不要提交临时产物 / 不要提交附件输出”。
不用写“跑测试 / 写 PR 描述 / 回写结果”,除非这个仓库有特殊命令或特殊格式。
不用写账号、token、内部路径、登录态、机器名;这些放在执行机本地配置、项目 policy 或 skill 里。
不用把同一套业务规则复制到每个 issue;稳定规则放到 .ai-dispatcher-policy.env 的 PROMPT_APPEND_TEXT 或 PROMPT_APPEND_FILE。
建议固定结构:
目标
一句话说明要达成什么。
背景
只写这次任务必须知道的上下文;可以引用 #123。
范围
验收
可检查的完成条件
需要跑的特殊验证,如果没有特殊要求可省略
代码型 issue 尽量短:
目标
修复外部回调重复处理导致的重复写入。
背景
参考 #123 的调查结论。
范围
验收
同一个 webhook event 重放不会重复写入
相关测试通过
测试 / E2E issue:
目标
在 staging 环境验证新用户注册到关键业务动作的完整链路。
重点
验收
issue 评论中给出测试报告
如果发现 bug,列出建议创建的后续 issue
调查型 issue:
目标
评估某方案是否适合当前阶段。
需要回答
解决什么问题
有哪些方案
推荐哪个,为什么
风险和下一步
维护型 issue 只用于机械同步已有 PR。遇到内容冲突不会自动解决,应改开普通代码型 issue。
代码任务:
labels: ai-todo, ai-task:code
测试或 E2E 任务:
labels: ai-todo, ai-task:test
调查任务:
labels: ai-todo, ai-task:investigate
维护任务:
labels: ai-todo, ai-task:maintain
ai-task:test 和 ai-task:investigate 只产出 issue 报告。
如果发现需要改代码,报告里说明问题,另开代码型 issue。
dispatcher 会对报告做最低质量校验。输出太短、缺少结构化章节、没有明确结论、没有证据 / 执行结果 / 风险说明,或者只有“Report complete / No further action required”这类空泛完成声明,会被标记为 ai-stuck,不会进入 ai-review。结论章节不要求固定标题,## 一句话结论、## 三句话结论、## 核心结论、## 结论摘要、## 推荐方案、## Findings 等都可以。
ai-task:maintain 不会创建 fresh 分支,也不会调用大模型。它只执行明确声明的机械维护动作,例如同步已有 PR 分支。
ai-task:investigate 最好输出结构化收敛结果,至少包含:
目标理解
已知事实
缺失信息
风险与边界
可选方案
推荐方案
建议拆分
下一步建议
GitHub Issue / PR 会直接渲染 Mermaid。报告遇到流程、状态流转、依赖关系、时序链路、系统边界时,建议补一张小图辅助理解,例如 flowchart、sequence diagram 或 state diagram。图只用于降低理解成本,不要替代结论、证据和文字说明。
报告型任务不能把核心调查、E2E 或长耗时验证放到后台后提前结束。必须等待核心命令完成,并把结果写入最终报告。
其中“建议拆分”只回答:是否值得拆、如果拆建议拆成哪几个任务、每个任务的完成定义是什么。默认不要自动开一串新 issue。
涉及支付、法律、政策、价格、平台条款、第三方服务能力或时效性信息时,调查报告必须访问官方来源核验,并列出官方 URL、访问日期和核验结论。无法访问或无法确认时,必须明确标注“未核验”或“无法确认”,不能仅凭模型记忆下结论。
如果报告末尾有“建议创建的后续 Issue”,候选项应使用固定标题 ## 建议创建的后续 Issue,并写成可见 checkbox 编号列表。编号对应隐藏结构化候选的数组顺序。
建议创建的后续 Issue
隐藏结构化块必须放在整份报告最后;引用清单、附录、备注等内容都放在隐藏块之前。JSON 必须是严格合法 JSON:body 里的换行写成 \n,双引号写成 ",不要放未转义的控制字符。
如果隐藏 JSON 损坏,dispatcher 会尝试从可见 checkbox 标题兜底创建 issue。兜底创建只保留标题、任务类型和来源链接,不包含完整正文,所以仍应优先保证隐藏 JSON 合法。
文字回复仍保留为兜底:
确认创建后续 issue:全部
确认创建后续 issue:1,3
确认创建后续 issue:只创建代码修复
issue 1 创建吧
后续 issue 全部创建吧
dispatcher 会根据报告中的隐藏结构化候选创建新 issue,并自动加上 ai-todo 和对应任务类型 label。创建结果会回写到原 issue。
报告会按 Markdown 直接渲染到 issue。dispatcher 负责统一回写;如果 worker 已经直接贴了报告,dispatcher 只记录执行状态,避免重复。
报告会默认脱敏,不应输出账号、token、验证码、数据库连接、内部 IP、内部文件路径或可直接复用的登录/攻击命令。
维护任务
如果要把已有 PR 分支同步到最新 main,不要发普通代码任务。使用 ai-task:maintain 和隐藏块:
默认推荐 strategy: "merge":
不需要 force push
保留 PR 分支历史
GitHub PR 会自动更新
对 dispatcher 自动执行最安全
也支持显式 rebase:
rebase 会使用 git push --force-with-lease,只在你明确需要线性历史时使用。
维护任务行为:
claim 成功后读取 PR head branch,不创建 ai/issue-N 新分支。
merge 成功后 push PR 分支;如果配置了 MAINTENANCE_TEST_COMMAND,会运行本地验证。
同步成功且验证通过:issue -> ai-review。
同步冲突:中止 merge/rebase,issue -> ai-stuck,评论列出冲突文件。
push 失败或验证失败:issue -> ai-stuck,评论写明原因和输出。
maintenance 是机械操作,失败后不会自动重试;需要人工处理,或新建普通代码任务解决冲突。
PR 不存在、PR 已关闭、隐藏块格式错误:issue -> ai-stuck。
依赖门禁
如果一个 issue 必须等其他 issue 或 PR 完成后才能做,不要只写自然语言说明。正文里加一个隐藏结构化块:
写 issue 时,正文可见部分仍然建议给人看:
依赖
PR #95 合并后再做
#91 完成决策后再做
dispatcher 只读取隐藏块;普通 #95、#91 引用只会作为上下文,不会阻塞任务。
支持的依赖:
{"type":"pr","number":95,"state":"merged"}:PR 必须已合并
{"type":"pr","number":95,"state":"closed"}:PR 已关闭或已合并
{"type":"issue","number":91,"state":"closed"}:issue 必须关闭
{"type":"issue","number":91,"state":"review"}:issue 必须带 ai-review
{"type":"issue","number":91,"state":"done"}:issue 关闭,或带完成标签
行为:
依赖未满足:从 ai-todo 切到 ai-blocked,评论列出阻塞项,不启动 worker。
依赖满足:后续 cron 自动从 ai-blocked 切回 ai-todo。
隐藏块格式错误:也会进入 ai-blocked,评论提示 JSON 格式问题。
跨仓库依赖暂不自动判断;需要先人工确认,或拆到同仓库 issue 里表达。
项目策略可配置完成标签:
DEPENDENCY_DONE_LABELS="ai-review,ai-done,done"
DEPENDENCY_CLOSED_IS_DONE=true
DEPENDENCY_PR_MERGED_IS_DONE=true
附加材料
issue 里如果有图片、PDF 或附件链接,dispatcher 会下载并提取可读内容,附加到 prompt。
图片会尽量做 OCR;PDF 会尽量抽文本。
引用 Issue
如果 issue 正文或评论里明确写了同仓库引用,例如 #728 或 GitHub issue 链接,dispatcher 会把被引用 issue 的摘要加入上下文。
规则很轻:
只抓同仓库 issue
最多抓 5 个
只抓一层,不递归展开
包含标题、状态、labels、body 摘要、最近评论和附件链接
摘要默认由 LLM 基于被引用 issue 的完整正文和评论生成,并按 issue 更新时间缓存;LLM 摘要失败时才降级为明确标注的机械摘要
附件链接从原始全文提取,不依赖摘要文本,避免摘要遗漏图片或 PDF
Skill 使用
可以在 issue 里写明要使用某个 AI skill 或工作模式,例如:
请按 xxx-skill 的模式做一次 E2E 验证。
issue 里只放任务目标、非敏感上下文和附件。
账号、token、内部路径、登录态等敏感信息应放在执行机本地配置或 skill 本地文件里,不要写进 issue。
结果回写
代码任务成功产出 PR:ai-review
代码任务续做已有 PR 分支并能定位到对应 PR:ai-review
维护任务成功同步 PR:ai-review
代码任务在 ai-review 中续做但没有新增 commit:仍保持 ai-review,并把 worker 的诊断/说明回写到 issue
测试 / 调查任务成功产出报告:ai-review
中断但有 commit:ai-paused
维护任务同步冲突、push 失败或验证失败:ai-stuck
没有形成稳定产物:ai-stuck
同时会写两类记录:
issue comments:claim / abandon / state / result
~/.ai-dispatcher/runs/*.json:本地结构化 run metadata
claim / abandon / state 这类机器事件在 GitHub 上显示为一行简短说明,完整协议数据放在隐藏 HTML comment 里。旧版纯 JSON comment 仍然兼容。
工作区残留
dispatcher 领取新任务前会检查工作区:
只有未跟踪文件:先打包到 ~/.ai-dispatcher/artifacts/dirty-worktree-backups/,再清理并继续领取。
有 tracked 文件修改:不自动处理,暂停领取,避免丢失有效代码。
任务结束后如果只残留未跟踪文件,也会同样备份并清理,避免卡住后续任务。
worker 异常退出时如果留下 tracked 修改,会保存 patch/stash 到 dirty-worktree-backups/,清空工作区,并在 issue 里回写备份位置。
手工重开
如果某个 issue 需要重新开始,直接把它改回 ai-todo。
这适用于:
ai-stuck 想重开
ai-review 想重新来一轮
中间状态异常后需要重新排队
如果当前是 ai-paused,而你想保留原 owner 续做,就不要改回 ai-todo。
手动测试
AI_DISPATCHER_STATE_DIR=~/.ai-dispatcher-my-project /path/to/dispatcher/ai-dispatcher.sh
tail -f ~/.ai-dispatcher-my-project/dispatcher.log
ls ~/.ai-dispatcher-my-project/runs/
当前边界
不是中心调度
不是原子锁
ai-paused 不自动切换 owner
PR 创建后仍然需要人工 review 和最终关闭 issue
TODO: 这是另一个优秀的项目,借鉴他的设计优点,改进ccloop:
AI Dispatcher
一个轻量的 GitHub Issue 驱动 worker。
它负责拿任务、启动 AI、把结果回写到 GitHub。
它解决什么问题
把这段流程自动化:
Issue -> AI 执行 -> PR 或报告 / paused / stuck
适合单仓库或少量仓库、仍然保留人工 review 的场景。
当前模型
ai-todo:待处理
ai-running:已有 worker 正在处理
ai-blocked:依赖未满足,暂不启动 worker
ai-paused:中断但有进展,仍由原 worker 续做
ai-review:PR 已创建,等待人工 review
ai-stuck:没形成稳定结果,需要人工处理
任务归属和抢占历史写到 issue comments 里,业务状态只放在 labels 上。
任务类型用额外 label 表示:
ai-task:code:代码任务,默认类型,完成后必须创建 PR
ai-task:test:测试 / E2E 验证任务,不改代码,不创建 PR,完成后回写测试报告
ai-task:investigate:调查分析任务,不改代码,不创建 PR,完成后回写调查报告
ai-task:maintain:维护任务,不启动 AI;由 dispatcher 同步已有 PR 分支
如果不加任务类型 label,按 ai-task:code 处理。
ai-paused:已经形成了可续做的分支进度,默认由原 owner 继续
ai-blocked:dispatcher 只做只读检查,不 claim、不切分支、不启动 AI
ai-stuck:这一轮没有形成可靠续做点,需要人工判断是否重开
ai-review:如果有人在 issue 里继续追问,原 owner 会自动续做并更新原 PR
claim 方式
当前用的是“comment 事件流 + 状态标签”:
worker 看到 ai-todo、属于自己的 ai-paused,或属于自己的 ai-review 追问
先 append 一条 machine-readable claim comment
回读 issue comments
按 comment 顺序确定胜者
胜者把 issue 切到 ai-running
loser 写 abandon comment 并退出
这不是原子锁,但比节点优先级和节点标签都更干净。
如果 issue 声明了依赖,claim 前会先做 dependency preflight:
部署需要什么
最小运行集是 3 个文件:
ai-dispatcher.sh
/.env
/.ai-dispatcher-policy.env
如果想省事初始化 worker,再加:
init-worker.sh
旧的 install.sh 仍可用,但新项目优先用 init-worker.sh,它会一次性处理 state dir、.env、项目 policy、GitHub labels、.claude-account 和 cron。
./init-worker.sh
--repo owner/repo
--workdir /path/to/project
--worker-id worker-a
--claude-account account-a
--base-branch main
常用参数:
--instance name:多实例并存时指定 state dir 后缀,默认用 repo 名
--state-dir path:显式指定 state dir
--worker-cmd cmd:默认优先使用 ~/.local/bin/claude-account,否则用 claude
--clone-url url:workdir 不存在时自动 clone
--no-cron:只生成配置,不安装定时任务
--dry-run:只打印计划,不写文件、不访问 GitHub
如果是接管已有 worker,一定要传原来的 --state-dir 或匹配的 --instance,否则会创建一个新的并行实例。
运行配置
/.env
WORKER_ID=worker-a
CLAUDE_CMD=claude
REPO=owner/repo
WORKDIR=/path/to/project
MAX_TURNS=200
可选:私有仓库附件下载优先使用本实例 token;未设置时回退到 gh auth token
GH_TOKEN=
可选:引用 issue 上下文默认先用 LLM 生成摘要,失败才降级机械摘要
REFERENCE_SUMMARY_MODE=llm
如果本机跑 Codex,可以把 CLAUDE_CMD 指到 codex-worker.sh。
WORKER_ID=worker-b
CLAUDE_CMD=/path/to/dispatcher/codex-worker.sh
REPO=owner/repo
WORKDIR=/path/to/project
MAX_TURNS=200
默认 state-dir 是 ~/.ai-dispatcher。如果一台机器要并行监控多个仓库,就给每个实例单独目录,例如:
~/.ai-dispatcher-project-a
~/.ai-dispatcher-project-b
对应 cron 里用 AI_DISPATCHER_STATE_DIR=/path/to/state-dir 区分实例。
Claude 账号并发
dispatcher 会按 Claude 账号做全局并发控制:同一个 .claude-account 同时只允许一个 worker 领取并执行 Claude 任务;拿不到账号锁时,本轮直接跳过,不改 issue label。不同 Claude 账号可以并行。
默认锁目录是 ~/.ai-dispatcher-account-locks。如果项目使用 Codex worker,或任务类型是 ai-task:maintain,不会占用 Claude 账号锁。必要时可在实例 .env 中设置:
CLAUDE_ACCOUNT_LOCK_ENABLED=true
CLAUDE_ACCOUNT_LOCK_DIR="$HOME/.ai-dispatcher-account-locks"
项目策略
项目根目录放 .ai-dispatcher-policy.env,常用字段:
BASE_BRANCH=main
TEST_COMMAND="npm test"
可选:维护任务同步 PR 后运行;留空则只同步并 push,不做本地验证
MAINTENANCE_TEST_COMMAND="npm test"
COMMIT_GUIDANCE="commit message 简洁说明改了什么"
PR_TITLE_GUIDANCE="PR title 格式:fix/feat/refactor: 简短描述 (#ISSUE)"
PR_BODY_GUIDANCE="PR body 包含改动摘要和测试结果"
可以从 policy.example.env 复制。
规则边界
dispatcher 代码只处理通用调度能力:claim、续做、状态流转、报告回写、附件提取、多实例运行。
仓库或业务特有规则不要写死进 dispatcher,优先放到项目根目录的 .ai-dispatcher-policy.env,必要时再通过 PROMPT_APPEND_FILE 补充长规则。
生产调查、只读约束、脱敏要求、某类 issue 的优先调查路径,默认都属于项目规则,不属于通用调度层。
如果一条规则只对某个仓库成立,就应放在该仓库的 policy / prompt 文件里;只有跨项目稳定复用后,才考虑上升到 dispatcher 本身。
报告渲染约束
报告型任务可以使用 Mermaid 辅助说明流程、依赖、状态流转或系统边界。dispatcher 会在回写 issue 前做轻量预检,目标是提前拦截 GitHub 常见渲染失败,而不是替 Mermaid 做完整语法解析。
建议写法:
注意:
节点 ID 只用英文、数字、下划线。
节点文字优先写成 A["文字"]。
节点文字和边标签里不要使用 ASCII 双引号;需要引用时用中文引号「」。
不要把整份报告包在 ```markdown 里;只有真正的 Mermaid、代码或日志片段才用 fenced block。
需求收敛
需求明确、验收标准清楚、一次 PR 能收完的任务,直接用 ai-task:code。
目标不清楚、范围偏大、实现路径不止一种、需要先调查现状的任务,先用 ai-task:investigate。
最稳的默认流程是:先收敛,再执行。不要让 AI 一边猜需求、一边改代码。
AI 可以给出拆分建议,但默认不自动创建多个子 issue;先由人工确认,再决定是否拆票。
如果调查报告包含可解析的后续 issue 候选,可以在原 issue 评论回复确认指令,由 dispatcher 创建。
如果一条规则只是在“需求不清楚时先调查、先收敛”,这仍然属于项目规则或工作流约定,不需要改 dispatcher 代码。
任务类型
Issue 写法规则
写 issue 时,只写“任务意图”和“验收标准”。不要重复写 worker 已经默认知道的执行命令。
默认不用写:
不用写“先 checkout / 拉 main / 新建分支 / 提交 / 开 PR”。
不用写“不要提交 token / 不要提交临时产物 / 不要提交附件输出”。
不用写“跑测试 / 写 PR 描述 / 回写结果”,除非这个仓库有特殊命令或特殊格式。
不用写账号、token、内部路径、登录态、机器名;这些放在执行机本地配置、项目 policy 或 skill 里。
不用把同一套业务规则复制到每个 issue;稳定规则放到 .ai-dispatcher-policy.env 的 PROMPT_APPEND_TEXT 或 PROMPT_APPEND_FILE。
建议固定结构:
目标
一句话说明要达成什么。
背景
只写这次任务必须知道的上下文;可以引用 #123。
范围
验收
代码型 issue 尽量短:
目标
修复外部回调重复处理导致的重复写入。
背景
参考 #123 的调查结论。
范围
验收
测试 / E2E issue:
目标
在 staging 环境验证新用户注册到关键业务动作的完整链路。
重点
验收
调查型 issue:
目标
评估某方案是否适合当前阶段。
需要回答
维护型 issue 只用于机械同步已有 PR。遇到内容冲突不会自动解决,应改开普通代码型 issue。
代码任务:
labels: ai-todo, ai-task:code
测试或 E2E 任务:
labels: ai-todo, ai-task:test
调查任务:
labels: ai-todo, ai-task:investigate
维护任务:
labels: ai-todo, ai-task:maintain
ai-task:test 和 ai-task:investigate 只产出 issue 报告。
如果发现需要改代码,报告里说明问题,另开代码型 issue。
dispatcher 会对报告做最低质量校验。输出太短、缺少结构化章节、没有明确结论、没有证据 / 执行结果 / 风险说明,或者只有“Report complete / No further action required”这类空泛完成声明,会被标记为 ai-stuck,不会进入 ai-review。结论章节不要求固定标题,## 一句话结论、## 三句话结论、## 核心结论、## 结论摘要、## 推荐方案、## Findings 等都可以。
ai-task:maintain 不会创建 fresh 分支,也不会调用大模型。它只执行明确声明的机械维护动作,例如同步已有 PR 分支。
ai-task:investigate 最好输出结构化收敛结果,至少包含:
目标理解
已知事实
缺失信息
风险与边界
可选方案
推荐方案
建议拆分
下一步建议
GitHub Issue / PR 会直接渲染 Mermaid。报告遇到流程、状态流转、依赖关系、时序链路、系统边界时,建议补一张小图辅助理解,例如 flowchart、sequence diagram 或 state diagram。图只用于降低理解成本,不要替代结论、证据和文字说明。
报告型任务不能把核心调查、E2E 或长耗时验证放到后台后提前结束。必须等待核心命令完成,并把结果写入最终报告。
其中“建议拆分”只回答:是否值得拆、如果拆建议拆成哪几个任务、每个任务的完成定义是什么。默认不要自动开一串新 issue。
涉及支付、法律、政策、价格、平台条款、第三方服务能力或时效性信息时,调查报告必须访问官方来源核验,并列出官方 URL、访问日期和核验结论。无法访问或无法确认时,必须明确标注“未核验”或“无法确认”,不能仅凭模型记忆下结论。
如果报告末尾有“建议创建的后续 Issue”,候选项应使用固定标题 ## 建议创建的后续 Issue,并写成可见 checkbox 编号列表。编号对应隐藏结构化候选的数组顺序。
建议创建的后续 Issue
首选确认方式:勾选要创建的项,然后给这条报告评论添加 🚀 reaction。dispatcher 会读取被勾选的编号并创建对应 issue。
隐藏结构化块必须放在整份报告最后;引用清单、附录、备注等内容都放在隐藏块之前。JSON 必须是严格合法 JSON:body 里的换行写成 \n,双引号写成 ",不要放未转义的控制字符。
如果隐藏 JSON 损坏,dispatcher 会尝试从可见 checkbox 标题兜底创建 issue。兜底创建只保留标题、任务类型和来源链接,不包含完整正文,所以仍应优先保证隐藏 JSON 合法。
文字回复仍保留为兜底:
确认创建后续 issue:全部
确认创建后续 issue:1,3
确认创建后续 issue:只创建代码修复
issue 1 创建吧
后续 issue 全部创建吧
dispatcher 会根据报告中的隐藏结构化候选创建新 issue,并自动加上 ai-todo 和对应任务类型 label。创建结果会回写到原 issue。
报告会按 Markdown 直接渲染到 issue。dispatcher 负责统一回写;如果 worker 已经直接贴了报告,dispatcher 只记录执行状态,避免重复。
报告会默认脱敏,不应输出账号、token、验证码、数据库连接、内部 IP、内部文件路径或可直接复用的登录/攻击命令。
维护任务
如果要把已有 PR 分支同步到最新 main,不要发普通代码任务。使用 ai-task:maintain 和隐藏块:
默认推荐 strategy: "merge":
不需要 force push
保留 PR 分支历史
GitHub PR 会自动更新
对 dispatcher 自动执行最安全
也支持显式 rebase:
rebase 会使用 git push --force-with-lease,只在你明确需要线性历史时使用。
维护任务行为:
claim 成功后读取 PR head branch,不创建 ai/issue-N 新分支。
merge 成功后 push PR 分支;如果配置了 MAINTENANCE_TEST_COMMAND,会运行本地验证。
同步成功且验证通过:issue -> ai-review。
同步冲突:中止 merge/rebase,issue -> ai-stuck,评论列出冲突文件。
push 失败或验证失败:issue -> ai-stuck,评论写明原因和输出。
maintenance 是机械操作,失败后不会自动重试;需要人工处理,或新建普通代码任务解决冲突。
PR 不存在、PR 已关闭、隐藏块格式错误:issue -> ai-stuck。
依赖门禁
如果一个 issue 必须等其他 issue 或 PR 完成后才能做,不要只写自然语言说明。正文里加一个隐藏结构化块:
写 issue 时,正文可见部分仍然建议给人看:
依赖
dispatcher 只读取隐藏块;普通 #95、#91 引用只会作为上下文,不会阻塞任务。
支持的依赖:
{"type":"pr","number":95,"state":"merged"}:PR 必须已合并
{"type":"pr","number":95,"state":"closed"}:PR 已关闭或已合并
{"type":"issue","number":91,"state":"closed"}:issue 必须关闭
{"type":"issue","number":91,"state":"review"}:issue 必须带 ai-review
{"type":"issue","number":91,"state":"done"}:issue 关闭,或带完成标签
行为:
依赖未满足:从 ai-todo 切到 ai-blocked,评论列出阻塞项,不启动 worker。
依赖满足:后续 cron 自动从 ai-blocked 切回 ai-todo。
隐藏块格式错误:也会进入 ai-blocked,评论提示 JSON 格式问题。
跨仓库依赖暂不自动判断;需要先人工确认,或拆到同仓库 issue 里表达。
项目策略可配置完成标签:
DEPENDENCY_DONE_LABELS="ai-review,ai-done,done"
DEPENDENCY_CLOSED_IS_DONE=true
DEPENDENCY_PR_MERGED_IS_DONE=true
附加材料
issue 里如果有图片、PDF 或附件链接,dispatcher 会下载并提取可读内容,附加到 prompt。
图片会尽量做 OCR;PDF 会尽量抽文本。
引用 Issue
如果 issue 正文或评论里明确写了同仓库引用,例如 #728 或 GitHub issue 链接,dispatcher 会把被引用 issue 的摘要加入上下文。
规则很轻:
只抓同仓库 issue
最多抓 5 个
只抓一层,不递归展开
包含标题、状态、labels、body 摘要、最近评论和附件链接
摘要默认由 LLM 基于被引用 issue 的完整正文和评论生成,并按 issue 更新时间缓存;LLM 摘要失败时才降级为明确标注的机械摘要
附件链接从原始全文提取,不依赖摘要文本,避免摘要遗漏图片或 PDF
Skill 使用
可以在 issue 里写明要使用某个 AI skill 或工作模式,例如:
请按 xxx-skill 的模式做一次 E2E 验证。
issue 里只放任务目标、非敏感上下文和附件。
账号、token、内部路径、登录态等敏感信息应放在执行机本地配置或 skill 本地文件里,不要写进 issue。
结果回写
代码任务成功产出 PR:ai-review
代码任务续做已有 PR 分支并能定位到对应 PR:ai-review
维护任务成功同步 PR:ai-review
代码任务在 ai-review 中续做但没有新增 commit:仍保持 ai-review,并把 worker 的诊断/说明回写到 issue
测试 / 调查任务成功产出报告:ai-review
中断但有 commit:ai-paused
维护任务同步冲突、push 失败或验证失败:ai-stuck
没有形成稳定产物:ai-stuck
同时会写两类记录:
issue comments:claim / abandon / state / result
~/.ai-dispatcher/runs/*.json:本地结构化 run metadata
claim / abandon / state 这类机器事件在 GitHub 上显示为一行简短说明,完整协议数据放在隐藏 HTML comment 里。旧版纯 JSON comment 仍然兼容。
工作区残留
dispatcher 领取新任务前会检查工作区:
只有未跟踪文件:先打包到 ~/.ai-dispatcher/artifacts/dirty-worktree-backups/,再清理并继续领取。
有 tracked 文件修改:不自动处理,暂停领取,避免丢失有效代码。
任务结束后如果只残留未跟踪文件,也会同样备份并清理,避免卡住后续任务。
worker 异常退出时如果留下 tracked 修改,会保存 patch/stash 到 dirty-worktree-backups/,清空工作区,并在 issue 里回写备份位置。
手工重开
如果某个 issue 需要重新开始,直接把它改回 ai-todo。
这适用于:
ai-stuck 想重开
ai-review 想重新来一轮
中间状态异常后需要重新排队
如果当前是 ai-paused,而你想保留原 owner 续做,就不要改回 ai-todo。
手动测试
AI_DISPATCHER_STATE_DIR=~/.ai-dispatcher-my-project /path/to/dispatcher/ai-dispatcher.sh
tail -f ~/.ai-dispatcher-my-project/dispatcher.log
ls ~/.ai-dispatcher-my-project/runs/
当前边界
不是中心调度
不是原子锁
ai-paused 不自动切换 owner
PR 创建后仍然需要人工 review 和最终关闭 issue