编程 Hermes-Agent 自进化 AI Agent 架构深度解析:三层记忆体系与闭环学习原理解密

2026-07-10 00:46:47 +0800 CST views 10

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 的出现,正是为了解决这两个根本性问题:

  1. 跨会话记忆的缺失:Agent 无法在多轮对话、多天使用中保持上下文连续性
  2. 经验无法积累:每次任务执行的结果无法固化为可复用的技能

它的 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:8b8B~45~6GB VRAM
qwen2.5:14b14B~28~12GB VRAM
phi3:mini3.8B~62~4GB VRAM

对于日常的文本处理、代码生成任务,8B 模型(llama3:8b)在速度和效果上取得了良好的平衡。


七、与主流框架横向对比

维度Hermes-AgentLangChainAutoGPTCrewAI
自进化能力✅ 闭环学习❌ 无❌ 无❌ 无
三层记忆✅ 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 代表的工程哲学

它做对了什么

  1. 三层记忆体系:用 SQLite + FTS5 实现零运维的持久化记忆,不依赖额外服务
  2. 闭环学习:从经验中生成技能,技能又反过来提升执行效率,形成正向飞轮
  3. 务实的技术选型:不用花哨的向量数据库,不用重型微服务架构,用单文件 SQLite 和纯文本 Skill 文件降低了门槛
  4. 真正的本地优先:Ollama 原生集成,所有数据本地存储,隐私完全可控
  5. 模型无关设计:Provider 抽象层让切换模型零感知,200+ 模型自由选择

它面临的挑战

  1. Python 性能瓶颈:对于高并发、高吞吐场景,GIL 限制了并行能力
  2. Skill 质量控制:自动生成的 Skill 需要人工审核,防止错误知识固化
  3. 大规模多 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 运行时)

推荐文章

Python 基于 SSE 实现流式模式
2025-02-16 17:21:01 +0800 CST
nuxt.js服务端渲染框架
2024-11-17 18:20:42 +0800 CST
JS中 `sleep` 方法的实现
2024-11-19 08:10:32 +0800 CST
微信内弹出提示外部浏览器打开
2024-11-18 19:26:44 +0800 CST
20个超实用的CSS动画库
2024-11-18 07:23:12 +0800 CST
程序员茄子在线接单