🤖HermesBlog
Hermes 实战教程 · 第4篇2026/8/9· Easy Understand Hermes Agent

实战:把 Hermes 当 Python 库用

Hermes 实战教程第4篇:Python 库。在代码里直接调用 Hermes。

实战:把 Hermes 当 Python 库用

实战:把 Hermes 当 Python 库用

嘿,朋友们!今天咱们来聊点硬核又好玩的东西——把 Hermes 当成一个库来用。别被“库”这个字吓到,其实意思就是:让你的外部程序(比如你自己的 Python 脚本、IDE、网页前端)直接驱动 Hermes 干活

官方这次一口气给了我们三种协议,就像三把不同的钥匙,开同一扇门(AIAgent 核心)。选哪把,取决于你的“门框”长啥样。

三把钥匙,开同一扇门

协议 传输方式 适合谁 代码位置
ACP stdio 上的 JSON-RPC VS Code、Zed、JetBrains 等 IDE 插件 acp_adapter/
TUI Gateway stdio 或 WebSocket 上的 JSON-RPC 想要精细控制会话、审批、流式事件的自定义宿主 tui_gateway/server.py
API Server HTTP + SSE Open WebUI、LobeChat 等 OpenAI 兼容前端 gateway/platforms/api_server.py

核心思想:三种协议驱动的是同一个 AIAgent 核心,只是“线材”和“接口面板”不同。

钥匙一:ACP(Agent Client Protocol)

这是给 IDE 用的。VS Code、Zed 这些编辑器已经会说 ACP 这门“外语”,所以 Hermes 直接说同一种语言就行。

hermes acp              # 在 stdio 上启动 ACP 服务
hermes acp --check      # 检查依赖是否装好
hermes acp --setup      # 交互式配置提供商和模型

它支持会话创建、提示词提交、流式消息块、工具调用事件、权限请求,甚至**会话分叉(fork)**和取消。工具输出会被渲染成 IDE 能懂的 Diff/ToolCall 块。

钥匙二:TUI Gateway(最灵活)

这是 Ink TUI(hermes --tui)自己用的协议,但任何外部程序都可以通过 stdio 或 WebSocket 说同样的“方言”。

方法列表超丰富,挑几个眼熟的:

prompt.submit           session.create          session.list
session.activate        session.close           session.interrupt
config.set / get        command.dispatch        client.capabilities
gateway.capabilities    ping                    clarify.lock
terminal.resize         clipboard.paste         image.attach

注意session.active_listsession.activatesession.close 这三个是进程内活会话控制,用于 TUI 的会话切换器。想找历史记录?用 session.list/resume

建会话时就能指定模型

session.create 现在支持按会话传 model / provider 覆盖。如果这对组合提供商根本伺候不了(比如 model: gpt-5.5provider: anthropic),网关会当场拒绝,报 JSON-RPC 错误码 -32602,而不是先建好会话、等第一轮才在提供商那边炸掉。错误里还会带上 modelprovider 和最多五条 suggestions 供你参考。放心,这个检查是离线的,只拦 Hermes 明确知道“不属于这家”的名字,自定义端点、聚合器、以及目录还没收录的新模型都照常放行。

重写历史:prompt.submit 的“时光倒流”

这个新特性很酷——编辑/重写/重新生成本质上就是一个带“截断”的 prompt.submit。但因为是破坏性写入,网关要求你明确声明意图

参数 含义
truncate_before_user_ordinal 从第几个用户轮次开始砍(从 0 数)。必须是整数,传布尔值会报 4004
truncate_before_row_id SQLite 行 ID,推荐用这个。和 ordinal 同时传会校验是否匹配(不匹配报 4030
confirm_truncate 必须传!声明“我就是要重写,不是普通发送”
confirm_empty_truncate 如果砍完整个对话空了(ordinal 0),还得额外传这个

重要:截断提交不会被“忙碌输入策略”吞掉。如果当前还有一轮在跑,普通的 prompt.submit 会被转向、改道或排队,但重写/编辑/重新生成会直接报 4009session busy)——因为排队会把“砍历史”这个动作丢掉,变成在未编辑的轮次后面追加一条普通消息。宿主应该调 session.interrupt 然后重试同一个提交,直到成功。桌面版 App 已经自动这么做了,所以 Hermes 还在思考时你编辑消息,它会先停掉当前轮次,再从编辑后的提示词重新跑。

还有:截断后,prompt.submit 结果会带 survivor_user_row_ids——这是幸存轮次的新行 ID 列表。因为重写会重新插入保留的前缀,所以你之前缓存的所有 row ID 都作废了!记得从这个列表重新绑定,否则下次重写会报 4018

钥匙三:API Server(HTTP + SSE)

这个最“大众脸”——OpenAI 兼容的 HTTP 接口。Open WebUI、LobeChat、LibreChat 这些前端直接就能接,任何语言的 Web 客户端都能用。

事件流

不管哪把钥匙,事件都长差不多:message.deltatool.startgateway.readyrequest.cancel…… 注意,审批、澄清、sudo/secret 这些“要你回答的问题”其实是网关发给客户端的 JSON-RPC 请求,不是事件。帧里带一个字符串 id,客户端用同样 id 的普通 JSON-RPC 响应来回答就行。

WebSocket 客户端注意了:连接建立、收到 gateway.ready 之后,记得调一次 client.capabilities 并传 {"server_requests": true},声明“我能回答这些请求”。不调的话,网关会把你当成不支持服务端请求的老版本,所有审批/澄清/sudo 请求都会立刻失败(审批算撤回,不算拒绝),而不是傻等超时。stdio TUI、桌面版和 dashboard 都通过共享的 JsonRpcRequestChannel 自动声明了。

网关撤回一个问题时(超时、中断、或在别处已回答),会发 request.cancel { id, method, reason },外部宿主只清除匹配的那个待处理提示,别误伤。session.resume / session.activate 的结果里还会带 open_requests,重连的客户端可以重新渲染并继续回答。

小结

三种协议,一个核心。选 ACP 给 IDE,选 TUI Gateway 要精细控制,选 API Server 图省事兼容。从今天起,Hermes 不只是命令行工具,更是你程序里的一个“智能引擎”。动手试试吧!

📖 官方文档

本文根据 Hermes Agent 官方文档编写,原文见:官方文档 › developer-guide/programmatic-integration