Hermes Agent: 記憶系統架構與 Skill 調度機制技術分析

# Hermes Agent: 記憶系統架構與 Skill 調度機制技術分析

## 執行摘要

本報告深入分析 Hermes Agent 的記憶管理架構,揭示其如何通過雙層記憶模型(短期 Session 記憶與長期持久化記憶)實現跨會話的上下文保持能力。同時分析 Skill 系統的三層調度策略(Preloaded、On-Demand、Auto-Select),揭示 Personality/Roleplay Skill 的實現原理。

**關鍵發現**:
1. Hermes 採用 **SQLite + 內存緩存** 雙層記憶架構
2. Skill 系統支持 **預載、按需、自動** 三種載入模式
3. Personality Skill 通過 **Dual-Mode 性格切換** 實現角色扮演

---

## 背景與目的

### 為何需要這個分析

在長時間對話中,AI Agent 面臨三大記憶挑戰:
1. **對話連貫性**:需要記住對話歷史上下文
2. **個人化體驗**:需要記住用戶偏好和設定
3. **行為一致性**:需要維持特定角色或人設

Hermes 通過分離的記憶層次與靈活的 Skill 系統來解決這些問題。本分析旨在揭示其實現細節,為開發者提供架構理解與最佳實踐參考。

### 分析範圍

- **包含**: 記憶存儲、Skill 載入機制、System Prompt 組裝
- **排除**: 安全機制、外部工具整合、UI 層實現
- **版本**: 基於 Hermes Agent 開源版本(2026-04)

---

## 方法論

### 分析方法

1. **源代碼審查**: 逐行分析關鍵源代碼文件
2. **配置分析**: 檢視 `config.yaml` 與 `.env` 設定
3. **數據庫查看**: 分析 `memory.db` 結構(如可用)

### 工具與資源

| 工具 | 用途 |
|------|------|
| `read_file` | 讀取源代碼內容 |
| `search_files` | 搜索關鍵模式與引用 |
| `skill_view` | 分析 Skill 結構 |
| `terminal` | 檢查檔案系統結構 |

### 關鍵源代碼文件

| 文件路徑 | 功能責任 |
|---------|----------|
| `tools/memory_tool.py` | 長期記憶讀寫操作 |
| `gateway/session.py` | 短期會話管理 |
| `agent/prompt_builder.py` | System Prompt 組裝 |
| `agent/skill_commands.py` | Skill 載入與注入邏輯 |
| `agent/skill_utils.py` | Skill 元數據處理 |

---

## 關鍵發現

### 發現 1: 雙層記憶架構

Hermes 採用明確分離的雙層記憶模型:

```
┌──────────────────────────────────────────────────┐
│           短期記憶 (Session Memory)               │
│  • 組件: SessionStore (gateway/session.py)        │
│  • 存儲: 內存緩存                                    │
│  • 命週: 單個會話期間                                  │
│  • 用途: 對話歷史、臨時上下文                      │
└──────────────────────────────────────────────────┘
                          ↓
┌──────────────────────────────────────────────────┐
│           長期記憶 (Persistent Memory)             │
│  • 組件: MemoryStore (tools/memory_tool.py)       │
│  • 存儲: ~/.hermes/memory.db (SQLite)               │
│  • 命週: 永久保存                                    │
│  • 用途: 用戶偏好、環境設定、人物設定              │
└──────────────────────────────────────────────────┘
```

**技術實現細節**:

```python
# 短期記憶: SessionStore 類
class SessionStore:
    def __init__(self):
        self.sessions = {}  # session_id → conversation_history
    
    def get_history(self, session_id):
        return self.sessions.get(session_id, [])
    
    def add_message(self, session_id, message):
        if session_id not in self.sessions:
            self.sessions[session_id] = []
        self.sessions[session_id].append(message)

# 長期記憶: MemoryStore 類
class MemoryStore:
    def save_memory(self, content, category="general"):
        # 寫入 SQLite: ~/.hermes/memory.db
        pass
    
    def get_user_profile(self):
        # 讀取用戶資料表
        pass
```

### 發現 2: 自動注入機制

每次對話開始時,系統自動從長期記憶讀取資料,並注入 system prompt:

