
Beads 中的 ready 工作流用bd ready查找无阻塞任务并原子认领【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads导读本文围绕 Beads 的 skill 文档 plugins/beads/skills/beads/commands/ready.md 展开讲解编码 Agent 如何通过 beads MCP 服务器的ready工具从依赖图中找出真正可以动手无阻塞依赖的任务并将其清晰地呈现给用户当用户选定任务后如何通过claim工具原子地开始工作。读完本文你将掌握bd ready的 blocker-aware 语义、输出格式、常用过滤参数以及bd ready --claim的原子认领原理并理解与bd blocked、bd create的配合方式。一、ready 的核心语义什么是可以动手的任务ready工具的作用是找出没有阻塞依赖、当前就可以开始的任务。这里的ready不是简单的状态判断而是blocker-aware感知阻塞者的语义一个 issue 即使处于 open 状态只要它存在一条仍为 open 的blocks类型依赖即依赖链上还有未关闭的阻塞者它就不算 ready。这一点在 Beads 源码中有明确印证。internal/workapi/ready.go中的BuildReadyFilter是bd ready语义的唯一权威定义它强制只包含 open 状态的 issueStatus: types.StatusOpen不包含 in_progress——这与bd list --ready展示的是同一个集合默认排除in_progress、blocked、deferred 和 hooked 的 issue通过GetReadyWork这条 blocker-aware 查询来找出真正可认领的工作。issueops/readycounter.go中对 ReadyCounter 角色的注释也点明了 ready 谓词的本质The ready predicate is BLOCKER-AWARE: it reads the dependency graph and the wisp tier, and no CountRequest can describe it.也就是说有多少 ready 工作这个问题无法用对单张表的谓词计数来回答必须读取依赖图和 wisp 层级——这正是ready与普通列表/计数命令的本质区别。二、Agent 使用 ready 的标准流程根据 ready.mdAgent 的标准动作序列是调用ready工具获取当前所有无阻塞依赖的任务以清晰格式呈现给用户每条任务至少包含四项信息Issue ID任务 IDTitle标题Priority优先级Issue type任务类型询问用户选择如果有 ready 任务请用户指定要处理哪一个用户选定后调用claim工具原子地开始工作没有 ready 任务时建议检查blocked任务看看卡在哪里、能否推动解决或者用create工具新建一条 issue。这套流程把找活 → 呈现 → 确认 → 认领 → 兜底串成一条完整的 agent 工作链让编码 Agent 在每次会话开始或上下文恢复后都能迅速定位自己该做什么。三、呈现 ready 任务的关键字段Agent 调用ready后拿到的结果中每个任务都带有以下字段呈现给用户时应当完整展示字段含义说明Issue ID任务 ID用于后续bd show id取详情、bd update id --claim认领Title标题任务的一句话描述Priority优先级P0–P4仅作为标签/排序依据不是状态图标Issue type任务类型task、bug、feature、epic、decision、merge-request 等从 cmd/bd/ready.go 的displayReadyList可以看到CLI 在 pretty 模式下每行输出为[优先级] [类型] ID: 标题并附上 Estimate预估分钟、Assignee负责人等附加信息plain 模式则输出编号列表。Agent 面向用户呈现时应保证 ID、Title、Priority、Issue type 四项齐全便于用户做出选择。四、blocker-aware 查询ready 与 blocked 的关系ready与blocked是一对互补视图。根据 blocked.mdBlocked issues have one or more dependencies with type blocks that are still open. Once all blocking dependencies are closed, the issue becomes ready and will appear inbd ready.即一条 issue 只要有任意一条blocks类型的依赖仍处于 open它就是 blocked当所有阻塞依赖都被关闭后它自动变为 ready出现在bd ready的结果中。在 cmd/bd/ready.go 中两条命令共用同一套 label 过滤逻辑blockedFilterFromFlags保证两侧视图对--label、--label-any、--exclude-label的解释完全一致不会因为命令不同而漂移。测试 cmd/bd/ready_test.go 中有专门用例验证这一语义test-still-blocked同时依赖一个已关闭的阻塞者test-closed-blocker-1和一个仍 open 的阻塞者test-open-blocker因此依然 blocked而test-ready-via-closed-blockers的全部阻塞依赖都已关闭于是进入 ready 集合。这直观地说明只要还有一条 open 的阻塞依赖任务就保持 blocked。五、bd ready 命令行全览过滤与排序参数虽然 skill 文档面向 MCP 工具调用但 MCP 的ready工具与 CLI 的bd ready共享同一套过滤器构建逻辑workapi.BuildReadyFilter。CLI 支持的主要参数如下定义见 cmd/bd/ready.go参数别名默认值说明--limit-n100最多显示条数0 表示不限workapi.DefaultReadyLimit--offset0跳过前 N 条仅 proxied-server 模式支持--priority-p0精确按优先级过滤--assignee-a按负责人过滤--unassigned-ufalse只显示未分配的任务--sort-spriority排序策略priority默认、hybrid、oldest--label-l标签过滤AND必须全部包含可搭配--label-any--label-any标签过滤OR至少包含一个--exclude-label排除含任意这些标签的 issue--label-pattern标签 glob 过滤如tech-*--label-regex标签正则过滤如tech-(debt\|legacy)--type-t按类型过滤task/bug/feature/epic/decision/merge-request别名 mr/feat/mol/dec/adr--mol只显示指定 molecule 内的步骤--parent过滤某 bead/epic 的后代--mol-type按 molecule 类型过滤swarm、patrol、work--prettytrue树形展示状态/优先级符号--plainfalse纯编号列表展示--include-deferredfalse包含未来 defer_until 的 issue--include-ephemeralfalse包含 ephemeralwisp记录--gatedfalse找出可 gate-resume 分发的 molecule--exclude-type排除指定类型逗号分隔或重复使用--explainfalse展示依赖感知的 ready/blocked 原因分析--claimfalse原子认领第一个匹配过滤条件的 ready issue--brieffalse省略大字段描述/设计/验收标准/笔记/payload/waiters需--json--metadata-field元数据等值过滤keyvalue可重复--has-metadata-key过滤具有该元数据 key 的 issue--json结构化 JSON 输出全局 flag其中两个组合限制值得注意--claim不能与--assignee、--gated、--mol、--explain、--brief、--offset组合冲突检查见 cmd/bd/ready_input.go 的gatherReadyInput与briefModeConflict--brief需要--json且不能与--claim、--gated、--mol、--explain组合。排序策略说明--sort支持三种策略均作用于 ready 集合priority按优先级排序为默认值、hybrid、oldest按创建时间最旧优先。若传入非法值BuildReadyFilter会返回ErrValidation包装的错误提示合法取值为hybrid, priority, oldest见 internal/workapi/ready.go。六、bd ready --claim原子认领的原理bd ready --claim是 ready 工作流的关键动作它把选择 → 认领 → 水合hydrate三步放进同一个事务Selection, the compare-and-set and the hydration share ONE transaction, so the row cannot move between being chosen and being reported.—— issueops/readyclaimer.go也就是说认领时不会出现选中的任务在报告前被别的 Agent 抢走的竞态。其底层接口是ReadyClaimer.ClaimNext一次只认领一条且认领的候选集合与bd ready列表展示的集合完全一致共享ReadyRequest类型保证列表展示过的任务才可能被认领认领成功后赢得的那一行会在事务内完成水合关系数量等返回的IssueWithCounts描述的是认领提交那一刻的真实状态没有可认领任务时返回nil而不是错误——空 ready 队列是排空后的稳态轮询 Agent 无需通过解析错误来发现没有活干认领不会记录历史条目当没有可认领项时而认领成功的行会获得恰好一个 lease租约这是心跳续期、租约过期回收机制能够恢复任务的句柄ephemeralwisp行默认不在认领范围内除非请求显式设置IncludeEphemeral认领 ephemeral 行不会授予 lease也不会写历史因此将 ephemeral 工作交给无人监督的 Agent 时回收责任需要调用方自己承担。CLI 层面对应实现在 cmd/bd/ready.go--claim走activeStore.ReadyClaimer()认领成功打印✓ Claimed issue: id: title空结果时输出No ready work to claim。同时--claim是写操作在嵌入模式下会触发自动提交dolt autocommit并设置SetLastTouchedID供后续命令追踪。ready 集合的规模统计ReadyCounter当bd ready --json返回的页面恰好满页时CLI 会通过ReadyCounter.CountReady再跑一次计数回答总共还有多少 ready 工作即Showing X of N中的 N。ReadyCounter与Reader、ReadyClaimer是三个独立的角色接口见 issueops/readycounter.go它的契约承诺CountReady(r).Total len(Reader.Ready(r with Limit0).Items)即计数与列表是同一个谓词的同一组答案。因此计数请求拒绝携带Limit/Offset——基数没有页的概念带 Limit 会变成前 N 个中有多少带 Offset 则会悄悄从集合大小里扣掉跳过的行见 internal/workapi/ready.go 的BuildReadyCountFilter。七、没有 ready 任务时怎么办blocked 与 create 兜底按 skill 文档当 ready 列表为空时Agent 应当引导用户走两条兜底路径1. 检查 blocked 任务bd blockedbd blocked是bd ready的互补视图展示所有被阻塞的任务并给出阻塞来源 Blocked issues (2): [P1] issue-3: Implement login page Blocked by 2 open dependencies: [issue-1, issue-2]对应实现见 cmd/bd/ready.go。bd blocked也支持--parent、--label、--label-any、--exclude-label过滤与 ready 视图共用同一套 label 归一化逻辑。查看 blocked 的价值在于理解工作为何卡住哪个依赖还没完成识别关键路径项被最多任务依赖的阻塞者规划依赖解决顺序先关闭阻塞者后续任务自动解锁进入 ready。bd blocked --explainbd ready --explain的姊妹能力还能输出依赖感知的原因分析每个 ready 项标注为何 ready如所有阻塞依赖已关闭、每个 blocked 项标注具体被谁、以何种状态阻塞并检测依赖环A → B → A。2. 新建任务bd create如果确实没有现成可做的工作Agent 可以用create工具新建一条 issue例如把用户的新想法登记为 task或把一个大目标登记为 epic从而让队列重新有内容可认领。八、ReadyFlag 作用域bd list --ready 与 bd ready 的一致性除独立命令外bd list --ready也使用同一套 blocker-aware 语义见 cmd/bd/ready.go 的命令注释bd list --ready uses the same blocker-aware ready-work semantics。两个入口共享workapi.BuildReadyFilter与ReadyFilterFromIssueFilter保证结果集合不会因入口不同而漂移。同时--ready与普通列表过滤器的组合受到严格约束ValidateReadyFlagScope见 issueops/reader_ready_scope.go会拒绝那些 blocker-aware 查询无法携带的过滤条件——例如--id、--title、--spec、各种时间范围--created-after等、--deferred、--overdue、--pinned、--priority-min/max、游标等。原因很直接ready 查询只携带列表词汇的一部分如果静默丢弃这些条件就会返回所有 ready issue 而不是用户点名要的那些因此宁可报错也绝不悄悄降级。而类型、标签、负责人、父级、元数据等投影能携带的字段则被完整保留。九、Agent 集成要点从 MCP ready 到会话协议将ready工具放进 agent 会话协议形成稳定节奏会话开始/上下文恢复后先跑bd ready或 MCPready获取当前可做任务清单向用户展示 ID、标题、优先级、类型用户选定后立即bd update id --claim或 MCPclaim原子认领避免与其他 agent/会话竞争同一任务工作中用bd show id取完整上下文用bd update记录笔记这些笔记在上下文压缩/会话重启后依然存活是 Beads 持久记忆的核心价值完成后bd close id --reason ...关闭任务其下游阻塞任务自动解锁进入 ready队列为空时检查bd blocked分析卡点或bd create新建任务然后回到第 1 步。Beads 的 skill 文档 plugins/beads/skills/beads/SKILL.md 中的 Session Protocol 正是这一循环的浓缩bd ready→bd show→bd update --claim→ 记笔记 →bd close→bd dolt push。十、小结ready工具/bd ready命令是 Beads 工作队列的取件口它以 blocker-aware 语义扫描依赖图只返回真正无阻塞、可立即开始的任务bd ready --claim通过单一事务保证认领的原子性与一致性bd blocked与bd create则构成空队列时的闭环兜底。对编码 Agent 而言掌握这套流程就等于拥有一个跨会话、可恢复、不会重复认领的持久任务队列。相关文件索引Skill 文档ready.md、blocked.md、SKILL.mdCLI 实现cmd/bd/ready.go、cmd/bd/ready_input.go过滤器构建internal/workapi/ready.go角色接口issueops/readyclaimer.go、issueops/readycounter.go、issueops/reader_ready_scope.go测试用例cmd/bd/ready_test.go【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考