看板工作器通道(Worker Lanes)
工作器通道(worker lane) 是看板调度程序可以将任务路由到的一类进程。每个通道都有一个身份标识(assignee 字符串)、一个生成机制,以及一旦生成后必须对任务执行的操作契约。
本页即为该契约。它面向两类受众:
- 运维人员:选择将哪些通道接入看板(创建哪些配置文件,使用哪些 assignee)。
- 插件/集成作者:希望添加新的通道形态(例如封装 Codex / Claude Code / OpenCode 的 CLI 工作器、容器化的审查工作器,或通过 API 拉取任务的非 Hermes 服务)。
如果你正在编写工作器本身的代码——即在通道内部运行的代理——kanban-worker skill 提供了更深层的过程细节。
层级结构
Hermes Kanban = canonical task lifecycle + audit trail
Worker lane = implementation executor for one assigned card
Reviewer = human or human-proxy that gates "done"
GitHub PR = upstreamable artifact (optional, for code lanes)
Hermes Kanban 拥有生命周期真相——ready → running → blocked / done / archived。工作器通道执行工作,但从不拥有该真相;它们所做的一切都通过 kanban_* 工具(或者对于非 Hermes 外部工作器,通过 API)回流到看板内核。审查者负责把控从“代码变更已编写”到“任务完成”的过渡。
通道提供的内容
要成为看板工作器通道,集成必须提供以下三要素:
1. Assignee 字符串
调度程序将 task.assignee 与 Hermes 配置文件名称(默认通道形态)或注册的非可生成标识符(插件通道形态——参见下文添加外部 CLI 工作器通道)进行匹配。如果任务的 assignee 无法解析,任务将保留在 ready 状态,并附带 skipped_nonspawnable 事件,以便看板运维人员进行修复;它们不会被静默丢弃或由任意回退机制执行。
2. 生成机制
对于 Hermes 配置文件通道,调度程序的 _default_spawn 会在任务固定的工作空间内运行 hermes -p <assignee> chat -q <prompt>(如果 $PATH 中没有 hermes shim,则运行等效的模块形式),并设置以下环境变量:
| 变量 | 携带内容 |
|---|---|
HERMES_KANBAN_TASK | 工作器正在操作的任务 ID |
HERMES_KANBAN_DB | 每个看板的 SQLite 文件的绝对路径 |
HERMES_KANBAN_BOARD | 看板 slug |
HERMES_KANBAN_WORKSPACES_ROOT | 看板工作空间树的根目录 |
HERMES_KANBAN_WORKSPACE | 当前任务工作空间的绝对路径 |
HERMES_KANBAN_RUN_ID | 当前运行的 ID(用于生命周期门控) |
HERMES_KANBAN_CLAIM_LOCK | 认领锁字符串(<host>:<pid>:<uuid>) |
HERMES_PROFILE | 工作器自身的配置文件名称(用于 kanban_comment 作者归属) |
HERMES_TENANT | 租户命名空间(如果任务有的话) |
对于非 Hermes 通道(通过插件注册),插件提供自己的 spawn_fn 可调用对象,该对象接收 task、workspace 和 board,并返回一个可选的 pid 用于崩溃检测。
3. 生命周期终止器
每个认领必须以以下三种方式之一确切结束:
kanban_complete(summary=..., metadata=...)—— 任务成功,状态翻转为done。kanban_block(reason=...)—— 任务等待人工输入,状态翻转为blocked。当运行kanban_unblock时,调度程序会重新生成任务。- 工作器进程在没有调用工具的情况下退出。内核会回收该进程并发出
crashed(PID 死亡)、gave_up(连续失败断路器触发)或timed_out(超过 max_runtime)。这是失败路径;健康的工作器不应在此结束。
看板内核强制要求每次运行必须由上述其中一种方式终止。既不调用任何终止工具又正常退出的工作器将被视为崩溃。
输出与“需要审查”约定
对于大多数涉及代码变更的任务,工作器完成的那一刻工作并未真正完成——它需要人工审查。看板内核不强制执行这种区分(“涉及代码变更的任务”定义模糊,且强制每个代码工作器使用 block 而非 complete 会破坏不需要审查的工作流)。这是一种叠加在其上的约定:
- 使用 Block 而非 Complete,且
reason前缀为review-required:,以便仪表盘 /hermes kanban show将该行显示为等待审查。 - 首先在
kanban_comment中放入结构化元数据,因为kanban_block仅携带人类可读的reason。评论是持久的注释渠道——每个与审计相关的字段(changed_files、tests_run、diff_path 或 PR url、decisions)都应放在那里。 - 审查者要么批准并解除阻塞,这会带着评论线程重新生成工作器以进行后续操作;要么通过另一条评论要求更改,下一个工作器运行会在
kanban_show的上下文中看到这些内容。
kanban-worker skill 包含了 kanban_complete(真正终结的任务——错别字修复、文档变更、研究撰写)和 review-required 阻塞模式的工作示例。
日志与审计轨迹
调度程序将每个任务的工作器 stdout/stderr 写入 <board-root>/logs/<task_id>.log。可以从看板元数据中审计日志:
task_runs行携带log_path、退出码(如果可用)、摘要和元数据。task_events行携带每一次状态转换(promoted、claimed、heartbeat、completed、blocked、gave_up、crashed、timed_out、reclaimed、claim_extended)。kanban_show返回上述两者,因此审阅者(或后续工作者)在阅读任务时无需访问仪表板即可获取完整历史记录。
仪表板渲染带有摘要、元数据块和退出状态徽章的运行历史。CLI 用户可以运行 hermes kanban tail <task_id> 来实时跟踪,或者运行 hermes kanban runs <task_id> 查看历史尝试列表。
现有泳道形态
Hermes 配置泳道(默认)
这是当前每个看板工作者采用的形态:受让人是一个配置名称,调度器生成 hermes -p <profile>,工作者自动加载 kanban-worker 技能以及 KANBAN_GUIDANCE 系统提示块,并使用 kanban_* 工具来终止运行。除了定义配置外,无需其他设置。
当为你的集群创建配置时,选择的名称应与你希望编排器路由到的角色相匹配。编排器(如果存在)通过 hermes profile list 发现你的配置名称——系统不假设任何固定的名册(请参阅 kanban-orchestrator 技能以了解合约中编排器一侧的情况)。
编排器配置泳道
配置泳道的一个特化:编排器是一个 Hermes 配置,其工具集包含 kanban,但排除用于实现的 terminal / file / code / web。它的工作是通过 kanban_create + kanban_link 将高层目标分解为子任务,然后退后一步。编排器技能编码了防诱惑规则。
添加外部 CLI 工作者泳道
将非 Hermes CLI 工具(Codex CLI、Claude Code CLI、OpenCode CLI、本地代码模型运行器等)作为看板工作者泳道接入尚不是一条平坦的道路。调度器的生成函数是可插拔的(spawn_fn 是 dispatch_once 的一个参数),插件可以为非 Hermes 受让人注册自己的 spawn_fn,但周围的集成工作——将 CLI 的退出码包装到 kanban_complete / kanban_block 调用中,将 CLI 的工作区/沙箱约定映射到调度器的 HERMES_KANBAN_WORKSPACE 环境变量,处理身份验证和每个 CLI 的策略——仍然是针对每个集成的设计工作。
如果你考虑添加 CLI 泳道,请创建一个 issue,描述具体的 CLI 和你试图启用的工作流。上述合约是任何此类泳道必须满足的约束;实现形态(每个 CLI 一个插件 vs 一个由配置参数化的通用 CLI 运行器插件)是开放的。
此问题的历史 issue 是 #19931,以及未合并已关闭的 Codex 特定 PR #19924——这些描述了最初的架构提案,但未落地运行器。
调度器处理的故障模式
因此,泳道作者无需重新实现这些:
- 过期的认领 TTL —— 一个认领后从未发送心跳/完成/阻塞的工作者会在
DEFAULT_CLAIM_TTL_SECONDS(默认 15 分钟)后被重新认领——但仅当工作者进程确实已死亡时。活跃的工作者(在单个无工具 LLM 调用中花费 20 多分钟的慢速模型)其认领会被延长而不是被杀死;只有死亡的 PID 才会被重新认领。 - 崩溃的工作者 —— 主机本地 PID 消失的工作者会被
detect_crashed_workers检测并回收;任务增加consecutive_failures计数,并在断路器触发时可能自动阻塞。 - 运行级重试 —— 当任务被重试(阻塞后、崩溃后、重新认领后)时,工作者可以在终止工具上使用
expected_run_id参数,以便在其自己的运行已被取代时快速失败。 - 每任务最大运行时 ——
task.max_runtime_seconds硬性限制每次运行的挂钟时间,无论 PID 是否存活。捕获那些真正死锁的工作者,否则活跃 PID 延长机制会让它们继续运行。 - 滞留任务检测 —— 一个就绪任务,如果其受让人在
kanban.stranded_threshold_seconds(默认 30 分钟)内未产生认领,将在hermes kanban diagnostics中显示为stranded_in_ready警告。严重程度在阈值的 2 倍时升级为错误,在 6 倍时升级为严重。在一个信号中捕获拼写错误的受让人、已删除的配置和宕机的外部工作者池——与身份无关,无需维护每个看板的允许列表。
相关
- Kanban 概览 —— 面向用户的介绍。
- Kanban 教程 —— 打开仪表板的演练。
kanban-worker—— 工作者进程加载的技能。kanban-orchestrator—— 编排器一侧。