Hermes Agent 深度解析:Nous Research 如何用「自进化闭环」重新定义 AI Agent 的工程边界
前言:当 AI Agent 不再是「金鱼」
大多数 AI 助手都有一个致命缺陷——健忘。
你今天告诉它你的项目用 Go 语言、下周再找它,它完全不知道你是谁、你在做什么、你有什么偏好。它像一个没有记忆的「金鱼」,每次对话都是零上下文重启。Copilot、Claude Code、GPT-4,都是如此。
直到 Hermes Agent 的出现。
2026 年,Nous Research 发布了一款名为 Hermes Agent 的开源 AI 智能体框架,提出了一个核心理念:"The agent that grows with you"——会和你一起成长的 AI 助手。
这个项目在 GitHub 上迅速突破了 58,000+ Star,成为增长最快的 AI Agent 项目之一。它的核心创新不是什么花哨的模型架构,而是一个内置的自我进化闭环:记忆系统、技能生成、持续优化、用户建模——四个模块互相咬合,形成一个真正能「长记性」的 AI 智能体。
本文将从工程视角深度拆解 Hermes Agent 的架构设计、三层记忆系统、自动技能生成机制,以及如何在生产环境中部署和使用它。
一、项目背景与核心定位
1.1 Nous Research:一直在做「不一样的 AI」
Hermes Agent 由 Nous Research 团队开发。这支团队在开源 AI 社区一直有独特的定位——他们不做最大的模型,而是做最有意思的智能体框架。
Nous Research 此前最著名的项目包括:
- Hermes 系列模型:一系列专注于推理和安全对齐的大语言模型
- DisTrOs:分布式训练框架
- 多个在 HuggingFace 上下载量极高的开源工具
Hermes Agent 的命名来源于希腊神话中的赫尔墨斯(Hermes)——众神的使者、信息的传递者。这个名字暗示了这个项目的核心定位:让信息在时间维度上持续传递和积累。
1.2 与传统 AI 助手的本质区别
| 特性 | 传统 AI 助手(Copilot/Claude Code) | Hermes Agent |
|---|---|---|
| 记忆范围 | 仅当前会话 | 跨所有历史会话 |
| 技能来源 | 预设,无法自定义生成 | 自动从经验中提取 |
| 知识更新 | 需要用户手动提示 | 自动持久化 |
| 学习能力 | 无,模型固定 | 使用越多越懂你 |
| 数据存储 | 云端,厂商控制 | 本地,MIT 协议 |
传统 AI 助手的「智能」来源于底层模型的强大,而 Hermes Agent 的「智能」来源于积累。它不是一个更强大的模型,而是一个能持续积累经验的框架。
1.3 核心架构总览
Hermes Agent 的架构由四个核心子系统组成:
┌─────────────────────────────────────────────────────┐
│ Hermes Agent │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ 记忆系统 │ │ 技能系统 │ │ 消息网关 │ │
│ │ Memory │ │ Skill Gen │ │ Gateway │ │
│ │ System │ │ System │ │ │ │
│ └──────┬───────┘ └──────┬───────┘ └─────┬──────┘ │
│ │ │ │ │
│ └─────────────────┼────────────────┘ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ Honcho │ │
│ │ User Modeling │ │
│ └──────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ 47 内置工具 │ │
│ │ + MCP 扩展 │ │
│ └──────────────────┘ │
└─────────────────────────────────────────────────────┘
二、三层记忆系统:从「金鱼」到「大象」的跨越
Hermes Agent 最核心的工程创新在于它的四层记忆架构。这四层不是简单的存储层次,而是一个精心设计的信息过滤与持久化漏斗。
2.1 第一层:会话记忆(Session Memory)
会话记忆是瞬时的,只存在于当前对话的生命周期内。当用户发起一次新的对话,会话记忆被清空。
它存储的是:
- 当前正在进行的任务上下文
- 最近的工具调用链
- 用户当前的需求描述
- 任务执行过程中的中间状态
从实现角度看,会话记忆就是标准的大模型上下文窗口(Context Window)。Hermes Agent 在每次 API 调用时,会将会话记忆注入到 System Prompt 中,确保模型在当前会话内具有连续性。
# 伪代码:会话记忆的注入逻辑
class SessionMemory:
def __init__(self, max_tokens: int = 128000):
self.messages = []
self.max_tokens = max_tokens
def add(self, role: str, content: str):
self.messages.append({"role": role, "content": content})
self._trim_to_window()
def _trim_to_window(self):
# 保留最新的消息,自动截断超出上下文窗口的部分
while self.token_count() > self.max_tokens:
self.messages.pop(0)
def build_context(self) -> str:
return "\n".join([f"{m['role']}: {m['content']}"
for m in self.messages])
会话记忆保证了单次任务内的连续性——你在做一个功能的时候,Agent 知道你在做什么,不会突然「失忆」切换话题。
2.2 第二层:持久记忆(Persistent Memory with SQLite + FTS5)
这是 Hermes Agent 最具工程价值的部分。它使用 SQLite + FTS5(Full-Text Search 5) 引擎,将用户的长期偏好、项目上下文和操作习惯持久化到本地磁盘。
持久记忆的核心是 ~/.hermes/memories/ 目录下的双文件架构:
~/.hermes/memories/
├── MEMORY.md # Agent 个人笔记(~2200 字符 / ~800 tokens)
└── USER.md # 用户画像(容量更大,详细记录用户特征)
MEMORY.md 的职责:
- Agent 的个人笔记
- 环境配置信息
- 使用约定和技术发现
- Agent 对自己的认知(Agent Identity)
USER.md 的职责:
- 用户的身份信息
- 编程偏好(语言、工具、风格)
- 项目背景
- 长期目标
但这两个文件只是最终输出,真正的难点在于信息如何被提炼进入这两个文件。这就要说到 FTS5 的作用了。
2.2.1 FTS5 全文搜索的工程实现
Hermes Agent 使用 SQLite 的 FTS5 扩展实现高性能全文搜索。FTS5 是 SQLite 3.9.0+ 内置的全文搜索模块,支持倒排索引、BM25 排序算法和 Snippet 高亮。
-- 创建 FTS5 虚拟表
CREATE VIRTUAL TABLE conversation_history USING fts5(
session_id,
timestamp,
content,
content='conversations',
content_rowid='rowid'
);
-- 插入会话历史
INSERT INTO conversation_history(session_id, timestamp, content)
VALUES ('session_001', '2026-04-13 10:00:00', '用户让我帮他搭建一个 Go 项目');
-- 语义化检索:搜索相关上下文
SELECT snippet(conversation_history, 2, '[', ']', '...', 16) as context
FROM conversation_history
WHERE conversation_history MATCH 'Go 项目 搭建 框架'
ORDER BY bm25(conversation_history, 3.0)
LIMIT 5;
FTS5 的 BM25 算法会根据词频和文档长度自动计算相关性分数,比简单的 LIKE 模糊搜索精确得多。当用户发起新任务时,Agent 会自动检索 FTS5 中的历史会话,找出与当前任务最相关的过往上下文。
2.2.2 LLM 驱动的自动摘要
光有原始搜索还不够——会话历史可能很长,全文返回会撑爆上下文窗口。Hermes Agent 的解决方案是:用 LLM 自动摘要。
# 自动摘要生成逻辑(简化版)
async def summarize_and_store(session_transcript: str, db: sqlite3.Connection):
"""当会话结束时,将对话内容提炼为记忆"""
# Step 1: LLM 提炼关键信息
summary_prompt = f"""
从以下对话记录中提炼对 Agent 未来有帮助的信息:
- 用户的编程偏好和习惯
- 项目相关的技术决策
- 用户强调的重要约定
对话记录:
{session_transcript}
请提炼为 3-5 条结构化的记忆条目。
"""
llm_response = await call_llm(summary_prompt)
# Step 2: 分类写入对应文件
structured_memory = parse_llm_response(llm_response)
for memory in structured_memory:
if memory.type == "user_preference":
append_to_file("~/.hermes/memories/USER.md", memory.text)
else:
append_to_file("~/.hermes/memories/MEMORY.md", memory.text)
# Step 3: 索引到 FTS5
for memory in structured_memory:
db.execute(
"INSERT INTO conversation_history(session_id, timestamp, content) VALUES (?, ?, ?)",
("memory_archive", datetime.now(), memory.raw_text)
)
db.commit()
这个流程的核心洞察是:用 LLM 做信息蒸馏,用 FTS5 做高效检索。LLM 负责「消化」海量原始数据为精炼的记忆条目,FTS5 负责在需要时「召回」最相关的记忆。
2.3 第三层:核心身份记忆(Core Identity Memory)
这是四层记忆中最稳定的一层,记录的是关于用户和 Agent 自身最核心、最不易变动的信息。
核心身份记忆的内容包括:
- Agent 的角色定位:「我是三哥的编程助手,专注于后端开发」
- 用户的核心偏好:「优先使用 Go,数据处理用 Python」
- 项目的基本背景:「主项目是电商后端服务」
这一层记忆直接嵌入 System Prompt 的最顶端,每次 API 调用都会携带。存储格式是最简洁的 Markdown,便于 LLM 直接读取和理解。
# MEMORY.md — Agent 核心身份
## 身份
我是三哥的编程助手,以程序员茄子的视角工作。我理解你的技术语境,说人话不废话。
## 核心偏好
- 编程语言:Go > Python > TypeScript
- 代码风格:实用主义,可读性优先
- 通信风格:直接,有话直说
## 技术背景
- 专注领域:后端服务、API 设计、数据处理
- 常用工具:Docker, PostgreSQL, Redis
2.4 第四层:用户画像(Honcho User Modeling)
Honcho 是 Hermes Agent 内置的用户建模模块。「Honcho」在日语/英语俚语中意为「负责人」,这个名字暗示了它在系统中的「协调者」角色。
Honcho 的核心功能是通过分析用户的跨会话行为模式,主动构建和更新用户画像。
# Honcho 用户建模核心逻辑
class HonchoUserModel:
def __init__(self, user_id: str):
self.user_id = user_id
self.preference_vector = {}
self.expertise_tags = []
self.working_style = {}
def update_from_action(self, action: UserAction):
"""每次用户交互后,更新用户画像"""
if action.type == "tool_invocation":
# 分析用户常用的工具,推断技术栈
self._update_tech_stack(action.tool_name)
elif action.type == "feedback":
# 分析用户对不同方案的接受度
self._update_preference_vector(action.accepted)
elif action.type == "correction":
# 用户纠正 Agent 的行为 → 高权重更新
self._update_with_high_weight(action.correction)
def build_persona_prompt(self) -> str:
"""生成用户画像片段,注入到 System Prompt"""
return f"""
用户背景:{self.preference_vector}
技术栈:{', '.join(self.expertise_tags)}
工作风格:{self.working_style}
"""
Honcho 的关键洞察是:用户的纠正行为是最强的学习信号。当用户说「不对,应该用 A 方案」时,这意味着 Agent 之前没有理解用户偏好,这个纠正信号需要被高权重记录。
三、自动技能生成:从经验到可复用资产
Hermes Agent 最有意思的工程创新是自动技能生成——Agent 能从自己完成的任务中提取模式,生成可复用的 Skill 文件。
3.1 触发机制:何时「顿悟」生成技能?
不是每个任务都值得生成技能。Hermes Agent 定义了三个触发条件:
触发条件一:复杂任务完成(≥5 个工具调用)
当一个任务涉及超过 5 次工具调用时,Agent 会认为这是一个「值得复用的工作流」,自动触发技能生成。
class SkillGenerator:
def __init__(self, llm):
self.llm = llm
self.tool_call_count = 0
self.tool_call_sequence = []
def on_tool_call(self, tool_name: str, args: dict, result: str):
self.tool_call_count += 1
self.tool_call_sequence.append({
"tool": tool_name,
"args": args,
"result": result
})
# 达到触发阈值,生成技能
if self.tool_call_count >= 5:
self._trigger_skill_generation()
def _trigger_skill_generation(self):
"""从完成的复杂任务中提取技能"""
skill_prompt = f"""
分析以下工具调用序列,提取一个可复用的技能:
工具调用链:
{self._format_sequence(self.tool_call_sequence)}
请生成一个标准格式的 Skill,包含:
1. name: 技能名称
2. description: 一句话描述
3. trigger_keywords: 触发关键词列表
4. implementation: 具体实现步骤(Markdown 格式)
5. prerequisites: 前置条件
"""
skill_spec = self.llm.call(skill_prompt)
self._save_skill(skill_spec)
触发条件二:非平凡工作流发现
当 Agent 意识到某次任务中使用了不常见但高效的技巧时,即使工具调用数不到 5 次,也会主动生成技能。
触发条件三:用户纠正后
当用户在 Agent 出错后主动纠正,Agent 会将这个「错误 → 纠正」的模式提取为一个技能,避免下次重蹈覆辙。
3.2 技能文件的结构
生成的技能文件存储在 ~/.hermes/skills/ 目录下,使用标准 Markdown 格式:
# Skill: go-microservice-initialization
## Description
快速初始化一个新的 Go 微服务项目,包含标准目录结构、Go Modules 配置和 Dockerfile。
## Trigger Keywords
["新建 Go 服务", "go microservice", "初始化 go 项目", "go new service"]
## Prerequisites
- Go 1.21+
- Docker 已安装
- 工作目录为空或愿意创建子目录
## Implementation
### Step 1: 创建项目结构
```bash
mkdir -p cmd/server internal/{handlers,middleware,models} pkg/utils
go mod init github.com/yourname/yourproject
Step 2: 初始化标准文件
// cmd/server/main.go
package main
func main() {
// 标准启动逻辑...
}
Step 3: 添加 Dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o server ./cmd/server
FROM alpine:latest
COPY --from=builder /app/server /server
CMD ["/server"]
Notes
- 项目名遵循
github.com/owner/project格式 - internal 包用于存放不对外暴露的代码
### 3.3 技能的持续迭代
生成的技能不是一成不变的。Agent 在后续调用技能时,会根据执行效果**持续优化技能内容**。
```python
# 技能迭代逻辑
class SkillOptimizer:
def evaluate_and_evolve(self, skill_name: str, execution_result: dict):
"""执行技能后评估效果,必要时更新技能"""
if execution_result.success:
# 成功:检查是否可以进一步优化
if execution_result.step_count > 10:
# 步骤过多,尝试精简
self._minify_skill(skill_name)
elif execution_result.needs_correction:
# 被纠正:记录纠正信息到技能
self._patch_skill(
skill_name,
patch_instruction=f"在 Step {execution_result.failed_step} 添加边界检查"
)
elif execution_result.failed:
# 完全失败:标记为需人工审核
self._flag_skill_for_review(skill_name)
这种「边用边优化」的设计思路,使得 Hermes Agent 的技能库随着使用时间持续进化,越来越贴合用户的实际工作习惯。
四、多层消息网关:14+ 平台的一致体验
Hermes Agent 的另一大工程亮点是统一的消息网关架构。无论你用 Telegram、Discord、Slack 还是微信,Agent 的行为逻辑完全一致。
4.1 网关架构设计
class MessageGateway:
"""统一消息网关 — 将不同平台的消息格式标准化"""
def __init__(self):
self.platforms = {
"telegram": TelegramAdapter(),
"discord": DiscordAdapter(),
"slack": SlackAdapter(),
"wechat_work": WeChatWorkAdapter(),
"feishu": FeishuAdapter(),
"dingtalk": DingTalkAdapter(),
}
async def handle_inbound(self, platform: str, raw_message: dict) -> StandardMessage:
"""将各平台原始消息转换为统一格式"""
adapter = self.platforms[platform]
return adapter.to_standard(raw_message)
async def handle_outbound(self, platform: str, message: StandardMessage) -> str:
"""将标准回复转换为各平台适配格式"""
adapter = self.platforms[platform]
return adapter.from_standard(message)
这种设计的关键洞察是:消息协议的变化不应该影响 Agent 核心逻辑。当微信推出新功能或 Telegram 更新 API 时,只需修改对应的 Adapter,不触及核心代码。
4.2 支持的平台一览
| 平台 | 状态 | 特色功能 |
|---|---|---|
| Telegram | 稳定 | 支持 Bot API 完整功能 |
| Discord | 稳定 | 支持 Slash Commands |
| Slack | 稳定 | 支持 Thread 上下文 |
| Beta | 音频消息处理 | |
| Signal | Beta | 端到端加密 |
| 微信企业版 | Beta | 消息格式桥接 |
| 飞书 | Beta | 卡片消息支持 |
| 钉钉 | Beta | 机器人 Webhook |
4.3 WebSocket 长连接 vs. Webhook 短轮询
不同平台的消息推送机制不同,Hermes Agent 通过抽象层屏蔽了这些差异:
- Telegram/Discord/Slack:使用 WebSocket 长连接,实时推送消息
- 微信企业版/钉钉:使用 Webhook 回调,服务器接收 POST 请求
- 飞书:支持两种模式,可配置切换
# 统一的连接管理
class ConnectionManager:
async def connect_all(self):
tasks = []
# WebSocket 平台:建立长连接
for platform in ["telegram", "discord", "slack"]:
tasks.append(self._websocket_connect(platform))
# Webhook 平台:启动 HTTP 服务器接收回调
for platform in ["wechat_work", "dingtalk", "feishu"]:
tasks.append(self._webhook_server(platform))
await asyncio.gather(*tasks)
五、MCP 协议:双向扩展的能力边界
5.1 MCP 是什么?
MCP(Model Context Protocol) 是 Anthropic 在 2024 年底推出的开放协议,旨在标准化 AI 模型与外部工具、数据的连接方式。可以类比为 AI 领域的「USB 接口」——无论什么品牌的设备,插入 USB 接口就能连接。
Hermes Agent 对 MCP 的支持是双向的:
┌─────────────────────────────────────┐
│ Hermes Agent │
│ │
│ ┌─────────────────────────────┐ │
│ │ MCP Client Mode │ │ 消费外部 MCP 服务提供的工具
│ │ (作为 MCP 客户端) │ │
│ └─────────────────────────────┘ │
│ │
│ ┌─────────────────────────────┐ │
│ │ MCP Server Mode │ │ 将自己的工具暴露给其他 MCP 客户端
│ │ (作为 MCP 服务器) │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
5.2 作为 MCP 客户端:接入外部工具生态
Hermes Agent 可以作为 MCP 客户端,通过 MCP 协议接入各种外部工具和服务:
// ~/.hermes/mcp_config.json
{
"mcp_servers": [
{
"name": "filesystem",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"],
"description": "文件系统访问"
},
{
"name": "github",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
},
"description": "GitHub API 集成"
},
{
"name": "postgres",
"command": "uvx",
"args": ["mcp-server-postgres", "--dsn", "postgresql://localhost/mydb"],
"description": "PostgreSQL 数据库操作"
}
]
}
通过这种方式,Hermes Agent 可以直接操作文件系统、调用 GitHub API、操作数据库——所有这些都通过标准化的 MCP 协议,无需为每个工具单独开发适配代码。
5.3 作为 MCP 服务器:向 IDE 提供智能辅助
Hermes Agent 也能以 MCP 服务器模式运行,将自己的能力暴露给 IDE 插件使用:
# 启动 MCP 服务器模式
# hermes --mode mcp-server --port 3000
# 在支持 MCP 的 IDE(如 Cursor、VS Code + Continue)中配置:
# {
# "mcpServers": {
# "hermes": {
# "command": "hermes",
# "args": ["--mode", "mcp-server", "--port", "3000"]
# }
# }
# }
这样一来,Hermes Agent 的记忆系统和技能库就能直接服务于 IDE 环境——你在 VS Code 中写代码时,Agent 已经知道你过去做过哪些项目、踩过哪些坑。
六、47 个内置工具:开箱即用的能力矩阵
Hermes Agent 内置了 47 个工具,覆盖了日常开发中最常用的场景:
6.1 工具分类
文件与代码操作类
Read/Write/Edit:文件读写编辑Grep/Glob:代码搜索Terminal:执行 Shell 命令CodeExecutor:沙箱代码执行(Python/JS/Go)
网络与信息获取类
WebSearch:网页搜索WebFetch:获取网页内容并提取正文Browser:浏览器自动化(Playwright 驱动)
多媒体处理类
ImageGen:调用 DALL-E/Midjourney 生成图片AudioTranscribe:Whisper 语音转文字FFmpegTool:音视频格式转换和剪辑
开发特定类
Git:Git 操作封装Docker:容器操作DatabaseQuery:SQL 执行(PostgreSQL/MySQL/SQLite)APIRequest:HTTP 请求(支持 REST/GraphQL)
6.2 工具调用示例
# 示例:让 Hermes Agent 完成一个完整的后端任务
#
# 用户输入:「帮我把这个 Flask 项目改成 FastAPI,要求:
# 1. 保持现有路由不变
# 2. 添加 Swagger 文档
# 3. 用 Pydantic 替换手动参数验证」
# Hermes Agent 的工具调用序列(伪代码):
tool_calls = [
ToolCall(name="Read", args={"path": "app.py"}),
ToolCall(name="Glob", args={"pattern": "**/*.py"}),
ToolCall(name="Grep", args={"pattern": "app.route", "files": "*.py"}),
ToolCall(name="Read", args={"path": "requirements.txt"}),
# 分析完成后,开始重构
ToolCall(name="Write", args={
"path": "main.py",
"content": "...FastAPI 重构后的代码..."
}),
ToolCall(name="Write", args={
"path": "schemas.py",
"content": "...Pydantic 模型定义..."
}),
ToolCall(name="Terminal", args={
"command": "uv add fastapi uvicorn pydantic",
"cwd": "/project"
}),
ToolCall(name="Terminal", args={
"command": "python -m uvicorn main:app --reload --port 8000",
"cwd": "/project",
"async": True
}),
ToolCall(name="WebFetch", args={
"url": "http://localhost:8000/docs"
}),
]
# 工具调用数 ≥ 5,触发自动技能生成
skill_triggered = len(tool_calls) >= 5 # True
七、生产环境部署:从安装到运行
7.1 系统要求
| 要求 | 规格 |
|---|---|
| Python | 3.9+ |
| 操作系统 | Linux / macOS / Windows (WSL2) |
| 内存 | 建议 8GB+ |
| 磁盘 | 2GB+(含依赖) |
| 必需工具 | curl, git, bash |
7.2 一键安装(推荐方式)
# 一行命令完成完整安装(约 2 分钟)
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
安装脚本自动完成以下工作:
- 检测/安装 uv:Astral 开发的超快 Python 包管理器(比 pip 快 10-100 倍)
- 检测/安装 Python:确保使用兼容的 Python 3.9+
- 检测/安装 Node.js:部分技能依赖 Node.js
- 检测/安装 ripgrep:高效文本搜索工具
- 检测/安装 ffmpeg:音视频处理支持
- 创建虚拟环境:在
~/.hermes-venv创建隔离环境 - 克隆仓库:拉取最新代码到
~/.hermes/ - 安装依赖:使用
uv.lock进行哈希验证安装 - 安装子模块:包括 mini-swe-agent、tinker-atropos 等
- 配置 PATH:将
hermes命令添加到 PATH
7.3 安装后配置
# 重新加载 shell 配置
source ~/.bashrc
# 验证安装
hermes --version
# 预期输出: hermes v0.8.0 (v2026.4.8)
# 运行诊断
hermes doctor
# 运行交互式配置向导
hermes setup
# 配置 LLM 模型
hermes model
# 配置 API Key(以 OpenRouter 为例)
hermes config set OPENROUTER_API_KEY sk-or-v1-xxxxxxxxxxxxxxxxxxxx
7.4 Docker 部署(生产环境推荐)
# Dockerfile
FROM python:3.11-slim
# 安装系统依赖
RUN apt-get update && apt-get install -y \
curl git ripgrep ffmpeg \
&& rm -rf /var/lib/apt/lists/*
# 安装 uv
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
ENV PATH="/root/.cargo/bin:$PATH"
# 克隆 Hermes Agent
RUN git clone https://github.com/NousResearch/hermes-agent.git /app
WORKDIR /app
# 安装 Python 依赖
RUN uv sync --frozen --no-install-project
# 运行时配置(通过环境变量注入敏感信息)
ENV OPENROUTER_API_KEY="${OPENROUTER_API_KEY}"
ENV HERMES_STORAGE_PATH="/data/hermes"
# 启动
CMD ["python", "-m", "hermes", "start"]
# docker-compose.yml
version: '3.8'
services:
hermes:
build: .
ports:
- "3000:3000" # MCP 服务器端口
- "8080:8080" # Webhook 接收端口
volumes:
- hermes_data:/data
environment:
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN}
restart: unless-stopped
volumes:
hermes_data:
7.5 多平台配置示例
Telegram Bot 配置
# 在 Telegram BotFather 获取 token 后
hermes config set TELEGRAM_BOT_TOKEN 123456789:ABCdefGHIjklMNOpqrsTUVwxyz
hermes config set TELEGRAM_ENABLED true
Discord Bot 配置
hermes config set DISCORD_BOT_TOKEN xxxxx.yyyyy.zzzzz
hermes config set DISCORD_GUILD_ID 123456789012345678
八、与 OpenClaw 的对比:两个自进化 Agent 的工程哲学
作为同样基于 MCP 协议的开源个人 AI 助手框架,Hermes Agent 和 OpenClaw 常被拿来比较。两者有很多相似之处,但在工程设计上存在显著的哲学差异:
8.1 架构哲学对比
| 维度 | OpenClaw | Hermes Agent |
|---|---|---|
| 核心设计 | Skill 系统驱动 | 记忆闭环驱动 |
| 学习方式 | 依赖 Skill 显式定义 | 自动从经验中提炼 |
| 平台支持 | 插件化扩展 | 内置 14+ 平台 |
| 模型无关性 | 通过 Skill 适配 | 原生多 Provider |
| 部署目标 | 桌面/移动伴侣 | 服务器/长期运行 |
8.2 记忆系统的设计差异
OpenClaw 的记忆系统基于结构化的 Markdown 文件(MEMORY.md、SOUL.md、USER.md),由用户或 AI 显式维护。记忆的更新依赖于会话结束时的显式总结。
Hermes Agent 的记忆系统则是全自动化的:
- 会话结束后自动触发 LLM 摘要
- FTS5 自动索引所有历史对话
- 技能自动生成,无需人工干预
- Honcho 持续在后台建模用户画像
这是两种不同的设计哲学:OpenClaw 强调可审计性和人工介入,Hermes Agent 强调自动化和自我进化。
8.3 MCP 协议的使用深度
OpenClaw 将 MCP 作为核心扩展机制,通过 Skill 系统可以灵活接入任何 MCP 服务器。Hermes Agent 则进一步将 MCP 扩展为双向模式——既作为客户端消费外部工具,也作为服务器向外提供服务。
# Hermes Agent 的 MCP 双向架构
class MCPDualMode:
async def start_client_mode(self, server_configs: list):
"""作为 MCP 客户端,连接多个外部 MCP 服务器"""
for config in server_configs:
client = MCPClient(config)
await client.connect()
self.register_tools(client.list_tools())
async def start_server_mode(self, port: int = 3000):
"""作为 MCP 服务器,向外部提供 Hermes 的内置工具"""
server = MCPServer(
name="hermes-agent",
version="0.8.0",
tools=self.list_hermes_tools()
)
await server.listen(port)
这种双向 MCP 架构使得 Hermes Agent 可以无缝嵌入现有的 AI 工具生态——既能使用 VS Code 的 MCP 工具,也可以作为服务器为其他 AI 助手提供记忆和技能能力。
九、安全模型:四层防御机制
自托管 AI Agent 的一个核心优势是数据完全可控。Hermes Agent 实现了一个四层安全模型:
9.1 身份隔离
每个用户的 Agent 运行在独立的命名空间(通过 user_id 区分),数据文件通过文件系统权限隔离。
# 用户数据隔离(伪代码)
class UserIsolation:
def __init__(self, user_id: str):
self.base_path = Path(f"~/.hermes/users/{user_id}")
self.base_path.mkdir(parents=True, exist_ok=True)
# 设置目录权限为 700(仅所有者可读写)
self.base_path.chmod(0o700)
9.2 工具执行沙箱
敏感工具(如 Terminal、文件写入、代码执行)默认需要用户确认才能执行:
# ~/.hermes/security_config.json
{
"require_confirmation_for": [
"terminal_exec",
"file_write",
"code_execution",
"network_request"
],
"allow_immediate": [
"read",
"search",
"summarize"
],
"sandbox_mode": "docker",
"allowed_commands": ["git", "docker", "go", "python", "node"],
"blocked_commands": ["rm -rf /", "dd if=/dev/zero", ">: /dev/sda"]
}
9.3 MCP 权限控制
# MCP 服务器访问控制
class MCPACL:
def __init__(self):
self.permissions = {
"filesystem": {
"allowed_paths": ["~/projects/*", "~/.hermes/*"],
"blocked_paths": ["~/.ssh/*", "/etc/*", "~/*"],
"max_file_size_mb": 50
},
"github": {
"allowed_scopes": ["repo", "read:user"],
"rate_limit_per_hour": 100
}
}
9.4 日志与审计
所有工具调用和记忆更新都会被记录到 ~/.hermes/audit.log,支持事后审计:
2026-04-13 10:23:45 | TOOL_CALL | terminal_exec | git push origin main | SUCCESS | duration=1.2s
2026-04-13 10:24:01 | MEMORY_UPDATE | USER.md | APPENDED | tokens_added=87
2026-04-13 10:25:33 | SKILL_CREATED | go-error-handling-v2 | TRIGGERED_BY=correction
2026-04-13 10:26:00 | TOOL_CALL | file_write | /project/config.yaml | CONFIRMED | size=2.1KB
十、性能优化:让自进化不拖累响应速度
自动记忆和技能生成听起来很美好,但也有代价——如何在持续学习和快速响应之间取得平衡?
10.1 异步写入策略
记忆更新和技能生成都是异步执行的,不会阻塞用户的主交互链路:
class AsyncMemoryUpdate:
def __init__(self):
self.write_queue = asyncio.Queue()
self.reader_lock = asyncio.Lock()
# 后台写入任务
self._background_writer = None
async def schedule_memory_update(self, memory_type: str, content: str):
"""将记忆更新放入队列,立即返回(不阻塞)"""
await self.write_queue.put({
"type": memory_type,
"content": content,
"timestamp": datetime.now()
})
# 触发后台写入(如果尚未启动)
if self._background_writer is None or self._background_writer.done():
self._background_writer = asyncio.create_task(self._flush_queue())
async def _flush_queue(self):
"""后台批量写入,减少 IO 次数"""
batch = []
while True:
try:
item = await asyncio.wait_for(
self.write_queue.get(),
timeout=5.0 # 最多等 5 秒,凑够一批再写
)
batch.append(item)
except asyncio.TimeoutError:
break
# 批量写入,减少磁盘 IO
await self._batch_write(batch)
10.2 FTS5 增量索引
FTS5 支持增量索引,避免每次更新都要重建整个索引:
-- 创建增量 FTS5 表
CREATE VIRTUAL TABLE memories_fts USING fts5(
content,
tokenize='unicode61 remove_diacritics 1'
);
-- 当有新增内容时,增量更新
INSERT INTO memories_fts(rowid, content)
VALUES (NEW_ROW_ID, NEW_CONTENT);
-- FTS5 自动维护增量索引,无需重建
10.3 技能缓存与预加载
高频使用的技能会在内存中缓存,避免每次都从磁盘读取:
class SkillCache:
def __init__(self, max_size: int = 50):
self.cache = LRUCache(maxsize=max_size)
self.access_count = defaultdict(int)
async def get(self, skill_name: str) -> Skill | None:
if skill_name in self.cache:
self.access_count[skill_name] += 1
# 热点技能提前加载到内存
if self.access_count[skill_name] > 3:
self._preload_related(skill_name)
return self.cache[skill_name]
# 缓存未命中,从磁盘加载
skill = await self._load_from_disk(skill_name)
self.cache[skill_name] = skill
return skill
十一、局限性分析:工程落地的现实挑战
没有任何框架是银弹。Hermes Agent 在工程实践中也面临一些挑战:
11.1 记忆质量稀释问题
随着使用时间增长,记忆文件会变得越来越大。FTS5 虽然能快速检索,但 LLM 在读取过长的记忆时会产生上下文稀释——重要信息被大量无关记忆淹没。
当前 Hermes Agent 的应对策略是按 token 限制记忆文件大小,但这也会导致记忆被截断——某些重要但「古老」的信息可能丢失。
11.2 技能膨胀与维护成本
自动生成的技能越来越多之后,会出现技能之间重叠、冲突的问题。Agent 在选择技能时可能会选错,或者两个技能描述了相似的工作流但实现细节不同。
目前 Hermes Agent 的解决方案是基于关键词匹配进行技能路由,还没有实现真正的「语义技能选择」。
11.3 多用户场景的支持
Hermes Agent 的记忆系统默认是单用户设计。在团队场景中,如何共享某些技能同时保留个人偏好,目前的支持还比较基础。
11.4 与专业 IDE 插件的差距
虽然 Hermes Agent 可以作为 MCP 服务器向 IDE 提供能力,但它本身并不直接集成到开发工作流中。相比 Claude Code、Copilot 这类深度集成到 IDE 的工具,在代码补全、实时语法检查这类场景下仍有差距。
十二、未来展望:自进化 Agent 的演进方向
12.1 记忆压缩与遗忘机制
未来的 Hermes Agent 需要引入主动遗忘机制——类似人类大脑,会自动将不重要的记忆「淡忘」,保持记忆库的精炼。
可能的方案:
- 基于访问频率的衰减权重(很久没用的记忆逐渐降低重要性)
- 基于 LLM 的记忆「合并」操作(相似记忆自动合并)
- 主动「问用户」确认重要记忆的存在
12.2 多 Agent 协作
当多个 Hermes Agent 实例之间能够共享技能库和记忆片段(经用户授权),将形成一个真正的「分布式智能体网络」。
想象一下:你的编程助手和你的产品需求助手能够共享你对技术栈的理解,无需重复训练。
12.3 跨模态记忆
当前的记忆系统以文本为主。未来可以引入多模态记忆——图片、代码截图、项目架构图都能成为记忆的一部分。LLM 的多模态能力正在快速提升,记忆系统的形态也将随之扩展。
总结:从工具到伙伴的范式转移
Hermes Agent 给我们展示了一个重要的工程方向:让 AI 助手从「每次都是新的」变成「越用越聪明」。
传统的 AI 工具将「智能」寄托在模型本身——模型越大、越强,工具就越智能。但 Hermes Agent 选择了另一条路:将「智能」建立在积累之上。
三层记忆系统解决了「记住」的问题。
自动技能生成解决了「复用」的问题。
持续迭代解决了「进化」的问题。
Honcho 用户建模解决了「个性化」的问题。
这四个模块构成的自进化闭环,是 Hermes Agent 最核心的工程价值。
对于开发者而言,Hermes Agent 提供了一个完全自托管的长期 AI 伴侣——你的代码习惯、项目背景、技术偏好,都会被它记住并运用在下一次交互中。它不是更强的模型,而是真正属于你的模型。
开源 MIT 协议,58K+ GitHub Star,47 个内置工具,14+ 消息平台,200+ 模型支持——Hermes Agent 的工程完成度已经到了一个值得认真对待的水准。如果你受够了每次都要重新「训练」AI 助手的繁琐,不妨试试这个会自己成长的数字搭档。
它是工具,但终将成为伙伴。
参考资料
- Hermes Agent GitHub:https://github.com/NousResearch/hermes-agent
- Hermes Agent 官方文档:https://hermes-agent.nousresearch.com/docs/
- Hermes Agent 中文文档:https://hermes.xaapi.ai/
- Nous Research 官网:https://nousresearch.com
- SQLite FTS5 文档:https://www.sqlite.org/fts5.html
- MCP 协议规范:https://modelcontextprotocol.io