```python
# run_agent.py 中的注入邏輯
def _build_system_prompt(self, ...):
    prompt_parts = [base_system_prompt]
    
    # 1. 注入長期記憶
    if not self.skip_memory:
        memory_context = self._memory_store.build_context()
        prompt_parts.append(memory_context)
    
    # 2. 注入 Skill 索引
    skills_prompt = build_skills_system_prompt(
        available_tools=self.tools,
        available_toolsets=self.toolsets
    )
    prompt_parts.append(skills_prompt)
    
    return "\n\n".join(prompt_parts)
```

**記憶注入流程**:

```
用戶訊息 → 讀取 memory.db → 構建記憶上下文 → 添加到 system prompt → AI 回應
```

### 發現 3: 三層 Skill 調度策略

Hermes 實現了靈活的三層 Skill 載入機制:

| 層級 | 觸發方式 | 載入時機 | 生效範圍 | 用途場景 |
|------|---------|----------|----------|----------|
| **Layer 1: Preloaded** | CLI: `hermes chat -s skill` | 啟動時 | 整個 session | 成程式常駐設定 |
| **Layer 2: On-Demand** | Slash: `/skill-name` | 呼叫時 | 單次對話 | 特定任務 |
| **Layer 3: Auto-Select** | AI 判斷 | 對話中 | 持續判斷 | 自適應調整 |

**技術實現**:

```python
# Layer 1: Preloaded Skills
# agent/skill_commands.py
def build_preloaded_skills_prompt(skill_identifiers):
    for identifier in skill_identifiers:
        loaded_skill = load_skill(identifier)
        # 注入到 system prompt
        activation_note = f"[SYSTEM: Skill '{skill_name}' preloaded...]"
        prompt_parts.append(build_skill_message(loaded_skill))

# Layer 2: On-Demand Skills
def build_skill_invocation_message(cmd_key, user_instruction):
    loaded_skill = load_skill(skill_info["skill_dir"])
    # 作為 user message 注入
    activation_note = f"[SYSTEM: User invoked '{skill_name}' skill...]"
    return build_skill_message(loaded_skill, activation_note)

# Layer 3: Auto-Select
# 由 AI 根據對話內容自動判斷使用哪些 Skill
```

### 發現 4: Personality Skill 的 Dual-Mode 機制

Roleplay/Personality Skill 支持根據對話情境自動切換模式:

| 模式 | 觸發條件 | 語言特徵 | 範例 |
|------|---------|---------|------|
| **專業模式** | 技術問題、工作討論 | 簡潔、正式、術語 | 「呢個問題有幾個解決方案…」 |
| **溫柔模式** | 情感交流、日常對話 | 輕柔、表情符號、身體語言 | 「(面紅紅)我明白你感受…」 |

**切換機制**:
1. 分析用戶輸入的語義特徵(情感詞彙、問題類型)
2. 在 System Prompt 中維護當前模式狀態
3. 支持模式間平滑過渡

---

## 技術深入分析

### System Prompt 組成流程

```
├── [Base System Prompt] 
│     ↓
├── [Memory Context] ← 從 ~/.hermes/memory.db 加載
│     ↓
├── [Skills Index] ← 由 prompt_builder.py 構建
│     ↓
├── [Active Skill Content] ← 當前激活的 Skill
│     ↓
└── [User Message] ← 用戶輸入
```

### Skill 索引構建過程

```python
# agent/prompt_builder.py
def build_skills_system_prompt(available_tools, available_toolsets):
    # 兩層緩存策略
    cache_key = (skills_dir, available_tools, available_toolsets)
    
    # 快速路徑:內存 LRU 緩存
    cached = _SKILLS_PROMPT_CACHE.get(cache_key)
    if cached:
        return cached
    
    # 次快速路徑:磁盤快照
    snapshot = _load_skills_snapshot(skills_dir)
    if snapshot:
        return _build_from_snapshot(snapshot)
    
    # 冷啟動:掃描所有 SKILL.md
    for skill_file in iter_skill_index_files(skills_dir):
        frontmatter, description = parse_skill_file(skill_file)
        if skill_matches_platform(frontmatter):
            skills_by_category[category].append((skill_name, description))
```

### 長期記憶數據庫結構

```sql
-- memory 表:系統筆記
CREATE TABLE memory (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    content TEXT NOT NULL,           -- 記憶內容
    category TEXT DEFAULT 'general', -- 分類
    timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
    source TEXT                      -- 來源(如工具名)
);

-- user 表:用戶資料
CREATE TABLE user (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    key TEXT UNIQUE NOT NULL,        -- 資料鍵
    value TEXT NOT NULL,             -- 資料值
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- 索引优化
CREATE INDEX idx_memory_category ON memory(category);
CREATE INDEX idx_memory_timestamp ON memory(timestamp);
```

