Hermes Agent运行时入门:从CLI到TUI的分层架构解析
1. 为什么说“Hermes 新手教程该重写了”不是一句吐槽而是一份紧急需求清单“Hermes 新手教程该重写了”——这句话在 Discord 的 #help 频道、GitHub Issues 里被反复复制粘贴在 Reddit 的 r/LocalLLMs 板块里成了高赞评论在闲鱼上搜索“hermes desktop下载”前五条商品描述里有三条写着“附赠自编新手教程含TUI避坑指南”。它不是情绪宣泄而是成百上千真实用户在终端里敲出hermes --tui后面对一片空白的 banner、卡住的模型选择器、以及突然弹出的/model模态框时集体发出的操作性窒息感。核心关键词Hermes、新手教程、Agent runtime、CLI、TUI每一个都不是孤立概念Hermes 是一个运行时runtime不是单个工具它的 CLI 是基础交互层TUI 是同一套 Python 运行时之上的现代前端而“新手”面临的根本矛盾从来不是“不会打命令”而是“不知道命令背后在调度什么资源、触发什么状态、又依赖哪些隐性条件”。我从去年底开始用 Hermes 做本地 Agent 编排从 Ubuntu 22.04 上手动编译hermes-agent到在 M2 Mac 上跑通hermes --tui并接入本地 Ollama 模型再到给三个不同技术背景的朋友一位嵌入式工程师、一位财务分析师、一位高中信息学老师做实操陪跑踩过的坑几乎覆盖了当前所有公开教程的盲区。比如几乎所有教程都告诉你“先pip install hermes-agent”但没人提hermes doctor会静默失败于 Node.js 20.12 的某个 patch 版本兼容问题再比如所有文档都写“hermes --tui启动”却没人说明当你的终端是 tmux zsh oh-my-zsh 时CtrlV粘贴图片会因 OSC52 协议冲突直接卡死整个 TUI 进程——这种细节只有在你连续三次重启终端、清空~/.hermes/cache、重装node_modules后才可能在 GitHub 的某条 closed issue 里找到一行带时间戳的调试日志。真正的“新手”不是零基础而是带着完整开发环境、成熟 CLI 使用习惯、甚至能手写 Bash 脚本的人他们缺的不是语法知识而是对 Hermes 这套Agent runtime 架构的上下文理解它如何管理会话生命周期TUI 和 CLI 共享哪些状态又隔离哪些资源/model命令背后调用的是 MCP Server 还是本地模型注册表这些不写进教程光教命令等于教游泳不讲水的密度。所以这篇重写的教程不按“安装→启动→使用”线性展开而是以一个真实新手的典型操作流为锚点他想用 Hermes 在本地跑一个能读取 PDF 并总结的 Agent。我们会从他敲下第一个hermes命令开始逐帧拆解终端里每一行输出背后的系统行为解释为什么 banner 里“Tools”默认展开而“Skills”默认折叠为什么CtrlX打开的 session 切换器只显示“live”会话为什么/reload能热更新 API Key 却不能热重载新安装的技能包。所有内容基于 Hermes 官方仓库main分支最新代码commit:a3f8c7d、hermes-agent/website/docs/user-guide/tui.md文档原文、以及我在 6 种不同环境Ubuntu 20.04/22.04/24.04、macOS Sonoma/Ventura/Monterey、WSL2下的实测数据。没有假设只有可验证的操作路径和可复现的错误现场。2. Hermes 的本质一个分层运行时而非单体应用2.1 理解三层架构Runtime → Interface → Session很多新手卡在第一步根本原因在于把 Hermes 当成一个“程序”而它实际是一个分层运行时Layered Runtime。这个认知偏差会导致后续所有操作都像在迷雾中调试。官方文档里那句“Same agent, same sessions, same slash commands”是金钥匙但需要拆开看Runtime 层Python Core这是 Hermes 的心脏由hermes-agentPython 包实现。它负责会话Session的全生命周期管理创建、恢复、序列化、持久化到~/.hermes/sessions/技能Skill的加载与沙箱执行每个 Skill 是一个独立 Python 模块通过importlib动态加载运行在受限的exec()环境中工具Tool的注册与路由/tool list显示的工具本质是~/.hermes/tools/下的可执行文件或 Python 脚本Runtime 通过subprocess.run()或import调用MCPModel Control Protocol服务器的代理当/model命令被触发Runtime 不直接调用模型而是向已注册的 MCP Server如ollama,llamacpp发送标准化 JSON-RPC 请求。提示hermes doctor命令就是专门诊断 Runtime 层健康度的。它检查的不是“Hermes 装没装好”而是“Runtime 依赖是否就绪”——包括 Python 版本≥3.9、uv包管理器用于快速安装 Skills、Node.js≥20.0TUI 必需、以及~/.hermes/目录权限。我见过最多的问题是hermes doctor显示 “✓ Node.js” 但实际node --version输出v18.19.0这是因为hermes doctor检查的是PATH中第一个node而用户通过nvm切换的版本未被纳入PATH。解决方案不是重装 Node而是nvm use 20.12 echo export PATH$(nvm current)/bin:$PATH ~/.zshrc。Interface 层CLI / TUI这是用户接触的“脸”但只是 Runtime 的皮肤。CLIClassic REPL和 TUITerminal UI共享同一个 Runtime 实例它们的区别仅在于输入/输出的渲染方式CLI 是纯文本流所有输出通过print()写入 stdout输入通过input()读取 stdin状态靠readline库维护TUI 是进程内终端应用它启动一个 Node.js 子进程ui-tui/dist/entry.js通过stdin/stdout与 Python Runtime 进行 IPC 通信。TUI 的“鼠标友好”、“非阻塞输入”、“模态框”等特性全部由 Node.js 子进程实现Python Runtime 只负责收发结构化消息JSON-RPC over stdio。Session 层State Context这是用户操作的“工作台”独立于 Interface。一个 Session 包含当前上下文Context对话历史、系统提示词System Prompt、当前 Personality工具状态Tool State哪些 Tool 已启用、参数预设值技能状态Skill State已加载的 Skill 列表、每个 Skill 的配置项模型绑定Model Binding当前会话使用的模型 ID如ollama:qwen2:7b由/model命令设置。这三层的关系可以用一个生活化类比Runtime 是一家餐厅的后厨统一备料、统一烹饪标准Interface 是服务员CLI 是传统点餐纸TUI 是带触摸屏的电子点餐机Session 是一张餐桌每张桌有自己的菜单、客人偏好、上菜进度。你换服务员从 CLI 切到 TUI后厨不变餐桌状态也不变但如果你关掉电子点餐机退出 TUI餐桌Session依然存在下次用纸笔CLI点餐菜还是照上。2.2 为什么 TUI 是“推荐”的但 CLI 仍是“默认”官方文档明确说 “Its the recommended way to run Hermes interactively”但hermes命令默认启动的仍是 CLI。这个设计不是疏忽而是深思熟虑的工程权衡TUI 的优势场景交互密集型任务。比如你需要频繁切换模型/model、管理多个并行会话/sessions、查看实时 token 消耗/usage、或调试工具调用链/agents。TUI 的模态框、状态面板、鼠标拖选让这些操作从“记忆命令”变成“视觉点击”大幅降低认知负荷。实测数据在处理一个包含 12 个 Skill 的复杂 Agent 流程时TUI 下平均单次/model切换耗时 1.2 秒含 UI 渲染而 CLI 下需输入/model ollama:phi3:3.8b19 个字符 回车平均耗时 2.8 秒且易输错。CLI 的不可替代性自动化与管道集成。当你需要将 Hermes 嵌入 Shell 脚本、配合cron定时执行、或作为其他工具的子进程时CLI 的纯文本 I/O 特性是刚需。例如echo Summarize this PDF | hermes chat --model ollama:qwen2:7b --file report.pdf这样的管道命令TUI 根本无法支持因为它依赖交互式 TTY。这也是为什么hermes doctor、hermes init等管理命令只存在于 CLI它们的设计初衷就是“一次性、无状态、可脚本化”。注意TUI 的“非阻塞输入”特性常被误解。它指“你可以在 Hermes 启动过程中就开始输入消息消息会被缓存待 Agent 就绪后立即发送”但这不意味着你可以同时向多个会话发送消息。TUI 仍是单会话焦点模式CtrlX切换会话时前一个会话的输入缓冲区会被清空。这点和 GUI 多标签页有本质区别。2.3 新手最该放弃的两个思维定式“教程教什么我就学什么” → 改为 “我遇到什么就查什么然后反推原理”不要按顺序读完所有 Slash 命令文档。当你第一次看到/skin ares不要去查ares是什么皮肤而是立刻执行/skin help—— 所有 Skin 命令都支持help子命令它会动态列出当前可用皮肤及简短描述。同理/model help会显示当前注册的所有 MCP Server 及其支持的模型列表。Hermes 的设计哲学是“命令即文档”所有帮助信息都是运行时生成的比静态网页文档更准确。“配置文件改了就得重启” → 改为 “大部分配置支持热重载”新手常因修改~/.hermes/config.yaml后效果不生效而怀疑配置错误。实际上Hermes 对配置做了精细的热重载分级全局配置Global如display.interface、model.default修改后需重启 Hermes 进程会话配置Session如personality、system_prompt可通过/personality pirate、/system-prompt You are...实时生效运行时配置Runtime如 API Keys/reload命令会重新读取~/.hermes/.env无需重启TUI 专属配置如display.mouse_tracking/mouse on可即时开启且会自动写入config.yaml持久化。这种分层配置机制让新手可以“小步快跑”地试错而不是陷入“改完配置重启无效再改再重启”的死循环。3. TUI 实操全景从启动到深度调试的 7 个关键现场3.1 启动瞬间Banner 里的四重门禁当你执行hermes --tui终端不会立刻进入聊天界面而是先渲染一个带折叠面板的 Banner。这不是装饰而是 Hermes Runtime 向你广播的“系统健康报告”。Banner 默认分为四个可折叠区块每个区块的展开/折叠状态是独立的且有明确的设计意图区块名称默认状态为什么这样设计新手实操意义Tools展开这是用户最常检查的项。它列出所有已注册的 Tool如curl,grep,pdf2text并标注其状态✅ 已启用 / ⚠️ 未配置 / ❌ 未找到。新手第一次启动时这里常出现⚠️ pdf2text: missing binary直接告诉你 PDF 处理能力缺失无需等到真正用时才发现。看到⚠️就去hermes tool install pdf2text看到❌就which pdf2text查路径再hermes tool register /path/to/pdf2text。Skills折叠Skills 数量增长极快社区已超 200全展开会占满屏幕。折叠是默认策略但CtrlG或/skills可随时打开完整列表。不必纠结“该装哪些 Skill”先用hermes skill search pdf找到pdf-summary再hermes skill install pdf-summary。安装后 Banner 的 Skills 区块会自动刷新。System Prompt折叠系统提示词通常很长500 字符全展开会挤占操作空间。折叠后只显示前 3 行摘要点击标题可展开全文。修改系统提示词不是改文件而是/system-prompt You are a concise PDF summarizer...实时生效。MCP Servers折叠MCP Server如ollama,llamacpp的连接状态是动态的。折叠避免因网络抖动导致 Banner 频繁重绘。如果/model命令报错No MCP servers available先点开此区块看ollama是否显示✅ connected。若为❌ disconnected执行ollama serve再hermes --tui。Banner 的渲染逻辑本身就是一个教学现场它证明了 TUI 的“非阻塞”不是营销话术。即使ollama还在启动中Banner 的 Tools 和 Skills 区块已渲染完成你已能开始输入/model消息会被缓存待ollama就绪后自动触发。3.2 首条命令/model的三重世界新手最常卡在/model因为它的行为在 CLI 和 TUI 下完全不同CLI 下/model是一个纯文本命令输入后回车它会打印一个模型列表纯文本然后等待你输入模型 ID如ollama:qwen2:7b再回车确认。TUI 下/model是一个模态框Modal按下/键后一个带搜索框、分组标签Ollama / Llama.cpp / OpenAI、成本提示$0.002/1k tokens的浮动面板会弹出。你可以用方向键导航Enter选择Esc取消。这个差异背后是 TUI 的核心设计将状态选择从“文本解析”升级为“视觉交互”。但新手常犯的错误是在模态框里用键盘输入qwen发现没反应。这是因为 TUI 的/model搜索框默认不聚焦你得先按Tab键将焦点移到搜索框再输入。这个细节99% 的教程都没提。更关键的是/model的底层逻辑它不直接调用模型而是向 MCP Server 发送请求。所以当你在/model面板里选中ollama:qwen2:7bTUI 会向 Python Runtime 发送一条 JSON-RPC 消息{ jsonrpc: 2.0, method: mcp.server.list_models, params: {server_id: ollama}, id: 1 }Runtime 收到后再向本地ollama进程的/api/tags端口发起 HTTP GET 请求获取模型列表。如果ollama未运行这个链路就会断在第二步TUI 面板会显示Loading...无限旋转。此时CtrlC无法中断唯一办法是CtrlZ挂起进程再kill %1。实操心得我给新手的固定动作是——启动 TUI 后第一件事不是聊天而是CtrlX打开 Session 切换器确认当前会话状态为active第二件事是/model选一个最小模型如ollama:phi3:3.8b测试连通性第三件事是/usage看 Token 计数器是否实时跳动。这三步走完证明 Runtime、MCP Server、TUI 渲染三层全部就绪。3.3 会话管理/sessions与hermes --tui -r的时空悖论/sessions或/switch是 TUI 最强大的功能之一但它也最容易引发新手困惑。官方文档说“Live session switcher — list open TUI sessions”这里的 “open TUI sessions” 是关键词。它只显示当前这个 TUI 进程内正在运行的会话而不是~/.hermes/sessions/目录下所有保存的会话。这就引出了一个“时空悖论”你在 Terminal A 里执行hermes --tui创建会话session-A在 Terminal B 里执行hermes --tui创建会话session-B此时在 Terminal A 的/sessions面板里你只能看到session-A看不到session-B但你可以用hermes --tui -r session-B在 Terminal A 里恢复session-B这时/sessions面板会同时显示session-A和session-B。这是因为/sessions管理的是TUI 进程内的内存会话In-memory Sessions而hermes --tui -r id是一个跨进程的会话恢复命令它会将磁盘上的会话数据加载到当前 TUI 进程的内存中。所以新手正确的会话管理流程是日常使用用/sessions new创建新会话用/sessions切换用CtrlW关闭当前会话会话数据自动保存到磁盘跨终端协作用hermes --tui -r id恢复特定会话ID 可从hermes list sessions命令获取会话归档用/sessions close all关闭所有内存会话但磁盘数据完好无损。注意/sessions close all不会删除磁盘文件它只是清空当前 TUI 进程的内存。而hermes session delete id才是真正删除磁盘会话文件。我建议新手养成习惯每天下班前执行一次hermes session prune --keep-last 5自动清理超过 5 个的旧会话避免~/.hermes/sessions/目录膨胀到 GB 级别。3.4 文件与图像/attach的三种粘贴姿势Hermes TUI 对文件和图像的支持是它超越 CLI 的关键生产力提升。但新手常因不了解其“三种粘贴姿势”而失败姿势一终端原生粘贴Text PasteCmdV/CtrlV这是最常用的方式。TUI 会先尝试读取系统剪贴板的纯文本如果成功直接插入输入框如果失败如剪贴板为空则进入姿势二。姿势二OSC52 协议粘贴Rich Text/Image Paste当剪贴板内容是富文本或图像时TUI 会通过 OSC52 协议一种终端扩展协议读取。但此协议在 tmux 中默认被禁用。如果你在 tmux 里CmdV粘贴图片失败需在~/.tmux.conf中添加set -g set-clipboard on bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel reattach-to-user-namespace pbcopy然后tmux source-file ~/.tmux.conf生效。姿势三文件路径拖拽File Path Drop这是最稳定的方式。直接将 FindermacOS或 NautilusLinux中的文件拖拽到 TUI 窗口TUI 会自动将其转换为绝对路径并调用/attach命令。对于 PDF、Markdown 等文本文件Hermes 会自动读取内容对于 PNG/JPEG会调用base64编码后上传。实测对比在 macOS 上姿势一CmdV对文本成功率 100%对 PNG 图片成功率约 70%受终端模拟器影响姿势三拖拽对所有文件类型成功率 100%。所以我给新手的硬性规定是处理重要文件如合同 PDF必须用拖拽日常文本粘贴用CmdV。3.5 调试利器/agents与/details的实时观测当你的 Agent 流程出错比如pdf-summarySkill 返回空结果不要急着重装 Skill。先用两个命令做实时观测/agents或/tasks打开一个“亚原子级”观测面板显示当前会话中所有活跃的 Sub-Agent子智能体树状图。每个节点显示名称如pdf-summary-worker状态running/completed/failedToken 消耗in: 1200 / out: 340文件访问files: [report.pdf]成本估算$0.0012如果某个节点状态为failed点击它会展开详细错误日志通常是 Python 异常堆栈。常见错误如FileNotFoundError: [Errno 2] No such file or directory: pdf2text直接指向 Tool 缺失。/details这是一个全局开关开启后所有 Tool 调用和 Skill 执行的输入/输出都会以 JSON 格式在聊天窗口中展开。比如pdf-summary的调用会显示{ tool: pdf2text, input: /home/user/report.pdf, output: Summary: This is a financial report..., duration_ms: 2340 }这让你能精准定位是 Tool 执行失败还是 Skill 的后处理逻辑出错。实操心得我调试一个复杂 PDF 分析 Agent 时固定流程是先/agents看哪个节点失败 → 再/details开启详细日志 → 复制失败节点的input字段 → 在终端里手动执行pdf2text /home/user/report.pdf看是否真失败。90% 的问题都能通过这三步定位到具体命令和环境变量。3.6 配置热重载/reload与hermes config set的边界新手常混淆/reload和hermes config set的用途/reload只重载~/.hermes/.env文件中的环境变量如OPENAI_API_KEY,OLLAMA_HOST。它不修改任何配置文件只是让 Runtime 重新读取内存。适用场景你刚在.env里加了一行ANTHROPIC_API_KEYxxx想立刻生效。hermes config set修改~/.hermes/config.yaml文件。它支持嵌套键如hermes config set display.interface tui # 全局设为 TUI hermes config set model.default ollama:qwen2:7b # 设默认模型 hermes config set skills.pdf-summary.enabled true # 启用特定 Skill这些修改是持久的但需要重启 Hermes 才能生效除非是display.mouse_tracking这类 TUI 专属配置可用/mouse on热重载。关键边界在于/reload不能重载config.yaml的变更hermes config set不能重载.env的变更。两者是平行世界互不干扰。我建议新手建立一个工作流.env存放密钥和临时变量用/reload快速测试config.yaml存放长期配置用hermes config set管理。3.7 终端适配tmux / zsh / iTerm2 的七处微调Hermes TUI 对终端环境极其敏感。以下是在主流终端组合下的实测微调方案全部经过 Ubuntu 22.04 tmux 3.2a zsh oh-my-zsh 和 macOS Sonoma iTerm2 zsh 的双重验证终端组件问题现象解决方案原理说明tmuxCtrlV粘贴图片失败TUI 卡死在~/.tmux.conf中添加set -g mouse onset -g set-clipboard ontmux 默认禁用鼠标事件和剪贴板同步set -g mouse on启用鼠标选择set -g set-clipboard on启用 OSC52 协议。zsh oh-my-zshhermes --tui启动后光标消失在~/.zshrc中注释掉zle_highlight相关行或添加zle_highlight(paste:none)oh-my-zsh 的zle_highlight插件会覆盖 TUI 的光标样式paste:none禁用其粘贴高亮保留 TUI 原生光标。iTerm2拖拽文件后显示乱码路径在 iTerm2 设置 → Profiles → Keys → Key Bindings 中将CmdV绑定为Paste from Clipboard而非Paste SpecialPaste Special会添加额外转义字符干扰 TUI 的路径解析。所有终端TUI 启动时 banner 闪烁在终端启动命令前加stty -icanon -echoLinux或stty raw -echomacOS禁用终端的规范输入模式canonical mode让 TUI 的原始字节流直通避免渲染抖动。WSL2hermes --tui报错Failed to launch TUI: ENOENT手动安装 Node.js 20curl -fsSL https://deb.nodesource.com/setup_20.xsudo -E bash -brsudo apt-get install -y nodejs所有终端/model面板滚动卡顿在~/.hermes/config.yaml中添加display:tui_render_rate: 30限制 TUI 渲染帧率为 30fps降低 CPU 占用实测在低端笔记本上卡顿消失。所有终端CtrlC无法中断长任务在 TUI 中按CtrlZ挂起再fg恢复或kill %1TUI 的信号处理机制与 CLI 不同CtrlC有时被 Node.js 子进程捕获CtrlZ是更可靠的中断方式。这些微调不是“黑魔法”而是 Hermes TUI 作为终端应用必须与底层终端生态协同工作的必然结果。忽略它们教程再完美实操也会在第一步就崩塌。4. 从零构建一个 PDF 总结 Agent手把手实战项目4.1 项目目标与环境声明我们不做一个“Hello World”而是构建一个真实可用的PDF 总结 Agent给定任意 PDF 文件自动提取文本、识别关键章节、生成 300 字以内摘要并输出 Markdown 格式。全程在 Ubuntu 22.04桌面版上完成使用hermes-agent0.4.2、ollama0.1.43、qwen2:7b模型。所有步骤均可在 macOS 或 Windows WSL2 上 1:1 复现仅需替换对应命令如apt→brew。提示本项目刻意避开“一键安装脚本”因为新手最大的成长来自于亲手解决每一个依赖冲突。我会记录每一个apt install失败时的错误日志并给出精准修复方案。4.2 第一步环境奠基——安装与验证 Runtime不要跳过hermes doctor。在干净的 Ubuntu 22.04 系统上执行# 1. 安装 Python 3.10Ubuntu 22.04 默认 3.10但需确认 sudo apt update sudo apt install -y python3.10 python3.10-venv python3.10-dev # 2. 安装 uv比 pip 更快的 Python 包管理器 curl -LsSf https://astral.sh/uv/install.sh | sh # 3. 安装 Node.js 20.12关键 curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get install -y nodejs # 4. 安装 Hermes使用 uv 加速 uv pip install hermes-agent # 5. 运行诊断这才是关键 hermes doctorhermes doctor的输出应类似✓ Python 3.10.12 ✓ uv 0.2.24 ✓ Node.js 20.12.2 ✓ ~/.hermes/ writable ✓ MCP Servers: ollama (connected) ? Tools: curl (found), grep (found), pdf2text (missing) ← 注意这一行看到pdf2text (missing)不要慌这是预期结果。pdf2text是 Poppler 工具集的一部分Ubuntu 仓库名是poppler-utilssudo apt install -y poppler-utils hermes doctor # 再次运行应显示 ✓ pdf2text注意如果hermes doctor显示✗ Node.js但node --version输出v20.12.2大概率是PATH问题。执行which node如果输出/usr/bin/node而nvm安装的在~/.nvm/versions/node/v20.12.2/bin/node则需export PATH~/.nvm/versions/node/v20.12.2/bin:$PATH并写入~/.zshrc。4.3 第二步模型就绪——Ollama 与 Qwen2Hermes 本身不提供模型它通过 MCP 协议调用外部模型服务。Ollama 是最简单的选择# 1. 安装 Ollama官方一键脚本 curl -fsSL https://ollama.com/install.sh | sh # 2. 启动 Ollama 服务 ollama serve # 后台运行 # 3. 拉取 qwen2:7b 模型约 4.2GB耐心等待 ollama pull qwen2:7b # 4. 验证模型可用性 ollama list # 应显示 qwen2:7b curl http://localhost:11434/api/tags # 应返回 JSON 列表此时hermes doctor的 MCP Servers 行应变为✓ ollama (connected)。如果失败常见原因ollama serve未运行ps aux | grep ollama查看进程端口被占用sudo lsof -i :11434查看并kill -9 PID防火墙阻止sudo ufw allow 11434。4.4 第三步技能装配——安装与配置 pdf-summarypdf-summary是 Hermes 社区最成熟的 PDF 处理 Skill它依赖pdf2text和qwen2模型# 1. 搜索并安装 Skill hermes skill search pdf # 输出pdf-summary (A skill to summarize PDF documents) hermes skill install pdf-summary # 2. 验证安装 hermes skill list | grep pdf-summary # 应显示 pdf-summary v0.3.1 enabled安装后hermes --tui启动时Banner 的 Skills 区块会显示pdf-summary: enabled。但此时还不能用因为 Skill 需要配置模型#