Hermes Agent 审批按钮源码解析:feishu.py:1906-1909 的 Allow Once/Session/Always/Deny 实现与 TaoToken 接入
1. 飞书里点下「Always」那一刻Hermes Agent 到底做了什么Hermes Agent 是一个把大模型能力接到聊天平台里的 Agent 框架飞书、Telegram 都能挂。它最实用的一个设计是当模型准备执行一条有副作用的命令时不会闷头就跑而是先在聊天窗口里弹出一排审批按钮让你人工点一下。这四个按钮就是 Allow Once、Session、Always、Deny对应「本次放行」「本会话放行」「永久放行」「拒绝」。如果你正在做飞书机器人、想让 Agent 帮你跑 git、ls、cat 这类命令又不想它哪天手滑执行 rm -rf那这套审批机制就是你的安全阀。而它的核心实现就藏在feishu.py第 1906 到 1909 行这短短几行里。很多人第一次看到这段代码会懵四个按钮怎么映射到四种权限audit log 又是在哪一步落盘的exec_allowlist 和按钮是什么关系这篇就按「先看问题场景 → 再讲 TaoToken 前置 → 给出可复制配置 → 验证请求 → 排错 → 收尾」的顺序走一遍。我会把feishu.py:1906-1909的分支逻辑逐行拆开给你能直接抄的审批回调配置片段再带你用 exec_allowlist 验证按钮行为、确认日志真的写进了磁盘。全程本地可复现不需要你先把整个 Agent 跑通才看得懂。先说清楚适合谁一是已经在用 Hermes Agent、被「Always」按钮坑过的人二是想给自己的飞书机器人加审批交互的开发者三是想搞明白「按钮回调 审计日志 命令白名单」这套组合拳怎么落地的人。如果你只是想让模型跑起来聊天那这篇偏底层可以先收藏。2. TaoToken 前置统一 Key 与 API 通道别让审批链路卡在鉴权上在拆按钮逻辑之前得先把模型调用这条链路铺好。Hermes Agent 的审批按钮之所以会弹出来前提是模型已经能正常对话、能发起工具调用。如果 Key 或 Base URL 配错你连按钮都见不到直接 401 就结束了。所以这一步是后面所有验证的地基。我这边统一用 TaoToken 来做模型通道。它的作用是给你一个兼容 OpenAI 风格的 API 入口把 Key 和 Base URL 收敛成一套飞书场景、本地调试、CI 里都能复用同一个通道不用每个平台各配一份。官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 根地址是 https://taotoken.net/api 注意这个 API 地址后面不加任何查询参数。具体要准备三样东西这也是后面所有配置里反复出现的「三件套」配置项取值说明Base URLhttps://taotoken.net/apiOpenAI 兼容入口末尾不要带斜杠API Key在控制台生成形如sk-...只显示一次记得存好Model ID按你订阅的模型填例如claude-sonnet-4-5之类以控制台实际列表为准Key 的生成入口在控制台的 API Keys 页面地址是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。生成之后先别急着填进 Hermes建议用一条 curl 单独验证通道通不通curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-5, messages: [{role: user, content: ping}], max_tokens: 16 }返回里能看到choices[0].message.content就说明通道没问题。这一步很关键因为 Hermes 的审批按钮依赖模型能正常返回工具调用意图通道不通的话你后面调feishu.py的按钮逻辑会一直以为是代码问题其实是 Key 没生效。如果你打算长期跑编码类 Agent、频繁触发审批可以考虑用 Coding Plan 那套订阅入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。它更适合高频调用场景省得每次都在额度上卡壳。模型对话的在线调试入口则是 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 想先确认某个 Model ID 能不能用直接在那里试一句最省事。把这三件套记牢Base URL、Key、Model ID。后面无论是 Hermes 的 config.yaml还是 Claude Code 的 settings.json填的都是这三样只是字段名不同。3. 可复制配置feishu.py:1906-1909 分支逻辑与审批回调片段现在进入正题。feishu.py第 1906 到 1909 行是飞书审批按钮回调的核心分支。它的结构大致是这样收到按钮点击事件后先取出button_id和user_id写一条 audit log然后根据button_id决定这次命令的放行范围。四个按钮对应四种语义allow_once只放行当前这一条命令执行完权限即失效。allow_session在当前会话生命周期内同类命令不再弹窗。allow_always写入持久化白名单之后一直放行这是最危险的一个。deny直接拒绝命令不执行同时记录拒绝原因。用伪代码还原这四行的分支意图方便你对照自己仓库里的真实实现# feishu.py:1906-1909 语义还原 def on_approval_button(button_id, user_id, command, session_id): audit_log(user_iduser_id, button_idbutton_id, commandcommand, tsnow()) if button_id allow_once: grant(command, scopeonce, session_idsession_id) elif button_id allow_session: grant(command, scopesession, session_idsession_id) elif button_id allow_always: require_admin_confirmation(user_id) # 二次确认别省 grant(command, scopealways) else: # deny reject(command, reasonuser_denied)注意allow_always那一步我在还原里特意加了require_admin_confirmation。原实现里如果没做二次确认强烈建议你补上因为「永远批」一旦写进白名单后面再想收回就得手动改配置文件。这是踩过的坑早期版本里 Always 是直接生效的结果有人点了之后Agent 连着跑了一串危险命令都没再拦。接下来是配置层。Hermes 的配置在~/.hermes/config.yaml和审批、沙箱、白名单相关的字段集中在这几块# ~/.hermes/config.yaml terminal: backend: docker # 危险命令丢进沙箱影响面小 security: tirith_enabled: true # 自动拦截高危命令 exec_allowlist: - git status - ls - cat - pwd exec_denylist: - rm -rf - curl|sh - sudoexec_allowlist和审批按钮是互补关系白名单里的命令直接放行不弹按钮白名单外、又不在 denylist 里的命令才会触发那四个按钮。所以你想复现按钮行为就得先确保测试命令不在 allowlist 里否则你点不到按钮会误以为回调没生效。如果你用的是 Claude Code 那套配置字段名不一样但三件套还是那三样。settings.json里长这样{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的Key, ANTHROPIC_MODEL: claude-sonnet-4-5 } }飞书侧的审批回调需要在飞书开放平台把卡片按钮的 action 指向你的回调地址payload 里带上button_id、command、session_id。回调处理函数就复用上面on_approval_button的逻辑。这样按钮点下去audit log 先落盘再决定放行范围顺序不能反——先授权后记日志出了事你查不到是谁批的。4. 验证请求跑一条危险命令看四个按钮和日志落盘配置写完得验证。第一步先确认 Hermes 能起来uv run python hermes启动后在飞书里给机器人发一条会触发审批的命令比如让它执行rm -rf /tmp/hermes-test测试目录别拿真实数据试。正常情况下聊天窗口会弹出那张带四个按钮的卡片。点Allow Once命令执行一次再发同样的命令应该再次弹窗说明 once 作用域没持久化。点Session同一会话内再发同类命令不再弹窗。点Deny命令不执行返回拒绝提示。这三个行为验证完基本能确认feishu.py:1906-1909的分支是通的。然后是 audit log。日志默认落在 Hermes 的数据目录下具体路径看你的配置常见的是~/.hermes/logs/audit.log。点完按钮后用这条命令确认落盘tail -n 20 ~/.hermes/logs/audit.log你应该能看到类似这样的记录{ts:2025-01-01T10:00:00Z,user_id:ou_xxx,button_id:allow_once,command:rm -rf /tmp/hermes-test,scope:once}每条记录都带user_id、button_id、command、scope这就是审计的四个关键字段。如果日志里只有 command 没有 user_id说明你的audit_log调用漏了参数回去补上。再验证 exec_allowlist。把git status加进 allowlist重启 Hermes发一条git status这次应该直接执行、不弹按钮。把rm -rf加进 denylist发一条rm -rf /tmp/x应该直接被拦连按钮都不弹。这两步验证完白名单和黑名单的优先级就清楚了denylist 优先于 allowlistallowlist 优先于按钮弹窗。最后确认模型通道没拖后腿。如果按钮弹出来了但点完没反应先看 Hermes 的日志里有没有模型调用报错。用前面那条 curl 再测一次通道确认 Base URL 和 Key 还有效。通道、按钮、日志三者都通这条链路才算完整。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节按真实会撞到的报错来对。每个报错我都给现象、根因、修法。401 Unauthorized。现象是 Hermes 启动后模型调用直接失败飞书里连按钮都看不到。根因九成是 Key 没生效或 Base URL 写错。检查config.yaml或settings.json里的 Key 是不是完整、有没有多余空格Base URL 是不是https://taotoken.net/api末尾别加斜杠也别加/v1具体以文档为准。修完用 curl 复测一次。local proxy failed。现象是请求发不出去日志里出现连接失败。根因通常是本地网络环境或代理配置干扰了出站请求。检查你的环境变量里有没有残留的HTTP_PROXY、HTTPS_PROXY有的话先清掉再试。Hermes 走的是标准 HTTPS 出站不需要额外代理层。reading choices 报错。现象是模型返回了内容但解析choices字段时报错常见于返回体不是预期的 OpenAI 结构。根因可能是 Model ID 填错或者通道返回了错误对象。先确认 Model ID 和控制台列表一致再用 curl 看原始返回体里有没有choices字段。如果返回的是{error: ...}那就是通道侧的问题检查 Key 权限。OAuth 相关报错。现象是飞书侧回调鉴权失败按钮点了没反应。根因是飞书应用的 OAuth 配置或回调地址没对齐。检查飞书开放平台里的事件订阅地址、卡片回调地址是否和你的服务一致token 校验是否通过。这块和模型通道无关别混在一起查。排查顺序建议固定成先 curl 验通道 → 再看 Hermes 启动日志 → 再查飞书回调 → 最后看 audit log。按这个顺序走能避免在错误的方向上浪费时间。如果通道侧需要重新生成 Key去 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 处理接入细节看文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。6. 把审批链路收进一套 Key长期跑更省心feishu.py:1906-1909这四行本质是把「一次授权」拆成了四个作用域再用 audit log 把每次点击钉在磁盘上。你复现的时候重点盯三件事按钮分支对不对、日志有没有 user_id、allowlist 和 denylist 的优先级是否符合预期。这三件都对了审批链路就稳了。模型通道这边用 TaoToken 把 Base URL、Key、Model ID 收敛成一套飞书、本地、CI 复用同一个入口省得每换一个平台就重配一遍。长期跑编码类 Agent 的话Coding Plan 那套订阅更适合高频场景入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。想先在线试模型用 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 最快。最后留个实用习惯每次改完config.yaml先跑一条 allowlist 里的命令确认不弹窗再跑一条 denylist 里的确认被拦最后跑一条两者都不在的确认弹按钮。三步走完配置才算真正生效。

