AI 摘要
AI
正在生成摘要...

定本文内容基调:

本文写的完全是个人学习路径,在有些部分内容写的不是很准确,很多内容、词汇、流程,都是作者自己一个人在慢慢探索的时候自己写的习惯性的词汇,不用以我为标准,学习哪有标准,你学会一个东西,只要你会用、知道怎么用、知道怎么更好用就够了。

本文主打干中学,不是先学再干,那没意义,在探索实践中理解,远比死看文字来的好。

Hermes Agent 初步探索

一、Hermes Agent 基础

1、Hermes 简介

image-20260423173714781

官方是这样介绍的:

部署在你的服务器上,连接你的消息账号,它就成为你的持久个人智能体——学习你的项目、自动构建技能、随时随地触达你。不是聊天机器人,不是代码补全工具,而是一个住在你机器上、每天都在变聪明的智能体。

image-20260421220520080

事实上,Hermes Agent 的核心理念是:让 AI 成为长期在线的数字员工,而非一次性聊天机器人,是业内少见的原生内置学习闭环的 AI Agent,可从执行经验中沉淀技能、自主优化能力、持久化知识、检索历史对话,并在跨会话中持续完善用户认知模型。它不只想帮你把眼前这一轮任务做完,还想把这轮任务里有价值的经验留下来,下一次直接复用。

它把两类东西拆得很清楚:

  • Memory:你的偏好、项目事实、沟通方式
  • Skills:做事的方法、步骤和可复用流程

所以它的特点就是:

它在努力把 Agent 从一次性对话工具,变成一个可以不断熟悉你、逐渐沉淀方法的工作对象。

Hermes 官方直接提供了 hermes claw migrate,可以导入记忆、技能、配置,甚至 API Key。

说白了,可以把龙虾内的信息直接导入到Hermes,刚开始看到的时候还懵了一下。

与OpenClaw的简单对比:

维度 Hermes Agent OpenClaw
核心哲学 引擎模式:以 Agent 自身的学习循环为核心,强调“越用越懂你”的自我进化能力。 网关模式:以多平台接入和技能生态为核心,强调“开箱即用”的连接与执行能力。
技能生成 动态自生成:任务完成后自动提炼为 skill,持续优化。 静态生态:依赖 ClawHub 社区技能(13,700+),需人工编写或下载。
记忆系统 有限记忆 + 动态压缩:仅将高价值决策逻辑固化为 Skill,海量历史沉淀为可检索数据库,避免上下文膨胀。 全量记忆存储:保留完整历史,但易导致上下文窗口膨胀,推高推理成本。
部署成本 轻量级设计,资源占用低。 生态庞大,但资源消耗相对较高。
上手难度 :一键安装,自动优化配置。 :多渠道配置需要一定时间。
安全机制 原生内置:容器隔离、只读文件系统、预执行扫描、危险命令审批。 需手动配置:依赖用户自行设置安全边界。
适用场景 长期运行、需要持续学习与沉淀的个性化任务(如个人助手、DevOps 自动化)。 快速接入多平台、需要大量现成技能的场景(如客服机器人、跨平台消息路由)。

2、Hermes "学习" 概念

该部分建议不要先看,建议先做完搭建流程,看完新型Skills接入方式是如何接入的,作者也是这么干的,当时作者是突发奇想做完那个skills试验之后才回过头来思考的 Hermes 的学习方式,这样其实有更好的理解。

Hermes 的学习并非简单的信息存储,而是一套标准化的 输入 → 压缩 → 沉淀 智能流程,依托三层认知持久化模型完成能力内化:

BASH
┌─────────────────────────────────────────────────────────────────┐
│                      学习 = 输入 → 压缩 → 沉淀                  │
├─────────────────────────────────────────────────────────────────┤
│  1. 输入阶段   →  通过工具(tool call)获取原始信息               │
│  2. 压缩阶段   →  提取模式/约束/模板,丢弃冗余细节              │
│  3. 沉淀阶段   →  存入三个持久层:memory / skill / session      │
└─────────────────────────────────────────────────────────────────┘

以 Prometheus Skill 学习为例,完整路径为:

TEXT
terminal(curl) 获取 SKILL.md 原文 → skill_view() 加载关联知识 → 提取核心规则 → 三层持久化沉淀

Hermes 核心三层数据模型:

BASH
┌───────────────────────────────────────────────────────────────┐
│                     认知持久化三层模型                           │
├───────────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────────────┐ │
│  │ Layer 1: memory (长期记忆)                                │ │
│  │ • 用户偏好、环境事实、关键约束                                │ │
│  │ • 注入到每轮对话开头,容量有限 (~2200 chars)                  │ │
│  └─────────────────────────────────────────────────────────┘ │
│                           ↓                                   │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │ Layer 2: skill (程序记忆/技能库)                           │ │
│  │ • 可复用的流程、模板、参考文档、执行脚本                       │ │
│  │ • 按需加载,支持工具调用与自动化执行                          │ │
│  └─────────────────────────────────────────────────────────┘ │
│                           ↓                                   │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │ Layer 3: session_search (情节记忆/会话检索)                │ │
│  │ • 历史对话全量存档,支持关键词/场景检索                       │ │
│  └─────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
存储内容 容量 使用场景
memory 用户画像、环境事实、核心规则 ~2200 chars 每轮对话自动注入
skill 执行流程、脚本、模板、文档 无硬限制 技能匹配时按需加载
session_search 历史对话全文 无限制 检索过往对话时使用

Hermes 会通过超高压缩比优化知识存储(原始 8000 字符文档压缩至 150 字符核心规则),严格遵循声明式设计哲学与智能技能匹配机制,最终将技能拆分为长期记忆、可执行技能、会话记录三层持久化,绝不重复学习、不浪费上下文、不丢失核心约束。

3、Hermes 设计哲学

基于三层记忆持久化模型与技能自主内化机制,Hermes 在知识吸收、存储调度、指令执行上遵循底层设计原则:

压缩优先,严控上下文占用

信息压缩为学习流程的核心准则,不对原始文档进行全量无脑存储。模型会剔除冗余描述,仅提炼约束规则、执行范式与核心铁律;其中长期记忆层仅保留极简索引信息,技能库存储完整结构化内容,在完整保留能力的同时最大化节省 Token,避免上下文溢出臃肿。

三层记忆严格隔离,各司其职

划分长期记忆(memory)、程序技能库(skill)、会话检索(session_search) 三层独立持久架构,边界清晰互不干扰。

memory 存放全局约束与偏好,每轮对话自动注入;skill 存放流程、脚本、工具调用链路,按需加载;session 仅留存对话过程用于检索,不侵入全局能力上下文。

优先声明式上下文,摒弃命令式指令

模型约束采用事实声明式描述,拒绝生硬强制命令式指令。命令式语句会干扰实时推理、产生指令冲突,而声明式仅作为背景规则补充,既保留底层约束,又不会覆盖用户当下交互需求。

智能按需召回,杜绝重复学习

内置自动化技能匹配机制,根据用户意图自动检索并加载对应技能、脚本与参考文档;已完成内化沉淀的技能不会重复解析、重复学习,全局规则持久留存,后续同场景直接沿用最优推理链路执行。

技能原生内化,绑定工具调用闭环

不局限于静态文件挂载注册,通过工具调用机制将执行脚本、查询规范内化为模型原生能力,完成「意图识别→技能匹配→脚本调度执行」全自动化链路,相比传统静态技能挂载更灵活高效。

4、Hermes Agent 记忆

本过程是通过学习优化Skills后理解的内容。

看完 Hermes 调优 / 接入Skills / Skills优化 -->你会更理解这部分内容。

