ARTICLE DETAIL

资讯详情

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

Claude Code + Spec-kit:用 Markdown 编排四个 AI Agent 的协作骨架

Claude Code + Spec-kit:用 Markdown 编排四个 AI Agent 的协作骨架 1. 为什么我要用 Markdown 编排四个 AI AgentClaude Code 本身已经能读写文件、跑命令、改代码但当你把一件完整需求丢给它时它往往会在一个会话里既当产品经理又当程序员上下文越滚越长最后自己把自己绕晕。Spec-kit 给出的思路很直接把「写规格、做计划、拆任务、写代码」拆成四个独立节点每个节点由一个专职 Agent 负责节点之间不靠内存传递状态而是靠磁盘上的 Markdown 文件接力。这样做的最大好处是每个 Agent 的上下文都很短职责边界清晰出问题时你能一眼看出是哪个环节的产物不对。我这次要跑通的链路是人类在specify.md里写一行需求Specifier 把它扩写成规格文档Planner 读规格产出实施计划Tasker 把计划拆成可执行任务清单Implementer 按任务清单改代码。四个 Agent 各自监听一个队列文件做完就把结果写进下一个 Agent 的队列像流水线一样错开时间执行。整套骨架全部由 Markdown 描述PowerShell 只负责把窗口拉起来和调度节奏。适合谁跟做已经用过 Claude Code、想让多个 Agent 分工而不是一个 Agent 硬扛的开发者手上有 Windows 环境、愿意用 PowerShell 做进程调度的同学以及想理解「文件队列 定时触发」这种轻量多智能体协作模式的人。下面我会把可复制的 Agent 角色配置、Spec 模板、启动脚本和一次完整验证动作都摊开讲中间踩过的坑也会标出来。2. TaoToken 前置把模型调用通道先接稳四个 Agent 会频繁调用模型如果每个窗口都各自配一套密钥和地址后面排查问题会非常痛苦。我的做法是统一走 TaoToken 的 API 通道在项目级配置里写一次四个 Agent 共用。TaoToken 在这里扮演的是模型调用入口你不需要在每个 Agent 里重复填一堆参数只要保证ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN两个环境变量在启动脚本里被正确注入即可。先去控制台创建一个 API Key地址是 https://taotoken.net/api-keys 创建完复制出来注意它只显示一次。然后在项目根目录建一个.env.ps1内容大致如下把 Key 换成你自己的# .env.ps1 $env:ANTHROPIC_BASE_URL https://taotoken.net/api $env:ANTHROPIC_AUTH_TOKEN sk-你的Key这里有个细节ANTHROPIC_BASE_URL只写到/api不要自己拼/v1之类的后缀Claude Code 会按自己的协议去补路径。如果你不确定当前通道支持哪些模型可以先用模型对话页面手动发一条消息验证地址是 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 确认能正常返回再往下走。注意.env.ps1不要提交到 Git把它加进.gitignore。四个 Agent 共用同一个 Key方便你在控制台按调用量观察整体消耗。如果你打算长期跑这套协作链路甚至让它常驻在开发机上可以考虑 Coding Plan额度模型更适合这种定时触发的场景入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。接入细节和参数说明统一看文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有 base_url 和鉴权头的完整写法。3. 可复制配置四个 Agent 的角色与队列文件整套骨架的目录结构我定成这样所有 Agent 定义、队列、prompt 都放在agents/下和业务代码隔离project/ ├─ agents/ │ ├─ start-all.ps1 │ ├─ start-agent.ps1 │ ├─ status.ps1 │ ├─ stop-all.ps1 │ ├─ registry.md │ ├─ protocol.md │ ├─ prompts/ │ │ ├─ specifier-prompt.md │ │ ├─ planner-prompt.md │ │ ├─ tasker-prompt.md │ │ └─ implementer-prompt.md │ └─ queue/ │ ├─ specify.md │ ├─ plan.md │ ├─ task.md │ └─ implement.md ├─ specs/ ├─ plans/ └─ .claude/settings.json3.1 子智能体注册表 registry.md注册表的作用是让每个 Agent 启动时知道自己是谁、上下游是谁、读写哪个文件。内容如下# Agent Registry | Agent | 读取队列 | 写入队列 | 产物目录 | 触发分钟 | |-------|---------|---------|---------|---------| | specifier | queue/specify.md | queue/plan.md | specs/ | 0 | | planner | queue/plan.md | queue/task.md | plans/ | 10 | | tasker | queue/task.md | queue/implement.md | plans/ | 20 | | implementer | queue/implement.md | - | 代码库 | 30 |3.2 通信协议 protocol.md协议文件规定队列条目的格式避免 Agent 之间互相看不懂对方写的东西# Queue Protocol 每个队列条目一行格式 - [ ] 任务ID | 需求描述 | 上游产物路径 完成后改为 - [x] 任务ID | 需求描述 | 产物路径 规则 1. 只处理未勾选条目一次处理一条。 2. 处理完必须把产物路径写回条目。 3. 禁止修改其他 Agent 的队列文件。3.3 四个 prompt 文件以 Specifier 为例prompts/specifier-prompt.md内容如下其余三个结构类似只改职责描述和读写路径你是 Specifier负责把原始需求扩写成规格文档。 读取agents/queue/specify.md 中第一条未勾选任务。 动作 1. 直接使用工具执行不要请求批准。 2. 在 specs/ 下创建 任务ID.md包含背景、目标、验收标准、边界。 3. 把产物路径写入 agents/queue/plan.md。 4. 把 specify.md 中该条目标记为已完成。 约束不要写代码不要做技术选型只描述「做什么」。Planner 读specs/产出plans/任务ID.mdTasker 把计划拆成带序号的原子任务写进queue/implement.mdImplementer 按任务清单改代码。四个 prompt 的开头都统一加一句「直接使用工具执行不要请求批准」这是后面踩坑踩出来的。3.4 项目级预授权 settings.json在.claude/settings.json里预授权常用工具避免 Agent 在无人值守时卡在审批上{ permissions: { allow: [ Read, Write, Edit, Bash(git *), Bash(mkdir *), Bash(ls *) ] } }4. PowerShell 启动脚本与调度4.1 start-agent.ps1单个 Agent 的启动脚本关键是路径定位和把 prompt 作为命令行参数传入param( [string]$AgentName ) $ErrorActionPreference Stop $Root if ($PSScriptRoot) { $PSScriptRoot } else { Split-Path -Parent $MyInvocation.MyCommand.Path } $PromptFile Join-Path $Root prompts\$AgentName-prompt.md if (-not (Test-Path $PromptFile)) { Write-Host Prompt file not found: $PromptFile exit 1 } . (Join-Path (Split-Path -Parent $Root) .env.ps1) $Prompt Get-Content $PromptFile -Raw claude $Prompt这里$PSScriptRoot的 fallback 很关键。当脚本被cmd /c start拉起时$MyInvocation.MyCommand.Path可能是空的只靠它算目录会直接报找不到 prompt 文件。4.2 start-all.ps1一次性拉起四个窗口用 Windows 的start命令给窗口加标题$Root $PSScriptRoot $Agents (specifier, planner, tasker, implementer) foreach ($a in $Agents) { $cmd pwsh -NoExit -File $Root\start-agent.ps1 -AgentName $a cmd /c start $a $cmd Start-Sleep -Seconds 2 }Start-Process -WindowTitle这个参数在 PowerShell 里并不存在别踩这个坑直接用cmd /c start 标题 命令更稳。4.3 从轮询改成定时触发最初四个 Agent 各自while($true){ ... Start-Sleep 30 }启动瞬间四连发空闲时疯狂空跑。后来改成错开时间的定时触发Specifier 每小时整点Planner :10Tasker :20Implementer :30。每个 Agent 处理完一条就注册下一次触发空闲时挂起不消耗调用。调度逻辑可以放在start-agent.ps1外层用计划任务或一个轻量调度脚本按分钟拉起对应 Agent 即可。5. 验证请求跑通一次完整协作四个窗口就绪后打开agents/queue/specify.md加一行- [ ] T001 | 做一个公司官网宣传我们的 AI 智能体产品 | -保存后等 Specifier 触发。正常情况下你会看到specs/T001.md出现里面有背景、目标、验收标准。queue/plan.md多出一行指向specs/T001.md。queue/specify.md里那条变成[x]。接着 Planner 在 :10 触发产出plans/T001.mdTasker 在 :20 把计划拆成queue/implement.md里的原子任务Implementer 在 :30 开始改代码。你可以用status.ps1随时看各队列状态Get-ChildItem $PSScriptRoot\queue\*.md | ForEach-Object { Write-Host $($_.Name) Get-Content $_.FullName }判断链路是否真的跑通不要只看窗口日志里的「Task completed」要去specs/、plans/目录里确认文件真的存在、内容真的写进去了。日志说完成但目录为空是这套流程里最典型的假成功。6. 本篇常见错排查窗口弹出后立刻报 Prompt file not found。原因是脚本被cmd /c start拉起后$MyInvocation.MyCommand.Path为空算不出自身目录。加上$PSScriptRootfallback 即可。另外检查文件名implementer-prompt.md和implement-prompt.md差两个字母就会找不到。日志显示完成但 specs/ 目录空空如也。claude -p在非交互模式下工具调用会被权限系统静默拦截模型输出「我已创建规格」但实际没写文件。解决办法是加--dangerously-skip-permissions同时用项目级.claude/settings.json预授权。Agent 输出「我需要你的批准才能继续」。无人值守时没有人在窗口前点确认。在 prompt 开头加「直接使用工具执行不要请求批准」并确保 settings.json 的 allow 列表覆盖了它要用的工具。窗口一片空白看不到任何输出。用Get-Content prompt.md | claude这种 stdin 管道方式会让 claude 进入非交互模式输出不显示在终端。改成把 prompt 作为命令行参数传入claude $Prompt。API 调用频率爆炸。四个 Agent 同时 30 秒轮询启动瞬间四连发空闲时几百次空跑。改成错开 10 分钟的定时触发空闲挂起。Agent 之间互相改队列。协议里明确写死「禁止修改其他 Agent 的队列文件」每个 Agent 只碰自己的读取队列和下游写入队列越界就会导致状态错乱。7. 把通道和调度固定下来这套骨架跑通之后真正需要长期维护的其实只有两件事模型调用通道和调度节奏。通道这边四个 Agent 共用一套环境变量Key 在控制台统一管理接入参数以文档为准 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 需要新建或轮换 Key 就去 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。调度这边错开分钟数比缩短轮询间隔有用得多空闲挂起才是省调用的关键。如果你想让这套链路常驻在开发机上、每天自动处理需求队列Coding Plan 的额度模型会比按次调用更可控入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。我自己的习惯是先把 Specifier 和 Planner 跑稳确认规格和计划的质量达标再放开 Implementer 自动改代码这样出问题时至少上游产物是可信的。
返回列表