相关新闻

live555推H264实时流花屏真相:RTP封包、时间戳与关键帧

live555推H264实时流花屏真相:RTP封包、时间戳与关键帧

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 10:13:59 阅读更多 →
Zabbix 监控 Cisco 1900 系列路由器:Cisco_1900 社区模板解析与部署实战

Zabbix 监控 Cisco 1900 系列路由器:Cisco_1900 社区模板解析与部署实战

【免费下载链接】community-templates Zabbix Community Templates repository 项目地址: https://gitcode.com/gh_mirrors/co/community-templates 点击查看 免费下载 本指南围绕 Zabbix 社区模板仓库中的 Cisco_1900 模板展开,这是一套面向 Cisco 190…

2026/10/17 10:13:59 阅读更多 →
2026年SSH远程开发实战:把Claude Code的settings改到TaoToken直写服务器代码

2026年SSH远程开发实战:把Claude Code的settings改到TaoToken直写服务器代码

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 10:12:59 阅读更多 →

最新新闻

AI输出即他人输入:构建可靠的模型输出流水线

AI输出即他人输入:构建可靠的模型输出流水线

1. 这篇文章真正要解决的问题 最近团队里一个同学向我吐槽:他们做的一个 AI 客服系统,明明单轮对话效果不错,但一接到真实业务链条里就频繁出问题。不是回复质量变差,而是 下游系统根本没法吃下 AI 的输出 ——要么 JSON 格式带…