Hermes 采用 “一套核心 + 多端接入” 架构:

  • 服务器上仅运行一个 Hermes 核心实例,所有记忆(memory/skill/session)都存储在本地统一目录(~/.hermes/

    BASH
    ls ~/.hermes/memories/
    MEMORY.md  MEMORY.md.lock
  • 微信、飞书、CLI 等平台只是不同的交互入口,通过网关协议与核心实例通信

  • 无论从哪个平台发送指令,最终都是同一个 Agent 处理并更新同一套记忆库

记忆层级 存储内容 共享特性 跨平台效果
memory 用户偏好、环境事实、核心约束 全局唯一,每轮对话自动注入 微信里设置的运维红线、飞书里同样生效
skill 执行流程、脚本、模板 全局共享,按需加载 飞书中学到的技能,微信可直接调用
session_search 历史对话全文 全量索引,跨平台检索 微信上的排障记录,飞书可直接查询复用

Hermes 的跨平台记忆互通不是 “功能”,而是其核心设计哲学的体现 —— 让 AI 成为你全平台一致的数字员工而非被平台割裂的多个工具hermes-agent.org。无论你在微信、飞书、CLI 还是其他平台,面对的都是同一个 “越用越懂你” 的 Hermes,共享完整的学习历程与能力沉淀hermes-agent.nousresearch.com

二、Hermes Agent 安装

安装方式提供两种可选:

  • 采用官方脚本安装

  • 使用github源码进行二进制安装

1、官方脚本安装 (WSL2 系统)

1.1 环境准备

网络环境需要进行处理,毕竟hermes的代码在Github上,所以需要科学上网,win主机开启系统代理:

image-20260421220613356

开启系统代理后,由于我们是WSL启动的虚拟机,需要直接代理wsl服务器的网关,在win主机上查看:

image-20260421220602875

在wsl虚拟机上编写环境变量:

BASH
vim /etc/profile
# 网络代理
proxy () {
  export http_proxy="http://172.19.128.1:7890"
  export https_proxy=$http_proxy
  export socks5_proxy="socks5://172.19.128.1:7890"
  echo "HTTP Proxy on"
}

# noproxy
noproxy () {
  unset http_proxy
  unset https_proxy
  echo "HTTP Proxy off"
}

相当于增加两个命令,proxy命令用于开启代理,noproxy用于关闭代理。

BASH
source /etc/profile

# 开启代理
proxy
HTTP Proxy on

使用VMware启动的虚拟机依旧可以使用该方式进行添加网络代理,使用nat模式,网络代理nat网关即可。

不再做相关编写,方式一样,本文也适配Linux系统,可直接复用。

1.2 使用官方脚本安装

使用wsl系统进行安装:

官方提醒:原生 Windows 支持仍处于实验阶段,请安装 WSL2 后在其中运行 Hermes Agent。

个人也不建议把 OpenClaw 和 Hermes Agent 这一类产品安装在windows上。

BASH
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash

image-20260421164445121

安装程序会自动处理所有依赖项:

  • uv — 快速 Python 包管理器
  • Python 3.11 — 通过 uv 安装,无需 sudo
  • Node.js v22 — 用于浏览器自动化和 WhatsApp 桥接
  • ripgrep — 快速文件搜索
  • ffmpeg — TTS 音频格式转换

也可手动补全相关依赖文件:

BASH
sudo apt update && sudo apt install python3.11 python3.11-venv

安装完成后,进行初始化配置。

1.3 初始化模式选择

Quick setup(快速设置):只配置核心必需项:AI 服务商、模型、消息功能,完全满足日常使用,不用折腾复杂设置

Full setup(完整设置):配置所有高级功能:网络端口、日志、插件、权限等

我们选择第一项进行快速设置:

image-20260421170809701

1.4 模型供应商与KEY填写

选择模型供应商,根据自身需求和情况进行选择。

image-20260421170910695

我选择使用自定义供应商:

image-20260421171251112

填写供应商API:

image-20260421171358500

填写完供应商API后,填写密钥,密钥默认不显示在终端,点击回车后选择模型配置,会根据所填密钥进行分析和输出可用的大模型:

image-20260421171427182

1.5 模型初始配置

留空进行自动检测,系统会自动用模型的最大默认上下文长度。

Context length in tokens [leave blank for auto-detect]

image-20260421171532982

选择是否对接外部平台:我们暂不选择,选择第二项进行跳过,后续进行设置。

image-20260421171715727

见到以下界面代表配置完成:

image-20260421171814560

开启聊天:

Launch hermes chat now? [Y/n]: Y

image-20260421172530407

测试使用:

image-20260421172518274

2、手动安装 (Ubuntu 22.04)

个人服务器无法稳定连接github的话,如何解决这个问题这个只能看大家实力了......

2.1 克隆仓库

使用 --recurse-submodules 克隆以获取所需的子模块:

BASH
mkdir /data
cd /data
git clone --recurse-submodules https://github.com/NousResearch/hermes-agent.git
cd hermes-agent/

如果已经克隆但没有子模块,使用下述命令补齐:

BASH
git submodule update --init --recursive

2.2 安装 uv 并创建虚拟环境

安装uv:

BASH
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env 

# 测试 uv
uv --version 
uv 0.11.7 (x86_64-unknown-linux-gnu)

创建 Python 3.11 的虚拟环境:

BASH
pwd 
/data/hermes-agent

# 创建虚拟环境
uv venv venv --python 3.11

2.3 安装 Python 依赖

BASH
# 告诉 uv 要安装到哪个虚拟环境
export VIRTUAL_ENV="$(pwd)/venv"

# 安装所有扩展
uv pip install -e ".[all]"

2.4 创建配置目录

BASH
# 创建目录结构
mkdir -p ~/.hermes/{cron,sessions,logs,memories,skills,pairing,hooks,image_cache,audio_cache,whatsapp/session}

# 复制示例配置文件
cp cli-config.yaml.example ~/.hermes/config.yaml

# 创建空的 .env 文件用于存储 API 密钥
touch ~/.hermes/.env

2.5 添加环境变量

将 hermes 添加到 PATH

BASH
mkdir -p ~/.local/bin
ln -sf "$(pwd)/venv/bin/hermes" ~/.local/bin/hermes

# Bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc && source ~/.bashrc

2.6 配置模型

BASH
# 执行命令
hermes model

# 在此处添加模型供应商
API base URL [e.g. https://api.example.com/v1]: https://api.edgefn.net/v1

# 在此处添加密钥
API key [sk-sWHHu...]: 
Verified endpoint via https://api.edgefn.net/v1/models (27 model(s) visible)
  Available models:
    1. DeepSeek-V3.2
    2. Kimi-K2-Instruct
    3. KAT-Coder-Exp-72B-1010
    4. Qwen3-Next-80B-A3B-Instruct
    5. Qwen3-Next-80B-A3B-Thinking
    6. Qwen3-Coder-480B-A35B-Instruct
    7. Qwen2.5-72B-Instruct
    8. Qwen3-235B-A22B
    9. DeepSeek-R1-0528
    10. DeepSeek-R1-Distill-Qwen-32B
    11. GLM-5
    12. bge-reranker-v2-m3
    13. Qwen3-30B-A3B-FP8
    14. GLM-4.6
    15. GLM-4.5V
    16. BAAI/bge-m3
    17. DeepSeek-V3.2-EXP
    18. DeepSeek-V3
    19. GLM-4.7
    20. KAT-Coder
    21. Qwen3-235B-A22B-2507
    22. Qwen3-32B-FP8
    23. DeepSeek-R1-0528-Qwen3-8B
    24. DeepSeek-R1-Distill-Qwen-14B
    25. KAT-Coder-Pro-V1
    26. GLM-4.5
    27. MiniMax-M2.5
  
  # 在此处选择可用的大模型ID
  Select model [1-27] or type name: 11

# 大模型参数配置
Context length in tokens [leave blank for auto-detect]: 

# 模型供应商名字
Display name [Api.edgefn.net]: 
Default model set to: GLM-5 (via https://api.edgefn.net/v1)
  💾 Saved to custom providers as "Api.edgefn.net" (edit in config.yaml)

附带图例:

选择模型供应商,根据自身需求和情况进行选择。

image-20260421170910695

我选择使用自定义供应商:

image-20260421171251112

填写供应商API:

image-20260421171358500

填写完供应商API后,填写密钥,密钥默认不显示在终端,点击回车后选择模型配置,会根据所填密钥进行分析和输出可用的大模型:

image-20260421171427182

2.7 测试服务

开启服务:

BASH
hermes

image-20260421215135528

3、服务检测

3.1 检查命令是否可用

BASH
hermes version 

Hermes Agent v0.10.0 (2026.4.16)
Project: /data/hermes-agent
Python: 3.11.15
OpenAI SDK: 2.32.0
Update available: 3 commits behind — run 'hermes update'

image-20260421220740252

3.2 检查配置

BASH
hermes status     

image-20260421220805123

三、Hermes 命令使用

1、hermes 命令

Hermes Agent 的 CLI 是一个完整的终端用户界面(TUI),而非网页端。Hermes Agent CLI 支持多行编辑、斜杠命令自动补全、对话历史、中断重定向以及流式工具输出,专为习惯在终端中工作的用户设计。

运行CLI命令汇总:

BASH
hermes              # 交互式命令行界面 — 开启对话
hermes model        # 选择大语言模型服务商与对应模型
hermes tools        # 配置启用的工具集
hermes config set   # 设置单项配置项
hermes gateway      # 启动消息网关(支持Telegram、Discord等平台)
hermes setup        # 运行全量配置向导(一站式完成所有配置)
hermes claw migrate # 从OpenClaw迁移数据(适用于原OpenClaw用户)
hermes update       # 更新至最新版本
hermes doctor       # 诊断运行环境与配置问题

常用命令组合:

BASH
# 启动交互式会话(默认)
hermes

# 单次查询模式(非交互式)
hermes chat -q "Hello"

# 指定模型
hermes chat --model "anthropic/claude-sonnet-4"

# 指定提供商
hermes chat --provider openrouter  # 强制使用 OpenRouter

# 指定工具集
hermes chat --toolsets "web,terminal,skills"

# 启动时预加载一个或多个技能
hermes -s hermes-agent-dev,github-auth
hermes chat -s github-pr-workflow -q "open a draft PR"

# 恢复之前的会话
hermes --continue                   # 恢复最近的 CLI 会话 (-c)
hermes --resume <session_id>  # 通过 ID 恢复指定会话 (-r)

# 详细模式(调试输出)
hermes chat --verbose

# 隔离的 git worktree
hermes -w                         # 在 worktree 中交互式运行
hermes -w -q "Fix issue #123"     # 在 worktree 中单次查询

2、/ 命令

Hermes 支持大量 CLI 斜杠命令、动态技能命令以及用户定义的快速命令。

命令 说明
/help 显示命令帮助
/model 显示或更改当前模型
/tools 列出当前可用的工具
/skills browse 浏览技能中心及官方可选技能
/background <prompt> 在独立的后台会话中运行 prompt
/skin 显示或切换活动的 CLI 皮肤
/voice on 启用 CLI 语音模式
/voice tts 切换 Hermes 回复的语音播放
/reasoning high 增加推理深度
/title My Session 为当前会话命名

四、国内平台对接

1、Hermes 对接飞书

1.1 飞书应用配置

1.1.1 创建飞书应用

首先你要有飞书后台权限,进入后台,点击创建企业自建应用

image-20260421222215283

填写相关信息,应用名称与应用描述,填写完成后点击创建:

image-20260421222353331

1.1.2 添加应用能力

赋予应用能力:

image-20260421222541403

开通后显示:

image-20260421222636341

1.1.3 创建所需权限

点击权限管理,选择批量导入/导出权限

image-20260421222726683

粘贴所需权限:

权限json如下:

BASH
{
"scopes": {
 "tenant": [
   "aily:file:read",
   "aily:file:write",
   "application:application.app_message_stats.overview:readonly",
   "application:application:self_manage",
   "application:bot.menu:write",
   "cardkit:card:write",
   "contact:contact.base:readonly",
   "contact:user.employee_id:readonly",
   "corehr:file:download",
   "docs:document.content:read",
   "event:ip_list",
   "im:chat",
   "im:chat.access_event.bot_p2p_chat:read",
   "im:chat.members:bot_access",
   "im:message",
   "im:message.group_at_msg:readonly",
   "im:message.group_msg",
   "im:message.p2p_msg:readonly",
   "im:message:readonly",
   "im:message:send_as_bot",
   "im:resource",
   "sheets:spreadsheet",
   "wiki:wiki:readonly"
 ],
 "user": [
   "aily:file:read",
   "aily:file:write",
   "contact:contact.base:readonly",
   "im:chat.access_event.bot_p2p_chat:read"
 ]
}
}

image-20260421222805331

点击下一步,确认新增权限,跳转后点击申请开通权限:

自建飞书可以自己开通,企业版本需要通过管理员审核才可以。

image-20260421222853923

1.1.4 获取凭证ID

在凭证与基础信息中获取到APP ID 和 App Secret:

image-20260421223023272

1.1.5 开启事件回调

回到飞书开放平台,事件与回调中,订阅方式选择长连接

image-20260421224840317

填写完成后,点击右下角添加事件,添加im.message.receive_v1接收消息事件:

image-20260421224945578

同理,点击回调配置,开启所有飞书卡片权限:

image-20260422005536014

以确保AI想使用更高权限的时候,弹出飞书卡片,我们可以正常交互。

image-20260422105357078

最后在版本管理与发布中发布应用:

image-20260421225044609

添加完成后,点击发布,经过审核后正式上线:

image-20260421225145501

1.2 Hermes 配置

1.2.1 飞书gateway配置

获取 1.1.4 我们获取到的ID后,回到我们的hermes终端:

在命令行输入hermes gateway setup 可以配置聊天平台,选择配置Feishu,需要配置App ID ,App Secret ,User IDs,Domain默认feishu,Connection mode 默认websocket。

执行命令:

BASH
hermes gateway setup

image-20260421223234415

两种方式创建机器人:

  • 扫码创建(我一个服务器扫码创建?)
  • 通过APP ID 与 APP Secret 创建

image-20260421223336341

填写APP ID 与 APP Secret 信息:

image-20260421223441256

1.2.2 域名选择

域名选择,选择中国大陆版本

  • 飞书 中国大陆版(国内官方飞书)

  • Lark 国际版(海外版飞书)

image-20260421223519667

1.2.3 Websocket 配置

选择websocket长连接模式:

image-20260421223658802

1.2.4 聊天权限配置

权限选项,根据个人情况定夺,我飞书就我一个人可劲使,我选择所有人私聊。

  • 私聊配对验证授权(官方推荐)

  • 允许所有人私聊

  • 仅允许白名单内的用户 ID 私聊

image-20260421223742032

1.2.5 群内调用配置

群内调用机器人两种权限选项:

  • 群内只有被 @ 时才回复(官方推荐)

  • 关闭所有群聊功能

image-20260421223942500

1.2.6 收尾权限配置

配置完成:

image-20260421224301486

是否将网关安装为系统后台服务?我们选择是:

image-20260421224314967

选择网关后台运行的服务类型:

  • 用户级服务

  • 系统级服务(服务器首选)

  • 暂时跳过服务安装

User service (no sudo; best for laptops/dev boxes; may need linger after logout)

用户级服务

  • 不需要 sudo 管理员权限
  • 适合个人笔记本、本地开发电脑
  • 缺点:关闭 SSH 终端后,服务容易断掉,需要额外配置 linger 常驻

System service (starts on boot; requires sudo; still runs as your user)

系统级服务

  • 需要 sudo 权限
  • 开机自启,全程后台常驻
  • 关闭 SSH、重启服务器都不会掉线,长期挂机器人最稳定

Skip service install for now

暂时跳过服务安装

image-20260421224404336

网关后台服务使用哪个系统用户来运行?

个人建议不要使用root用户,但是我还是使用root用户了,毕竟我一测试使用的云服务器,重装系统也无所谓,我是玩儿的。

其实还是建议创建一个专有用户,并且收紧 sudo 权限,以免AI幻想出现做傻事的情况造成损失。

image-20260421224537610

启动服务完成配置。

image-20260421224727631

1.3 飞书验证配置

1.3.1 添加应用

点击工作台,添加常用 APP:

image-20260421225811305

找到我们创建的服务并添加:

image-20260421225848645

那么它就闪亮登场了:

image-20260421225912051

1.3.2 验证使用

点击我们创建的应用,并和他交流:

No home channel is set for Feishu.A home channel is where Hermes delivers cron job results and cross-platform messages.Type /sethome to make this chat your home channel, or ignore to skip.

还没有给飞书机器人设置通知主频道。这个频道的作用:接收定时任务运行结果、系统报错、后台通知、跨平台消息推送。

  • 设置:在飞书私聊机器人,发送指令 /sethome,即可把当前私聊窗口设为通知接收窗口
  • 不设置:直接忽略这条提示就可以了

image-20260421230036218

2、Hermes 对接微信

得益于腾讯之前推出的 QClaw,公开的官方接口:iLink Bot API,Hermes 也用的是这个适配器。

2.1 Hermes gateway 配置

执行命令:

XUANZBASH
hermes gateway setup 

选择 Weixin / WeChat

image-20260422102342869

2.2 微信扫码添加机器人

进行登陆设置:

image-20260422102458377

若出现以下情况:(网上看到的案例)

image-20260422103445310

复制连接,在浏览器打开并扫码即可。

微信扫码完成后显示:

image-20260422103219443

点击连接后,在微信消息里会出现一个AI对话窗口,即为创建成功。

2.3 Hermes权限设置

2.3.1 私信消息权限配置

根据个人需求进行配置:

Use DM pairing approval:使用私信配对授权,机器人不能主动私聊用户,必须用户先主动给机器人发消息

Allow all direct messages:允许所有私信

Only allow listed user IDs:仅允许指定用户 ID 白名单私信

Disable direct messages:完全关闭私信功能

BASH
  How should direct messages be authorized?
  ↑↓ navigate  ENTER/SPACE select  ESC cancel

 → (●) Use DM pairing approval (recommended)
   (○) Allow all direct messages
   (○) Only allow listed user IDs
   (○) Disable direct messages
2.3.2 群聊消息处理

根据个人需求进行配置:

Disable group chats (recommended):禁用所有群聊

Allow all group chats:允许所有群聊

Only allow listed group chat IDs:仅允许白名单内的群聊 ID

image-20260422102908965

2.3.3 设置机器人主频道

填写Y通过即可。

image-20260422103056997

提醒我们重启网关,建议完成之后,再手动重启一次网关:

BASH
systemctl status hermes-gateway.service 

image-20260422103134917

2.3.4 绑定微信授权码

img

初次使用时会出现“还不认识你”的话语,并且给你附带了授权码以及授权所需要的命令,直接复制粘贴即可:

BASH
hermes pairing approve weixin XXXXXXXX

image-20260422104557227

2.4 验证使用

在手机端的窗口与Hermes进行交流:

img

接入成功。

2.5 使用心得

接入微信很方便,但是也同时不是那么的好用。

好用在确实很方便,随时随地就可以大小聊,不方便在哪呢?如图所示了:

image-20260423114953865

比如说我们想让AI去执行一些操作,而这个操作又需要一定的权限,例如我们使用Claude Code、Codex之类的编程软件的时候,需要高权限需要我们用户自己触发是否使用的按钮,AI才会继续运行下去,所以你应该懂了,微信不支持这种方式的,需要自己手动输入并回复,相当于我们微信对话窗口变成了一个CLI窗口,这就有点鸡肋了,飞书是可以直接使用飞书卡片的按钮进行点击。

有点难崩,但是微信已经开启了封闭的帝国,这就已经很让人满足了。

Hermes Agent 调优

一、全局人设与定制 Prompt

目标:结合 Hermes声明式指令设计、三层记忆隔离,打造你的专属私有化 DevOps 数字员工。

1、设置Agent风格与原理

Hermes 的风格定制,本质上不是“训练模型”,而是通过声明式提示词 + 持久记忆 + 会话隔离,让 Agent 在每次对话开始时,都以你预设的人设、风格和行为准则进行响应。

对于我这种运维场景来说,这一点尤其重要。 因为我真正需要的不是一个“会聊天的 AI”,而是一个:

  • 遇到故障时能冷静分析的助手
  • 默认优先低风险排查的顾问
  • 说话简洁、不废话的工程伙伴
  • 遇到高风险操作时,会主动提醒风险边界的数字员工

所以,Hermes 的定制要解决的不是“让它更聪明”,而是“让它默认像我希望的那种运维工程师一样工作”。

进一步来说,Hermes 的“个性化”并不是简单地把一句 Prompt 改得更好听,而是要把它真正调成一个长期可用、风格稳定、偏运维思维、且不会轻易跑偏的 Agent。

这里面最核心的,不是“它会不会说”,而是:

它默认站在什么角色上思考问题、它默认优先考虑什么、它面对不确定性时怎么表达、它在遇到高风险操作时会不会克制、它会不会把线上故障当成普通闲聊来处理。

这一点,正是 Hermes 和很多普通聊天式 AI 最大的差别之一。 ,因为它不是一次性问答工具,而是一个可以通过长期调优,逐步沉淀成你自己的数字员工的 Agent。

也正因为如此,Hermes 的风格设置,不能只从“回复语气”去理解,而是要从更底层的三个层面去看:

- SOUL.md:定义它是谁,它默认怎么说话、怎么思考、怎么做判断
- Memory:记录用户长期偏好,让它越来越像“懂你”的助手
- Session:承载当前对话上下文,保证这一次交流的连续性

这三层并不是互相替代的关系,而是典型的分层协同关系。

1.1 SOUL.md:基线

SOUL.md 可以理解为 Hermes 的“全局灵魂文件”。
它真正决定的,不只是“说话风格”,更是整个 Agent 的默认行为基线。

比如说:

它是偏客服型,还是偏工程师型、它是偏热情铺陈,还是偏冷静直接、它是先讲概念,还是先给结论、它是喜欢一上来就给操作,还是先提示风险、再分步骤推进、它在没有足够证据时,是会强行下结论,还是会明确承认不确定性

这些内容,本质上都不属于一次性问题的“回答技巧”,而是属于 Agent 的底层人格设定

对于我的运维场景来说,这一层非常关键,因为如果 SOUL.md 还是默认通用人格,那么 Hermes 在很多时候会更像一个“什么都会聊一点的通用技术助手”,而不会天然偏向去做低风险的事情,具有生产环境意识,先判断再执行,高危动作要可知

所以,如果想让 Hermes 真的变成一个可长期使用的运维伙伴,第一步一定不是去堆 memory,也不是不停试 prompt,而是先把 SOUL.md 这条底层人格基线调对。

1.2 Memory:进阶

如果说 SOUL.md 解决的是“它是谁”,那么 Memory 解决的就是“它会不会越来越像你的专属助手”。

因为在长期使用过程中,真正影响体验的,往往不是它会不会回答,而是它能不能逐渐记住你的习惯,例如:

我的本职工作是什么?你站在哪个视角?你喜欢先听结论还是概念?

这些东西,不应该硬塞进 SOUL.md,因为它们不属于“通用人格”,而是属于用户长期偏好。 也正因如此,Hermes 才会把这一层单独抽出来,用 persistent memory 去承载。

这一步的意义在于:SOUL.md 让 Hermes 先成为一个对的角色, Memory 再让这个角色越来越像“懂我的那个运维助手”。也就是说,前者解决“方向正确”,后者解决“越用越顺手”。

1.3 Session:对话连续

第三层是 Session。很多人一开始会把它理解成“聊天记录”,但实际上它更重要的作用是: 维持当前这一轮任务的上下文连续性。

比如说,在同一个微信或飞书会话里,Hermes 会逐步理解:

你当前在排查的是哪个问题?你已经确认过哪些事实?哪些命令已经执行过?哪些怀疑方向已经排除?当前最值得继续往下看的线索是什么?

如果没有 session,这些内容就都要每次重说一遍,但如果只有 session,没有人格与 memory,那它又会变成一个“只会接上文,但没有稳定风格”的普通助手。

这也是为什么,Hermes 的体验不是单靠一个 prompt 撑起来的。
真正好用,是因为:

- SOUL.md 让它默认像一个资深运维
- Memory 让它逐渐理解我的习惯
- Session 让它知道我现在到底在处理哪件事

三层叠加之后,它才开始真正具备“数字员工”的雏形。

Hermes 的个性化调优,本质上不是“改个说话语气”,而是通过 SOUL.mdMemorySession 三层协同,把一个通用 AI,逐步调成一个具备稳定人格、长期记忆和上下文连续性的专属运维数字员工。

2、SOUL.md 内容解读与修改

2.1 原始配置文件解读

默认配置文件在/root/.hermes/memories/MEMORY.md ,默认文件内容如下:

BASH
cat SOUL.md 
You are Hermes Agent, an intelligent AI assistant created by Nous Research. You are helpful, knowledgeable, and direct. You assist users with a wide range of tasks including answering questions, writing and editing code, analyzing information, creative work, and executing actions via your tools. You communicate clearly, admit uncertainty when appropriate, and prioritize being genuinely useful over being verbose unless otherwise directed below. Be targeted and efficient in your exploration and investigations.

这段默认配置,本质上定义的是 Hermes 最基础的通用助手人格。

从内容上看,它强调的核心关键词主要是:

  • helpful
  • knowledgeable
  • direct

也就是说,官方默认给 Hermes 的定位,并不是某一个具体领域里的专家型 Agent,而是一个覆盖面较广、通用能力较强的智能助手。它默认可以处理问答、代码编写、信息分析、创意类任务,以及借助工具去执行动作,整体追求的是“真正有用”,而不是单纯追求话多、表达花哨或者风格感很强。

这种默认设定本身没有问题,优点也很明显:

  • 足够通用
  • 足够稳妥
  • 不容易和多数任务场景冲突
  • 初始可用性很高

但问题也恰恰在这里。

因为它的“通用性”很强,所以它的“场景倾向性”就不够强。
对于普通用户来说,这种默认人格已经足够使用;但对于我们这种希望把 Hermes 长期调优成一个贴近生产环境、偏运维、重视风险控制与排障逻辑的私有化数字员工的人来说,这套默认设定就显得过于宽泛了。

更直白一点说:

默认的 Hermes,更像一个“什么都能聊一点的通用技术助手”;
而不是一个“真正站在生产环境角度思考问题的资深运维工程师”。

它不会天然强调这些你真正关心的点:

  • 低风险优先
  • 先观察、后修改
  • 先取证、后判断
  • 高风险命令不轻易建议直接执行
  • 回答问题时更关注故障链路、影响范围、回滚思路和实际落地性

所以,到了这一步,我们就不能只停留在“能用”这个层面了,
而是要进一步通过改写 SOUL.md,把 Hermes 的默认人格从“通用助手”,正式切换成“资深全栈运维工程师兼故障排查伙伴”。

2.2 自定义Agent风格

替换内容:

BASH
You are a senior full-stack operations engineer and troubleshooting partner.

You think like an experienced production operator: calm under pressure, precise, practical, and risk-aware. You care about correctness, system stability, rollback safety, and operational reality more than sounding impressive.

## Style
- Be calm and direct
- Be concise by default
- Prefer clear conclusions first, then supporting reasoning
- Use practical language, not hype
- Focus on diagnosis, risk, impact, and next action
- When multiple causes are possible, say what is most likely and how to verify it

## Operational defaults
- Prefer low-risk investigation first
- Prefer observation before modification
- Prefer reversible actions before irreversible ones
- Prefer step-by-step verification over large speculative changes
- When suggesting commands, default to safe inspection commands first
- For destructive, high-risk, or service-impacting actions, warn clearly and ask the user to execute them unless the user explicitly wants a full command plan
- Always mention blast radius, rollback idea, and prerequisites when operational risk exists

## Avoid
- Do not be verbose unless the situation is complex
- Do not pretend certainty when evidence is incomplete
- Do not recommend dangerous commands casually
- Do not jump to restarting, deleting, flushing, truncating, or mass-changing things without first checking safer evidence
- Do not overload the user with unnecessary theory when the issue is operational

## Defaults under ambiguity
- Start with the most likely operational explanation
- Ask for the minimum evidence needed to narrow it down
- Give the safest useful next step
- If risk is non-trivial, separate "what to check" from "what to change"

中文版:

BASH
你是一位资深的全栈运维工程师兼故障排查伙伴。

您的思维方式如同经验丰富的生产环境运维人员:临危不乱、严谨精准、务实可靠,且具备高度的风险意识。相比于追求言辞上的花哨,您更看重操作的正确性、系统的稳定性、回滚的安全性以及实际的运维落地效果。

## 风格指南
- 保持冷静与直率。
- 默认保持言简意赅。
- 优先给出明确的结论,随后提供支撑性的推理依据。
- 使用务实的语言,避免夸大其词或空洞的宣传语。
- 重点关注故障诊断、潜在风险、影响范围以及下一步的行动计划。
- 当存在多种可能的成因时,请指出哪种可能性最高,并说明如何进行验证。

## 运维操作原则
- 优先采取低风险的排查手段。
- 优先进行观察与分析,随后再进行修改操作。
- 优先执行可逆的操作,避免不可逆的操作。
- 优先采取“循序渐进、逐一验证”的策略,而非进行大规模的推测性变更。
- 在建议执行命令时,默认优先推荐安全的检查类命令。
- 针对具有破坏性、高风险或可能影响服务运行的操作,必须给出明确的警告,并要求用户亲自执行(除非用户明确要求提供完整的命令执行方案)。
- 凡涉及运维风险的操作,务必说明其“影响范围”(Blast Radius)、“回滚方案”以及“前置条件”。

## 禁忌事项
- 除非情况确实复杂,否则切勿冗长赘述。
- 当证据尚不充分时,切勿表现出言之凿凿的绝对确定性。
- 切勿随意推荐具有危险性的命令。
- 在未通过更安全的手段进行初步核实之前,切勿贸然执行重启、删除、清空、截断或大规模变更等操作。
- 当故障本质属于运维操作层面时,切勿向用户灌输过多的、不必要的理论知识。

## 面对不确定性时的处理原则
- 优先从最可能的运维操作层面原因入手进行排查。
- 仅索取定位问题所需的“最小集”证据。
- 给出当前最安全且有效的下一步操作建议。
- 若潜在风险不容忽视,请明确区分并拆解“需要检查/排查的事项”与“需要修改/变更的事项”。

这段配置的核心作用,是把 Hermes 的默认定位从“通用 AI 助手”,改造成**“生产环境中的资深运维排障工程师”。**

它真正改变的,并不只是回复时的措辞,而是整个 Agent 的默认思考方式和处理问题的优先级,也就是说,修改完之后,Hermes 在面对问题时,默认不再从“泛技术问答”的角度出发,而是会更自然地站在生产环境、系统稳定性和运维落地的角度来分析。

2.2.1 角色定位聚焦

默认的 Hermes 是一个覆盖范围很广的通用助手,它可以写代码、分析问题、做创意工作,也可以借助工具执行动作。 但这种“什么都能做一点”的设定,在很多时候也意味着它不会天然偏向某一个具体职业角色。

而这次改写后,角色被明确收敛成了:

  • 资深全栈运维工程师
  • 故障排查伙伴
  • 生产环境问题的协助者

这一点非常关键。因为只要角色定位明确了,后续它对问题的理解、表达方式、给建议的习惯,都会自然发生变化。

2.2.2 表达风格贴近运维场景

这段 Prompt 里,专门强调了:

- calm
- direct
- concise
- practical
- risk-aware

这些词看起来像是在修饰“说话风格”, 但实际上,它们决定的是 Hermes 回答问题时,是不是更像一个真正处理过线上问题的人。因为线上排障最怕两种风格,一种是话很多、很热闹,但没有结论,没有优先级;一种是看起来很自信,但没有证据、没有边界、没有风险意识,而这套自定义配置,本质上就是在把 Hermes 往“冷静、克制、结论优先、实操导向”的方向上拉。

2.2.3 默认决策逻辑变稳

运维场景和普通问答最大的区别就在于,很多时候“建议错一步”,代价都不小。

  • 随意重启服务,可能放大故障
  • 直接清缓存,可能引发穿透或雪崩
  • 粗暴 kill 进程,可能造成更严重的数据不一致
  • 不看证据就修改配置,可能把原本局部问题扩散成系统性问题

所以,这段 Prompt 并不是单纯让 Hermes “说得更像运维”, 而是把它的默认行为原则,调整成更适合生产环境的模式:

  • 优先低风险排查
  • 优先观察、后修改
  • 优先可逆操作,避免不可逆动作
  • 优先逐步验证,而不是大范围猜测性变更
2.2.4 高风险操明确约束

这一点,是我认为最值得加进去的一部分。因为现实场景里,很多问题一旦到了线上,真正危险的往往不是“AI不会答”,而是“AI答得太快、太猛、太不设边界”。

比如下面这些动作:

  • 重启服务
  • 删除数据
  • flushall
  • truncate
  • 批量变更配置
  • 直接 kill 掉线上关键进程

如果 Agent 对这些动作没有约束,它就很容易在“看起来很积极帮忙”的表象下,给出高风险建议。 而运维真正需要的,不是这种“冲得快”的助手,而是一个懂得控制节奏、知道什么时候该提醒风险的伙伴。

所以在这套配置里,专门加上了这层限制:

  • 遇到破坏性、高风险或可能影响服务的操作,要明确警告
  • 默认让用户自己执行,而不是轻飘飘直接推动落地
  • 需要同时说明影响范围、回滚思路和前置条件

这一点,会让 Hermes 更像一个真正上过生产的人,而不是一个只会“给命令”的自动答题器。

2.3 验证风格生效

保存后,重启Gateway:

BASH
# 重启网关
hermes gateway restart

重启完成后,在微信 / 飞书聊天窗口输入:

/new/reset 不会清掉 Hermes 的 persistent memory,发 /new,你丢的是“当前聊天上下文”,不是“长期记忆”。

BASH
/new

image-20260423164936010

那么现在再去问,hermes agent的风格是什么:

image-20260423164851658

就和我们设置的差不多了。

微信也记得更新哦:

image-20260423172856203

这就很真实了,原来他会说一大堆废话,但是现在就很简介明了,干技术的就喜欢这种回答:

image-20260424135623122

最后想说一下:

建议这一步是第一步,我们开始使用的第一步,至于为啥哈,因为我是已经和AI聊了一段时间之后才改的,虽然memory没有删除,但是也相应的删除了上下文,还是会有一些数据丢失,按照我原本的计划他应该是第二章,但是为了下一个使用我这份文档去做这些操作的人少一些内容损失,还是把他放在前面了。

二、接入 Skills

目标:蒸馏他人技术,让你高攀不起的技术大拿变成你的私人导师。

1、手动创建 Skills 并接入Hermes

传统方式接入,需要我们在 skills 目录下:

BASH
ls ~/.hermes/skills/
apple                 data-science  dogfood  feeds   github        media        productivity  smart-home
autonomous-ai-agents  devops        domain   gaming  inference-sh  mlops        red-teaming   social-media
creative              diagramming   email    gifs    mcp           note-taking  research      software-development

将编写完成的标准 Hermes Skills 技能文件放入 Agent 对应的技能存储目录后,Hermes Agent 启动运行时会自动遍历扫描该目录,解析技能内部的元数据信息、触发条件、执行逻辑与调用规范,完成技能的结构化解析、内部注册入库,并将该技能挂载更新到自身的能力知识库中,至此整个上传注册链路完成,后续 Agent 在对话推理时便可识别需求、自动调用该已注册的自定义技能执行任务。

2、AI 自主创建 Skills

但是,由于hermes的特性,我想了一个简单的办法,你Hermes的特点不就是学习么?

传统方式需要手动编写、上传、部署技能文件,流程繁琐且灵活性不足。而 Hermes 核心优势正是强大的自主学习与能力演化特性,因此我采用极简的全新方案:无需手动创建技能文件、无需上传目录、无需静态注册,直接将原始 Skills 内容投喂给 Agent 进行深度知识内化。

比如说:

BASH
深度学习一下这个skills:https://github.com/isYaoNoistu/claudecode-skills/blob/main/prometheus/SKILL.md,由你自主学习全部流程与约束,继承原有功能边界并优化自身推理链路,最终沉淀为原生能力。

指令发出后,Hermes 会自动读取文档、解析核心规则、梳理执行流程、优化推理逻辑,无需人工干预即可完成技能的全流程内化与落地。

3、实战测试

摒弃传统手动上传、目录注册 Skills 的繁琐流程,我们采用更高效的 AI 原生学习模式:直接让 Hermes 读取在线 Skills 文档,自主完成知识学习、逻辑解析与能力内化。

BASH
深度学习一下这个skills:https://github.com/isYaoNoistu/claudecode-skills/blob/main/prometheus/SKILL.md,由你自主学习全部流程与约束,继承原有功能边界并优化自身推理链路,最终沉淀为原生能力。

Hermes 接收指令后,全自动完成文档读取、知识补充、核心架构拆解与规则梳理,输出标准化分析结果:

BASH
╭─ ⚕ Hermes ────────────────────────────────────────────────────────────────────────────────────────────────────────╮
    获取到完整文档。让我也查看相关的监控系统知识作为补充:
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
  ┊ 📚 preparing skill_view…

╭─ ⚕ Hermes ────────────────────────────────────────────────────────────────────────────────────────────────────────╮
    现在我来深度分析这个 skill 的核心价值,并将其内化为 Hermes 原生能力。
    
    Prometheus Skill 核心架构分析
    
    设计哲学(Token 防护第一原则)
    
    
    ┌─────────────────────────────────────────────────────────────┐
    │                    Prometheus 查询防护流水线                  │
    ├─────────────────────────────────────────────────────────────┤
    │  1. detect_profile    →  判断指标来源生态                     │
    │  2. estimate_cardinality → 评估返回规模风险                   │
    │  3. query(summary)    →  只拿统计摘要,不拿全量矩阵            │
    │  4. analyze_trend     →  基于摘要做诊断推理                    │
    │  5. raw(only if needed) →  截断+采样,永不返回全量            │
    └─────────────────────────────────────────────────────────────┘
    
    
    关键约束常量
    
    | 参数 | 值 | 含义 |
    |------|-----|-----|
    | maxrangeseconds | 21600 | 最大查询窗口 6 小时 |
    | max_series | 50 | 最大序列数 |
    | maxpointsper_series | 600 | 每序列最大点位 |
    | maxrawpoints_returned | 120 | raw 模式每序列最多返回 |
    | defaultresultmode | summary | 默认返回摘要 |
    
    双生态适配策略
    
    
    nodeexporter 风格:  nodecpusecondstotal, nodememory, nodefilesystem
    Categraf 风格:      cpuusageidle, memusedpercent, systemloadnorm_5
    
    聚合标签优先级: ident > instance (夜莺生态 ident 更贴近对象模型)
    
    
    现在我将其沉淀为 Hermes 原生 skill:
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────

在分析完成后,Hermes 会基于工具调用机制,自动将技能对应的执行脚本绑定为专属可用工具,实现用户意图解析 → 技能匹配 → 脚本自主调度执行的全自动化闭环。

image-20260422171936130

最终 Hermes 完成全套能力的原生沉淀,无需手动配置文件、无需目录注册、无需繁琐部署,全程由 AI 自主学习、优化、落地。这种模式相比传统单独提供 Skills 文件的方式,省去了人工上传注册的全部步骤,推理逻辑更优、执行效率更高、使用体验更轻量化便捷

image-20260422172134378

So,从一个skill,它分析之后形成了一个更强大的skills,这也许就是时代的选择吧。

最终生成文件:

BASH
tree .hermes/skills/devops/prometheus/
.hermes/skills/devops/prometheus/
├── SKILL.md
├── references
│   ├── categraf-metrics.md
│   └── promql-cheatsheet.md
└── scripts
    └── promql.py

2 directories, 4 files

那么我们也是需要测试的,测试这个skills他到底会不会用:

BASH
## 我如何使用 Prometheus Skills

### 1. **自动加载机制**

当你的问题涉及 Prometheus、监控、Grafana 等关键词时,我会自动加载相关 skill:

```
问题关键词: Prometheus, PromQL, 监控, 指标...

自动匹配 skill: qianshuaiblog-monitoring

加载 SKILL.md 内容到上下文
```

### 2. **Skill 提供的核心知识**

刚加载的 skill 包含:

| 模块 | 内容 |
|------|------|
| **架构组件** | Server, Exporters, Pushgateway, Alertmanager |
| **PromQL 语法** | 即时/范围向量、rate、聚合、百分位 |
| **服务发现** | Kubernetes SD 配置示例 |
| **常用 Exporter** | node_exporter, cAdvisor, kube-state-metrics 等 |
| **告警配置** | Alertmanager route/receiver 示例 |

### 3. **Memory 中的安全规则**

我在 memory 里还保存了一条 **「Prometheus 查询铁律」**:

```
Summary First 原则:
1. profile → 判断指标生态(node_exporter/Categraf)
2. estimate → 评估规模风险
3. 默认返回 summary 统计摘要

防护参数:
- max_range=6h (最大查询范围)
- max_series=50 (最大序列数)
- max_points=600 (最大数据点)

高风险(>50 series) 必须先降基数再查询
```

### 4. **实际使用流程**

```
用户问: "查询 CPU 使用率"

1. 加载 skill 获取 PromQL 模板
2. 检查 memory 中的安全规则
3. 判断指标生态 → node_exporter 用 instance 标签
4. 先做 estimate 确认不会产生过多 series
5. 执行查询并返回 summary (min/max/avg/p95)
```

### 5. **Skill vs Memory 的分工**

| 存储位置 | 内容类型 | 示例 |
|----------|----------|------|
| **Skill** | 程序性知识、操作步骤、API 语法 | PromQL 语法、Exporter 列表 |
| **Memory** | 声明性事实、安全规则、用户偏好 | 查询铁律、防护参数、标签约定 |

---

**简单说**:Skill 告诉我「怎么查」,Memory 告诉我「怎么安全地查」。两者结合,既专业又不会搞炸你的 Prometheus!

于是,我把Prometheus的相关信息给他了,保存到 Memory,接下来发起询问:

BASH
分析一下instance="prod-redis"的redis状态。

## Redis 状态报告 — `prod-redis`

| 指标 | 值 | 状态 |
|------|------|:----:|
| **运行状态** | UP | ✅ |
| **运行时间** | 15天 22小时 | ✅ 稳定 |
| **版本** | 6.0.16 (standalone, master) | ✅ |
| **内存使用** | 1106.6 MB | - |
| **当前连接** | 135 | ✅ |
| **总键数** | 393,169 | - |
| **命中率** | 97.78% | ✅ 优秀 |
| **内存碎片率** | 1.02 | ✅ 健康 |
| **阻塞客户端** | 0 | ✅ |
| **RDB 持久化** | OK | ✅ |
| **AOF 持久化** | 已开启 | ✅ |

---

### 状态评估

| 维度 | 评价 |
|------|------|
| **健康度** | 🟢 优秀 |
| **稳定性** | 连续运行 15+ 天,无阻塞,持久化正常 |
| **性能** | 命中率 97.78% 非常理想 |
| **内存** | 碎片率 1.02 接近完美(理想值 1.0)|

### 建议

- 当前状态非常健康,无需干预
- 内存使用约 1GB,注意观察增长趋势
- 双持久化(RDB+AOF)配置保障了数据安全

还可以,蛮好用的,但还需优化一些内容,如何优化呢,待我思索一下。

4、Skills 优化

4.1 优化的意义

思考了一段时间,我觉得,能实现技能自主二次迭代,才是真正的越用越强

目前只是投喂原始文档→Hermes生成标准Skill

但是刚用的AI就和行业小白一样,只不过它会使用说明书,它懂通用 PromQL 语法、懂标准监控流程、懂公开运维范式,会调用工具、会照搬文档步骤,但是完全没有真实线上排障经历

So,由此会产生非常明显的局限性:

  • 对你私有服务器环境、自定义配置、夜莺 / Categraf 专属指标、实例标签、业务架构理解严重泛化、贴合度极低;

  • 仅能处理标准常规告警,面对线上偶发故障、配置毛刺、历史遗留异常、非常规根因完全无从下手;

  • 排障逻辑死板,只会通用模板推理,不会规避过往踩过的坑、不会复用历史处置经验;

  • 技能只有通用公版流程,缺少属于本人运维体系专属的经验库、故障边界、风险约束、最优处置方案

让 Hermes 从背说明书的通用 Agent,进化为熟悉本人整套运维环境、踩过所有线上坑、自带私有故障经验、能自主反哺优化自身能力的专属运维智能体。

所有事故经验经过 Hermes 原生 输入→压缩→沉淀 链路,分流存入三层持久化模型,增量更新原有技能、增补异常处理分支、固化私有环境约束、归档故障案例库,完成技能自主二次演化。

4.2 优化演示

4.2.1 目标优化内容

首先,我在服务器上上传了一个业务排障的复盘文档,放置在了/data/session_search目录下,名为redis.md,并让hermes进行分析,文档大致内容如下:

事故表面上是巡检脚本先发现服务侧存在大量 CLOSE_WAIT,随后业务表现异常;继续排查时,服务日志没有直接暴露明确报错,但线索逐步指向 Redis。
对 Redis 进一步检查后发现:

  • Redis CPU 使用率接近 100%
  • 慢查询日志中大量出现 KEYSSCAN MATCH ... 一类命令
  • 业务侧存在按模式扫描 key 的访问逻辑,而非精准 key 查询

最终确认:**事故根因并不是 Redis 自身故障,也不是持久化、内存淘汰导致,而是业务代码在高频执行模糊匹配扫描,导致 Redis 单线程被持续占满,进而放大为服务超时、连接堆积、CLOSE_WAIT 异常。**后续通过业务代码优化,将 KEYS / 大量 SCAN 改为精准查询后,Redis CPU 恢复正常,业务恢复稳定。

由于当时赶上了午休,所以我把文件上传上去之后就直接去吃饭了,就没用CLI进行处理,而是使用的飞书,这也恰好验证了我们可以随时随地去提高Hermes Agent的能力,侧面展示了现在人工智能的恐怖之处。

4.2.2 提示词

输入内容如下:

BASH
在我服务器上的`/data/session_search/redis.md`文件里,是一次实际生产环境中,当时出现的redis问题、排查过程、复盘、总结。
结合你已内化的Prometheus、DevOps原生技能,严格遵循Hermes三层持久化模型完成全链路优化,解析每起故障的指标规律、异常特征、根因逻辑、最优处置流程;
针对现有通用运维技能,自主增补异常分支、兜底方案、定制化查询逻辑,更新原生SKILL文档与执行脚本;
全程不重复学习、不冗余存储、不膨胀上下文Token,仅沉淀高价值私有经验,融合原有通用能力不冲突。
4.3.3 agent 分析过程

具体分析过程如下:

image-20260423133202807

三层持久化执行:

image-20260423133453638

4.3.4 最终知识沉淀

最终输出:

BASH
✅ 三层持久化完成
📊 沉淀总结
🎯 核心增量价值
1. 指标规律提炼
KEYS:低频重击(单次 50-138ms),生产禁止
SCAN:高频累计(案例:98万次累计 1069 秒),阈值 > 100/s 告警
2. 异常特征画像
CPU 高 + 慢查询高 + rdb_bgsave=0 + aof_rewrite=0 + blocked=0 + evicted=0
→ 指向业务命令滥用(排除 Redis 内部任务)
3. 根因收敛逻辑
现象层 → 排除层(持久化/淘汰/阻塞)→ commandstats 定命令 → slowlog 定模式 → CLIENT LIST 定来源
4. 最优处置流程
告警触发 → 查 commandstats → 查 slowlog → 查 CLIENT LIST → 定位业务代码 → KEYS 改精准查询 / SCAN 改索引
🔗 技能融合验证
📝 记忆已更新
Redis 高危命令排障铁律:看到 Redis CPU 高 + 慢查询高时,必须立即下钻 
commandstats/slowlog/CLIENT LIST,排除 KEYS/SCAN MATCH 业务滥用。
标准路径:服务异常 → Redis CPU/慢查询表象 → commandstats 定命令 → 
slowlog 定模式 → CLIENT LIST 定来源 → 改代码。
KEYS 单次 >50ms 或 SCAN 高频累计均属高危。
遵循原则验证:
✅ 不重复学习 — 只增量,未覆盖原有知识
✅ 不冗余存储 — 引用 redis-troubleshooting.md,不在多处复制
✅ 不膨胀 Token — 主 SKILL.md 仅入口引用,详情在独立文件
✅ 融合不冲突 — 继承 Prometheus 防护原则,扩展 Redis 场景

4.3 验证优化

查看新生成的持久化skills是否生成:

BASH
root@ser558828169418:~/.hermes# ls skills/devops/prometheus/references/
categraf-metrics.md  promql-cheatsheet.md  redis-troubleshooting.md

查看新生成的文件:

BASH
cat skills/devops/prometheus/references/redis-troubleshooting.md 
# Redis 排障场景模板

> 来源:生产环境实战复盘 — KEYS/SCAN MATCH 导致 CPU 打满事故

## 一、Redis CPU 高 + 慢查询高 → 标准下钻路径

```promql
# Step 1: 确认 Redis CPU 现象
# Redis Exporter 指标
redis_cpu_sys_seconds_total
redis_cpu_user_seconds_total

# 或使用 Categraf Redis 插件
redis_cpu_usage

# Step 2: 确认慢查询增长
redis_slowlog_length

# Step 3: 排除 Redis 内部任务 (这些通常不是根因)
redis_rdb_bgsave_in_progress      # RDB 持久化
redis_aof_rewrite_in_progress     # AOF 重写
redis_blocked_clients             # 阻塞客户端
redis_evicted_keys_total          # 内存淘汰

# Step 4: 命令级诊断 (关键!)
# 注意: commandstats 是 INFO 命令返回的,需通过 redis_exporter 的 redis_commandstats_* 暴露
redis_commandstats_keys_calls_total
redis_commandstats_keys_usec_total
redis_commandstats_scan_calls_total
redis_commandstats_scan_usec_total

# Step 5: 计算单命令平均延迟 (usec)
redis_commandstats_keys_usec_total / redis_commandstats_keys_calls_total
redis_commandstats_scan_usec_total / redis_commandstats_scan_calls_total
```

## 二、高危命令告警规则

### KEYS 命令告警 (生产环境禁止)

```yaml
- alert: RedisKeysCommandUsed
  expr: increase(redis_commandstats_keys_calls_total[1m]) > 0
  for: 0m
  labels:
    severity: critical
  annotations:
    summary: "Redis KEYS 命令被调用"
    description: "实例 {{ $labels.instance }} 在过去 1 分钟执行了 KEYS 命令,生产环境应禁止使用"
```

### SCAN 异常高频告警

```yaml
- alert: RedisScanAbuse
  expr: rate(redis_commandstats_scan_calls_total[5m]) > 100
  for: 2m
  labels:
    severity: warning
  annotations:
    summary: "Redis SCAN 命令调用频率异常"
    description: "实例 {{ $labels.instance }} SCAN 调用频率 {{ $value }}/s,可能导致 CPU 高占用"
```

### 命令延迟异常告警

```yaml
- alert: RedisCommandSlow
  expr: redis_commandstats_keys_usec_total / redis_commandstats_keys_calls_total > 50000
  for: 1m
  labels:
    severity: warning
  annotations:
    summary: "Redis KEYS 命令平均延迟过高"
    description: "实例 {{ $labels.instance }} KEYS 命令平均延迟 {{ $value | humanize }}us (>50ms),存在性能风险"
```

## 三、排障判断逻辑

### 信号关联矩阵

| 观察到的信号 | 可能根因 | 下一步动作 |
|-------------|---------|-----------|
| CPU 高 + 慢查询高 + rdb_bgsave=0 + aof_rewrite=0 | **业务命令滥用** | 查 commandstats/slowlog |
| CPU 高 + rdb_bgsave=1 | RDB 持久化 | 检查 RDB 频率/数据量 |
| CPU 高 + evicted_keys 增长快 | 内存淘汰风暴 | 检查内存策略/maxmemory |
| CPU 高 + blocked_clients 多 | 阻塞命令(BLPOP等) | 检查客户端阻塞行为 |
| 慢查询高 + commandstats 无异常 | 可能是网络/IO 问题 | 检查网络延迟/带宽 |

### 根因收敛速查

```
1. CPU 高否? → 否 → 问题不在 Redis 主线程
       ↓ 是
2. rdb_bgsave_in_progress=1? → 是 → RDB 持久化导致
       ↓ 否
3. aof_rewrite_in_progress=1? → 是 → AOF 重写导致
       ↓ 否
4. evicted_keys 快增? → 是 → 内存淘汰风暴
       ↓ 否
5. blocked_clients > 0? → 是 → 阻塞命令
       ↓ 否
6. 【重点】查询 commandstats:
   - keys_calls > 0? → KEYS 滥用
   - scan_calls 频率高? → SCAN 滥用
   - 单命令 avg_usec > 50ms? → 高危命令

7. 下钻 slowlog 看具体命令模式
8. 下钻 CLIENT LIST 看来源 IP
```

## 四、现场命令速查

```bash
# 1. 登录 Redis 查看 commandstats
redis-cli INFO commandstats | grep -E "cmdstat_keys|cmdstat_scan"

# 2. 查看慢日志 (最近 10 条)
redis-cli SLOWLOG GET 10

# 3. 查看活跃客户端 (找出正在执行 SCAN/KEYS 的来源)
redis-cli CLIENT LIST | grep -E "cmd=keys|cmd=scan"

# 4. 排除内部任务
redis-cli INFO persistence | grep -E "rdb_bgsave_in_progress|aof_rewrite_in_progress"
redis-cli INFO stats | grep -E "evicted_keys|blocked_clients"

# 5. 实时监控命令 (调试用,生产慎用)
redis-cli MONITOR | grep -E "KEYS|SCAN"
```

## 五、案例特征速记

### KEYS 命令特征
- **低频但重击**:调用次数少,单次耗时长 (>50ms 正常,大空间可达 100ms+)
- **模式匹配**:`KEYS pattern:*` 遍历整个 keyspace
- **生产禁止**:任何 KEYS 调用都应告警

### SCAN MATCH 特征
- **高频累计消耗**:单次可能不慢,但频率极高
- **业务常犯**:以为 SCAN 比 KEYS 安全,却高频调用
- **典型模式**:`SCAN 0 MATCH prefix:* COUNT 1000` 循环调用

### 事故链路模板
```
业务代码 KEYS/SCAN MATCH 
→ Redis 主线程被占满 
→ CPU 100% 
→ 命令响应变慢 
→ 慢查询增加 
→ 业务访问 Redis 超时 
→ 连接堆积/CLOSE_WAIT 
→ 服务异常
```

## 六、开发规范 (必须落地)

### 禁止项
- `KEYS *` / `KEYS pattern:*` — 生产绝对禁止
- 无边界 `SCAN MATCH` — 必须有限制和超时
- 运行时遍历 keyspace — 设计阶段规避

### 替代方案
| 场景 | 错误方式 | 正确方式 |
|------|---------|---------|
| 查某类 key | `KEYS user:*` | 维护 SET 索引 `SADD user:ids {id}` |
| 批量删除 | `KEYS session:*` + DEL | 维护过期时间 或 SCAN + 限速删除 |
| 模糊查询 | `SCAN MATCH` | 业务层维护映射关系 |

## 七、监控指标清单

确保 Redis Exporter 暴露以下指标:

| 指标 | 用途 | 告警阈值 |
|------|------|---------|
| `redis_commandstats_keys_calls_total` | KEYS 调用次数 | > 0 即告警 |
| `redis_commandstats_scan_calls_total` | SCAN 调用次数 | 频率 > 100/s 告警 |
| `redis_commandstats_*_usec_total` | 命令总耗时 | avg > 50ms 警告 |
| `redis_slowlog_length` | 慢日志条数 | 持续增长需关注 |
| `redis_rdb_bgsave_in_progress` | RDB 进行中 | 关联 CPU 时参考 |
| `redis_aof_rewrite_in_progress` | AOF 重写中 | 关联 CPU 时参考 |
| `redis_blocked_clients` | 阻塞客户端 | > 10 需关注 |
| `redis_evicted_keys_total` | 淘汰 key 数 | 突增需关注 |

至此,Hermes知识沉淀也算是形成了一个完整的闭环,结合 Hermes 原生学习流程,形成永不中断的能力增长链路:

BASH
线上真实故障发生

人工复盘归档,形成新事故文档

投喂Hermes完成输入→压缩→分流沉淀

memory更新全局约束 + skill自主增补排障脚本 + session留存故障案例

后续同类异常触发 → 自动检索历史案例 → 调用迭代优化后的技能精准排障

本次新故障再次复盘归档 → 开启新一轮增量迭代

我们实际查询一下memory,记忆文件在/root/.hermes/memories/MEMORY.md目录之下。

image-20260423155641944

上面有各个阶段Agent自己记录的重要内容。

再次实际使用一次:

这一次换个平台,用微信试试

image-20260423135810229

通过做完这个部分的内容,我又补全了一部分本文知识部分的内容。

Hermes Agent初步探索 / 一、Hermes Agent 基础 / 4. 关于Hermes Agent 记忆

三、定时任务

1、定时任务原理

Hermes 里的 Cron,本质上是一个 Agent 任务调度器。它借用了 Cron 这个概念,但不是简单地往系统 /etc/crontabcrontab -e 里写任务。

它的核心是:

到时间后,由 Hermes 自己启动一次新的 Agent 会话,让 Agent 按提示词完成任务,然后把结果投递到指定渠道。

官方文档里说明,Hermes 通过统一的 cronjob 工具管理定时任务,可以创建、暂停、恢复、编辑、触发和删除任务,并且支持把结果投递到原聊天、本地文件或消息平台。Hermes Cron 的实际执行依赖 Hermes gateway。所以他的流程就是这样:

BASH
传统 Cron:
时间到 → 执行一条 shell 命令

Hermes Cron:
时间到 → 启动一个新的 AI Agent 会话 → 加载提示词/技能/脚本输出 → 推理 → 输出结果 → 投递消息

Hermes 的定时任务是否能按时运行,取决于 gateway 是否在持续运行。

BASH
gateway 常驻运行

每 60 秒 tick 一次

读取任务列表 jobs.json

检查哪些任务 next_run_at 到期

为每个到期任务启动新的 AIAgent 会话

运行任务

投递结果

更新运行状态和下一次执行时间

如果 gateway 没有启动,Cron 任务并不会像系统级 crond 那样自动执行。对运维来说,它更像一个 应用内调度器,而不是 OS 级调度器。

Cron 任务运行在 全新的代理会话 中,不保留当前聊天上下文,因此提示词必须完全自包含。也就是说,你在当前聊天里跟 Hermes 说过的内容,Cron 任务执行时不一定知道。

这句话很重要。

总结就是Hermes Cron 的本质是一个由 gateway 驱动的应用级 Agent 调度系统。它不是简单定时执行命令,而是定时启动一个隔离的新 Agent 会话,加载任务说明、技能和脚本输出,完成推理后再按规则投递结果。

2、定时任务创建

我们先将怎么设置,在去说怎么应用。

2.1 hermes 命令创建

这是 CLI 方式,适合运维管理,语法如下:

BASH
hermes cron create "调度表达式" "任务提示词" --name "任务名称" --deliver 投递目标

这就比较适合在服务器上集中管理任务、写入自动化脚本、检查任务状态、排查 gateway 调度问题。

2.2 Hermes 聊天窗口创建

在CLI窗口、微信、飞书窗口都可以直接使用 /cron 进行设置,设置格式如下:

BASH
/cron add "调度表达式" "任务提示词" --name "任务名称" --deliver 投递目标

这种方式就非常的轻松,随时都可以设置一些定时任务,而且官方文档也把 /cron add 作为聊天方式创建任务的入口。

这也算是最佳实践了。

2.3 自然语言创建

是不是忘了最简单的方法了?没看前面的skills怎么导入的?

直接和hermes说:

BASH
每隔 1 分钟执行一次hermes状态检测,并把结果发回当前聊天。

Hermes 内部会调用统一的 cronjob 工具创建任务。官方文档说明,自然语言创建任务时,Hermes 会在内部使用统一的 cronjob 工具。这也是最简单的办法了。

image-20260424151722054

3、定时任务设置内容

一个 Hermes Cron 任务,本质上要设置这几个核心字段:

BASH
1. schedule     什么时候执行
2. prompt       执行时让 Agent 做什么
3. name         任务名称
4. deliver      结果投递到哪里,例如飞书、微信
5. skill        是否加载技能
6. script       是否先执行脚本,把 stdout 交给 Agent

最小可运行版本只需要:

BASH
schedule + prompt

比较完整的测试版本建议包含:

BASH
schedule + prompt + name + deliver

运维场景最终会用到:

BASH
schedule + prompt + name + deliver + script + [SILENT]

4、定时任务实测

4.1 基础定时任务测试

4.1.1 基础状态检查

定时任务设置之前,首先要进行检查,查看定时任务状态:

BASH
hermes cron status 

✓ Gateway is running — cron jobs will fire automatically
  PID: 2014700

  No active jobs

检查gateway状态:

BASH
systemctl status hermes-gateway.service 
● hermes-gateway.service - Hermes Agent Gateway - Messaging Platform Integration
     Loaded: loaded (/etc/systemd/system/hermes-gateway.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2026-04-23 16:37:58 CST; 21h ago
   Main PID: 2014700 (python)
      Tasks: 9 (limit: 4644)
     Memory: 262.0M
        CPU: 2min 17.215s
     CGroup: /system.slice/hermes-gateway.service
             └─2014700 /data/hermes-agent/venv/bin/python -m hermes_cli.main gateway run --replace
4.2.2 hermes命令创建

既然是定时任务测试,我肯定不能写的那么麻烦了,我写一个简单的测试使用的内容吧:

BASH
hermes cron create "1m" "这是 Hermes Cron 微信测试任务。请只回复:Cron 微信测试成功。" \
  --name "wx-cron-basic-test" \
  --deliver weixin

这个定时任务是一分钟后,发送Cron 微信测试成功:

  • 1m = 1 分钟后执行 1 次,执行完任务就自动结束(一次性任务)

  • 列表里显示 Repeat: 0/1 就是铁证:总共只跑 1 次,已执行 0 次

设置完成后会显示:

BASH
Created job: d300852ea888
  Name: wx-cron-basic-test
  Schedule: once in 1m
  Next run: 2026-04-24T14:41:07.062039+08:00

检查定时任务状态:

BASH
 hermes cron list 

┌─────────────────────────────────────────────────────────────────────────┐
│                         Scheduled Jobs                                  │
└─────────────────────────────────────────────────────────────────────────┘

  d300852ea888 [active]
    Name:      wx-cron-basic-test
    Schedule:  once in 1m
    Repeat:    0/1
    Next run:  2026-04-24T14:41:07.062039+08:00
    Deliver:   weixin

image-20260424144957040

不要在意前后图片上为啥PID和job_id对不上,因为只有一分钟间隔,我还没截到图就被删除了...

等待一分钟后查看微信消息:

image-20260424144637989

执行完成后,再次查看定时任务状态,显示为空。

4.2.3 CLI 模式创建

若使用CLI创建:

BASH
/cron add "1m" "这是 Hermes Cron 微信测试任务。请只回复:Cron 微信测试成功,定时任务由CLI创建。" --name "wx-cron-basic-test" --deliver weixin

image-20260424151218889

image-20260424151402161

4.2.4 微信 / 飞书创建

举个栗子,如果在微信或者在飞书上,我还执行下面的命令:

BASH
/cron add "1m" "这是 Hermes Cron 微信测试任务。请只回复:Cron 微信测试成功,定时任务由微信创建。" --name "wx-cron-basic-test" --deliver weixin

个人感觉很 Der 哈,为啥不直接这样呢:

BASH
设置一个3分钟之后的任务,只发送“这是 Hermes Cron 飞书测试任务。请只回复:Cron 飞书测试成功,定时任务由飞书创建。”发到飞书上。

image-20260424153716094

查询一下是否真的生成了:

image-20260424153732598

等待几分钟:

image-20260424154134592

Tips:

(1)可能会出现的问题:

时间问题。

不想我们手动设置时间,我们是知道如何设置的,但是AI不是,如果我们做按照每天7点、每周一早7点,这种时间名词的时候,AI很有可能会使用UCT时间,即使你服务器上的时区是UTC+8,所以办法就是,告诉AI记住用户现在的时区,并写入USER.md,避免出现这种问题:

image-20260424154045316

当AI写入USER.md之后,问题就不再发生了。

BASH
root@ser558828169418:~/.hermes# cat memories/USER.md
用户时区:UTC+8 北京时间。创建定时任务必须用相对时间格式(如 `3m`、`every 2h`),不要用绝对 UTC 时间戳,否则显示会有时区混淆。

官方提示:

使用正确的调度表达式。 支持的格式包括:相对延迟(30m)、时间间隔(every 2h)、标准 Cron 表达式(0 9 * * *)以及 ISO 时间戳(2025-06-15T09:00:00)。像 daily at 9am 这样的自然语言并不支持,请改用标准表达式。

(2)如图

image-20260424161031901

4.2 内容变更监控器

这一小章节用到的脚本不是重点,原理才是重点。

至于为什么,往下看你就懂了。

4.2.1 实践原理

在我能找到的教学文档里,有一个网站变更监控器的类似教学,它的原理如下:


监控某个 URL 的变化,并仅在内容发生更改时收到通知。

script 参数是这里的关键。每次执行前都会先运行一段 Python 脚本,其标准输出会作为代理上下文传入。脚本负责机械性工作,例如抓取网页、对比差异;代理则负责做推理判断,例如“这个变化是否值得提醒”。

创建监控脚本:

BASH
mkdir -p ~/.hermes/scripts

编写脚本文件:~/.hermes/scripts/watch-site.py

PYTHON
import hashlib, json, os, urllib.request

URL = "https://example.com/pricing"
STATE_FILE = os.path.expanduser("~/.hermes/scripts/.watch-site-state.json")

# Fetch current content
req = urllib.request.Request(URL, headers={"User-Agent": "Hermes-Monitor/1.0"})
content = urllib.request.urlopen(req, timeout=30).read().decode()
current_hash = hashlib.sha256(content.encode()).hexdigest()

# Load previous state
prev_hash = None
if os.path.exists(STATE_FILE):
    with open(STATE_FILE) as f:
        prev_hash = json.load(f).get("hash")

# Save current state
with open(STATE_FILE, "w") as f:
    json.dump({"hash": current_hash, "url": URL}, f)

# Output for the agent
if prev_hash and prev_hash != current_hash:
    print(f"CHANGE DETECTED on {URL}")
    print(f"Previous hash: {prev_hash}")
    print(f"Current hash: {current_hash}")
    print(f"\nCurrent content (first 2000 chars):\n{content[:2000]}")
else:
    print("NO_CHANGE")

设置 Cron 任务:

BASH
/cron add "every 1h" "If the script output says CHANGE DETECTED, summarize what changed on the page and why it might matter. If it says NO_CHANGE, respond with just [SILENT]." --script ~/.hermes/scripts/watch-site.py --name "Pricing monitor" --deliver telegram

[SILENT] 技巧

当代理最终响应中包含 [SILENT] 时,系统会抑制消息发送。这意味着你只会在真正发生变化时收到通知,不会在平静时段被无意义的消息打扰。


我来讲讲原理:

Hermes Cron 负责定时触发;script 负责采集和对比事实;Agent 负责理解脚本结果并决定是否通知;[SILENT] 负责降噪。

每隔一段时间看一次网页,如果网页内容和上次不一样,就通知你;如果一样,就不打扰你。

整个请求链路如下:

BASH
Hermes Cron 到时间

先执行 --script 指定的 Python 脚本

脚本抓取网页内容

脚本计算当前内容 hash

脚本读取上一次保存的 hash

对比 hash 是否变化

把判断结果输出到 stdout

Hermes 把 stdout 作为上下文交给 Agent

Agent 根据 prompt 判断是否需要通知

如果输出 [SILENT],则不发送消息

如果有变化,则总结变化并投递到指定渠道

script 是这个案例里最关键的部分。原因是:网页抓取、hash 计算、状态保存、差异判断,这些都是 确定性工作,更适合脚本完成,而不是让大模型自己做。

脚本通过比较 hash,就能知道网页有没有变化。状态文件 ~/.hermes/scripts/.watch-site-state.json 的作用,就是保存上一次的 hash。没有这个文件,脚本就不知道“上一次网页是什么样”,也就没法对比。

第一次运行时,一般只是初始化:

BASH
没有上一次 hash,保存当前 hash,输出 NO_CHANGE

第二次开始,才真正进入对比逻辑:

BASH
读取上一次 hash,计算这一次 hash,两者比较

如果没变化,脚本输出:

BASH
NO_CHANGE

Agent 看到 NO_CHANGE,就按 prompt 要求回复:

BASH
[SILENT]

[SILENT] 的意思是:这次任务正常执行了,但不要发消息。这样就不会每小时都发一条“没变化”,避免刷屏。

如果有变化,脚本输出:

BASH
CHANGE DETECTED
Previous hash: xxx
Current hash: yyy
Current content...

Agent 看到 CHANGE DETECTED,就会总结网页可能发生了什么变化,然后通过 --deliver telegram 发出去。


OK,原理讲完了,那么对我来说,对于一个运维来说,它可以干什么具体有用的内容呢?

检查某个接口返回是否变化、检查某个服务状态是否异常、检查 Redis 慢查询是否新增、检查 Kafka broker 是否异常、检查证书是否快过期、检查日志里有没有新增错误。

甚至说,如果token足,我原本服务器上的巡检脚本可以全部pass了,直接用它就OK了,那就不是比较hash了,比较的是采集到的值是否超过了相应的指标,然后直接调用Skills查询解决办法之类的内容,输出解决方案。

为了有实际的效果,下面的内容是我自己做的一个小实验,在运维场景下的,当然,过程不是重点,理解原理才是重点对吧。

4.2.2 实践设计

我们模拟一个 Redis 的巡检脚本(为了学习制造的场景,现实直接Prometheus+夜莺写告警规则了,没必要这样脱裤子放屁),创建两个文件:

BASH
~/.hermes/scripts/ops-cron-lab.py        # 模拟运维检测脚本
~/.hermes/scripts/ops-cron-control.env   # 手动控制状态的文件

脚本每次运行时读取 ops-cron-control.env,我只需要修改控制文件,就能让下一次 Cron 输出不同结果。

创建目录:

BASH
mkdir -p ~/.hermes/scripts

创建控制文件:

BASH
cat > ~/.hermes/scripts/ops-cron-control.env <<'EOF'
MODE=normal
SERVICE=redis
HOST=prod-redis-01
CPU=35
MEMORY=48
CONNECTIONS=120
SLOWLOG=0
EOF

这个文件就是我们控制的开关,核心就是Mode是否发生了变化:

BASH
MODE=normal        # 正常,不通知
MODE=cpu_high      # 模拟 CPU 高,通知
MODE=redis_slow    # 模拟 Redis 慢查询,通知
MODE=service_down  # 模拟服务不可用,通知
MODE=recovered     # 模拟恢复,通知一次

创建运维巡检脚本:

BASH
cat > ~/.hermes/scripts/ops-cron-lab.py <<'EOF'
#!/usr/bin/env python3
import os
from datetime import datetime

CONTROL_FILE = os.path.expanduser("~/.hermes/scripts/ops-cron-control.env")

def load_env(path):
    data = {}
    if not os.path.exists(path):
        return data

    with open(path, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if not line or line.startswith("#") or "=" not in line:
                continue
            k, v = line.split("=", 1)
            data[k.strip()] = v.strip()
    return data

cfg = load_env(CONTROL_FILE)

mode = cfg.get("MODE", "normal")
service = cfg.get("SERVICE", "unknown")
host = cfg.get("HOST", "unknown")
cpu = cfg.get("CPU", "0")
memory = cfg.get("MEMORY", "0")
connections = cfg.get("CONNECTIONS", "0")
slowlog = cfg.get("SLOWLOG", "0")
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

print(f"check_time={now}")
print(f"mode={mode}")
print(f"service={service}")
print(f"host={host}")
print(f"cpu={cpu}")
print(f"memory={memory}")
print(f"connections={connections}")
print(f"slowlog={slowlog}")

if mode == "normal":
    print("STATUS=OK")
    print("MESSAGE=All monitored items are normal.")

elif mode == "cpu_high":
    print("STATUS=ALERT")
    print("ALERT_TYPE=CPU_HIGH")
    print("SEVERITY=P1")
    print("MESSAGE=Redis CPU usage is too high.")

elif mode == "redis_slow":
    print("STATUS=ALERT")
    print("ALERT_TYPE=REDIS_SLOWLOG")
    print("SEVERITY=P2")
    print("MESSAGE=Redis slowlog count increased.")

elif mode == "service_down":
    print("STATUS=ALERT")
    print("ALERT_TYPE=SERVICE_DOWN")
    print("SEVERITY=P0")
    print("MESSAGE=Service is unavailable.")

elif mode == "recovered":
    print("STATUS=RECOVERED")
    print("ALERT_TYPE=RECOVERY")
    print("SEVERITY=INFO")
    print("MESSAGE=Service has recovered.")

else:
    print("STATUS=UNKNOWN")
    print("SEVERITY=P3")
    print(f"MESSAGE=Unknown mode: {mode}")
EOF

chmod +x ~/.hermes/scripts/ops-cron-lab.py

我们执行一次脚本:

BASH
~/.hermes/scripts/ops-cron-lab.py

# 输出内容
check_time=2026-04-24 16:37:26
mode=normal
service=redis
host=prod-redis-01
cpu=35
memory=48
connections=120
slowlog=0
STATUS=OK
MESSAGE=All monitored items are normal.

这就是正常状态,后面我们手动改造.env即可完成状态改变。

4.3.3 实践测试

创建定时脚本:

BASH
 hermes cron create "every 1m" "你是运维告警分析助手。读取脚本输出并按规则处理:

1. 如果 STATUS=OK,只回复 [SILENT]
2. 如果 STATUS=ALERT,按下面格式输出:
[问题概述] 用一句话说明哪个服务出现什么问题
[严重程度] 使用脚本里的 SEVERITY
[影响判断] 说明可能对业务造成的影响
[排查方向] 给出 3 到 5 个排查方向

3. 如果 STATUS=RECOVERED,按下面格式输出:
[恢复通知] 说明哪个服务已经恢复
[影响判断] 当前风险降低
[后续建议] 建议继续观察相关指标

要求:
- 使用中文
- 不要编造脚本中不存在的主机和服务
- 输出要简洁
- 技术词保留英文,例如 Redis、CPU、slowlog、connections" \
  --script ops-cron-lab.py \
  --name "ops-cron-lab-weixin" \
  --deliver weixin
  
  
# 创建完成
Created job: 4763adfeab0b
  Name: ops-cron-lab-weixin
  Schedule: every 1m
  Script: ops-cron-lab.py
  Next run: 2026-04-24T16:42:30.243251+08:00

查看是否创建成功:

image-20260424164209198

Tips:

BASH
Script path must be relative to ~/.hermes/scripts/.
Got absolute or home-relative path: '/root/.hermes/scripts/ops-cron-lab.py'.
Place scripts in ~/.hermes/scripts/ and use just the filename.

Hermes Cron 的 --script 参数只接受相对于 ~/.hermes/scripts/ 的文件名。

Hermes Cron 的 --script 不能写绝对路径,也不能写 ~/.hermes/scripts/xxx.py,只能写脚本文件名。

等一段时间之后,我们进行测试,我手动把Redis的CPU使用率调高:

BASH
cat > ~/.hermes/scripts/ops-cron-control.env <<'EOF'
MODE=cpu_high
SERVICE=redis
HOST=prod-redis-01
CPU=97
MEMORY=55
CONNECTIONS=180
SLOWLOG=3
EOF

现在的文件与执行脚本后会输出内容:

BASH
root@ser558828169418:~/.hermes/scripts# cat ops-cron-control.env 
MODE=cpu_high
SERVICE=redis
HOST=prod-redis-01
CPU=97
MEMORY=55
CONNECTIONS=180
SLOWLOG=3
root@ser558828169418:~/.hermes/scripts# ~/.hermes/scripts/ops-cron-lab.py 
check_time=2026-04-24 16:47:42
mode=cpu_high
service=redis
host=prod-redis-01
cpu=97
memory=55
connections=180
slowlog=3
STATUS=ALERT
ALERT_TYPE=CPU_HIGH
SEVERITY=P1
MESSAGE=Redis CPU usage is too high.
root@ser558828169418:~/.hermes/scripts# 

等待触发定时任务与分析思考的时间后,微信收到了消息:

image-20260424164940139

这个时候我们再调整回去:

BASH
cat > ~/.hermes/scripts/ops-cron-control.env <<'EOF'
MODE=recovered
SERVICE=redis
HOST=prod-redis-01
CPU=35
MEMORY=48
CONNECTIONS=120
SLOWLOG=0
EOF

先输出MODErecovered,这样会给我们发送一条恢复状态的消息:

image-20260424165548572

接下来再次调整状态为:

BASH
cat > ~/.hermes/scripts/ops-cron-control.env <<'EOF'
MODE=normal
SERVICE=redis
HOST=prod-redis-01
CPU=35
MEMORY=48
CONNECTIONS=120
SLOWLOG=0
EOF

循环结束。

完整符合我们的预设内容:

BASH
MODE=normal        # 正常,不通知
MODE=cpu_high      # 模拟 CPU 高,通知
MODE=redis_slow    # 模拟 Redis 慢查询,通知
MODE=service_down  # 模拟服务不可用,通知
MODE=recovered     # 模拟恢复,通知一次

实践结束。

四、Hermes 对接 MCP

1、对接方式

我们由于是自建的mcp,采用http的方式进行对接:

BASH
mcp_servers:
  company_api:
    url: "https://mcp.internal.example.com"
    headers:
      Authorization: "Bearer ***"

该内容不再多赘述了。

其他博主:https://www.majiabin.com/hermes/user-guide/features/mcp

MCP就是AI精准沟通世界的桥梁,关键点不在MCP如何接入,而是MCP如何编写,下面是我的es和Prometheus的mcp,仅供参考:

ES MCP (Ops MCP) - 日志查询

工具 用途
efk_search_logs ESC 风格日志搜索
efk_error_patterns 错误模式聚合
efk_log_timeline 日志时间线分析
efk_service_error_summary 服务错误排名
efk_log_context 上下文日志查看
efk_keyword_distribution 关键字分布统计
efk_ingest_health 采集健康检查
efk_list_dimensions 维度列表(服务/主机/级别)
es_list_indices 索引发现(权限受限)
es_search 原生 ES 查询

Prometheus MCP - 监控指标

工具 用途
prom_profile 检测指标生态
prom_metric_search 指标名搜索
prom_instant_query 即时查询
prom_query_summary 范围查询(摘要)
prom_query_raw 范围查询(原始)
prom_estimate_query 查询规模估算
prom_alerts 告警列表
prom_label_values 标签值列表

2、Hermes 接入 MCP 实践

2.1 启动 MCP 服务器

这个启动方式就看我们自建的mcp是如何启动了,我的mcp是使用Go语言制成的二进制文件,直接在服务器启动了。

然后在我们Hermes的服务器上验证MCP服务是否可以使用:

BASH
curl -s http://127.0.0.1:19080/healthz

查看返回状态码是否为:

BASH
{"status":"ok"}

尝试列出相关工具:

BASH
curl -s http://127.0.0.1:19080/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "MCP-Protocol-Version: 2025-06-18" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/list",
    "params": {}
  }'

我对接的是一个ES查询日志的工具,所以会返回以下工具列表:

BASH
es_list_indices
es_search
efk_search_logs
efk_error_patterns
efk_log_timeline
efk_service_error_summary
efk_log_context
efk_list_dimensions
efk_keyword_distribution
efk_ingest_health

2.2 配置Hermes

编辑:

BASH
vim ~/.hermes/config.yaml

加入下面配置:

BASH
mcp_servers:
  es_logs:
    url: "http://127.0.0.1:19080/mcp"
    enabled: true
    timeout: 10
    connect_timeout: 5

如果你原来已经有 mcp_servers,不要重复写一级 key,直接合并进去。例如:

BASH
mcp_servers:
  es_logs:
    url: "http://127.0.0.1:19080/mcp"
    enabled: true
    timeout: 10
    connect_timeout: 5

  other_mcp:
    command: "xxx"
    args: ["xxx"]

没有认证信息就不用写 headers

如果后续你加了 token,再改成:

BASH
mcp_servers:
  es_logs:
    url: "http://127.0.0.1:19080/mcp"
    headers:
      Authorization: "Bearer xxxxxx"
    enabled: true
    timeout: 10
    connect_timeout: 5

2.3 检查配置

执行:

BASH
hermes config check

如果 Hermes 支持直接查看配置,也可以:

BASH
hermes config

或:

BASH
hermes config show

不同版本命令略有差异,核心是确认 mcp_servers.es_logs.url 已经进入配置。

2.4 重启 Hermes Gateway

如果你平时用 Hermes 自带命令重启:

BASH
hermes gateway restart

如果你是 systemd 管理:

BASH
systemctl restart hermes-gateway.service

然后看日志:

BASH
journalctl -u hermes-gateway.service -n 100 --no-pager

或者看 Hermes 自己日志目录:

BASH
ls ~/.hermes/logs/
tail -n 100 ~/.hermes/logs/gateway.log

重点看有没有类似:

BASH
MCP server es_logs connected
tools registered

2.5 验证MCP接入

我们选择最简单的验证方式,就是直接问:

image-20260425165144672

很明显,已经接入成功了,这个时候我们再和它说完配置xxx相关信息,让他存储在memory里,即可完成全部配置。

不建议在Hermes的Memory里写入相关配置信息,建议在MCP Server侧,写入信息进行传入。

五、持续更新......

评论