mcpField
K
kanban-worker

kanban-worker

github.com/nousresearchAgent 工作流258.1k148 次安装今天更新
代码仓库

关于 kanban-worker

kanban-worker 是供 Hermes 分派任务时加载的技能,说明如何处理工作区、提交任务交接、诊断重试、等待人工输入,以及在完成时附上交付文件。

主要功能

  1. 01处理临时、共享和 worktree 工作区
  2. 02规范完成摘要与元数据
  3. 03在任务完成时附加交付文件
  4. 04以明确的决策请求阻塞任务
  5. 05根据先前运行结果诊断重试
  6. 06遵守租户与任务边界

适用场景

  1. 01提交包含测试详情的代码变更
  2. 02交付报告或其他生成文件
  3. 03等待人工决策时暂停任务
  4. 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> --json
  • kanban_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 是供使用终端的人工操作员使用的。

评论

支持 Markdown