2026/10/17 10:54:11 阅读更多 →
AI输出如何成为下游系统的可靠输入:基于FastAPI与Redis Streams的异步消费链路设计

AI输出如何成为下游系统的可靠输入:基于FastAPI与Redis Streams的异步消费链路设计

在 AI 应用开发中,很多人习惯把注意力放在模型本身:提示词写得好不好、生成结果流不流畅、推理速度快不快。但真正把 AI 能力落地到业务系统时,还有一个经常被忽略的问题——模型返回的那段文本,不是一个孤立的结果,它…

2026/10/17 10:54:11 阅读更多 →
哈夫曼编码实现数据编码与解码:从原理到C工程实践

哈夫曼编码实现数据编码与解码:从原理到C工程实践

哈夫曼编码大概是《数据结构》这门课里最“实用主义”的一章——它不只是一个考点,而是真的有工程价值。这次的项目题目是哈夫曼编码实现数据编码与解码,简单说就是:统计文本中每个字符的出现频率,用频率构造一棵哈夫曼树&#xf…

2026/10/17 10:54:11 阅读更多 →
【免费】Trae AI零基础编程入门:从VS Code迁移到TaoToken统一Key的快速上手

【免费】Trae AI零基础编程入门:从VS Code迁移到TaoToken统一Key的快速上手

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 10:54:11 阅读更多 →
算法重点题:破解教学痛点与面试断层的思维训练手册

算法重点题:破解教学痛点与面试断层的思维训练手册

1. 这不是一本普通习题集:它是一把打开算法思维的实体钥匙“计算机算法设计与分析 第4版(王晓东)重点题”——这个标题乍看像教辅书目录里再普通不过的一行字,但在我带过十几届算法课程、批改过上万份作业和试卷之后,我…

2026/10/17 10:54:11 阅读更多 →
农行网银支付Java接口对接实战:从签名验签到回调避坑指南

农行网银支付Java接口对接实战:从签名验签到回调避坑指南

简介:面向需要在Java环境中集成农业银行网银支付功能的开发者,提供完整接口文档与可运行Demo。压缩包共147个文件、约5.1MB,包含class字节码、jsp动态页面、html说明页面、jar依赖库、properties配置及cer证书、truststore信任库等类型&#…

2026/10/17 10:53:11 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →