Skip to content

hermes agent 看板教程

这是对 Hermes 看板系统所设计的四个用例的演练,假设你已在浏览器中打开了仪表板。如果你还没有阅读过 Kanban 概览,请先从那里开始——本篇假设你已经了解什么是任务(task)、运行(run)、受理人(assignee)和调度器(dispatcher)。

Terminal window
hermes kanban init # 可选;首次执行任何 `hermes kanban <anything>` 命令会自动初始化
hermes dashboard # 在浏览器中打开 http://127.0.0.1:9119
# 点击左侧导航栏中的 Kanban

仪表板是 观察系统最舒适的地方。由调度器产生的智能体工人(Agent workers)永远不会看到仪表板或 CLI——它们通过一套专用的 kanban_* 工具集kanban_show, kanban_list, kanban_complete, kanban_block, kanban_heartbeat, kanban_comment, kanban_create, kanban_link, kanban_unblock)来驱动看板。所有三个界面——仪表板、CLI、工人工具——都路由到同一个各看板唯一的 SQLite 数据库(默认看板为 ~/.hermes/kanban.db,之后创建的任何看板为 ~/.hermes/kanban/boards/<slug>/kanban.db),因此无论变更来自哪一方,每个看板的内容都是一致的。

本教程全程使用 default 看板。如果你想要多个隔离的队列(每个项目/仓库/领域一个),请参阅概览中的 Boards (多项目) —— 相同的 CLI / 仪表板 / 工人流程适用于每个看板,且工人物理上无法看到其他看板上的任务。

在整个教程中,标记为 bash 的代码块是 运行的命令。标记为 # worker tool calls 的代码块是生成的工人的模型发出的工具调用——在这里展示是为了让你看到端到端的闭环,而不是因为你需要亲自运行它们。

视图

从左到右共有六列:

  • Triage(分选) — 原始想法,在投入工作前,规范制定者(specifier)会细化其规范。点击任何分选卡片上的 ✨ Specify 按钮(或从聊天中运行 hermes kanban specify <id> / /kanban specify <id>),辅助 LLM 将会一键把简短的描述转变为完整的规范(目标、方法、验收标准),并将其提升至 Todo 列。在 config.yamlauxiliary.triage_specifier 项下可以配置运行此功能的模型。
  • Todo(待办) — 已创建但正在等待依赖项,或尚未分配。
  • Ready(就绪) — 已分配并等待调度器(dispatcher)领取。
  • In progress(进行中) — 工人正在积极执行该任务。在开启 “Lanes by profile”(按配置文件分列,默认开启)的情况下,此列会按受理人进行子分组,以便你一目了然地看到每个工人正在做什么。
  • Blocked(阻塞) — 工人请求人工输入,或断路器(circuit breaker)跳闸。
  • Done(完成) — 已完成。

顶部栏设有搜索、租户和受理人的过滤器,以及一个 Lanes by profile 切换开关和一个 Nudge dispatcher 按钮。点击该按钮可立即运行一次调度周期,而无需等待守护进程的下一个间隔。点击任何卡片即可在右侧打开其抽屉详情。

如果配置文件泳道(Lanes by profile)显得杂乱,可以将其切换为关闭状态,此时 “进行中”(In Progress)列将折叠为一个按领取时间排序的扁平列表:

示例

你正在构建一个功能。经典的流程:设计模式(schema)、实现 API、编写测试。这是三个具有 父任务→子任务 依赖项的任务。

Terminal window
SCHEMA=$(hermes kanban create "Design auth schema" \
--assignee backend-dev --tenant auth-project --priority 2 \
--body "Design the user/session/token schema for the auth module." \
--json | jq -r .id)
API=$(hermes kanban create "Implement auth API endpoints" \
--assignee backend-dev --tenant auth-project --priority 2 \
--parent $SCHEMA \
--body "POST /register, POST /login, POST /refresh, POST /logout." \
--json | jq -r .id)
hermes kanban create "Write auth integration tests" \
--assignee qa-dev --tenant auth-project --priority 2 \
--parent $API \
--body "Cover happy path, wrong password, expired token, concurrent refresh."

由于 APISCHEMA 设为父级,而 testsAPI 设为父级,因此只有 SCHEMA 会起始于 ready(就绪)状态。另外两个任务将停留在 todo(待办)中,直到它们的父级任务完成。这就是“依赖项提升引擎”在发挥作用——在有 API 可供测试之前,不会有其他工人领取编写测试的任务。

在下一次调度周期(默认 60 秒,或者如果你点击了 Nudge dispatcher 则立即执行)中,backend-dev 配置文件将产生一个环境变量中带有 HERMES_KANBAN_TASK=$SCHEMA 的工人。以下是该工人在智能体内部的工具调用循环示例:

# worker tool calls — 不是你运行的命令
kanban_show()
# → 返回 title, body, worker_context, parents, prior attempts, comments
# (工人读取 worker_context,使用终端/文件工具设计模式,
# 编写迁移脚本,运行其自身的检查,提交代码 —— 真正的工作在这里发生)
kanban_heartbeat(note="schema drafted, writing migrations now")
kanban_complete(
summary="users(id, email, pw_hash), sessions(id, user_id, jti, expires_at); "
"refresh tokens stored as sessions with type='refresh'",
metadata={
"changed_files": ["migrations/001_users.sql", "migrations/002_sessions.sql"],
"decisions": ["bcrypt for hashing", "JWT for session tokens",
"7-day refresh, 15-min access"],
},
)

kanban_show 默认将 task_id 设置为 $HERMES_KANBAN_TASK,因此工人不需要知道自己的 ID。kanban_complete 将摘要(summary)和元数据(metadata)写入当前的 task_runs 行,关闭该次运行,并将任务转换为 done(完成)——这一切都是通过 kanban_db 原子化完成的。

SCHEMA 变为 done 时,依赖引擎会自动将 API 提升至 ready。当 API 工人领取任务并调用 kanban_show() 时,它会看到附加在父级交接信息中的 SCHEMA 的摘要和元数据——这样它无需重新阅读冗长的设计文档就能了解模式决策。

点击看板上已完成的架构任务,抽屉详情将显示所有内容:

示例

底部的 Run History(运行历史) 部分是关键的补充。一次尝试:结果为 completed(已完成),工人为 @backend-dev,以及耗时、时间戳和完整的交接摘要。元数据块(changed_files, decisions)也存储在该次运行中,并呈现给任何读取此父任务的下游工人。

你可以随时在终端查看相同的数据——这些命令是在查看看板,而不是工人:

Terminal window
hermes kanban show $SCHEMA
hermes kanban runs $SCHEMA
# # OUTCOME PROFILE ELAPSED STARTED
# 1 completed backend-dev 0s 2026-04-27 19:34
# → users(id, email, pw_hash), sessions(id, user_id, jti, expires_at); refresh tokens ...

你拥有三个工人(一名翻译员、一名转录员、一名文案撰稿人)和一堆相互独立的任务。你希望这三个工人并行工作,并能看到明显的进展。这是看板最简单的用例,也是原始设计所优化的方向。

创建工作任务:

Terminal window
for lang in Spanish French German; do
hermes kanban create "Translate homepage to $lang" \
--assignee translator --tenant content-ops
done
for i in 1 2 3 4 5; do
hermes kanban create "Transcribe Q3 customer call #$i" \
--assignee transcriber --tenant content-ops
done
for sku in 1001 1002 1003 1004; do
hermes kanban create "Generate product description: SKU-$sku" \
--assignee copywriter --tenant content-ops
done

启动网关然后离开即可 —— 它托管了嵌入式调度器,会自动在同一个 kanban.db 上领取所有这三个专家配置文件的任务:

Terminal window
hermes gateway start

现在将看板过滤到 content-ops 租户(或者直接搜索 “Transcribe”),你将看到如下界面:

示例

两个转录任务已完成,一个正在运行,两个处于就绪状态等待下一次调度周期。“进行中”(In Progress)列按配置文件分组(“Lanes by profile” 默认设置),因此你可以看到每个工人的活动任务,而无需在混合列表中扫视。一旦当前任务完成,调度器将立即把下一个就绪任务提升为运行状态。随着三个守护进程并行处理三个受理人池,整个内容队列将在无需进一步人工干预的情况下消耗完毕。

故事 1 中提到的所有关于结构化交接的内容在这里依然适用。一个翻译工人在完成任务时会发出 kanban_complete(summary="translated 4 pages, style matched existing marketing voice", metadata={"duration_seconds": 720, "tokens_used": 2100}) —— 这对于分析以及任何依赖该任务的下游任务都非常有用。

故事 3 — 带重试机制的角色流水线

Section titled “故事 3 — 带重试机制的角色流水线”

这就是看板系统优于扁平待办事项列表(TODO list)的地方。PM 编写规范,工程师负责实现,审查者(reviewer)拒绝了第一次尝试,工程师根据修改意见再次尝试,最后审查者批准通过。

仪表板视图,已按 auth-project 过滤:

示例

三阶段链条清晰可见:Spec: password reset flowDONE,pm)、Implement password reset flowDONE,backend-dev)、Review password reset PRREADY,reviewer)。每个任务底部都有绿色的父级链接,并以子级作为依赖项。

