Beads bd gate 指南:用异步门控(Gate)编排编码 Agent 工作流
2026/9/12 16:23:28 网站建设 项目流程

Beads bd gate 指南:用异步门控(Gate)编排编码 Agent 工作流

【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads

导读

bd gate是 Beads 中用于异步协调工作流的核心命令族:它以"门控(Gate)"这一特殊 issue 类型表达等待条件,阻塞下游步骤直到外部条件(人工审批、定时器、GitHub Actions 运行、PR 合并、跨 rig 的 bead 关闭)被满足。本文将围绕 docs/cli-reference/gate.md 完整讲解 gate 的七个子命令与五种门控类型,并结合 cmd/bd/gate.go、cmd/bd/gate_discover.go 的源码与 cmd/bd/gate_test.go 中的测试,说明其底层判定逻辑。读完你将掌握:如何创建 gate 阻塞某 issue、如何用bd gate check自动评估并关闭已满足的 gate、如何用bd gate discover为 CI 门控自动发现 GitHub run ID,以及如何在多 Agent 场景中通过 waiters 实现"完工唤醒"。

Gate 是什么:异步等待条件

在 Beads 中,gate 是一种特殊的 issue(issue 类型为gate,作为异步等待条件阻塞工作流步骤。它的核心语义(见 cmd/bd/gate.go):

  • gate 会在 formula 步骤带有gate字段时被自动创建;
  • 必须被关闭(人工或通过 watcher),被阻塞的步骤才能继续;
  • 被 gate 阻塞的 issue不会出现在bd ready,直到 gate 被 resolve。

从依赖图的角度看,"gate 是一个 issue",可以像普通 issue 一样被接入依赖图:docs/core-concepts/dependencies.md 演示了用bd dep add issue-2 <gate-id>让 issue-2 等待一个 gate。

五种 Gate 类型

类型等待条件自动判定方式
human人工确认手动执行bd gate resolve <id>(Phase 1)
timer时间到期当前时间超过created_at + timeout(Phase 2)
gh:runGitHub Actions workflow 运行完成且成功gh run view <id> --json status,conclusion(Phase 3)
gh:prPR 被合并gh pr view <id> --json state,title(Phase 3)
bead另一个 rig 的 bead 关闭通过路由查询目标 bead 状态(Phase 4)

对于beadgate,await_id的格式为<rig>:<bead-id>(例如other-project:op-abc123)。从 cmd/bd/gate.go 的实现看,checkBeadGate会剥离<rig>:前缀,以bead-id作为路由查找键;若格式非法(前缀或 ID 为空)会保持 pending 并给出错误提示,TestCheckBeadGate_InvalidCrossRigFormat(cmd/bd/gate_test.go)专门验证了这一行为。

bd gate list:查看门控

列出当前 beads 数据库中所有 gate issue。默认只显示**打开(open)**的 gate,使用--all包含已关闭的。

bd gate list [flags]

Flags:

-a, --all Show all gates including closed -n, --limit int Limit results (default 50) (default 50)

源码细节:bd gate list支持可选 issue-id 参数(见 cmd/bd/gate.go)。不带参数时按IssueType=gate且排除StatusClosed过滤全库;带参数时只列出阻塞该 issue 的依赖 gatefilterIssueGates,通过GetDependencies取得依赖集后过滤出 gate 类型),避免误把全库 gate 当成目标 issue 的门控。列表输出会把打开与关闭的 gate 分开展示,并提示To resolve a gate: bd close <gate-id>

bd gate show:查看单个门控详情

显示某个 gate issue 的详细信息,包括其 waiters。与bd show类似,但会校验该 issue 确实是 gateIssueType != "gate"时报错,见 cmd/bd/gate.go)。

bd gate show <gate-id> [flags]

输出字段(renderGateShow)包括:状态符号、gate ID、标题、Status、Await Type、Await ID(如有)、Timeout(如有)、Waiters 列表、Description。配合--json全局开关可输出结构化 JSON。

bd gate resolve:手动关闭门控

关闭一个 gate issue,解除等待该 gate 的步骤。其语义等价于bd close <gate-id>,只是名字更明确;可用--reason说明解决原因。

bd gate resolve <gate-id> [flags]

Flags:

-r, --reason string Reason for resolving the gate

对应human类型 gate 的默认关闭路径:store.CloseIssue(ctx, gateID, reason, actor, "")(见 cmd/bd/gate.go),成功后输出✓ Gate resolved: <id>humangate 也出现在 docs/core-concepts/dependencies.md 的 Gate Types 表中,是唯一完全依赖人工判定的类型。

bd gate create:创建临时门控

创建一个临时 gate issue 阻塞另一个 issue,直到该 gate 被 resolve。被阻塞的 issue 在 gate 解决前不会出现在bd ready中。

bd gate create [flags]

Flags:

--await-id string Condition identifier (run ID, PR number, etc.) --blocks string Issue ID to block (required) -r, --reason string Reason for the gate --timeout string Timeout duration (e.g., 2h, 30m) -t, --type string Gate type (human, timer, gh:run, gh:pr) (default "human") --title string Custom gate title (default: "Gate: <type>")

示例:

bd gate create --blocks bd-abc bd gate create --type=human --blocks bd-abc --reason="Need design review" bd gate create --type=timer --blocks bd-abc --timeout=2h bd gate create --type=gh:pr --blocks bd-abc --await-id=42 bd gate create --blocks bd-abc --title="Gate: awaiting owner sign-off"

底层实现要点(见 cmd/bd/gate.go):

  • --blocks为必填,缺失时直接报错(MarkFlagRequired);
  • --timeout通过time.ParseDuration解析,支持2h30m等 Go duration 格式;
  • 新 gate 的 title 默认为Gate: <type>,若带await-id则为Gate: <type> <await-id>,也可用--title完全自定义;
  • 创建后会自动为 gate 与目标 issue 建立DepBlocks类型的依赖边,使被阻塞 issue 在 gate 打开时保持非 ready;
  • gh:run/gh:pr类型,repoMetadataForGate会从被阻塞 issue 的 metadata 中继承并校验 GitHub 仓库选择器(OWNER/REPOHOST/OWNER/REPO),供后续 check 跨仓库查询使用(见 cmd/bd/gate.go);
  • 成功后输出✓ Created gate <id> (type: ...),并提示Resolve with: bd gate resolve <id>

bd gate check:评估并自动关闭已满足的门控

评估 gate 条件,自动关闭已满足的 gate。默认检查所有打开的 gate,可用--type按类型过滤。

bd gate check [flags]

Flags:

--dry-run Show what would happen without making changes -e, --escalate Escalate failed/expired gates -l, --limit int Limit results (default 100) (default 100) -t, --type string Gate type to check (gh, gh:run, gh:pr, timer, bead, all)

--type的取值与过滤语义shouldCheckGate,见 cmd/bd/gate.go):

--type匹配范围
(空)或all全部类型
gh所有gh:前缀类型(gh:run+gh:pr
gh:run仅 GitHub Actions workflow 运行
gh:pr仅 PR 合并状态
timer仅定时器
bead仅跨 rig bead 门控

GitHub gate 通过ghCLI 查询状态:

  • gh:run执行gh run view <id> --json status,conclusion
  • gh:pr执行gh pr view <id> --json state,title

判定规则(resolve / escalate / pending),来自 cmd/bd/gate.go 及checkGHRunStatusInRepoWithRunner(cmd/bd/gate.go)、checkGHPRWithRunner(cmd/bd/gate.go)、checkTimer(cmd/bd/gate.go):

类型已满足(resolve)升级(escalate)挂起(pending)
gh:runstatus=completedconclusion=success(skipped 也视为成功)completedconclusion为 failure / canceled / 其他非成功值;或 run 不存在运行中(in_progress / queued / pending / waiting)
gh:prstate=MERGEDstate=CLOSED(未合并关闭);或 PR 不存在state=OPEN
timer当前时间 > created_at + timeout设计上永不开级escalated恒为 false)未到期(报告剩余时间)
bead目标 beadstatus=closed不适用目标 bead 仍打开或查找失败

示例:

bd gate check # Check all gates bd gate check --type=gh # Check only GitHub gates bd gate check --type=gh:run # Check only workflow run gates bd gate check --type=timer # Check only timer gates bd gate check --type=bead # Check only cross-rig bead gates bd gate check --dry-run # Show what would happen without changes bd gate check --escalate # Escalate expired/failed gates

输出与汇总:每个 gate 显示✓ resolved / ⚠ ESCALATE / ○ pending状态行,最后汇总Checked N gates: X resolved, Y escalated, Z errors;配合全局--json会输出结构化结果(checked / resolved / escalated / errors / dry_run,见printGateCheckSummary)。--dry-run只打印"would resolve / would escalate"而不落库;--escalate开启后,升级的 gate 会调用gt escalate(主题为Gate escalation: <id>,严重级别 HIGH)通知相关方(见escalateGate,cmd/bd/gate.go)。

bd gate add-waiter:注册完工唤醒

将某个 Agent 注册为 gate bead 上的 waiter。gate 关闭时,waiter 会通过bd gate wake收到唤醒通知。waiter 通常是 worker 的地址(如my-project/workers/agent-1)。

bd gate add-waiter <gate-id> <waiter> [flags]

典型使用场景:bd done --phase-complete用它注册 gate 唤醒通知。实现上(cmd/bd/gate.go)会先校验该 issue 确实是 gate,再检查 waiter 是否已注册(已注册则幂等返回),最后把 waiter 追加写入 issue 的waiters字段。这一机制让多 Agent 流水线中的下游 Agent 可以"睡着",直到上游 gate 关闭被唤醒,而不是忙轮询。

bd gate discover:自动发现 GitHub run ID

为等待 CI/CD 完成的 gate 自动发现 GitHub workflow run ID。它找出await_type="gh:run"没有 await_id(或 await_id 是非数字的 workflow 名称提示)的打开 gate,查询最近的 GitHub workflow runs,用启发式规则匹配,并把匹配到的 run ID 写回 gate 的await_id,使后续bd gate check轮询能查询该 run 的状态。

