Hermes Agent + 飞书卡片交互:打造智能自动化工作流

前言

在日常使用 Hermes Agent 的过程中,我逐渐探索出一套高效的飞书卡片交互方案。通过卡片按钮替代传统的文字选择,用户只需轻点按钮即可完成复杂操作,大大提升了交互体验和自动化效率。

本文记录了从零开始实现飞书卡片交互的全过程,包括遇到的问题和解决方案。

飞书卡片交互示意

实现过程遇到的问题

问题一:卡片按钮点击报错

现象:点击飞书卡片按钮后,日志报错:

1
2
TypeError: GatewayRunner._handle_message_with_agent() missing 3 required 
positional arguments: 'source', '_quick_key', and 'run_generation'

原因_handle_card_button_event 调用 _handle_message_with_agent 时缺少3个参数,而调用处没传这些参数。

解决方案:修改 gateway/run.py,在调用处传入必要的参数:

1
2
3
4
5
if canonical == "card":
source = event.source
_quick_key = self._session_key_for_source(source)
_run_generation = self._begin_session_run_generation(_quick_key)
return await self._handle_card_button_event(event, source, _quick_key, _run_generation)

问题二:所有按钮都被当作审批处理

现象:发送的卡片按钮点击后没有任何响应,agent 似乎在等待什么。

原因_on_card_action_trigger 方法把所有带 hermes_action 的按钮都当作审批按钮处理,导致 agent 线程阻塞等待一个永远不来的 approval_id

解决方案:只有当 approval_id 存在时才走审批流程:

1
2
3
4
5
6
7
if hermes_action:
approval_id = action_value.get("approval_id")
if approval_id is not None:
return self._handle_approval_card_action(...)
# 非审批按钮:直接提交事件处理
self._submit_on_loop(loop, self._handle_card_action_event(data))
return P2CardActionTriggerResponse()

问题三:send_message 工具的 card 参数格式

现象:尝试发送卡片时报错,参数无法识别。

原因card 参数必须是 JSON 字符串,而不是对象。

错误写法

1
send_message(target="feishu", card={...})  # 错误

正确写法

1
2
import json
send_message(target="feishu", card=json.dumps({...})) # 正确

问题四:飞书卡片不支持编辑更新

现象:希望点击后卡片内容变化,但飞书不支持编辑已发送的卡片。

原因:飞书开放平台的交互卡片不支持编辑更新。

解决方案

  • 方案A:点击后发送一条新消息(普通文本或新卡片)告知结果
  • 方案B:更新后发送一条新卡片替换原卡片
  • 方案C:使用 patch_card_to_resolved 方法更新卡片显示选择结果

问题五:补丁管理 - 更新 Hermes 后补丁丢失

现象:更新 Hermes 后,之前修改的代码被覆盖,卡片交互功能失效。

原因:直接修改源代码文件,更新会被覆盖。

解决方案:使用补丁管理系统集中管理所有修改:

1
2
3
4
5
# 查看补丁状态
python3 ~/.hermes/hermes-patches/apply_patches.py --status

# 更新后批量应用所有补丁
python3 ~/.hermes/hermes-patches/apply_patches.py --apply

已追踪的补丁列表:

补丁 说明
001-context_engine-api_mode.patch ContextEngine.update_model 增加 api_mode 参数
002-commands-card-command.patch 注册 /card 命令到 COMMAND_REGISTRY
003-browser-tool-sandbox.patch 浏览器沙盒 flags 兼容 AGENT_BROWSER_ARGS
004-send-message-card-support.patch send_message 工具增加 card 参数
005-run-card-button-fix.patch 卡片按钮点击处理(调用处 + 函数定义)
006-feishu-card-methods.patch Feishu 平台 patch_card_to_resolved 等方法

为什么选择卡片交互?

传统的对话式交互需要用户手动输入文字来选择操作,不仅效率低下,还容易出现输入错误。卡片交互带来了以下优势:

  • 操作直观:按钮清晰可见,点击即可执行
  • 减少错误:避免了文字输入的拼写错误
  • 提升效率:用户可以快速完成选择,无需打字
  • 视觉友好:卡片可以包含丰富的视觉元素

