深度拆解 HermesAgent(五):记忆系统与用户建模

深度拆解 HermesAgent(五):记忆系统与用户建模 ------ AI Agent 如何"记住"你

系列导读 :本文是 [HermesAgent 深度拆解系列](#HermesAgent 深度拆解系列) 的第五篇。记忆是 Agent 跨会话连续性的基石。本文将深入分析 HermesAgent 的多层记忆架构、会话搜索机制,以及基于 Honcho 的辩证用户建模系统。

上一篇 :[多终端后端与 Gateway 网关](#多终端后端与 Gateway 网关) | 下一篇研究功能与测试体系


一、为什么记忆系统是 AI Agent 的"生死线"?

想象一下你的手机每天晚上都会重置所有数据------联系人、聊天记录、设置、照片全部清空。你还能正常使用吗?

大多数 AI Agent 目前就处于这种"每晚失忆"的状态。每次对话结束,一切归零。

HermesAgent 的 Nous Research 团队深刻理解这个问题,设计了五层记忆架构来解决这个问题。


二、五层记忆架构

复制代码
┌───────────────────────────────────────────────────┐
│                   记忆金字塔                        │
│                                                   │
│            ┌───────────────┐                      │
│            │   L5: 技能记忆  │  从经验中提取的可复用技能  │
│            │  ~/.hermes/   │                      │
│            │   skills/     │                      │
│            ├───────────────┤                      │
│            │ L4: 用户建模   │  跨会话用户画像         │
│            │  (Honcho)     │                      │
│            ├───────────────┤                      │
│            │ L3: Agent策展  │  Agent自主决定保存的知识  │
│            │  ~/.hermes/   │                      │
│            │   memory/     │                      │
│            ├───────────────┤                      │
│            │ L2: 会话搜索   │  FTS5 + LLM 跨会话回忆  │
│            ├───────────────┤                      │
│            │ L1: 会话记忆   │  SQLite 对话记录        │
│            │  (SessionDB)  │                      │
│            └───────────────┘                      │
└───────────────────────────────────────────────────┘

第一层:会话记忆(SessionDB)

实现hermes_state.py 中的 SessionDB

这是最基础的记忆层------原始的对话记录。所有对话都被完整保存到 SQLite 数据库:

python 复制代码
# hermes_state.py 简化示意
class SessionDB:
    def __init__(self, db_path: str):
        self.conn = sqlite3.connect(db_path)
        self._init_tables()
        self._init_fts5()  # 初始化全文搜索引擎
    
    def save_message(self, session_id: str, role: str, content: str):
        """保存一条消息"""
        self.conn.execute(
            "INSERT INTO messages (session_id, role, content, timestamp) VALUES (?,?,?,?)",
            (session_id, role, content, time.time())
        )
        self.conn.commit()
    
    def get_history(self, session_id: str, limit: int = 50) -> list[dict]:
        """获取会话历史"""
        rows = self.conn.execute(
            "SELECT role, content FROM messages WHERE session_id=? ORDER BY timestamp DESC LIMIT ?",
            (session_id, limit)
        ).fetchall()
        return [{"role": r[0], "content": r[1]} for r in reversed(rows)]

存储位置~/.hermes/sessions.db

特点

  • ✅ 完整保存所有对话
  • ✅ 支持按 session_id 隔离
  • ✅ 零外部依赖(SQLite 内置于 Python)
  • ✅ 内置 FTS5 全文搜索

第二层:会话搜索(FTS5 + LLM 摘要)

光有保存还不够,还需要能检索。HermesAgent 使用 SQLite FTS5 实现全文搜索,再结合 LLM 做语义摘要:

python 复制代码
class SessionDB:
    def search_sessions(self, query: str, limit: int = 10) -> list[dict]:
        """跨会话全文搜索"""
        # FTS5 全文搜索
        rows = self.conn.execute("""
            SELECT session_id, role, content, rank
            FROM messages_fts
            WHERE messages_fts MATCH ?
            ORDER BY rank
            LIMIT ?
        """, (query, limit)).fetchall()
        
        # LLM 语义摘要(可选)
        if rows and self.auxiliary_client:
            context = "\n".join([r[2] for r in rows])
            summary = self.auxiliary_client.summarize(
                f"用户问题: {query}\n\n相关对话:\n{context}",
                max_tokens=500
            )
            return {"summary": summary, "sources": rows}
        
        return rows

搜索流程

复制代码
用户: "上次我们讨论的那个部署方案是什么来着?"
    │
    ▼
提取关键词: ["部署", "方案"]
    │
    ▼
FTS5 搜索: MATCH '部署 方案'
    │
    ▼
找到 5 条相关历史消息
    │
    ▼
LLM 摘要: "你们上次讨论了三种部署方案:
           1. Docker Compose(推荐)
           2. Kubernetes(适合生产)
           3. 裸机部署(成本最低)"
    │
    ▼
注入当前对话上下文 → Agent 基于历史回答

第三层:Agent 策展记忆

这是 HermesAgent 最独特的设计------Agent 自己决定什么值得记住

复制代码
~/.hermes/memory/
├── long_term/          # 长期记忆文件
│   ├── project_setup.md
│   ├── deployment_prefs.md
│   └── coding_style.md
└── short_term/         # 短期记忆(近期摘要)
    └── recent_context.md

策展流程

  1. 定期 Nudge:系统定时向 Agent 发送"整理记忆"的提醒
  2. 评估价值:Agent 回顾近期交互,评估哪些信息有持久化价值
  3. 提取知识:将碎片化信息提炼为结构化知识
  4. 写入文件 :保存到 ~/.hermes/memory/long_term/
python 复制代码
# agent/memory_manager.py 简化示意
class MemoryManager:
    async def curate_memories(self, user_id: str):
        """Agent 策展记忆"""
        # 获取近期未处理的消息
        recent = self.session_db.get_recent_unprocessed(user_id)
        
        if not recent:
            return
        
        # 让 Agent 评估并提取有价值的信息
        prompt = f"""
        回顾以下近期对话,提取值得长期记住的信息:
        
        {format_conversations(recent)}
        
        请输出 JSON 格式:
        {{
            "memories": [
                {{
                    "topic": "主题",
                    "content": "具体内容",
                    "importance": "high/medium/low"
                }}
            ]
        }}
        """
        
        response = await self.llm.generate(prompt)
        memories = parse_memories(response)
        
        # 保存到长期记忆
        for memory in memories:
            await self.save_long_term_memory(user_id, memory)

第四层:Honcho 用户建模

集成 Honcho 辩证用户建模系统:

复制代码
┌──────────────┐     ┌──────────────┐
│  当前用户画像  │ ←→  │  新的观察证据  │
│  (Thesis)    │     │ (Antithesis) │
└──────┬───────┘     └──────┬───────┘
       │                     │
       └──────→ 合成 ←──────┘
              (Synthesis)
                  │
                  ▼
           ┌──────────────┐
           │ 更新后的用户画像│
           └──────────────┘

用户画像持续深化

复制代码
第 1 次对话 → {"role": "开发者", "language": "Python"}
第 5 次对话 → {"role": "后端开发者", "language": "Python", 
              "framework": "FastAPI", "style": "务实"}
第 20 次对话 → {"role": "AI 方向创业者", "language": "Python",
               "focus": "AI Agent", "company": "Avatime 超我科技",
               "style": "务实、不喜欢过度工程化",
               "working_hours": "主要在白天", ...}

第五层:技能记忆

这不是传统的"记忆",而是从经验中提取的可复用技能 。我们已在第二篇中详细分析,这里不再展开。


三、记忆上下文注入

所有层级的记忆最终都需要注入到 Agent 的系统提示词中,才能影响 Agent 的行为:

python 复制代码
# agent/prompt_builder.py 简化示意
class PromptBuilder:
    def build_system_prompt(self, user_id: str, platform: str) -> str:
        parts = []
        
        # 1. 基础系统提示词
        parts.append(BASE_SYSTEM_PROMPT)
        
        # 2. 用户画像(Honcho)
        user_profile = self.honcho.get_user_profile(user_id)
        if user_profile:
            parts.append(f"\n## 关于当前用户\n{user_profile}")
        
        # 3. 长期记忆
        long_term = self.memory_manager.get_relevant_memories(user_id)
        if long_term:
            parts.append(f"\n## 你记住的重要信息\n{long_term}")
        
        # 4. 活跃技能
        active_skills = self.skills_manager.get_active_skills()
        if active_skills:
            parts.append(f"\n## 你掌握的技能\n{active_skills}")
        
        # 5. 平台特定指令
        if platform == "cli":
            parts.append(CLI_SPECIFIC_INSTRUCTIONS)
        elif platform == "telegram":
            parts.append(TELEGRAM_SPECIFIC_INSTRUCTIONS)
        
        return "\n".join(parts)

四、上下文压缩

随着记忆增多,上下文窗口可能不够用。HermesAgent 通过 agent/context_compressor.py 实现自动上下文压缩

python 复制代码
class ContextCompressor:
    async def compress(self, messages: list[dict], max_tokens: int) -> list[dict]:
        """压缩对话历史以适应上下文窗口"""
        current_tokens = estimate_tokens(messages)
        
        if current_tokens <= max_tokens:
            return messages  # 不需要压缩
        
        # 策略:保留最近的 N 条消息 + 压缩更早的消息
        recent = messages[-10:]  # 最近 10 条完整保留
        older = messages[:-10]
        
        if older:
            # 用 LLM 压缩旧消息
            summary = await self.auxiliary_client.summarize(
                format_messages(older), max_tokens=500
            )
            compressed = [{"role": "system", "content": f"[历史对话摘要] {summary}"}]
            return compressed + recent
        
        return messages

此外还支持 Anthropic 提示词缓存agent/prompt_caching.py),对于重复的系统提示词部分可以利用 API 缓存减少 token 成本。


五、存储设计

5.1 文件系统布局

复制代码
~/.hermes/
├── config.yaml           # 用户配置
├── .env                  # API 密钥
├── sessions.db           # SQLite 会话数据库(含 FTS5 索引)
├── memory/               # Agent 策展记忆
│   ├── short_term/
│   └── long_term/
├── skills/               # 技能文件
│   └── *.md
├── skins/                # CLI 皮肤
└── profiles/             # 多实例配置
    ├── work/
    └── personal/

5.2 Profile 隔离

HermesAgent 支持通过 HERMES_HOME 环境变量实现完全隔离的多实例:

bash 复制代码
# 工作实例
HERMES_HOME=~/.hermes/profiles/work hermes

# 个人实例
HERMES_HOME=~/.hermes/profiles/personal hermes

代码中有 119+ 处 引用 get_hermes_home() 确保路径隔离,这意味着每个 Profile 有完全独立的:

  • 会话记录
  • 记忆文件
  • 技能
  • 配置
  • 用户画像

六、与 OpenClaw 记忆系统的初步对比

(完整的对比分析将在后续专题文章中展开)

维度 HermesAgent OpenClaw
存储 SQLite + 文件系统 多种后端(SQL/向量DB)
搜索 FTS5 + LLM 摘要 向量搜索 (LanceDB)
用户建模 Honcho 辩证建模 无显式用户建模
Agent 策展 ✅ Agent 自主决定 ❌ 规则驱动
上下文压缩 ✅ 自动压缩 ✅ 自动管理
多实例隔离 HERMES_HOME Profile 多 Profile 支持
技能作为记忆 ✅ 从经验提取技能 ❌ 无技能系统

七、对 Avagent 的启示

1. 五层记忆是"数字分身"的基础设施

如果 Avatime 的愿景是"让每个人拥有 AI 数字分身",那记忆系统就是分身的"大脑"。HermesAgent 的五层架构提供了很好的参考框架。

2. Agent 策展 vs 规则驱动

让 Agent 自己决定"记住什么"比人类预设规则更灵活。但需要注意:

  • 设置遗忘机制,防止记忆过载
  • 记忆质量需要可审计(用户能查看 Agent 记住了什么)
  • 提供遗忘接口(用户能让 Agent "忘记"某些事)

3. FTS5 + LLM 摘要的混合策略

零额外依赖 + 语义理解,非常适合初期快速落地。后期可以升级为向量搜索。

4. 用户建模差异化

Honcho 的辩证建模是一个亮点。Avagent 可以考虑构建更贴合"数字分身"场景的用户建模------不仅记录偏好,还要建模行为模式、思维方式、表达风格


八、小结

HermesAgent 的记忆系统不是简单的"存取"机制,而是一个完整的"感知-记忆-回忆-策展"循环

  • 感知:从对话中提取信息
  • 存储:多层级的持久化
  • 回忆:FTS5 全文搜索 + LLM 语义摘要
  • 策展:Agent 自主决定什么值得记住
  • 建模:Honcho 持续深化用户画像

这种设计让 Agent 真正拥有了"连续性"------它不是每次都从零开始,而是带着之前的经验和对你的理解来面对每一次新的交互。

这,才是一个"数字分身"应该有的样子。


系列导航


本文基于 HermesAgent v0.10.0 源码分析,项目持续迭代中。

相关推荐
红色星际1 小时前
进军具身机器人和Robotaxi的智驾公司
大数据·人工智能·机器人
Bruce_Liuxiaowei1 小时前
《轻量化制播系统技术应用指南(2026版)》解读:县级融媒体的“减负增效“新路径
大数据·人工智能·媒体
IT届小白1 小时前
Medical-Qwen3-14B基于Ollama内网私有化部署方案
人工智能·大模型
pczpcz81 小时前
openclaw连接shopify
ai编程
2601_956139421 小时前
文旅行业品牌全案公司哪家强
大数据·人工智能·python
生活观察站1 小时前
中文在线亮相横琴—澳门国际数字艺术博览会国际数字创意论坛:AI漫剧打开内容创作新想象
大数据·人工智能
@PHARAOH1 小时前
WHAT - 大语言模型 Memory 系统设计入门
人工智能·语言模型·自然语言处理
新新学长搞科研1 小时前
【高质量能源会议推荐】第十一届能源与环境研究进展国际学术会议(ICAEER 2026)
人工智能·物联网·算法·机器学习·能源·环境·新能源
dfdfadffa1 小时前
如何创建仅在首次订阅时执行一次计算的 RxJS 懒加载 Observable
jvm·数据库·python