Hermes Agent 深度拆解:自进化 AI Agent 架构全解析——从闭环学习到持久记忆的工程真相
前言:为什么 Hermes Agent 值得你花时间理解
2026 年 2 月 25 日,AI 研究实验室 Nous Research 在 GitHub 上发布了一个名为 Hermes Agent 的开源项目。没有发布会,没有新闻通稿,上线六周后 Star 数从零飙升至 4.7 万,单日新增超过 6400 颗——这个速度仅次于 OpenClaw,被中文开发者社区戏称为"爱马仕"。
但 Star 数从来不能说明一切。真正让我花时间研究这个项目的,是它的核心定位:self-improving AI agent——一个真正能"越用越聪明"的 AI Agent,而不是一个简单的前端套壳或聊天机器人。
在翻完它的源码库、issue 区、贡献者文档和官方 Discord 之后,我的判断是:这个项目在架构层面有真正值得工程人员学习的东西。尤其是它把"闭环学习"(Closed Learning Loop)做成了原生能力,而不是事后打补丁——这一点对所有做 AI Agent 开发的工程师都有参考价值。
本文将从一个工程师的视角,完整拆解 Hermes Agent 的架构设计、核心机制、自进化学习循环的实现细节,并提供部署实战和代码示例。
一、背景与问题:为什么现有 Agent 框架都在"吃老本"
在聊 Hermes Agent 之前,我们需要先理解它试图解决的根本问题。
传统 Agent 框架的通病:几乎所有主流 Agent 框架——无论是 LangChain Agents、AutoGPT 还是各种"RAG + Tool Calling"方案——都有一个共同缺陷:它们是静态的。
你配置好工具链、设定好 Prompt,Agent 就能工作。但当它遇到一个新的任务类型,完成之后,这个经验就消失了。下次遇到类似的场景,它还得从头推理,不会自动把"上次是怎么做的"沉淀下来。
这就好像一个员工,每天完成工作但从不复盘、不做笔记、不积累 SOP——永远在重复发明轮子。
三条技术路线在试图解决这个问题:
- Prompt Engineering 路线:不断优化 Prompt,让模型"记住"更多模式。治标不治本。
- 知识库 RAG 路线:把文档塞进去,希望模型检索到。但它解决的是"知识查询"问题,不是"能力增长"问题。
- Hermes 的路线:让 Agent 自主把执行经验封装成可执行技能(Skill),并在后续任务中复用和优化。
第三条路线的核心工程挑战是:如何在没有人工干预的情况下,让 AI Agent 可靠地把"成功经验"变成"可复用代码/Skill",而不是变成一堆无效的 Prompt 修改?
这就是 Hermes Agent 要回答的问题。
二、核心架构:五大模块如何协同工作
Hermes Agent 的技术架构由五个核心模块组成,这五个模块不是简单拼凑,而是经过深思熟虑的协同设计:
┌─────────────────────────────────────────────────────────────────┐
│ Hermes Agent Architecture │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Self-Evolving│ │ Hierarchical│ │ Multi-Platform│ │
│ │ Learning Loop │◄──►│ Memory System │◄──►│ Gateway │ │
│ │ │ │ │ │ │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ └───────────────────┼────────────────────┘ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ Universal Model Layer │ │
│ │ (OpenAI/Claude/Gemini/ │ │
│ │ Ollama/本地模型) │ │
│ └──────────────────────────┘ │
│ ▼ │
│ ┌──────────────────────────┐ │
│ │ Security Guardrails │ │
│ │ (命令执行控制/内容过滤) │ │
│ └──────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
2.1 自进化学习循环(Self-Evolving Learning Loop)
这是 Hermes 区别于所有其他 Agent 框架的核心模块,也是工程实现上最有难度的部分。
一个完整的学习闭环包含五个环节:
任务执行 → 评估触发 → 技能抽象 → 技能优化 → 持久化存储
↑ │
└────────────── FTS5 召回 ←────────────────────┘
第一阶段:任务执行
Agent 接收用户任务,自主规划并执行。执行过程中会调用工具(终端、文件系统、浏览器、API 等),并记录完整的执行轨迹(trajectory)。
第二阶段:评估触发
每完成 15 次工具调用,或者一个复杂任务结束,系统自动触发自评估。这里的关键是不需要人工介入——评估逻辑由 LLM 本身完成,但有结构化的评估框架引导:
评估维度:
- 任务完成度:目标是否达成?
- 效率评分:步骤是否冗余?
- 错误恢复:从失败中恢复的能力如何?
- 可复用性:这次执行模式以后还能用吗?
第三阶段:技能抽象(Skill Creation)
如果评估认为这次执行模式值得复用,Agent 会自动将工作流封装为 Markdown 格式的 Skill 文件:
# Skill: 自动化 GitHub Issue 创建与标签分类
## 触发条件
当用户提供以下任意一种表达时触发:
- "帮我创建一个 issue"
- "提交一个 bug"
- "新建 issue"
## 执行步骤
1. 使用 `gh issue create` 创建 issue
2. 调用 GitHub API 获取当前仓库标签列表
3. 根据 issue 内容关键词(bug/feature/docs/test)自动匹配标签
4. 使用 `gh issue edit` 更新标签
## 参数
- repo: 仓库名(格式:owner/repo)
- title: issue 标题
- body: issue 正文(支持 Markdown)
- type: 类型推断(自动从内容中提取)
## 依赖工具
- gh CLI
- GitHub API
## 版本历史
- v1.0: 初始版本,基于 2026-06-15 的执行经验生成
- v1.1: 增加自动标签分类,2026-07-02 优化
这就是 Hermes 的关键设计:Skill 是 Markdown 文件,不是代码文件。这意味着任何人都可以阅读、编辑和复用,不需要编程知识。Skill 的可访问性被最大化了。
第四阶段:技能优化(Skill Self-Improvement)
当已有 Skill 在执行过程中失败,Agent 会自动分析失败原因,并对 Skill 进行优化:
失败分析流程:
1. 捕获错误类型和上下文
2. 判断是 Skill 本身的问题还是环境变化
3. 如果是 Skill 问题 → 生成优化方案
4. 验证优化方案(用 test case)
5. 更新 Skill 文件
第五阶段:持久化存储
所有 Skill 文件存储在 ~/.hermes/skills/ 目录下,以 Markdown 格式保存,文件名即 Skill 名称:
~/.hermes/skills/
├── github-issue-creator.md
├── docker-log-analyzer.md
├── api-response-cache.md
├── cron-job-manager.md
└── ...
2.2 分层持久记忆系统(Hierarchical Memory System)
Hermes 的记忆系统借鉴了认知科学的三种记忆类型,设计了一套分层架构:
| 记忆类型 | 存储内容 | 持久化方式 | 召回方式 |
|---|---|---|---|
| 情景记忆(Episodic) | 会话历史、对话轨迹 | SQLite(JSON 序列化) | 时间范围检索 |
| 语义记忆(Semantic) | MEMORY.md 文件 | 文件系统 | 全文关键词检索 |
| 程序性记忆(Procedural) | Skill 文件(技能流程) | Markdown 文件 | FTS5 索引召回 |
语义记忆的工程实现:
MEMORY.md 是用户和 Agent 共建的知识文件。当 Agent 判断某个事实"值得长期记住"时,会追加到这个文件:
# MEMORY.md - 用户知识库
## 用户偏好
- 编程语言:Go > Python > TypeScript
- 数据库偏好:PostgreSQL(上线项目),SQLite(轻量工具)
- 不喜欢:过度封装,复杂的依赖链
## 技术栈
- 主要开发:macOS + VSCode + iTerm2
- 部署环境:阿里云 ECS + Docker
- CI/CD:GitHub Actions
## 项目上下文
- 当前项目:内部监控告警系统
- 技术选型:Go + Prometheus + Grafana
- 主要痛点:告警风暴,需要去重聚合逻辑
## 最后更新时间
2026-07-15 14:23:07
FTS5 全文索引:Hermes 使用 SQLite 的 FTS5(Full-Text Search 5)扩展对对话历史建立全文索引。这是一个工程上非常聪明的选择:
- 零外部依赖:SQLite 是 Python 内置库,不需要额外安装 Elasticsearch 或 Meilisearch
- 高性能:FTS5 专为全文检索优化,支持 BM25 排序算法
- 本地化:所有数据存在本地,不上云,满足隐私需求
- 持久化:数据库文件存放在
~/.hermes/memory.db,重启不丢失
# FTS5 索引的工程价值——代码示例
# Hermes 使用 FTS5 实现跨会话记忆召回的内部逻辑
import sqlite3
import json
import os
def search_memory(query: str, top_k: int = 5):
"""
基于 FTS5 的对话历史召回
使用 BM25 算法排序,相关性最高的对话优先返回
"""
conn = sqlite3.connect(os.path.expanduser("~/.hermes/memory.db"))
cursor = conn.cursor()
# FTS5 MATCH 查询,支持 AND/OR/NOT 逻辑
sql = """
SELECT session_id, timestamp,
snippet(history_content, 1, '**', '**', '...', 32) as snippet,
bm25(memory_fts) as rank
FROM memory_fts
WHERE memory_fts MATCH ?
ORDER BY rank
LIMIT ?
"""
# query 会自动进行词干提取(stemming)
cursor.execute(sql, (query, top_k))
results = cursor.fetchall()
conn.close()
return [
{"session_id": r[0], "timestamp": r[1], "snippet": r[2], "rank": r[3]}
for r in results
]
# 使用示例:召回所有涉及"Docker 容器"的历史对话
results = search_memory("Docker 容器 排查 内存")
for r in results:
print(f"[{r['session_id']}] {r['snippet']}")
2.3 全模型兼容层(Universal Model Layer)
Hermes Agent 不绑定任何一家模型厂商,这是它区别于 OpenAI Agent SDK 或 Claude Agent 的关键策略。
# hermes 配置文件 ~/.hermes/config.yaml 示例
model_providers:
# OpenAI 系列(GPT-4o、GPT-5 等)
openai:
api_base: "https://api.openai.com/v1"
default_model: "gpt-4o"
# Anthropic 系列(Claude 4 系列)
anthropic:
api_base: "https://api.anthropic.com"
default_model: "claude-sonnet-4-20250514"
# Google Gemini
google:
api_base: "https://generativelanguage.googleapis.com/v1"
default_model: "gemini-2.5-pro"
# 本地 Ollama(完全离线)
ollama:
api_base: "http://localhost:11434/v1"
default_model: "qwen2.5:14b"
# OpenRouter(聚合 200+ 模型)
openrouter:
api_base: "https://openrouter.ai/v1"
default_model: "anthropic/claude-sonnet-4"
# 国内模型(阿里千问、智谱 GLM、月之暗面 Kimi)
chinese:
qwen:
api_base: "https://dashscope.aliyuncs.com/compatible-mode/v1"
default_model: "qwen3-8B"
zhipu:
api_base: "https://open.bigmodel.cn/api/paas/v4"
default_model: "glm-4-flash"
# 模型路由策略
routing:
default: "openrouter/claude-sonnet-4"
coding: "openrouter/claude-sonnet-4"
research: "openrouter/openai/o3-mini-high"
local_fallback: "ollama/qwen2.5:14b" # 网络故障时自动切换到本地模型
这个设计的工程价值在于:当某个模型 API 出现故障或限流时,Hermes 可以自动切换到备用模型,整个执行过程不会中断。
2.4 多平台消息网关(Multi-Platform Gateway)
Hermes 统一了 15+ 消息平台的接入,通过一个 gateway 进程管理所有平台的连接:
支持的平台:
├── 即时通讯:Telegram、Discord、Slack、WhatsApp、Signal、Matrix
├── 邮件:Email(IMAP/SMTP)
├── 国产平台:微信(企业版)、飞书、钉钉
├── 物联网:Home Assistant
└── 开发工具:CLI(本地终端)、SSH(远程服务器)
网关架构设计(Python asyncio 实现):
# gateway 架构简化版
import asyncio
from abc import ABC, abstractmethod
class PlatformAdapter(ABC):
"""各平台的统一适配器接口"""
@abstractmethod
async def connect(self):
pass
@abstractmethod
async def send_message(self, message: str, target: str):
pass
@abstractmethod
async def receive_message(self) -> tuple[str, str]:
"""返回 (sender_id, message_content)"""
pass
class HermesGateway:
"""
统一网关:管理所有平台连接,运行单一进程
消息统一格式:{"platform": "telegram", "from": "user123", "content": "..."}
"""
def __init__(self):
self.platforms: dict[str, PlatformAdapter] = {}
self.message_queue: asyncio.Queue = asyncio.Queue()
async def register(self, platform_name: str, adapter: PlatformAdapter):
"""注册新的平台适配器"""
await adapter.connect()
self.platforms[platform_name] = adapter
# 启动该平台的接收循环
asyncio.create_task(self._receive_loop(platform_name, adapter))
async def _receive_loop(self, platform: str, adapter: PlatformAdapter):
"""每个平台独立接收循环,互不阻塞"""
while True:
try:
sender, content = await adapter.receive_message()
await self.message_queue.put({
"platform": platform,
"sender": sender,
"content": content,
"timestamp": asyncio.get_event_loop().time()
})
except Exception as e:
# 单平台故障不影响其他平台
await asyncio.sleep(5) # 5秒后重试
async def broadcast(self, message: str, target_platforms: list[str] = None):
"""向指定平台(或全部平台)广播消息"""
targets = target_platforms or list(self.platforms.keys())
await asyncio.gather(
*[self.platforms[p].send_message(message, "broadcast")
for p in targets if p in self.platforms]
)
这个架构的设计亮点是事件驱动:所有平台的消息进入统一队列后,由 Hermes Agent 的核心推理引擎处理,响应逻辑与平台无关。
2.5 安全护栏体系(Security Guardrails)
由于 Hermes Agent 能够执行终端命令,安全设计至关重要。Hermes 采用多层安全机制:
# ~/.hermes/security.yaml
security:
# 命令执行白名单(明确允许的命令)
allowed_commands:
- git
- docker
- npm
- pip
- curl
- kubectl
- gh
- cat
- ls
- grep
- find
- tar
- zip
# 危险命令黑名单(绝对禁止)
blocked_commands:
- rm -rf / # 递归删除根目录
- :(){ :|:& };: # Fork 炸弹
- dd if=/dev/zero
- mkfs
- shutdown
- reboot
- chmod -R 000
# 文件系统访问限制(沙盒目录)
filesystem:
sandbox_root: "~/.hermes/sandbox"
allow_beyond_sandbox: false # 是否允许访问沙盒外文件
dangerous_extensions:
- .exe
- .dmg
- .bat
- .ps1
# 网络访问限制
network:
allowed_domains:
- "*.github.com"
- "api.openai.com"
- "api.anthropic.com"
blocked_ports:
- 22 # SSH(防止远程隧道)
- 3306 # MySQL
- 5432 # PostgreSQL
- 6379 # Redis(防止未授权访问)
max_request_size_mb: 10
三、自进化循环的工程实现:代码级拆解
光有架构描述不够,我们来看一个真实的自进化循环执行流程,用代码说明它到底是怎么工作的。
3.1 任务执行与轨迹记录
# hermes-agent/core/loop.py(概念代码,基于官方架构文档重构)
from dataclasses import dataclass, field
from typing import Callable
import json
from datetime import datetime
@dataclass
class ToolCall:
"""单次工具调用记录"""
tool_name: str
arguments: dict
result: str
duration_ms: float
success: bool
timestamp: datetime = field(default_factory=datetime.now)
@dataclass
class ExecutionTrace:
"""完整执行轨迹"""
task_id: str
user_prompt: str
tool_calls: list[ToolCall] = field(default_factory=list)
final_output: str = ""
evaluation_score: float = 0.0
skills_created: list[str] = field(default_factory=list)
@property
def total_calls(self) -> int:
return len(self.tool_calls)
@property
def success_rate(self) -> float:
if not self.tool_calls:
return 0.0
return sum(1 for tc in self.tool_calls if tc.success) / len(self.tool_calls)
def add_tool_call(self, tool_name: str, args: dict,
result: str, duration: float, success: bool):
self.tool_calls.append(ToolCall(
tool_name=tool_name,
arguments=args,
result=result,
duration_ms=duration,
success=success
))
class SelfEvolvingLoop:
"""
自进化学习循环核心逻辑
触发条件:每 15 次工具调用 或 任务完成
"""
def __init__(self, memory_system, llm_client, skill_manager):
self.memory = memory_system
self.llm = llm_client
self.skills = skill_manager
self.call_counter = 0
self.eval_threshold = 15 # 每 15 次调用触发评估
async def execute_task(self, user_prompt: str) -> ExecutionTrace:
trace = ExecutionTrace(
task_id=f"task_{datetime.now().timestamp()}",
user_prompt=user_prompt
)
while not self.is_task_complete(trace):
# 1. LLM 决定下一步行动
decision = await self.llm.decide_next_action(
prompt=user_prompt,
trace=trace,
available_tools=self.get_available_tools()
)
if decision.type == "tool_call":
# 2. 执行工具调用并记录
start = datetime.now()
result = await self.execute_tool(decision.tool_name, decision.args)
duration = (datetime.now() - start).total_seconds() * 1000
trace.add_tool_call(
tool_name=decision.tool_name,
args=decision.args,
result=str(result),
duration=duration,
success=not result.get("error")
)
self.call_counter += 1
# 3. 检查是否需要触发自评估
if self.call_counter >= self.eval_threshold:
await self._trigger_self_evaluation(trace)
self.call_counter = 0
elif decision.type == "response":
trace.final_output = decision.text
# 任务完成后再次评估(最终评估)
await self._trigger_self_evaluation(trace)
await self._consider_skill_creation(trace)
return trace
async def _trigger_self_evaluation(self, trace: ExecutionTrace):
"""触发自评估:LLM 对当前轨迹进行复盘"""
eval_prompt = f"""
请对以下执行轨迹进行自评估:
用户任务:{trace.user_prompt}
工具调用次数:{trace.total_calls}
成功率:{trace.success_rate:.1%}
评估维度(0-10分):
1. 任务完成度:结果是否达到了用户目标?
2. 执行效率:步骤是否冗余?有无更短路径?
3. 错误处理:失败后恢复得如何?
4. 可复用性:这个执行模式以后还能用吗?
请给出结构化的 JSON 评估结果。
"""
evaluation = await self.llm.generate_structured(
eval_prompt,
schema={
"task_completion": "float 0-10",
"efficiency": "float 0-10",
"error_recovery": "float 0-10",
"reusability": "float 0-10",
"summary": "string 评估总结",
"lessons_learned": "list 经验教训"
}
)
trace.evaluation_score = (
evaluation["task_completion"] * 0.4 +
evaluation["efficiency"] * 0.2 +
evaluation["error_recovery"] * 0.2 +
evaluation["reusability"] * 0.2
)
await self.memory.store_evaluation(trace, evaluation)
async def _consider_skill_creation(self, trace: ExecutionTrace):
"""
判断是否值得创建 Skill
核心逻辑:可复用性得分 >= 7/10 时创建
"""
if trace.evaluation_score < 7.0:
return # 质量不够,不创建
existing = await self.skills.find_similar(trace.user_prompt)
if existing:
# 已有类似 Skill → 优化它
await self.skills.improve(existing, trace)
else:
# 没有类似 Skill → 创建新的
skill_path = await self.skills.create_from_trace(trace)
trace.skills_created.append(skill_path)
3.2 Skill 创建:从轨迹到可执行技能
# hermes-agent/core/skill_manager.py(概念代码)
import os
import re
from pathlib import Path
from datetime import datetime
SKILLS_DIR = Path.home() / ".hermes" / "skills"
class SkillManager:
"""Skill 的创建、优化和召回管理"""
async def create_from_trace(self, trace: ExecutionTrace) -> str:
"""从执行轨迹自动生成 Skill Markdown 文件"""
skill_content = await self._llm_generate_skill_markdown(trace)
skill_name = self._infer_skill_name(trace.user_prompt)
safe_name = re.sub(r'[^\w\s-]', '', skill_name).strip().replace(' ', '-').lower()
file_path = SKILLS_DIR / f"{safe_name}.md"
file_path.parent.mkdir(parents=True, exist_ok=True)
file_path.write_text(skill_content)
await self._index_skill(file_path, skill_content)
return str(file_path)
async def _llm_generate_skill_markdown(self, trace: ExecutionTrace) -> str:
"""使用 LLM 生成结构化的 Skill Markdown"""
prompt = f"""
基于以下执行轨迹,生成一个可复用的 Skill Markdown 文件。
用户任务:{trace.user_prompt}
工具调用序列:{[tc.tool_name for tc in trace.tool_calls]}
最终输出:{trace.final_output}
请生成符合以下格式的 Markdown:
# Skill: <从任务推断的名称>
## 触发条件
<什么情况下应该调用这个 Skill>
## 执行步骤
<步骤化的执行流程,每步对应一个工具调用>
## 参数定义
<Skill 的输入参数>
## 依赖环境
<需要哪些工具/权限>
## 边界情况
<常见错误和应对方式>
## 版本信息
- v1.0: 初始版本,基于 {datetime.now().strftime('%Y-%m-%d')} 执行经验生成
"""
return await self.llm.generate(prompt)
async def improve(self, existing_skill_path: str, new_trace: ExecutionTrace):
"""对已有 Skill 进行增量优化"""
existing_content = Path(existing_skill_path).read_text()
improvement_prompt = f"""
当前 Skill 内容:
{existing_content}
新增执行经验(这次执行有什么改进点?):
工具调用:{[tc.tool_name for tc in new_trace.tool_calls]}
请在保留现有内容的基础上,补充:
1. 新的边界情况处理
2. 优化后的执行步骤(如果有更优路径)
3. 新增版本记录条目
"""
improved = await self.llm.generate(improvement_prompt)
Path(existing_skill_path).write_text(improved)
四、部署实战:从零到生产级别的完整指南
4.1 快速安装(Linux/macOS/WSL2)
# 一键安装脚本(推荐)
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
# 验证安装
hermes --version
# 查看帮助
hermes --help
4.2 Docker 部署(生产推荐)
# docker-compose.yml
version: '3.8'
services:
hermes-agent:
image: nousresearch/hermes-agent:latest
container_name: hermes-agent
restart: unless-stopped
environment:
# 模型配置
- HERMES_DEFAULT_MODEL=openrouter/anthropic/claude-sonnet-4
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
# 安全配置
- HERMES_SECURITY_MODE=strict
- HERMES_ALLOW_SUDO=false
# 记忆持久化(关键!)
- HERMES_MEMORY_DIR=/data/memory
- HERMES_SKILLS_DIR=/data/skills
# 日志级别
- RUST_LOG=info
volumes:
# 持久化记忆和技能(数据不丢失)
- hermes-data:/data
- /var/run/docker.sock:/var/run/docker.sock:ro # 按需
ports:
- "8000:8000" # REST API
- "8001:8001" # WebSocket(实时消息)
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
volumes:
hermes-data:
driver: local
# 启动
docker compose up -d
# 查看日志
docker compose logs -f hermes-agent
4.3 本地模型部署(Ollama,完全离线运行)
# docker-compose.local.yml(使用 Ollama 本地模型)
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
environment:
- OLLAMA_HOST=0.0.0.0:11434
volumes:
- ollama-data:/root/.ollama
ports:
- "11434:11434"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
hermes-agent:
image: nousresearch/hermes-agent:latest
environment:
- HERMES_DEFAULT_MODEL=ollama/qwen2.5:14b
- OLLAMA_API_BASE=http://ollama:11434/v1
depends_on:
- ollama
volumes:
ollama-data:
# 先拉取模型
docker exec -it ollama ollama pull qwen2.5:14b
docker exec -it ollama ollama pull nomic-embed-text
# 启动完整栈
docker compose -f docker-compose.local.yml up -d
4.4 多模型路由配置
# ~/.hermes/config.yaml
model_routing:
rules:
- trigger: "写代码|编程|debug|重构"
model: "openrouter/anthropic/claude-sonnet-4"
- trigger: "搜索|调研|分析"
model: "openrouter/openai/gpt-4o"
- trigger: "快速回答|简单问题"
model: "ollama/qwen2.5:7b"
- trigger: "私密内容|内部数据"
model: "ollama/qwen2.5:14b"
fallback_chain:
- "openrouter/anthropic/claude-sonnet-4"
- "openrouter/openai/gpt-4o"
- "ollama/qwen2.5:14b"
五、MCP 协议集成:Hermes Agent 的工具扩展能力
5.1 MCP 是什么
MCP(Model Context Protocol)是 2026 年 AI Agent 领域最重要的协议之一,Hermes 对 MCP 的原生支持使其工具能力可以无限扩展。
没有 MCP:
Agent 需要为每个工具写独立的适配代码
├── Slack 集成 → SlackAdapter
├── GitHub 集成 → GitHubAdapter
├── 数据库 → DBAdapter
└── 文件系统 → FileSystemAdapter
有了 MCP:
Agent 只需要实现 MCP Client
所有工具按统一协议接入
├── MCP Server: Slack
├── MCP Server: GitHub
├── MCP Server: PostgreSQL
└── MCP Server: File System
5.2 Hermes 中的 MCP 集成配置
# ~/.hermes/config.yaml
mcp:
servers:
# GitHub MCP Server——直接在对话中操作 GitHub
github:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}"
# 文件系统 MCP Server——安全的文件操作
filesystem:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem"]
env:
ALLOWED_DIRECTORY: "/home/user/projects"
# PostgreSQL MCP Server——数据库查询
postgres:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-postgres"]
env:
DATABASE_URL: "postgresql://user:pass@localhost:5432/mydb"
# Brave Search MCP Server——网络搜索
brave-search:
command: "npx"
args: ["-y", "@modelcontextprotocol/server-brave-search"]
env:
BRAVE_API_KEY: "${BRAVE_SEARCH_API_KEY}"
5.3 MCP 生态 2026 年最新数据
| 指标 | 数据 |
|---|---|
| 官方 MCP Servers | 80+ |
| 社区 MCP Servers | 2000+ |
| NPM 上的 MCP 包 | 500+ |
| 支持 MCP 的 Agent 框架 | 15+(含 Cursor、Claude Desktop、OpenClaw、Zed) |
| 日均 MCP 调用量(社区) | 1000 万次以上 |
# 安装热门 MCP Server
# GitHub 操作(提 issue/PR/代码审查)
npx -y @modelcontextprotocol/server-github
# PostgreSQL 数据库(直接用自然语言查数据)
npx -y @modelcontextprotocol/server-postgres
# Brave 搜索(不依赖 Google)
npx -y @modelcontextprotocol/server-brave-search
# Puppeteer 浏览器自动化
npx -y @modelcontextprotocol/server-puppeteer
# Kubernetes 集群管理
npx -y @modelcontextprotocol/server-kubernetes
六、与主流 Agent 框架的横评
| 维度 | Hermes Agent | OpenClaw | LangChain Agents | AutoGPT |
|---|---|---|---|---|
| 自进化能力 | 原生闭环 | 内置记忆 | 需要手动配置 | 无 |
| Skill 系统 | Markdown 可编辑 | Workflow | LangChain Chain | 无 |
| 记忆持久化 | FTS5+文件 | LCM 压缩 | 需额外配置 | 无 |
| 多平台支持 | 15+ 平台 | 多渠道 | 需定制 | 无 |
| 本地模型 | Ollama 原生 | 支持 | 支持 | 支持 |
| MCP 支持 | 原生 | 支持 | 通过 LangChain MCP | 无 |
| 部署难度 | 简单 | 简单 | 复杂 | 中等 |
| GitHub Stars | 21.6 万+ | 对比基线 | N/A | 16 万+ |
七、工程反思:自进化 Agent 的边界与挑战
7.1 Skill 质量失控风险
当 Agent 自主创建的 Skill 越来越多,如何保证 Skill 的质量不会随着版本迭代而退化?
目前 Hermes 的机制是:每次失败的 Skill 调用都会触发优化,但如果优化方向错了(比如把一个本应被废弃的 Skill 修了又修),Skill 会变得越来越复杂、越来越难以理解。
这是一个 LLM 自动化的固有风险:自我改进的系统如果没有外部约束,可能会在局部最优解里越陷越深。
7.2 记忆数据库的膨胀
FTS5 全文索引 + SQLite 会话存储,在长期运行后会产生大量数据。当记忆库达到 GB 级别时,检索延迟会显著上升。此外,目前的召回是基于关键词 FTS5 的,没有向量嵌入,在语义相似性召回上不如专门的向量数据库。
7.3 安全的自进化边界
这是最核心的哲学问题:如果 Agent 有权限修改自己的 Skill(行为逻辑),那么它的行为边界由谁来定义?
Hermes 的安全护栏(security.yaml)是静态配置的,Agent 本身无法修改它。但如果 Agent 学会了绕过安全限制,安全配置文件本身被损坏,系统的安全性就会完全失效。
这实际上是 2026 年整个 AI Agent 领域都在面对的核心问题:可审计性 + 可控性 + 自进化能力,这三者如何共存?
八、总结与展望
Hermes Agent 的出现,标志着 AI Agent 从"工具调用框架"时代,进入"持续学习系统"时代。
从工程实现的角度,Hermes 有几个值得所有 AI 开发者学习的点:
- Skill 即 Markdown:把执行经验用最通用的格式保存,最大化了可复用性
- FTS5 替代向量数据库:用 SQLite 解决 90% 的召回需求,不需要引入沉重的外部依赖
- 事件驱动的多平台网关:一个进程管所有平台,架构清晰,扩展容易
- 安全护栏与自进化并行:安全不是事后补救,而是和进化机制同步设计
展望未来:我认为 Hermes 的路线会启发更多框架采用"原生自进化"设计。但最终,决定 Agent 系统能走多远的,不是它的功能有多强大,而是它的可预测性和可审计性——人类需要能够理解 Agent 为什么会做出某个决策,而不是只看到结果。
在这个意义上,Hermes Agent 是一个非常好的起点,但绝不是终点。
参考资源
- GitHub 仓库:NousResearch/hermes-agent(MIT 协议,21.6 万 Star)
- 官方文档:docs.hermesagent.ai
- Desktop 版本:desktop.hermesagent.org.cn(Tauri 构建,跨平台桌面端)
- MCP 生态:modelcontextprotocol.io
- 阿里云一键部署:计算巢、无影云电脑、轻量应用服务器
本文首发于 程序员茄子,cid=1,tag: Hermes Agent|AI Agent|自进化|Nous Research|MCP|Python|2026