卡片发送机制

通过 send_message 工具的 card 参数发送交互式卡片:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
send_message(
action="send",
target="feishu",
card=json.dumps({
"config": {"wide_screen_mode": True},
"header": {
"title": {"content": "请选择操作", "tag": "plain_text"},
"template": "blue"
},
"elements": [
{"tag": "markdown", "content": "请选择要执行的操作:"},
{"tag": "hr"},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "确认"},
"type": "primary",
"value": {"hermes_action": "confirm_action"}
},
{
"tag": "button",
"text": {"tag": "plain_text", "content": "取消"},
"type": "danger",
"value": {"hermes_action": "cancel_action"}
}
]
}
]
})
)

按钮点击事件处理

按钮点击后,Hermes 会收到 /card button {"hermes_action": "xxx"} 格式的消息,自动解析并执行对应操作:

action 格式 用途 示例
opt_序号_描述 多选项 opt_1_入库, opt_2_出库
confirm_xxx 确认操作 confirm_delete, confirm_send
cancel_xxx 取消操作 cancel_edit, cancel_backup
yes_xxx / no_xxx 是/否选择 yes_restart, no_save

hermes_action 命名规范

良好的命名规范可以让代码更易维护:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 多选项:用 opt_序号_描述
hermes_action = "opt_1_入库"
hermes_action = "opt_2_出库"
hermes_action = "opt_3_查询库存"

# 确认操作:用 confirm_动作
hermes_action = "confirm_delete"
hermes_action = "confirm_send"

# 取消操作:用 cancel_动作
hermes_action = "cancel_edit"
hermes_action = "cancel_backup"

# 是/否选择:用 yes_动作 / no_动作
hermes_action = "yes_restart"
hermes_action = "no_save"

卡片模板规范

为了保持一致性,我们建立了标准的卡片模板规范:

场景 模板颜色 按钮类型
普通选择 blue primary / default
警告确认 orange primary / danger
成功反馈 green primary
重要操作 red / purple primary / danger

异步交互流程

卡片交互是异步的,流程如下:

  1. 发送卡片 -> Agent 发送带按钮的卡片给用户
  2. 等待点击 -> 用户在飞书中点击按钮
  3. 事件触发 -> Hermes 收到 /card button 事件
  4. 执行操作 -> Agent 根据 action 执行对应逻辑
  5. 结果反馈 -> 发送新卡片或消息展示结果

应用场景

场景一:生姜进销存管理

通过卡片快速执行入库、出库、查询等操作:

  • 入库:扫描单据 -> 卡片确认 -> 自动更新库存
  • 出库:选择货主 -> 输入数量 -> 卡片确认出库
  • 查询:输入查询条件 -> 卡片展示结果 -> 选择操作

场景二:自动化任务确认

执行重要操作前,通过卡片让用户确认:

  • 文件删除确认
  • 服务器重启确认
  • 批量操作确认

场景三:多步骤工作流

将复杂任务拆分为多个卡片步骤:

  1. 步骤选择卡片 -> 用户选择要执行的任务
  2. 参数输入卡片 -> 用户输入必要参数
  3. 确认执行卡片 -> 用户确认后执行
  4. 结果展示卡片 -> 展示执行结果和后续选项

总结

通过 Hermes Agent 与飞书卡片交互的结合,我们可以实现:

  • 更高效的交互 - 点击代替打字
  • 更低的错误率 - 减少手动输入
  • 更好的用户体验 - 直观友好的界面
  • 更灵活的自动化 - 支持复杂工作流

这种交互模式特别适合需要频繁进行选择确认的业务场景,如进销存管理、任务审批、数据查询等。

遇到问题不要怕,每一次调试都是学习的机会。关键是做好记录和总结,方便以后遇到类似问题时快速解决。

参考资源


如果你也有好的自动化工作流经验,欢迎交流分享!