Hermes Agent 源码解析(二):入口与 CLI —— 从 `hermes` 命令到交互式 REPL

Hermes Agent 源码解析(二):入口与 CLI ------ 从 hermes 命令到交互式 REPL

你有没有好奇过,在终端敲下 hermes 回车到看到 AI 回复之间,发生了什么?这篇就一路追下去。

如果你正在做一个自己的 CLI 工具,Hermes 的启动链路里有很多值得借鉴的设计------尤其是它的配置三层合并和技能注入缓存优化。

启动链路

1. hermes shell 脚本

仓库根目录的 hermes 是一个 shell 脚本(而非 Python 文件)。它负责:

  • 定位项目根目录下的 .venv
  • 设置 PYTHONPATH
  • cli.py 传递命令行参数

2. hermes_bootstrap.py ------ Windows 兼容层

这个文件只有 129 行,但设计精妙:

python 复制代码
# 在 Windows 上设置 PYTHONUTF8=1 和 PYTHONIOENCODING=utf-8
# 修复 cp1252 编码下 print("café") 的 UnicodeEncodeError
# 同时对子进程(execute_code sandbox、delegation children)生效

它的设计原则是:POSIX 上什么都不做,因为 99% 的 Linux/macOS 已经是 UTF-8 默认环境。

3. cli.py 的 HermesCLI 类

CLI 入口在 cli.py,行数 ~14,442。核心结构:

scss 复制代码
HermesCLI.__init__()
  ├── Rich 渲染 Banner(ASCII art 标题)
  ├── 加载配置 load_cli_config()
  ├── 初始化皮肤引擎
  └── 扫描技能目录

HermesCLI.run()
  ├── 启动输入循环
  ├── prompt_toolkit 管理输入区域
  ├── KawaiiSpinner 管理 API 调用动画
  └── process_command() 处理斜杠命令
配置加载链路
javascript 复制代码
load_cli_config()
  ├── 硬编码 DEFAULT_CONFIG(hermes_cli/config.py)
  ├── 读取 ~/.hermes/config.yaml(用户设置)
  ├── 读取 ~/.hermes/.env(仅 API 密钥)
  ├── deep-merge 三层合并
  └── 返回完整配置字典
斜杠命令注册中心

所有斜杠命令集中定义在 hermes_cli/commands.pyCOMMAND_REGISTRY 列表中:

python 复制代码
CommandDef("mycommand", "描述文字", "Session",
           aliases=("mc",), args_hint="[arg]"),

每个 CommandDef 包含:

  • name --- 规范名(无斜杠)
  • description --- 描述
  • category --- 分类(Session / Configuration / Tools & Skills / Info / Exit)
  • aliases --- 别名元组
  • cli_only / gateway_only --- 平台限制

设计亮点:这个注册中心是单点事实来源(Single Source of Truth)。所有下游消费者自动派生:

消费者 自动生成内容
CLI process_command() 派发
Gateway GATEWAY_KNOWN_COMMANDS frozenset
微信 BotCommand 菜单列表
Slack /hermes 子命令路由
自动补全 SlashCommandCompleter 的候选项

这意味着添加一个新命令 只需要在 COMMAND_REGISTRY 加一行,再在 process_command() 加一个 handler。

Skills 注入策略

技能文件的加载不嵌入 system prompt,而是以 user message 注入:

python 复制代码
# agent/skill_commands.py
# 扫描 ~/.hermes/skills/,注入为 user message
# 这样不破坏 prompt cache 的稳定性

这是一个非常重要的缓存优化 ------ system prompt 变了会清空 API 侧的 prefix cache,而 user message 变化不影响。

Skin 皮肤引擎

hermes_cli/skin_engine.py 提供纯数据驱动的视觉定制:

python 复制代码
# 皮肤是纯 YAML 数据,无需改代码
# 内置 4 个皮肤:default(金色)、ares(深红)、mono(灰度)、slate(冷蓝)
# 用户可在 ~/.hermes/skins/ 放自定义 .yaml

皮肤控制:Banner 颜色、Spinner 表情/动词、工具输出前缀、品牌名称、提示符符号等。


欢迎一起讨论! 14k 行的 God Class,你项目里有类似的大文件吗?你是怎么处理的?

完整源码在 GitHub → NousResearch/hermes-agent

📢 关注公众号「爱写代码的小任」,获取最新开源更新日志和开发者工具动态。如果觉得这篇文章有用,欢迎转发给身边的开发者朋友。

#源码解析 #HermesAgent #CLI设计 #开源项目

下一篇我们进入最核心的部分 ------ AIAgent 类的 run_conversation() 主循环。

相关推荐
坐吃山猪9 天前
【Hanako】README08_LEVEL4_插件系统架构
python·架构·agent·源码阅读
LienJack14 天前
《Claude Code 源码解析系列》第7章|Skill
claude·源码阅读
LienJack14 天前
《Claude Code 源码解析系列》第8章|Agent 协作
claude·源码阅读
LienJack14 天前
《Claude Code 源码解析系列》第3章|Prompt 编写
claude·源码阅读
LienJack14 天前
《Claude Code 源码解析》第2章|ReAct 主循环
claude·源码阅读
LienJack15 天前
《Claude Code 源码解析系列》第一章-工程架构
人工智能·源码阅读
倾颜23 天前
React 19 源码主线拆解 04:Fiber 到底是什么,React 为什么需要 Fiber?
前端·react.js·源码阅读
Bigger1 个月前
第十章:我是如何剖析 CLI 里的终极 Agent 能力的(电脑控制与浏览器接管)
前端·claude·源码阅读
Bigger1 个月前
第九章:我是如何剖析 Claude Code 的 CLI 里的安全沙盒与指令拦截机制的
前端·claude·源码阅读