bd gate discover [flags]

Flags:

-b, --branch string Filter runs by branch (default: current branch) -n, --dry-run Preview mode: show matches without updating -l, --limit int Max runs to query from GitHub (default 10) -a, --max-age duration Max age for gate/run matching (default 30m0s)

匹配启发式matchGateToRun,见 cmd/bd/gate_discover.go):

  1. Workflow 名称提示匹配(+200):当await_id是非数字的 workflow 名时,只考虑该 workflow 的 run(workflowNameMatches兼容大小写不敏感精确匹配、.yml/.yaml后缀归一化);
  2. Commit SHA 匹配(+100):run 的headSha等于当前本地 git commit SHA;
  3. 分支匹配(+50):run 的headBranch等于当前分支(默认取当前 git 分支,getGitBranchForGateDiscovery,失败回退main);
  4. 时间邻近度(+30/+20/+10):run 创建时间与 gate 创建时间相差小于 5 分钟得 30 分,小于 10 分钟得 20 分,小于 30 分钟得 10 分;
  5. 运行状态偏好(+5):in_progressqueued的 run 更可能是当前这次。

总得分 ≥ 30 才接受匹配(有 workflow 提示时,仅 workflow 匹配 200 分即足够;无提示时需分支/commit 加分),否则视为无匹配。--max-age控制匹配的时间窗口上限,默认 30 分钟。

跨仓库(cross-repo)行为matchGatesToRunsbranchFilterForRepo):当 gate 的metadata.repo指向其他仓库时,发现过程只查询该仓库的 runs,绝不会用当前仓库同名 workflow 的 run 去匹配;自动检测到的本地分支不会套用到外部仓库(用户显式传入的--branch除外),且无 workflow 提示的外部 gate 会被跳过查询,避免错误地把另一个仓库的 run ID 永久钉在 gate 上。

示例:

bd gate discover # Auto-discover run IDs for all matching gates bd gate discover --dry-run # Preview what would be matched (no updates) bd gate discover --branch main --limit 10 # Only match runs on 'main' branch

完整实战:从 CI 门控到多 Agent 编排

场景一:等待 CI 通过再继续

# 1. 创建等待 CI 的 gate,阻塞 deploy 任务 bd gate create --type=gh:run --blocks bd-deploy-7 \ --await-id=ci.yml --reason="Wait for CI green on main" # 2. 在 CI 尚未产生 run 时自动发现并钉住 run ID bd gate discover --dry-run # 先预览 bd gate discover # 应用匹配 # 3. 定期评估,成功则自动关闭 bd gate check # CI 成功后自动 resolve bd gate check --escalate # CI 失败时升级告警 # 4. 人工兜底关闭 bd gate resolve bd-deploy-7.gate-abc123 --reason "Verified manually"

场景二:定时冷却门控

bd gate create --type=timer --blocks bd-hotfix-9 --timeout=30m --reason "Cooldown" bd gate check --type=timer # 到期后自动 resolve

场景三:PR 合并门控

bd gate create --type=gh:pr --blocks bd-issue-2 --await-id=42 bd gate check --type=gh:pr # PR 合并(MERGED)后自动放行

场景四:多 Agent 阶段衔接(配合 waiters)

# Agent A 完成阶段,注册下游 Agent B 作为 waiter bd gate add-waiter bd-deploy-7.gate-abc123 "my-project/workers/agent-2" # gate 关闭后,Agent B 收到 bd gate wake 唤醒通知,无需轮询

定期自动化建议

docs/core-concepts/dependencies.md 建议周期性运行bd gate check自动关闭已满足的 gate,例如 cron:

*/5 * * * * cd /path/to/repo && bd gate check

常见问题与边界

  • gh CLI 缺失gh:run/gh:pr/discover依赖ghCLI(源码通过exec.LookPath("gh")检查,见 cmd/bd/gate.go),未安装时报错gh CLI not found
  • timer gate 没有 timeoutcheckTimerTimeout == 0时返回错误no timeout set,保持 pending;
  • gate 不是 issueshow/resolve/add-waiter均会校验IssueType,非 gate 类型直接报错;
  • bead gate 路由:跨 rig 的 bead gate 通过 bead ID 前缀在routes.jsonl中路由解析(见 cmd/bd/gate.go),本地未命中时会按 local → prefix route → contributor 的顺序回退(routedBeadGateGetter);
  • discover不支持 proxied-server 模式:源码中runGateDiscoverusesProxiedServer()时直接报错(cmd/bd/gate_discover.go)。

相关文档与源码

  • CLI 参考:docs/cli-reference/gate.md、docs/CLI_REFERENCE.md
  • 核心概念:docs/core-concepts/dependencies.md(Gate Types 表格、bd create --type=gate的另一种创建方式与依赖接线)
  • 源码实现:cmd/bd/gate.go(gate 命令族与判定逻辑)、cmd/bd/gate_discover.go(run ID 发现与跨仓库匹配)
  • 测试验证:cmd/bd/gate_test.go(类型过滤、bead 跨 rig 路由、gh状态判定、workflow 发现持久化、metadata 校验等覆盖)

【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询