关于 kanban-worker
kanban-worker 是供 Hermes 分派任务时加载的技能,说明如何处理工作区、提交任务交接、诊断重试、等待人工输入,以及在完成时附上交付文件。
主要功能
- 01处理临时、共享和 worktree 工作区
- 02规范完成摘要与元数据
- 03在任务完成时附加交付文件
- 04以明确的决策请求阻塞任务
- 05根据先前运行结果诊断重试
- 06遵守租户与任务边界
适用场景
- 01提交包含测试详情的代码变更
- 02交付报告或其他生成文件
- 03等待人工决策时暂停任务
- 04在运行失败或阻塞后恢复任务
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nousresearch/ hermes-agent --skill kanban-worker安装后在 Claude Code 中输入/kanban-worker确认已加载。
详细介绍
Kanban Worker — 注意事项与示例
你会看到此技能,是因为 Hermes Kanban dispatcher 使用
--skills kanban-worker启动了你作为工作器——它会为每个派发的工作器自动加载。生命周期(6 个步骤:了解情况 → 工作 → 心跳 → 阻塞/完成)也位于自动注入到系统提示词中的KANBAN_GUIDANCE块内。此技能提供更深入的细节:良好的交接格式、重试诊断和边缘情况。
工作区处理
工作区类型决定了你在 $HERMES_KANBAN_WORKSPACE 中应如何操作:
| 类型 | 内容 | 如何操作 |
|---|---|---|
scratch | 全新的临时目录,仅供你使用 | 可自由读写;任务归档时会被垃圾回收。 |
dir:<path> | 共享的持久目录 | 其他运行实例会读取你写入的内容。请将其视为长期状态。路径保证为绝对路径(内核会拒绝相对路径)。 |
worktree | 位于已解析路径的 Git 工作树 | 如果 .git 不存在,先在主仓库中运行 git worktree add <path> ${HERMES_KANBAN_BRANCH:-wt/$HERMES_KANBAN_TASK},然后切换目录并正常工作。在此处提交更改。 |
租户隔离
如果设置了 $HERMES_TENANT,任务就属于某个租户命名空间。读取或写入持久记忆时,请在记忆条目前加上租户标识,以免上下文在租户之间泄漏:
- 正确:
business-a: Acme is our biggest customer - 错误(会泄漏):
Acme is our biggest customer
良好的摘要与元数据格式
kanban_complete(summary=..., metadata=...) 交接信息供下游工作器读取你完成的工作。以下模式效果良好:
编码任务:
kanban_complete(
summary="shipped rate limiter — token bucket, keys on user_id with IP fallback, 14 tests pass",
metadata={
"changed_files": ["rate_limiter.py", "tests/test_rate_limiter.py"],
"tests_run": 14,
"tests_passed": 14,
"decisions": ["user_id primary, IP fallback for unauthenticated requests"],
},
)
需要人工审核的编码任务(review-required):
对于大多数会更改代码的任务,在人工审核者检查之前,工作都不能算真正完成。请阻塞任务而不是完成任务,并在 reason 前加上 review-required: ,这样仪表板就会将该任务标记为需要审核。由于 kanban_block 只包含面向人工的理由,且评论是持久的批注渠道,因此请先在评论中写入结构化元数据(更改的文件、测试数量、diff/PR URL)。审核者要么批准并运行 hermes kanban unblock <id>(这会重新启动你,并附上评论串以供跟进),要么通过另一条评论要求修改。
import json
kanban_comment(
body="review-required handoff:\n" + json.dumps({
"changed_files": ["rate_limiter.py", "tests/test_rate_limiter.py"],
"tests_run": 14,
"tests_passed": 14,
"diff_path": "/path/to/worktree", # or PR url if pushed
"decisions": ["user_id primary, IP fallback for unauthenticated requests"],
}, indent=2),
)
kanban_block(
reason="review-required: rate limiter shipped, 14/14 tests pass — needs eyes on the user_id/IP fallback choice before merging",
)
仅当任务确实已到终点时才使用 kanban_complete,例如修复一处单行拼写错误、不会造成任何功能影响的文档更改,或交付物本身就是研究报告的研究任务。
研究任务:
kanban_complete(
summary="3 competing libraries reviewed; vLLM wins on throughput, SGLang on latency, Tensorrt-LLM on memory efficiency",
metadata={
"sources_read": 12,
"recommendation": "vLLM",
"benchmarks": {"vllm": 1.0, "sglang": 0.87, "trtllm": 0.72},
},
)
审核任务:
kanban_complete(
summary="reviewed PR #123; 2 blocking issues found (SQL injection in /search, missing CSRF on /settings)",
metadata={
"pr_number": 123,
"findings": [
{"severity": "critical", "file": "api/search.py", "line": 42, "issue": "raw SQL concat"},
{"severity": "high", "file": "api/settings.py", "issue": "missing CSRF middleware"},
],
"approved": False,
},
)
请妥善组织 metadata,让下游解析器(审核者、聚合器、调度器)无需重新阅读你的正文也能使用这些信息。
交付文件(artifacts=[...])
如果你的任务生成了人们真正需要的文件——例如图表、PDF、电子表格、生成的图片或压缩包——请将它们的绝对路径传给 kanban_complete(artifacts=[...])。网关通知器会将每个文件作为原生附件上传给订阅该任务的人,这样交付文件就会和完成消息一起出现在他们的聊天中,而不是只提供一个还得让他们自行获取的路径。
kanban_complete(
summary="Q3 revenue analysis: 14% QoQ growth, EMEA the laggard. Chart + full PDF attached.",
artifacts=["/tmp/q3-revenue.png", "/tmp/q3-report.pdf"],
metadata={"rows_analyzed": 48000, "growth_qoq": 0.14},
)
图片和视频会内嵌显示;PDF、docx、csv/xlsx/json/yaml、pptx、zip/tar/gz、音频和 html 会作为文件上传。规则:
- 只能使用绝对路径,且完成任务时文件必须仍然存在——不要指向已删除的临时文件。
- 只提交真正的交付文件。 跳过中间日志、临时文件,以及人们已经拥有的输入文件。
artifacts是通知器读取的顶层参数。不要将交付文件路径塞进metadata(例如metadata.codex_lane.artifacts)并指望它们会被上传——通知器只会扫描顶层的artifacts列表,并尽力从summary/result文本中查找。Metadata 中的路径用于下游工作进程记录,而非交付。- 单个字符串会自动转换为只含一个元素的列表,并与任何现有的
metadata.artifacts合并,且不会重复。
同一机制也适用于 kanban 之外:任何 Agent 界面只需在回复中写入文件的绝对路径,就能交付文件;Slack/Discord/Telegram 等会以原生方式上传文件,而 artifacts 参数则是 kanban 的结构化入口。
认领你实际创建的卡片
如果你的运行创建了新的 kanban 任务(通过 kanban_create),请在 kanban_complete 中将任务 ID 传入 created_cards。内核会验证每个 ID 是否存在且由你的配置文件创建;任何虚构的 ID 都会导致完成操作报错,并列出问题所在,而且被拒绝的尝试会永久记录在任务的事件日志中。只能列出你从成功的 kanban_create 返回值中获取的 ID——绝不要从文字中编造 ID、粘贴之前运行中的 ID,或认领其他工作进程创建的卡片。
# GOOD — capture return values, then claim them.
c1 = kanban_create(title="remediate SQL injection", assignee="security-worker")
c2 = kanban_create(title="fix CSRF middleware", assignee="web-worker")
kanban_complete(
summary="Review done; spawned remediations for both findings.",
metadata={"pr_number": 123, "approved": False},
created_cards=[c1["task_id"], c2["task_id"]],
)
# BAD — claiming ids you don't have captured return values for.
kanban_complete(
summary="Created remediation cards t_a1b2c3d4, t_deadbeef", # hallucinated
created_cards=["t_a1b2c3d4", "t_deadbeef"], # → gate rejects
)
如果 kanban_create 调用失败(异常、tool_error),卡片就没有创建——不要为它填写虚构的 ID。请重试创建,或省略该 ID 并在摘要中说明失败情况。对自由格式摘要的文本扫描也会检查无法解析的 t_<hex> 引用;这些引用不会阻止完成,但会作为提示警告显示在仪表板的任务上。
能快速得到答复的阻塞原因
不佳:"stuck"——人们不知道具体情况。
良好:用一句话说明你需要对方做出的具体决定。较长的背景信息请作为评论留下。
kanban_comment(
task_id=os.environ["HERMES_KANBAN_TASK"],
body="Full context: I have user IPs from Cloudflare headers but some users are behind NATs with thousands of peers. Keying on IP alone causes false positives.",
)
kanban_block(reason="Rate limit key choice: IP (simple, NAT-unsafe) or user_id (requires auth, skips anonymous endpoints)?")
阻塞消息会显示在仪表板/网关通知器中。评论则提供更深入的背景信息,供人们打开任务时阅读。
值得发送的心跳
良好的心跳会说明进度:"epoch 12/50, loss 0.31"、"scanned 1.2M/2.4M rows"、"uploaded 47/120 videos"。
不佳的心跳:"still working"、空备注、间隔不到一秒。最多每隔几分钟发送一次;对于耗时约 2 分钟以内的任务,则完全跳过。
重试场景
如果你打开任务后,kanban_show 返回的 runs: [...] 中有一个或多个已关闭的运行记录,说明这是一次重试。先前运行的 outcome / summary / error 会告诉你哪里出了问题。不要重复那条路径。常见的重试诊断信息:
outcome: "timed_out"— 上一次尝试触及了max_runtime_seconds。你可能需要将工作拆分成多个部分,或缩短工作内容。outcome: "crashed"— 内存溢出或段错误。请减少内存占用。outcome: "spawn_failed"+error: "..."— 通常是配置文件问题(凭据缺失、PATH 错误)。请通过kanban_block向人工操作员求助,而不是盲目重试。outcome: "reclaimed"+summary: "task archived..."— 操作员在上一次运行期间归档了任务;你可能根本不应该继续运行,请仔细检查状态。outcome: "blocked"— 上一次尝试已阻塞;现在讨论串中应该已经有解除阻塞的评论。
通知路由
你可以通过向 ~/.hermes/config.yaml 添加 notification_sources,将网关配置为接收跨配置文件的 Kanban 任务通知。
notification_sources: ['*']接受来自所有配置文件的订阅。notification_sources: ['default', 'zilor-ppt']或"default,zilor-ppt"将订阅限制为指定的配置文件。- 省略此键可保留默认行为(配置文件隔离)。
请勿
- 将
delegate_task用作kanban_create的替代。delegate_task用于你本次运行中的短期推理子任务;kanban_create用于跨 Agent 移交,且任务会持续超过一次 API 循环。 - 使用
clarify向人工操作员提问。你以无头模式运行——没有实时用户可以回答。该调用会超时(默认约 120 秒),任务会悄无声息地停留在running状态,也不会发出需要输入的信号。请改用kanban_comment(提供上下文)+kanban_block(reason=...)(需要做出决定);这样任务会以阻塞状态显示在看板上,操作员可以看到它,在评论中给出答复并解除阻塞,而你会带着讨论串重新启动。 - 除非任务正文有说明,否则不要修改
$HERMES_KANBAN_WORKSPACE以外的文件。 - 不要创建分配给自己的后续任务——请分配给合适的专员。
- 不要完成实际上尚未完成的任务。应将其阻塞。
注意事项
任务状态可能会在调度和启动之间发生变化。 从调度程序认领任务到进程实际启动期间,任务可能已被阻塞、重新分配或归档。务必先运行 kanban_show。如果它报告状态为 blocked 或 archived,请停止——你不应该继续运行。
工作区可能包含过期的文件。 尤其是 dir: 和 worktree 工作区,可能留有先前运行生成的文件。请阅读评论讨论串;其中通常会说明你为何再次运行,以及工作区当前的状态。
有工具可用时,不要依赖 CLI。 kanban_* 工具适用于所有终端后端(Docker、Modal、SSH)。在容器化后端中,从终端工具运行 hermes kanban <verb> 会失败,因为那里没有安装 CLI。如有疑问,请使用工具。
CLI 备用方式(用于脚本)
每个工具都有对应的 CLI 命令,供人工操作员和脚本使用:
kanban_show↔hermes kanban show <id> --jsonkanban_complete↔hermes kanban complete <id> --summary "..." --metadata '{...}'kanban_block↔hermes kanban block <id> "reason"kanban_create↔hermes kanban create "title" --assignee <profile> [--parent <id>]- 等等。
在 Agent 内部请使用工具;CLI 是供使用终端的人工操作员使用的。