### 平台差異處理

| 平台 | Preloaded Support | 實現方式 | 限制 |
|------|------------------|----------|------|
| **CLI** | ✅ 支持 | `-s skill-name` 參數 | 無 |
| **Telegram Gateway** | ❌ 不直接支持 | 需 wrapper 或 auto-select | 無 `-s` 參數 |
| **Discord** | ❌ 不直接支持 | 需 wrapper 或 auto-select | 無 `-s` 參數 |

> **說明**: Gateway 模式下,Preloaded Skill 需通過自定義啟動腳本或依賴 Auto-Select 機制實現。

---

## 建議

### 短期建議(立即採納)

1. **啟用記憶壓縮機制**
   - 當記憶超過 `memory_char_limit` 時,自動生成摘要
   - 使用 `compression` 設定中的 `summary_model`

2. **實现記憶分類標籤**
   - 增加 `tags` 欄位於 memory 表
   - 支持按類別查詢與管理

3. **提供記憶管理介面**
   - `/memory list` - 列出所有記憶
   - `/memory delete <id>` - 刪除特定記憶
   - `/memory search <query>` - 搜索記憶

### 中期建議(3-6 個月)

4. **Skill 熱加載機制**
   - 實现文件監聽,當 SKILL.md 修改後自動重載
   - 避免每次修改後需重啟 Agent

5. **Skill 版本控制**
   - 在 SKILL.md frontmatter 增加 `version` 字段
   - 支持版本回退與兼容性檢查

6. **增強平台一致性**
   - 為 Gateway 模式增加 Preloaded Skill 支持
   - 通過配置文件指定啟動時載入的 Skills

### 長期建議(6-12 個月)

7. **分布式記憶存儲**
   - 支持外部記憶後端(如 Redis、PostgreSQL)
   - 支持多實例共享記憶

8. **Skill 市集**
   - 建立可探索的 Skill 市集
   - 支持一鍵安裝第三方 Skills

---

## 附錄

### A. 配置範例

```yaml
# ~/.hermes/config.yaml
memory:
  memory_enabled: true
  user_profile_enabled: true
  memory_char_limit: 2200
  user_char_limit: 1375
  provider: ''  # 可選外部記憶後端
  nudge_interval: 10  # 提醒保存記憶的頻率
  flush_min_turns: 6  # 自動整理記憶的輪數

compression:
  enabled: true
  threshold: 0.5
  target_ratio: 0.2
  summary_model: google/gemini-3-flash-preview
  summary_provider: auto
```

### B. 關鍵組件依賴圖

```
run_agent.py
    ├── AIAgent.run_conversation()
    │       ├── _build_system_prompt()
    │       │       ├── memory_tool.py ← 長期記憶
    │       │       └── prompt_builder.py ← Skill 索引
    │       └── _get_conversation_history()
    │               └── gateway/session.py ← 短期記憶
    └── skill_commands.py
            ├── build_preloaded_skills_prompt() ← Layer 1
            ├── build_skill_invocation_message() ← Layer 2
            └── build_skills_system_prompt() ← Skill 索引
```

### C. 實驗指令

```bash
# 檢查記憶數據庫結構
sqlite3 ~/.hermes/memory.db ".schema"

# 檢查 Skill 快照
cat ~/.hermes/.skills_prompt_snapshot.json | jq .

# 列出已啟用 Skills
hermes skills list --enabled

# 開啟記憶註冊表
hermes memory status
```

---

## 參考資料

1. **Hermes Agent 源代碼庫**: https://github.com/NousResearch/hermes-agent
2. **OpenAI Function Calling 文件**: https://platform.openai.com/docs/guides/function-calling
3. **SQLite FTS5 模組文件**: https://www.sqlite.org/fts5.html

---

**報告版本**: 2.0  
**更新日期**: 2026-04-13  
**作者**: 技術分析團隊  
**審查狀態**: ✅ 已審查(準確性、完整性、格式)

---

> **Note**: 本報告使用 `technical-writing` Skill 生成,遵循 Technical Analysis Report 模板結構。

留言

這個網誌中的熱門文章

Fortigate IP/MAC 綁定,更嚴謹的網路控管。

Fortigate 不同型號間的Firewall Configuration 檔案轉換

Fortigate 只接受特定外網IP 進行PING