其中最有趣的是实现任务,因为它经历过被阻塞(blocked)和重试。以下是三个智能体协作的完整流程,以每个工人的模型所执行的工具调用形式展示:

# --- PM 工人在 $SPEC 任务上启动并编写验收标准 ---
# worker tool calls
kanban_show()
kanban_complete(
summary="规范已批准;POST /forgot-password 发送邮件,"
"GET /reset/:token 渲染表单,POST /reset 应用新密码",
metadata={"acceptance": [
"过期的 token 返回 410",
"重复使用最近 3 次的密码返回 400 并附带消息",
"重置成功后使所有活动会话失效",
]},
)
# → $SPEC 已完成;$IMPL 自动从 todo 提升至 ready
# --- 工程师工人在 $IMPL 任务上启动(第一次尝试) ---
# worker tool calls
kanban_show() # 在 worker_context 中读取 $SPEC 的摘要和验收元数据
# (工程师编写代码,运行测试,开启 PR)
# 审查意见到达 —— 工程师认为这些担忧是合理的,并阻塞任务
kanban_block(
reason="审查反馈:缺少密码强度检查,重置链接并非一次性"
"(30分钟内可重复使用)",
)
# → $IMPL 转换为 blocked;运行 1 关闭,结果为 outcome='blocked'

现在,你(人类,或者一个单独的审查者配置文件)阅读阻塞原因,决定修复方向是明确的,并从仪表板的 “Unblock” 按钮点击取消阻塞——或者通过 CLI / 斜杠命令:

Terminal window
hermes kanban unblock $IMPL
# 或者从聊天窗口:/kanban unblock $IMPL

调度器将 $IMPL 重新提升至 ready,并在下一次周期重新启动 backend-dev 工人。这次启动是同一个任务下的 新运行(new run)

# --- 工程师工人在 $IMPL 任务上启动(第二次尝试) ---
# worker tool calls
kanban_show()
# → worker_context 现在包含了运行 1 的阻塞原因,因此该工人知道
# 哪两件事需要修复,而不需要重新阅读整个规范
# (工程师添加了 zxcvbn 检查,使重置 token 变为一次性,重新运行测试)
kanban_complete(
summary="添加了 zxcvbn 强度检查,重置 token 现在是一次性的"
"(成功后存储并删除)",
metadata={
"changed_files": [
"auth/reset.py",
"auth/tests/test_reset.py",
"migrations/003_single_use_reset_tokens.sql",
],
"tests_run": 11,
"review_iteration": 2,
},
)

点击实现任务。抽屉详情显示了 两次尝试

示例

  • Run 1 — 由 @backend-dev 阻塞(blocked)。审查反馈就在结果下方:“缺少密码强度检查,重置链接并非一次性(30分钟内可重复使用)”。
  • Run 2 — 由 @backend-dev 完成(completed)。全新的摘要,全新的元数据。

每一次运行都是 task_runs 表中的一行,拥有自己的结果、摘要和元数据。重试历史并不是层叠在“最新状态”任务之上的概念性补丁——它是主要的表现形式。当重试的工人打开任务时,build_worker_context 会向其展示之前的尝试记录,因此第二次尝试的工人能看到第一次为何被阻断,并针对性地解决这些具体发现,而不是从头开始。

接下来由审查者接手。当他们打开 Review password reset PR 时,会看到:

示例

父级链接是已完成的实现任务。当审查者的工人在 Review password reset PR 上启动并调用 kanban_show() 时,返回的 worker_context 会包含父任务“最近一次完成运行”的摘要和元数据——因此审查者在查看差异(diff)之前,就已经读到了“添加了 zxcvbn 强度检查,重置 token 现在是一次性的”以及变更文件列表。

真实环境中的工人会失败。丢失凭据、OOM(内存溢出)杀掉进程、瞬时网络错误。调度器有两道防线:一个在连续 N 次失败后自动阻塞的断路器(circuit breaker),防止看板无限震荡;以及一个崩溃检测(crash detection)机制,用于回收那些在 TTL 过期前进程 PID 消失的任务。

一个部署任务因为配置文件的环境变量中未设置 AWS_ACCESS_KEY_ID 而无法启动工人:

Terminal window
hermes kanban create "Deploy to staging (missing creds)" \
--assignee deploy-bot --tenant ops \
--max-retries 3

dispatcher 会尝试启动 worker。启动失败(RuntimeError: AWS_ACCESS_KEY_ID not set)。dispatcher 会释放 claim,递增失败计数器,并在下一次 tick 再次尝试。因为这个示例设置了 --max-retries 3,所以连续失败三次后熔断器会触发:任务进入 blocked,outcome 为 gave_up。如果你省略该标志,Hermes 会使用 kanban.failure_limit(默认值:2)。在人工解除阻塞之前,不会再重试。

