Hermes-Agent 自进化 AI Agent 架构深度解析:三层记忆体系与闭环学习原理解密
2026年,一个名为 Hermes-Agent 的开源项目在 GitHub 上狂揽 10万+ Star,被称为"目前增长最快的开源 AI Agent 项目"。它由独立 AI 实验室 Nous Research 推出,MIT 协议开源,核心定位只有一个:"The self-improving AI agent"——一个与你共同成长的 AI Agent。本文将从源码架构出发,深入解析 Hermes-Agent 的三层记忆体系、闭环学习机制、200+ 模型兼容性,以及如何在生产环境中用它构建真正本地化、隐私优先的 AI 工作流。
一、背景:为什么我们需要一个"自进化"的 Agent?
在聊 Hermes-Agent 之前,先回顾一下当前 AI Agent 生态的现状。
2024-2025 年,LangChain、AutoGPT、CrewAI 等框架先后涌现。它们解决了"如何给 LLM 装上工具"的问题,但在实际使用中,开发者很快发现了一个核心矛盾:这些 Agent 都是"无状态"的。
你让 Claude 帮你写了一个 API 对接脚本,关掉对话,下次再打开,它完全不记得你之前用的是什么技术栈、偏好什么风格、你公司的代码规范是什么。每次对话都是从零开始——就像雇了一个每天自动失忆的员工。
更痛苦的是"重复劳动"问题。你让 Agent 完成了"从 PDF 提取条款写入 Excel"这个任务,下一个任务其实是同一个模式的不同变体,但 Agent 依然要从头分析、从零推理。
Hermes-Agent 的出现,正是为了解决这两个根本性问题:
- 跨会话记忆的缺失:Agent 无法在多轮对话、多天使用中保持上下文连续性
- 经验无法积累:每次任务执行的结果无法固化为可复用的技能
它的 slogan 非常精准:"The agent that grows with you"——一个会与你共同成长的 Agent。
二、核心架构总览:从目录结构看设计哲学
理解一个开源项目的架构,最直接的方式是看它的目录结构。Hermes-Agent 的全局配置默认存放在用户主目录下的 ~/.hermes/ 目录,结构如下:
~/.hermes/
├── config.yaml # 全局配置:模型、终端、压缩策略、工具开关
├── .env # API keys、各平台 token、敏感凭证
├── auth.json # OAuth 认证信息
├── SOUL.md # Agent 的人设/灵魂文件(类似 OpenClaw 的 SOUL.md)
├── MEMORY.md # Agent 的长期记忆文件
├── USER.md # 用户画像和偏好
├── memories/ # 记忆存储目录
├── skills/ # Agent 创建或安装的技能
├── cron/ # 定时任务配置
├── sessions/ # 网关会话相关
├── state.db # SQLite 状态数据库
└── logs/ # 运行日志
这个目录结构本身就透露了设计哲学:所有数据都在本地,没有云端锁定。state.db 是 SQLite 数据库,存储会话状态;memories/ 和 skills/ 是纯文本文件,可直接编辑,可版本控制。
项目技术栈:
| 组件 | 技术选型 |
|---|---|
| 核心语言 | Python 3.11+ |
| 长期记忆存储 | SQLite + FTS5 全文索引 |
| 默认模型后端 | Ollama(本地)+ Nous Portal(云端) |
| 消息网关 | 支持 7 类平台(飞书、Discord、Telegram 等) |
| 内置工具数 | 40+ |
| 兼容模型数 | 200+ |
| 项目规模 | ~3 万行 Python 代码(v0.14.0) |
三、三层记忆体系:Hermes 如何模拟人类认知过程
Hermes-Agent 之所以被称为"越用越懂你"的智能体,核心在于其独创的三层记忆架构。它不仅仅是在存储聊天记录,更是在模拟人类的认知过程:从短期的工作记忆,到长期的事实沉淀,再到抽象的技能复用。
3.1 第一层:会话记忆(Session Memory)——当下的专注
这是最表层的一层,对应人类的工作记忆(Working Memory)。它负责维护当前对话窗口的上下文,确保多轮对话的逻辑连贯性。
实现机制:
# Hermes 的会话记忆实现(简化版示意)
class SessionMemory:
def __init__(self, session_id: str, max_context_ratio: float = 0.7):
self.session_id = session_id
self.messages: list[Message] = []
self.max_context_ratio = max_context_ratio
def add_message(self, role: str, content: str):
self.messages.append(Message(role=role, content=content))
# 当对话长度接近 context window 阈值时,触发动态摘要
if self._near_threshold():
self._auto_summarize()
def _auto_summarize(self):
"""动态摘要策略:当接近 context 限制时压缩早期内容,而非简单截断"""
summary = self._llm_summarize(self.messages[:-5]) # 保留最近 5 轮
self.messages = [summary] + self.messages[-5:]
关键设计点:动态摘要而非简单截断。当对话长度接近 LLM 的 context window 阈值时,Hermes 不会粗暴地丢弃早期内容,而是调用 LLM 对早期对话进行语义压缩,保留关键决策和上下文信息。
生命周期:随会话开始而创建,随会话结束或重置而清除。
3.2 第二层:持久记忆(Persistent Memory)——跨时空的事实库
这是 Hermes 区别于普通 Chatbot 的核心。它将跨会话的关键事实、用户偏好、项目背景持久化存储,确保"隔夜不忘"。
技术底座:SQLite + FTS5
Hermes 没有使用花哨的向量数据库(如 Chroma、Milvus),而是直接用 SQLite 的 FTS5 扩展模块。这个选择非常务实:
-- 消息表:记录所有对话
CREATE TABLE messages (
id INTEGER PRIMARY KEY,
session_id TEXT,
role TEXT, -- 'user' 或 'assistant'
content TEXT,
created_at TIMESTAMP
);
-- 启用全文索引
CREATE VIRTUAL TABLE messages_fts USING fts5(content, content=messages, content_rowid=id);
-- 持久记忆表:跨会话的关键事实
CREATE TABLE persistent_memories (
id INTEGER PRIMARY KEY,
category TEXT, -- 'user_profile' | 'project_context' | 'knowledge_base'
content TEXT,
provenance TEXT, -- 来源追溯:谁/何时写入
last_accessed TIMESTAMP,
access_count INTEGER DEFAULT 0
);
-- 检索时使用 FTS5 全文搜索
SELECT content FROM messages_fts WHERE messages_fts MATCH 'API 对接 项目配置';
为什么选择 SQLite + FTS5 而不是向量数据库?
| 对比维度 | 向量数据库 (Chroma/Milvus) | SQLite + FTS5 |
|---|---|---|
| 部署复杂度 | 需要额外服务进程 | SQLite 是嵌入式,无额外依赖 |
| 全文语义匹配 | 强(语义相似度) | 中等(关键词+词干) |
| 精确召回 | 弱(依赖 embedding 模型) | 强(FTS5 布尔查询) |
| 数据规模 | 适合海量向量数据 | 适合千-万级记录 |
| 运维成本 | 高(服务发现、高可用) | 零(单文件数据库) |
Hermes 的设计哲学是:实用主义优先。对于个人 Agent 场景,SQLite + FTS5 完全够用,且零运维成本。向量检索留给需要大规模语义搜索的高级场景(可通过插件扩展)。
三类持久记忆数据:
@dataclass
class PersistentMemory:
category: str
content: str
provenance: str
last_accessed: datetime
access_count: int
# 用户画像
# 内容:技术栈偏好、回复风格偏好、工作习惯
# 例子:{"role": "frontend", "style": "concise", "timezone": "Asia/Shanghai"}
# 项目上下文
# 内容:当前项目背景、已完成任务、失败原因记录
# 例子:{"task": "pdf_contract_parser", "status": "done", "notes": "使用 pdfplumber 库"}
# 知识库
# 内容:文档摘要、网页摘录、API 规范、项目代码说明
# 例子:{"source": "company_api_doc", "summary": "认证使用 JWT Bearer Token"}
3.3 第三层:技能记忆(Skill Memory)——程序化的能力
这是 Hermes 最独特的一层——它不只存储记忆,还会将经验固化为可执行的技能(Skill)。
技能文件是 Markdown 格式的纯文本,放在 ~/.hermes/skills/ 目录下:
<!-- skill: pdf_contract_parser.md -->
<!-- 技能名称:从 PDF 提取合同关键条款 -->
<!-- 创建时间:2026-07-01 -->
<!-- 创建者:hermes_agent -->
<!-- 使用次数:3 -->
<!-- 上次成功:2026-07-08 -->
# 合同关键条款提取技能
## 使用场景
从 PDF 合同文件中提取以下关键信息:
- 甲方/乙方名称
- 合同金额
- 付款周期
- 违约条款
- 签署日期
## 使用工具
- `pdfplumber` 库读取 PDF 文本
- 正则表达式匹配关键字段
- 写入 Excel 使用 `openpyxl`
## 已知坑
- 扫描版 PDF(无文字层)需要先用 OCR 处理
- 多页合同需要按页拆分后逐页提取
## 示例命令
```bash
python extract_contract.py --input contract.pdf --output result.xlsx
这个技能文件是如何生成的?答案在下一节的"闭环学习系统"中。
### 3.4 三层协作机制
三层记忆并非孤立运作,而是通过一套信号系统互相触发:
用户提问
↓
检索顺序:会话记忆 → 持久记忆 → 技能记忆
↓
上下文组装(Context Assembly)
↓
LLM 推理 + 工具调用
↓
任务完成 → 评估是否值得写入记忆
↓
写入对应的记忆层
具体触发逻辑:
- **同一会话内的即时追问** → 优先查会话记忆
- **跨会话的背景问题**("我之前那个项目用的是什么库?")→ 查持久记忆(FTS5 检索)
- **新任务的模式识别**("又一个合同要处理")→ 查技能记忆,找到 `pdf_contract_parser.md` 直接复用
---
## 四、闭环学习系统:Agent 如何从经验中"长出"技能
Hermes-Agent 最核心的创新,不是某个具体功能,而是一套**内置的闭环学习系统(Closed Learning Loop)**。它不是事后打补丁,而是从 Day 1 就融入了核心架构。
### 4.1 闭环的五个环节
完成任务
↓
策划记忆(Planned Memory)
↓
创建 Skill
↓
Skill 自改进(Skill Evolution)
↓
FTS5 召回(On-demand Retrieval)
↓
用户建模(User Profiling)
↓
循环(回到"完成任务")
**1. 策划记忆(Planned Memory)**
任务完成后,Agent 自主判断"什么值得记住"。判断标准包括:
- 这个任务涉及的领域是否是用户经常使用的?
- 这次执行中有没有遇到坑、踩过的雷值得记录?
- 用户的偏好是否发生了变化(比如开始用新的技术栈)?
**2. 创建 Skill**
当 Agent 发现某个任务模式出现第二次(或以上)时,它会自动将这个模式封装为一个 Skill 文件:
```python
# 闭环学习中的 Skill 自动生成逻辑(伪代码)
class SkillGenerator:
def after_task(self, task: Task, result: TaskResult):
# 检查是否达到创建技能的条件
if task.pattern_recognized(count=2):
skill_content = self._extract_pattern(task)
skill_path = f"~/.hermes/skills/{task.category}.md"
self._write_skill_file(skill_path, skill_content)
print(f"✅ 新技能已创建:{skill_path}")
def _extract_pattern(self, task: Task) -> str:
"""从任务历史中提炼可复用的模式"""
prompt = f"""
从以下任务执行记录中,提取可复用的技能步骤:
任务:{task.description}
执行过程:{task.execution_log}
已知问题:{task.issues_encountered}
输出格式:Markdown 技能文件,包含使用场景、工具、步骤、已知坑。
"""
return llm.generate(prompt)
3. Skill 自改进(Skill Evolution)
创建 Skill 只是开始。Hermes 还内置了 Skill 的生命周期管理:
- Active:技能正常运行
- Stale:技能长时间未使用,可能过时
- Archived:技能被合并或废弃
class SkillLifecycleManager:
def on_task_failure(self, skill: Skill, error: Exception):
"""当使用某 Skill 失败时,自动尝试修复"""
# 触发 Auto-Patch 机制
fixed_content = self._llm_fix_skill(skill, error)
skill.content = fixed_content
skill.last_fixed = datetime.now()
print(f"🔧 技能已自动修复:{skill.name}")
def on_optional_upgrade(self, skill: Skill):
"""闲置过久的技能,提示归档或合并"""
if skill.usage_count == 0 and skill.age_days > 30:
self._prompt_archive(skill)
def merge_narrow_skills(self, category: str):
"""将同一类别的多个窄技能合并为一个广技能(需手动确认)"""
narrow_skills = self.list_by_category(category)
if len(narrow_skills) >= 3:
merged = self._llm_merge_skills(narrow_skills)
self._prompt_user_confirm(merged)
4. FTS5 召回
当新任务到来时,Agent 通过 FTS5 检索历史经验,找到最相关的 Skill 或记忆片段:
# FTS5 召回实现
def retrieve_relevant_context(query: str, top_k: int = 5) -> list[Memory]:
conn = sqlite3.connect("~/.hermes/state.db")
cursor = conn.cursor()
# FTS5 布尔查询 + 排名
sql = """
SELECT m.*, bm25(messages_fts) as rank
FROM messages_fts
JOIN messages m ON messages_fts.rowid = m.id
WHERE messages_fts MATCH ?
ORDER BY rank
LIMIT ?
"""
cursor.execute(sql, (query, top_k))
return [Memory(**row) for row in cursor.fetchall()]
4.2 对应认知科学的三种记忆类型
Hermes 的三层设计并非凭空捏造,而是有认知科学依据的:
| 记忆类型(认知科学) | Hermes 层 | 存储形式 | 生命周期 |
|---|---|---|---|
| 情景记忆(Episodic) | 会话记忆 | LLM Context / SQLite | 会话级 |
| 语义记忆(Semantic) | 持久记忆 | SQLite + FTS5 | 永久 |
| 程序性记忆(Procedural) | 技能记忆 | Markdown 文件 | 永久 + 演进 |
五、200+ 模型兼容:架构如何解耦模型层
Hermes-Agent 的另一大卖点是兼容 200+ 大模型,从 GPT-4o、Claude 3 到通义千问,从云端 API 到完全本地运行的 Ollama 模型。
这种灵活性来自其精心设计的模型抽象层:
┌─────────────────────────────────────────────┐
│ Hermes Agent Core │
│ (三层记忆 + 闭环学习 + 工具调度) │
├─────────────────────────────────────────────┤
│ Provider Abstraction Layer │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ OpenAI │ │Anthropic│ │ Ollama │ ... │
│ │Provider │ │Provider │ │Provider │ │
│ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────────┤
│ HTTP API Interface │
│ POST /v1/chat/completions │
└─────────────────────────────────────────────┘
每种模型通过统一的 Provider 接口接入:
from abc import ABC, abstractmethod
class LLMProvider(ABC):
@abstractmethod
def chat(self, messages: list[dict], **kwargs) -> str:
"""统一的 chat 接口"""
pass
@abstractmethod
def get_name(self) -> str:
"""返回 provider 名称"""
pass
class OllamaProvider(LLMProvider):
def __init__(self, base_url: str = "http://localhost:11434"):
self.base_url = base_url
def chat(self, messages: list[dict], model: str = "llama3:8b", **kwargs) -> str:
response = requests.post(
f"{self.base_url}/api/chat",
json={"model": model, "messages": messages, **kwargs},
timeout=kwargs.get("timeout", 120)
)
return response.json()["message"]["content"]
def get_name(self) -> str:
return "ollama"
class OpenAIProvider(LLMProvider):
def __init__(self, api_key: str):
self.client = OpenAI(api_key=api_key)
def chat(self, messages: list[dict], model: str = "gpt-4o", **kwargs) -> str:
response = self.client.chat.completions.create(
model=model, messages=messages, **kwargs
)
return response.choices[0].message.content
def get_name(self) -> str:
return "openai"
通过这个抽象层,用户可以在 config.yaml 中一键切换模型:
# config.yaml
model:
provider: "ollama" # 切换为本地 Ollama
model: "llama3:8b" # 或 "qwen2.5:14b" 等
# provider: "openai" # 切换为 OpenAI
# model: "gpt-4o"
# 完全离线场景:所有推理走 Ollama,零 API 费用
六、Docker 部署与 Ollama 本地化实战
Hermes-Agent 支持 Docker 一键部署,结合 Ollama 实现完全本地化的 AI 工作流:
# docker-compose.yml
version: '3.8'
services:
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes-agent
volumes:
- ./hermes_data:/root/.hermes
- /var/run/docker.sock:/var/run/docker.sock
environment:
- OLLAMA_BASE_URL=http://host.docker.internal:11434
- HERMES_MODEL=llama3:8b
- HERMES_PROVIDER=ollama
network_mode: host
restart: unless-stopped
ollama:
image: ollama/ollama:latest
container_name: ollama
volumes:
- ./ollama_data:/root/.ollama
ports:
- "11434:11434"
restart: unless-stopped
# GPU 加速(如 NVIDIA GPU 可用)
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
启动后验证:
# 检查 Hermes 运行状态
docker logs hermes-agent
# 检查 Ollama 模型加载
curl http://localhost:11434/api/tags
# 测试本地 LLM 调用
curl -X POST http://localhost:11434/api/chat \
-d '{"model":"llama3:8b","messages":[{"role":"user","content":"Hello"}]}'
性能基准测试(Ollama + RTX 3090):
| 模型 | 参数量 | 推理速度 (tok/s) | 内存占用 |
|---|---|---|---|
| llama3:8b | 8B | ~45 | ~6GB VRAM |
| qwen2.5:14b | 14B | ~28 | ~12GB VRAM |
| phi3:mini | 3.8B | ~62 | ~4GB VRAM |
对于日常的文本处理、代码生成任务,8B 模型(llama3:8b)在速度和效果上取得了良好的平衡。
七、与主流框架横向对比
| 维度 | Hermes-Agent | LangChain | AutoGPT | CrewAI |
|---|---|---|---|---|
| 自进化能力 | ✅ 闭环学习 | ❌ 无 | ❌ 无 | ❌ 无 |
| 三层记忆 | ✅ SQLite+FTS5 | ⚠️ 简单 Buffer | ❌ 无 | ❌ 无 |
| 本地模型 | ✅ Ollama 原生 | ⚠️ 需配置 | ❌ 云端 | ❌ 云端 |
| 技能系统 | ✅ 自动生成 Markdown | ❌ 无 | ❌ 无 | ❌ 无 |
| 工具数量 | 40+ | 大量(生态丰富) | 少量 | 中等 |
| 部署难度 | ⭐⭐ 简单 | ⭐⭐⭐⭐ 复杂 | ⭐⭐ 简单 | ⭐⭐⭐ 中等 |
| 隐私性 | ⭐⭐⭐⭐⭐ 极高 | ⭐⭐⭐ 中等 | ⭐⭐ 低 | ⭐⭐ 低 |
| 社区活跃度 | 10万+ Star,增长最快 | 6万+ Star,最成熟 | 11万+ Star,热度下降 | 增长中 |
选型建议:
- 本地优先、隐私敏感 → Hermes-Agent + Ollama
- 快速构建 RAG 应用 → LangChain(生态成熟)
- 多代理协作复杂任务 → CrewAI
- 个人效率工具(无本地需求) → AutoGPT(上手最快)
八、工程实践:构建一个本地化 PDF → Excel 工作流
作为实战演示,以下是用 Hermes-Agent 构建一个"从 PDF 提取合同关键条款并写入 Excel"的自动化工作流:
8.1 环境准备
# 1. 安装 Hermes-Agent
curl -fsSL https://github.com/NousResearch/hermes-agent/releases/install | sh
# 2. 配置 Ollama(国内镜像加速)
export OLLAMA_HOST=https://ollama.nicecc.cloud
ollama pull llama3:8b
# 3. 初始化 Hermes
hermes init --local # 本地模式,不连接云端
# 4. 安装 PDF 处理技能(可从社区安装)
hermes skills install pdf-tools
# 5. 验证安装
hermes --version
hermes models list # 确认 Ollama 模型已识别
8.2 配置文件
# ~/.hermes/config.yaml
agent:
name: "Hermes"
soul: "~/.hermes/SOUL.md"
memory_dir: "~/.hermes/memories"
skills_dir: "~/.hermes/skills"
model:
provider: "ollama"
base_url: "http://localhost:11434"
model: "llama3:8b"
temperature: 0.7
timeout: 180
tools:
enabled:
- file_reader
- file_writer
- web_search
- docker
- shell
- pdf_processor
memory:
fts5_enabled: true
auto_summarize: true
summarize_threshold_ratio: 0.7
8.3 任务执行
# 在终端启动 Hermes
hermes chat
# 用户输入:
# "帮我处理 /Users/qnnet/contracts/ 目录下的所有 PDF 合同,
# 提取关键条款,生成一个汇总 Excel 文件到桌面上"
# Hermes 的执行过程(内部):
# 1. 检索 ~/.hermes/skills/ 是否存在 pdf_contract_parser.md
# → 找到!直接加载使用
# 2. 扫描目录下的所有 .pdf 文件
# 3. 对每个 PDF 调用 pdfplumber 提取文本
# 4. 用 LLM 提取关键字段(金额、日期、甲乙方)
# 5. 用 openpyxl 生成 Excel 汇总表
# 6. 完成后评估:是否需要更新 pdf_contract_parser.md?
# → 发现多碟游戏/特殊格式的处理需求,更新 Skill 文件
8.4 核心代码片段
#!/usr/bin/env python3
"""Hermes PDF 合同提取工具(简化版)"""
import pdfplumber
import re
from pathlib import Path
from openpyxl import Workbook
def extract_contract_info(pdf_path: Path) -> dict:
"""从 PDF 提取合同关键条款"""
with pdfplumber.open(pdf_path) as pdf:
text = "\n".join(page.extract_text() for page in pdf.pages)
# 甲方/乙方
parties = re.findall(r"(甲方|乙方|供应商|客户)[::]\s*(.+)", text)
# 合同金额
amount = re.search(r"(?:合同金额|总价|金额)[::]\s*([¥$]?\d+(?:,\d{3})*(?:\.\d{2})?)", text)
# 付款周期
payment = re.search(r"(?:付款周期|结算方式)[::]\s*(.+?)(?:\n|$)", text)
# 签署日期
date = re.search(r"\d{4}[-/年]\d{1,2}[-/月]\d{1,2}[日]?", text)
return {
"filename": pdf_path.name,
"parties": dict(parties),
"amount": amount.group(1) if amount else "未找到",
"payment": payment.group(1).strip() if payment else "未找到",
"date": date.group(0) if date else "未找到",
}
def generate_summary_xlsx(contracts: list[dict], output: Path):
"""生成汇总 Excel"""
wb = Workbook()
ws = wb.active
ws.title = "合同汇总"
headers = ["文件名", "甲方", "乙方", "合同金额", "付款周期", "签署日期"]
ws.append(headers)
for c in contracts:
ws.append([
c["filename"],
c["parties"].get("甲方", c["parties"].get("供应商", "")),
c["parties"].get("乙方", c["parties"].get("客户", "")),
c["amount"],
c["payment"],
c["date"],
])
# 自动调整列宽
for col in ws.columns:
max_length = max(len(str(cell.value or "")) for cell in col)
ws.column_dimensions[col[0].column_letter].width = max_length + 2
wb.save(output)
print(f"✅ 汇总已生成:{output}")
if __name__ == "__main__":
import sys
contract_dir = Path(sys.argv[1] if len(sys.argv) > 1 else ".")
output_file = Path(sys.argv[2] if len(sys.argv) > 2 else "contract_summary.xlsx")
pdfs = list(contract_dir.glob("*.pdf"))
results = [extract_contract_info(p) for p in pdfs]
generate_summary_xlsx(results, output_file)
九、性能优化与工程最佳实践
9.1 模型选择策略
不是什么任务都需要 GPT-4o。根据任务复杂度动态选择模型:
class ModelRouter:
"""根据任务复杂度自动路由到合适的模型"""
SIMPLE_TASKS = ["format_conversion", "file_naming", "simple_search"]
MEDIUM_TASKS = ["code_review", "document_summarization", "api_debugging"]
HARD_TASKS = ["architecture_design", "complex_refactoring", "multi_file_planning"]
def route(self, task: str) -> tuple[str, str]:
complexity = self._classify(task)
if complexity in self.SIMPLE_TASKS:
return ("ollama", "phi3:mini") # 3.8B,速度快
elif complexity in self.MEDIUM_TASKS:
return ("ollama", "llama3:8b") # 8B,均衡
else:
return ("openai", "gpt-4o") # 云端,能力强
9.2 记忆压缩策略
避免 context window 浪费:
class ContextOptimizer:
"""优化上下文组装的策略"""
# 保留优先级排序
PRIORITY_ORDER = [
"system_prompt", # 系统指令(始终保留)
"user_preferences", # 用户偏好(从持久记忆加载)
"current_task", # 当前任务描述(最新)
"recent_turns", # 最近 N 轮对话
"relevant_memories", # FTS5 检索到的相关记忆
"relevant_skills", # 相关技能摘要
]
def build_context(self, available: list[str], max_tokens: int) -> str:
"""按优先级贪婪填充 context"""
selected = []
total_tokens = 0
for item in self.PRIORITY_ORDER:
item_tokens = self._estimate_tokens(available.get(item, ""))
if total_tokens + item_tokens <= max_tokens:
selected.append(available.get(item, ""))
total_tokens += item_tokens
return "\n".join(selected)
9.3 技能懒加载
避免启动时加载所有技能:
from pathlib import Path
from functools import lru_cache
class LazySkillLoader:
"""按需加载技能,避免内存浪费"""
def __init__(self, skills_dir: Path):
self.skills_dir = skills_dir
self._cache = {}
@lru_cache(maxsize=50)
def load_skill(self, skill_name: str) -> Skill:
"""首次访问时加载,之后使用缓存"""
skill_path = self.skills_dir / f"{skill_name}.md"
return Skill.parse_file(skill_path)
def invalidate(self, skill_name: str):
"""技能更新后清除缓存"""
self._cache.pop(skill_name, None)
self.load_skill.cache_clear()
十、总结:Hermes-Agent 代表的工程哲学
它做对了什么
- 三层记忆体系:用 SQLite + FTS5 实现零运维的持久化记忆,不依赖额外服务
- 闭环学习:从经验中生成技能,技能又反过来提升执行效率,形成正向飞轮
- 务实的技术选型:不用花哨的向量数据库,不用重型微服务架构,用单文件 SQLite 和纯文本 Skill 文件降低了门槛
- 真正的本地优先:Ollama 原生集成,所有数据本地存储,隐私完全可控
- 模型无关设计:Provider 抽象层让切换模型零感知,200+ 模型自由选择
它面临的挑战
- Python 性能瓶颈:对于高并发、高吞吐场景,GIL 限制了并行能力
- Skill 质量控制:自动生成的 Skill 需要人工审核,防止错误知识固化
- 大规模多 Agent 协作:当前以单 Agent 为主,多 Agent 协作能力尚在演进
未来展望
Hermes-Agent 正在成为 2026 年最具代表性的开源 AI Agent 之一。它证明了一个核心观点:AI Agent 的价值不只是"能帮你做事",更是"能记住怎么做事"。随着项目在多 Agent 协作、模型蒸馏、Skill 自动化质量控制等方向的持续迭代,它有望成为本地 AI 工作流的标配工具。
对于每个追求效率的开发者来说,花 30 分钟装好 Hermes-Agent + Ollama,让它陪你处理一个真实任务——你会发现,这可能是你今年最值得的一次技术投入。
参考项目:
- GitHub: NousResearch/hermes-agent (MIT License, 10万+ Star)
- Nous Research 官网: nousresearch.ai
- Ollama: ollama.com(本地 LLM 运行时)