点击该被阻塞的任务:

示例

共有三次运行,error 字段显示的错误均相同。前两次是 spawn_failed(可重试),第三次是 gave_up(终止)。上方的事件日志显示了完整序列:created → claimed → spawn_failed → claimed → spawn_failed → claimed → gave_up

在终端上查看:

Terminal window
hermes kanban runs t_ef5d
# # OUTCOME PROFILE ELAPSED STARTED
# 1 spawn_failed deploy-bot 0s 2026-04-27 19:34
# ! AWS_ACCESS_KEY_ID not set in deploy-bot env
# 2 spawn_failed deploy-bot 0s 2026-04-27 19:34
# ! AWS_ACCESS_KEY_ID not set in deploy-bot env
# 3 gave_up deploy-bot 0s 2026-04-27 19:34
# ! AWS_ACCESS_KEY_ID not set in deploy-bot env

如果配置了 Telegram / Discord / Slack,网关会在 gave_up 事件发生时发出通知,这样你无需查看看板也能获知故障。

有时启动成功了,但工人进程随后死亡——段错误(segfault)、OOM、或 systemctl stop。调度器会轮询 kill(pid, 0) 并检测死亡的 PID;随后释放占用,任务回到 ready 状态,并在下一个周期交给一个新的工人。

种子数据中的示例是一个因内存不足而失败的迁移任务:

Terminal window
# Worker claims, starts scanning 2.4M rows, OOM kills it at ~2.3M
# Dispatcher detects dead pid, releases claim, increments attempt counter
# Retry with a chunked strategy succeeds

抽屉详情显示了完整的两次尝试历史:

示例

  • Run 1crashed(崩溃),带有错误信息 OOM kill at row 2.3M (process 99999 gone)
  • Run 2completed(已完成),其元数据中包含 "strategy": "chunked with LIMIT + WHERE id > last_id"

重试的工人在其上下文中看到了 Run 1 的崩溃记录,并选择了一个更安全的策略;这些元数据让未来的观察者(或事后分析报告撰写者)能清晰地看出发生了什么变化。

结构化交接 — 为什么摘要(summary)和元数据(metadata)至关重要

Section titled “结构化交接 — 为什么摘要(summary)和元数据(metadata)至关重要”

在上述每一个故事中,工人们在结束时都调用了 kanban_complete(summary=..., metadata=...)。这并非装饰性的——它是工作流各阶段之间主要的交接通道。

当任务 B 的工人在启动并调用 kanban_show() 时,它获取的 worker_context 包括:

  • B 的历史尝试记录(过往运行:结果、摘要、错误、元数据),以便重试的工人不会重复失败的路径。
  • 父任务结果 — 对于每一个父任务,包含其最近一次完成运行的摘要和元数据 —— 这样下游工人就能看到上游工作 为什么 做以及 怎么 做的。

这取代了困扰扁平看板系统的“翻找评论和工作产出”的繁琐过程。PM 在规范任务的元数据中编写验收标准,工程师工人就能在父级交接中结构化地看到它们。工程师记录他们运行了哪些测试以及通过了多少个,审查者的工人在打开代码差异(diff)之前,手中就已经拿到了这份列表。

批量关闭保护(Bulk-close guard)的存在是因为这些数据是针对每次运行的。如果你在 CLI 中运行 hermes kanban complete a b c --summary X 将会被拒绝 —— 将相同的摘要复制粘贴到三个任务中几乎总是错误的。如果不带交接标志的批量关闭对于常见的 “我完成了一堆管理杂务” 的情况仍然有效。工人工具界面根本没有提供批量操作的变体;出于同样的原因,kanban_complete 始终一次只能处理单个任务。

为了保证完整性 —— 这是一个仍在进行中的任务抽屉(来自故事 1 的 API 实现,已被 backend-dev 领取但尚未完成):

示例

状态为 Running(运行中)。当前活跃的运行记录出现在 Run History(运行历史)部分,结果为 active 且没有 ended_at(结束时间)。如果该工人死亡或超时,调度器会以相应的结果关闭此次运行,并在下次领取时开启一次新的运行 —— 尝试记录(attempt row)永远不会消失。

  • Kanban 概览 — 完整的数据模型、事件词汇表和 CLI 参考。
  • hermes kanban —help — 每个子命令、每个标志位。
  • hermes kanban watch —kinds completed,gave_up,timed_out — 实时流式传输整个看板的终端事件。
  • **hermes kanban notify-subscribe —platform telegram —chat-id ** — 当特定任务完成时,获取网关推送。
-
0:000:00