知识模块
🤖 Agent 知识模块
长期记忆

长期记忆

长期记忆是 Agent 的"知识库",实现跨会话的信息持久化存储。它使 Agent 能够记住用户偏好、积累领域知识、复用历史经验,是智能体持续进化的基础。


一、什么是长期记忆?

1.1 定义

长期记忆(Long-Term Memory) 是 Agent 将信息持久化存储到外部存储系统中的机制,生命周期跨越多个会话,支持按需检索和更新。

1.2 核心特征

┌─────────────────────────────────────────────────────────────┐
│                    长期记忆核心特征                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  存储位置:外部存储(向量数据库、关系数据库)         │   │
│  │  生命周期:永久                                       │   │
│  │  容量限制:理论上无限制                               │   │
│  │  访问方式:需要检索后注入到短期记忆                   │   │
│  │  访问速度:毫秒到秒级(取决于存储和检索方式)         │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  典型内容:                                                 │
│  • 用户画像和偏好设置                                        │
│  • 历史对话记录和关键信息                                    │
│  • 领域知识库和文档                                          │
│  • 任务状态和执行记录                                        │
│  • 学习到的经验和规则                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

1.3 与短期记忆的关系

┌─────────────────────────────────────────────────────────────┐
│                  短期记忆与长期记忆的协作                    │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│                    ┌─────────────┐                          │
│                    │  用户输入   │                          │
│                    └──────┬──────┘                          │
│                           │                                 │
│                           ↓                                 │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                    检索长期记忆                       │  │
│  │  • 根据用户ID获取偏好                                │  │
│  │  • 语义检索相关历史知识                              │  │
│  └──────────────────────┬───────────────────────────────┘  │
│                         │                                  │
│                         ↓                                  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                    注入短期记忆                       │  │
│  │  • 将检索结果加入 Context Window                     │  │
│  │  • 与当前对话上下文合并                              │  │
│  └──────────────────────┬───────────────────────────────┘  │
│                         │                                  │
│                         ↓                                  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                    LLM 推理                          │  │
│  └──────────────────────┬───────────────────────────────┘  │
│                         │                                  │
│                         ↓                                  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                    写入长期记忆                       │  │
│  │  • 提取重要信息持久化                                │  │
│  │  • 更新用户画像                                      │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

二、长期记忆的分类

2.1 按内容类型分类

类型说明存储方式示例
用户画像用户的属性和偏好关系型数据库语言偏好、沟通风格、兴趣领域
对话记忆历史对话记录向量数据库重要对话、用户说过的话
知识记忆领域知识和文档向量数据库产品文档、技术手册、FAQ
经验记忆学习到的经验规则关系型数据库成功案例、失败教训、最佳实践
任务记忆任务执行状态关系型数据库进行中的任务、中间结果

2.2 按存储结构分类

┌─────────────────────────────────────────────────────────────┐
│                    长期记忆存储分类                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │              向量数据库 (Vector Database)              │ │
│  │                                                       │ │
│  │  特点:                                               │ │
│  │  • 存储文本的向量表示(Embedding)                     │ │
│  │  • 支持语义相似度检索                                  │ │
│  │  • 适合非结构化文本记忆                                │ │
│  │                                                       │ │
│  │  适用场景:                                           │ │
│  │  • 对话历史存储                                       │ │
│  │  • 知识库问答                                         │ │
│  │  • 语义搜索                                           │ │
│  │                                                       │ │
│  │  代表产品:Chroma, Milvus, Pinecone, Weaviate        │ │
│  └───────────────────────────────────────────────────────┘ │
│                                                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │            关系型数据库 (Relational Database)          │ │
│  │                                                       │ │
│  │  特点:                                               │ │
│  │  • 存储结构化数据                                      │ │
│  │  • 支持复杂 SQL 查询                                   │ │
│  │  • 支持 ACID 事务                                      │ │
│  │                                                       │ │
│  │  适用场景:                                           │ │
│  │  • 用户画像管理                                       │ │
│  │  • 任务状态跟踪                                       │ │
│  │  • 精确数据查询                                       │ │
│  │                                                       │ │
│  │  代表产品:PostgreSQL, MySQL, SQLite                  │ │
│  └───────────────────────────────────────────────────────┘ │
│                                                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │            图数据库 (Graph Database)                   │ │
│  │                                                       │ │
│  │  特点:                                               │ │
│  │  • 存储实体和关系                                      │ │
│  │  • 支持图遍历查询                                      │ │
│  │  • 适合复杂关系网络                                    │ │
│  │                                                       │ │
│  │  适用场景:                                           │ │
│  │  • 知识图谱                                           │ │
│  │  • 实体关系记忆                                       │ │
│  │                                                       │ │
│  │  代表产品:Neo4j, NebulaGraph                         │ │
│  └───────────────────────────────────────────────────────┘ │
│                                                             │
└─────────────────────────────────────────────────────────────┘

三、向量数据库详解

3.1 向量数据库原理

┌─────────────────────────────────────────────────────────────┐
│                    向量数据库工作原理                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 文本向量化                                              │
│     ┌─────────────────────────────────────────────────┐    │
│     │   "用户喜欢简洁的回答"                           │    │
│     │           ↓                                      │    │
│     │   Embedding Model (如 text-embedding-3-small)   │    │
│     │           ↓                                      │    │
│     │   [0.023, -0.145, 0.678, ..., 0.234]            │    │
│     │   1536 维向量                                    │    │
│     └─────────────────────────────────────────────────┘    │
│                                                             │
│  2. 向量存储                                                │
│     ┌─────────────────────────────────────────────────┐    │
│     │   向量数据库存储:                                │    │
│     │   ID: "mem_001"                                  │    │
│     │   Vector: [0.023, -0.145, ...]                  │    │
│     │   Metadata: {"type": "preference", "user": "u1"}│    │
│     │   Document: "用户喜欢简洁的回答"                  │    │
│     └─────────────────────────────────────────────────┘    │
│                                                             │
│  3. 向量检索                                                │
│     ┌─────────────────────────────────────────────────┐    │
│     │   Query: "用户的沟通风格"                        │    │
│     │           ↓                                      │    │
│     │   Query Vector: [0.034, -0.123, ...]            │    │
│     │           ↓                                      │    │
│     │   计算相似度 (余弦相似度/欧氏距离)                │    │
│     │           ↓                                      │    │
│     │   返回最相似的 Top-K 个结果                      │    │
│     └─────────────────────────────────────────────────┘    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

3.2 Chroma 实战示例

基础用法

import chromadb
from chromadb.utils import embedding_functions
 
# 初始化客户端(内存模式)
client = chromadb.Client()
 
# 或持久化到磁盘
# client = chromadb.PersistentClient(path="./chroma_db")
 
# 使用 OpenAI Embedding
openai_ef = embedding_functions.OpenAIEmbeddingFunction(
    api_key="your-api-key",
    model_name="text-embedding-3-small"
)
 
# 创建集合
collection = client.create_collection(
    name="agent_memory",
    embedding_function=openai_ef,
    metadata={"description": "Agent 长期记忆存储"}
)

存储记忆

# 存储用户偏好
collection.add(
    documents=[
        "用户偏好使用中文进行交流",
        "用户喜欢简洁的技术回答",
        "用户关注 Python 和机器学习领域"
    ],
    metadatas=[
        {"type": "preference", "category": "language", "user_id": "user_123"},
        {"type": "preference", "category": "style", "user_id": "user_123"},
        {"type": "preference", "category": "interest", "user_id": "user_123"}
    ],
    ids=["pref_1", "pref_2", "pref_3"]
)
 
# 存储对话记忆
collection.add(
    documents=[
        "用户询问了关于 RAG 技术的问题,表示对知识库检索很感兴趣",
        "用户正在开发一个 AI 助手项目,使用 LangChain 框架"
    ],
    metadatas=[
        {"type": "conversation", "date": "2024-01-15", "user_id": "user_123"},
        {"type": "context", "date": "2024-01-15", "user_id": "user_123"}
    ],
    ids=["conv_1", "ctx_1"]
)

检索记忆

# 语义检索
results = collection.query(
    query_texts=["用户的语言偏好是什么?"],
    n_results=3,
    where={"user_id": "user_123"}  # 元数据过滤
)
 
print(results)
# {
#   'documents': [['用户偏好使用中文进行交流', ...]],
#   'metadatas': [[{'type': 'preference', ...}, ...]],
#   'distances': [[0.12, 0.34, 0.45]]
# }
 
# 更新记忆
collection.update(
    ids=["pref_1"],
    documents=["用户偏好使用英文进行技术讨论,中文进行日常交流"],
    metadatas=[{"type": "preference", "category": "language", "user_id": "user_123", "updated": True}]
)
 
# 删除记忆
collection.delete(ids=["conv_1"])

3.3 LangChain 集成

from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
from langchain.memory import VectorStoreRetrieverMemory
from langchain.chains import ConversationChain
from langchain_openai import OpenAI
 
# 创建向量存储
embeddings = OpenAIEmbeddings()
vectorstore = Chroma(
    embedding_function=embeddings,
    persist_directory="./chroma_memory"
)
 
# 创建记忆检索器
retriever = vectorstore.as_retriever(
    search_kwargs={"k": 3}  # 返回最相似的3条记忆
)
 
# 创建向量记忆
memory = VectorStoreRetrieverMemory(retriever=retriever)
 
# 保存记忆
memory.save_context(
    {"input": "我叫小明,是一名 Python 开发者"},
    {"output": "你好小明!很高兴认识你。作为 Python 开发者,有什么我可以帮助你的吗?"}
)
 
memory.save_context(
    {"input": "我对机器学习很感兴趣"},
    {"output": "很好的兴趣方向!机器学习是 Python 最热门的应用领域之一..."}
)
 
# 在对话中使用
llm = OpenAI(temperature=0)
conversation = ConversationChain(
    llm=llm,
    memory=memory,
    verbose=True
)
 
# 提问会自动检索相关记忆
response = conversation.predict(input="你还记得我的职业吗?")
# 会检索到之前保存的"小明是一名 Python 开发者"

四、关系型数据库详解

4.1 适用场景

关系型数据库适合存储结构化的长期记忆:

┌─────────────────────────────────────────────────────────────┐
│                关系型数据库存储的记忆类型                    │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 用户画像表 (user_profiles)                              │
│     ┌─────────────────────────────────────────────────┐    │
│     │ user_id (PK) | preferences | created_at | ...   │    │
│     │ user_123     | {"lang":"zh"} | 2024-01-01 | ... │    │
│     └─────────────────────────────────────────────────┘    │
│                                                             │
│  2. 对话记录表 (conversation_history)                       │
│     ┌─────────────────────────────────────────────────┐    │
│     │ id | user_id | role | content | timestamp | ... │    │
│     │ 1  | user_123| user | 你好    | 2024-01-15 | ...│    │
│     └─────────────────────────────────────────────────┘    │
│                                                             │
│  3. 任务状态表 (task_states)                                │
│     ┌─────────────────────────────────────────────────┐    │
│     │ task_id | user_id | status | result | ...       │    │
│     │ task_1  | user_123| running| null   | ...       │    │
│     └─────────────────────────────────────────────────┘    │
│                                                             │
│  4. 经验知识表 (learned_rules)                              │
│     ┌─────────────────────────────────────────────────┐    │
│     │ id | rule | confidence | last_used | ...        │    │
│     │ 1  | "用户喜欢简洁回答"| 0.9 | 2024-01-15 | ... │    │
│     └─────────────────────────────────────────────────┘    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

4.2 SQLite 实战示例

import sqlite3
import json
from datetime import datetime
from typing import Optional, Dict, List
 
class RelationalMemoryStore:
    """关系型长期记忆存储"""
    
    def __init__(self, db_path: str = "agent_memory.db"):
        self.conn = sqlite3.connect(db_path)
        self.conn.row_factory = sqlite3.Row
        self._init_tables()
    
    def _init_tables(self):
        """初始化数据表"""
        cursor = self.conn.cursor()
        
        # 用户画像表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS user_profiles (
                user_id TEXT PRIMARY KEY,
                preferences JSON,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        
        # 重要记忆表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS important_memories (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id TEXT NOT NULL,
                memory_type TEXT NOT NULL,
                content TEXT NOT NULL,
                importance REAL DEFAULT 0.5,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                last_accessed TIMESTAMP,
                access_count INTEGER DEFAULT 0,
                FOREIGN KEY (user_id) REFERENCES user_profiles(user_id)
            )
        ''')
        
        # 创建索引
        cursor.execute('''
            CREATE INDEX IF NOT EXISTS idx_memory_user 
            ON important_memories(user_id)
        ''')
        cursor.execute('''
            CREATE INDEX IF NOT EXISTS idx_memory_type 
            ON important_memories(memory_type)
        ''')
        
        self.conn.commit()
    
    def save_user_preference(self, user_id: str, preferences: Dict):
        """保存用户偏好"""
        cursor = self.conn.cursor()
        cursor.execute('''
            INSERT OR REPLACE INTO user_profiles (user_id, preferences, updated_at)
            VALUES (?, ?, CURRENT_TIMESTAMP)
        ''', (user_id, json.dumps(preferences, ensure_ascii=False)))
        self.conn.commit()
    
    def get_user_preference(self, user_id: str) -> Optional[Dict]:
        """获取用户偏好"""
        cursor = self.conn.cursor()
        cursor.execute('''
            SELECT preferences FROM user_profiles WHERE user_id = ?
        ''', (user_id,))
        row = cursor.fetchone()
        if row:
            return json.loads(row['preferences'])
        return None
    
    def save_memory(self, user_id: str, memory_type: str, content: str, importance: float = 0.5):
        """保存重要记忆"""
        cursor = self.conn.cursor()
        cursor.execute('''
            INSERT INTO important_memories (user_id, memory_type, content, importance)
            VALUES (?, ?, ?, ?)
        ''', (user_id, memory_type, content, importance))
        self.conn.commit()
        return cursor.lastrowid
    
    def get_memories(self, user_id: str, memory_type: Optional[str] = None, limit: int = 10) -> List[Dict]:
        """获取记忆列表"""
        cursor = self.conn.cursor()
        
        if memory_type:
            cursor.execute('''
                SELECT * FROM important_memories 
                WHERE user_id = ? AND memory_type = ?
                ORDER BY importance DESC, created_at DESC
                LIMIT ?
            ''', (user_id, memory_type, limit))
        else:
            cursor.execute('''
                SELECT * FROM important_memories 
                WHERE user_id = ?
                ORDER BY importance DESC, created_at DESC
                LIMIT ?
            ''', (user_id, limit))
        
        return [dict(row) for row in cursor.fetchall()]
    
    def update_memory_access(self, memory_id: int):
        """更新记忆访问记录"""
        cursor = self.conn.cursor()
        cursor.execute('''
            UPDATE important_memories 
            SET last_accessed = CURRENT_TIMESTAMP, 
                access_count = access_count + 1
            WHERE id = ?
        ''', (memory_id,))
        self.conn.commit()
    
    def cleanup_old_memories(self, days: int = 90, min_importance: float = 0.3):
        """清理过时的低重要性记忆"""
        cursor = self.conn.cursor()
        cursor.execute('''
            DELETE FROM important_memories 
            WHERE importance < ? 
            AND datetime(created_at) < datetime('now', ?)
        ''', (min_importance, f'-{days} days'))
        deleted = cursor.rowcount
        self.conn.commit()
        return deleted
    
    def close(self):
        """关闭连接"""
        self.conn.close()

五、混合存储架构

5.1 架构设计

┌─────────────────────────────────────────────────────────────────────┐
│                    混合存储架构                                      │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│                     ┌─────────────────┐                             │
│                     │   记忆写入请求   │                             │
│                     └────────┬────────┘                             │
│                              │                                      │
│                              ↓                                      │
│                     ┌─────────────────┐                             │
│                     │   记忆分类器    │                             │
│                     └────────┬────────┘                             │
│                              │                                      │
│          ┌───────────────────┼───────────────────┐                 │
│          │                   │                   │                 │
│          ↓                   ↓                   ↓                 │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐           │
│   │ 结构化记忆  │    │ 非结构化记忆│    │ 关系记忆    │           │
│   │ (用户画像)  │    │ (对话内容)  │    │ (实体关系)  │           │
│   └──────┬──────┘    └──────┬──────┘    └──────┬──────┘           │
│          │                  │                  │                  │
│          ↓                  ↓                  ↓                  │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐           │
│   │   关系型    │    │   向量库    │    │   图数据库  │           │
│   │  Database   │    │  Vector DB  │    │  Graph DB   │           │
│   │  (SQLite)   │    │  (Chroma)   │    │   (Neo4j)   │           │
│   └─────────────┘    └─────────────┘    └─────────────┘           │
│                                                                     │
│                              │                                      │
│                              ↓                                      │
│                     ┌─────────────────┐                             │
│                     │   统一检索接口  │                             │
│                     └─────────────────┘                             │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

5.2 实现示例

from typing import List, Dict, Any, Optional
import chromadb
import sqlite3
import json
 
class HybridMemoryStore:
    """混合存储的长期记忆系统"""
    
    def __init__(self, sqlite_path: str = "memory.db", chroma_path: str = "./chroma"):
        # 初始化向量数据库
        self.vector_store = chromadb.PersistentClient(path=chroma_path)
        self.vector_collection = self.vector_store.get_or_create_collection(
            name="agent_memory"
        )
        
        # 初始化关系数据库
        self.rel_conn = sqlite3.connect(sqlite_path)
        self._init_rel_db()
    
    def _init_rel_db(self):
        """初始化关系数据库"""
        cursor = self.rel_conn.cursor()
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS user_profiles (
                user_id TEXT PRIMARY KEY,
                preferences JSON,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS entity_memories (
                id INTEGER PRIMARY KEY,
                user_id TEXT,
                entity_type TEXT,
                entity_name TEXT,
                attributes JSON,
                UNIQUE(user_id, entity_type, entity_name)
            )
        ''')
        self.rel_conn.commit()
    
    def save_memory(self, user_id: str, content: str, memory_type: str, metadata: Dict = None):
        """智能保存记忆到合适的存储"""
        metadata = metadata or {}
        metadata["user_id"] = user_id
        metadata["memory_type"] = memory_type
        
        # 结构化记忆存入关系数据库
        if memory_type in ["preference", "profile", "entity"]:
            self._save_to_rel_db(user_id, content, memory_type, metadata)
        
        # 所有记忆都存入向量数据库(支持语义检索)
        self._save_to_vector_db(content, metadata)
    
    def _save_to_rel_db(self, user_id: str, content: str, memory_type: str, metadata: Dict):
        """保存到关系数据库"""
        cursor = self.rel_conn.cursor()
        
        if memory_type == "preference":
            # 更新用户偏好
            cursor.execute('''
                INSERT OR REPLACE INTO user_profiles (user_id, preferences)
                VALUES (?, ?)
            ''', (user_id, content))
        
        elif memory_type == "entity":
            # 保存实体记忆
            cursor.execute('''
                INSERT OR REPLACE INTO entity_memories 
                (user_id, entity_type, entity_name, attributes)
                VALUES (?, ?, ?, ?)
            ''', (
                user_id, 
                metadata.get("entity_type", "unknown"),
                metadata.get("entity_name", ""),
                json.dumps(metadata, ensure_ascii=False)
            ))
        
        self.rel_conn.commit()
    
    def _save_to_vector_db(self, content: str, metadata: Dict):
        """保存到向量数据库"""
        doc_id = f"{metadata['user_id']}_{metadata['memory_type']}_{hash(content)}"
        self.vector_collection.add(
            documents=[content],
            metadatas=[metadata],
            ids=[doc_id]
        )
    
    def retrieve_memories(self, user_id: str, query: str, limit: int = 5) -> List[Dict]:
        """检索记忆(混合检索)"""
        results = []
        
        # 1. 从向量数据库检索(语义相似)
        vector_results = self.vector_collection.query(
            query_texts=[query],
            n_results=limit,
            where={"user_id": user_id}
        )
        
        if vector_results["documents"]:
            for i, doc in enumerate(vector_results["documents"][0]):
                results.append({
                    "content": doc,
                    "metadata": vector_results["metadatas"][0][i],
                    "score": 1 - vector_results["distances"][0][i],  # 转换为相似度
                    "source": "vector"
                })
        
        # 2. 从关系数据库检索(精确匹配)
        # 这里可以添加精确查询逻辑
        
        return results
    
    def get_user_profile(self, user_id: str) -> Optional[Dict]:
        """获取用户画像(从关系数据库)"""
        cursor = self.rel_conn.cursor()
        cursor.execute('''
            SELECT preferences FROM user_profiles WHERE user_id = ?
        ''', (user_id,))
        row = cursor.fetchone()
        if row:
            return json.loads(row[0])
        return None

六、长期记忆的管理策略

6.1 记忆生命周期管理

┌─────────────────────────────────────────────────────────────┐
│                    记忆生命周期                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐ │
│  │  创建   │ ─→ │  存储   │ ─→ │  检索   │ ─→ │  更新   │ │
│  │  Create │    │  Store  │    │Retrieve │    │  Update │ │
│  └─────────┘    └─────────┘    └─────────┘    └─────────┘ │
│       │              │              │              │       │
│       │              │              │              │       │
│       ↓              ↓              ↓              ↓       │
│  评估重要性      选择存储层      检索策略      更新策略     │
│  提取关键信息    元数据标注      排序过滤      冲突处理     │
│                                                            │
│                                            │               │
│                                            ↓               │
│                                     ┌─────────────┐       │
│                                     │   遗忘      │       │
│                                     │   Forget    │       │
│                                     └─────────────┘       │
│                                            │               │
│                                            ↓               │
│                                     TTL过期删除            │
│                                     LRU淘汰清理            │
│                                     低重要性清理           │
│                                                            │
└─────────────────────────────────────────────────────────────┘

6.2 记忆更新策略

class MemoryUpdateStrategy:
    """记忆更新策略"""
    
    @staticmethod
    def should_update(new_info: str, old_memory: str) -> bool:
        """判断是否需要更新记忆"""
        # 简化示例:实际应用中可用 LLM 判断
        # 如果新信息与旧记忆冲突,则需要更新
        return new_info != old_memory
    
    @staticmethod
    def merge_memories(old_memory: str, new_info: str, llm_client) -> str:
        """合并新旧记忆"""
        prompt = f"""
        旧记忆:{old_memory}
        新信息:{new_info}
        
        请将新旧信息合并为一条更新后的记忆。
        如果有冲突,以新信息为准。
        只输出合并后的记忆内容,不要解释。
        """
        # return llm_client.generate(prompt)
        return f"{old_memory}{new_info}"  # 简化实现
    
    @staticmethod
    def detect_conflict(new_info: str, existing_memories: List[str], llm_client) -> bool:
        """检测新信息是否与现有记忆冲突"""
        prompt = f"""
        现有记忆:
        {chr(10).join(f'- {m}' for m in existing_memories)}
        
        新信息:{new_info}
        
        新信息是否与现有记忆冲突?回答"是"或"否"。
        """
        # response = llm_client.generate(prompt)
        # return "是" in response
        return False  # 简化实现

6.3 记忆遗忘策略

import time
from typing import List, Dict
 
class MemoryForgettingStrategy:
    """记忆遗忘策略"""
    
    def __init__(self, ttl_days: int = 90, max_access_age_days: int = 30):
        self.ttl_days = ttl_days
        self.max_access_age_days = max_access_age_days
    
    def calculate_forget_score(self, memory: Dict) -> float:
        """
        计算遗忘分数 (0-1,越高越应该遗忘)
        
        考虑因素:
        - 创建时间(越久越应该遗忘)
        - 最后访问时间(越久未访问越应该遗忘)
        - 访问次数(越多访问越不应该遗忘)
        - 重要性评分(越重要越不应该遗忘)
        """
        now = time.time()
        
        # 时间衰减
        created_days = (now - memory.get("created_at", now)) / 86400
        last_access_days = (now - memory.get("last_accessed", now)) / 86400
        
        # 访问频率因子
        access_count = memory.get("access_count", 0)
        access_factor = 1 / (1 + access_count * 0.1)
        
        # 重要性因子
        importance = memory.get("importance", 0.5)
        importance_factor = 1 - importance
        
        # 综合遗忘分数
        forget_score = (
            created_days / self.ttl_days * 0.3 +
            last_access_days / self.max_access_age_days * 0.3 +
            access_factor * 0.2 +
            importance_factor * 0.2
        )
        
        return min(forget_score, 1.0)
    
    def should_forget(self, memory: Dict) -> bool:
        """判断是否应该遗忘"""
        forget_score = self.calculate_forget_score(memory)
        return forget_score > 0.7  # 遗忘阈值

七、面试高频问题

Q1: 向量数据库检索不准怎么办?

答案要点

解决方案:

1. 数据层优化
   • 数据清洗:去除噪声、重复数据
   • Chunking 策略:合理切分文档
   • 元数据丰富:添加时间、类型等标签

2. 检索层优化
   • 混合检索:语义检索 + 关键词检索
   • Rerank 模型:对检索结果重排序
   • Query 改写:优化用户查询语句

3. 应用层优化
   • Prompt 指示:告诉 LLM "如果检索内容无关,请回答不知道"
   • 多轮检索:根据初步结果扩展查询
   • 用户反馈:收集用户反馈优化检索

Q2: 为什么需要混合存储(向量+关系)?

答案要点

存储类型优势劣势
向量数据库语义检索、理解同义精确查询差、无事务
关系数据库精确查询、事务支持无语义理解
混合存储综合优势架构复杂、维护成本

混合存储价值

  • 用户偏好用关系库(精确查询)
  • 对话内容用向量库(语义检索)
  • 统一检索接口封装复杂性

Q3: 如何设计一个支持"用户偏好记忆"的 Agent?

答案要点

设计步骤:

1. 提取
   - 识别用户偏好表述(如"我喜欢简洁的回答")
   - 可用规则或 LLM 进行提取

2. 存储
   - 结构化存入关系数据库
   - 同时存入向量库支持语义检索

3. 检索
   - 会话开始时根据用户 ID 检索偏好
   - 将偏好注入 System Prompt

4. 更新
   - 当用户表达新偏好时触发更新
   - 冲突检测:新偏好覆盖旧偏好

5. 应用
   - 在推理时自动应用偏好设置

Q4: 长期记忆如何与短期记忆协作?

答案要点

协作流程:

1. 会话开始
   - 检索用户画像和偏好
   - 注入到 System Prompt

2. 对话进行中
   - 检索相关历史知识
   - 注入到 Retrieved Context

3. 会话结束
   - 提取重要信息
   - 写入长期记忆

4. 定期维护
   - 压缩旧记忆
   - 清理过时信息

Q5: Chroma、Milvus、Pinecone 有什么区别?如何选择?

答案要点

特性ChromaMilvusPinecone
部署方式本地/嵌入式自托管/云服务纯云服务
适用规模小型项目中大型项目各种规模
学习曲线
成本免费开源免费/云付费按使用付费
性能中等
推荐场景开发测试、小项目企业自建、大规模快速上线、免运维

选择建议

  • 开发测试:Chroma(简单快速)
  • 企业自建:Milvus(开源可控)
  • 快速上线:Pinecone(免运维)

八、总结

核心概念回顾

概念定义关键要点
长期记忆持久化存储的外部记忆跨会话、需检索
向量数据库存储文本向量,支持语义检索Chroma, Milvus, Pinecone
关系数据库存储结构化数据,支持精确查询用户画像、任务状态
混合存储向量+关系数据库结合综合优势、架构复杂
记忆管理更新、遗忘、压缩策略生命周期管理

一句话总结

长期记忆通过向量数据库实现语义检索,通过关系数据库实现精确查询,混合存储架构综合两者优势,配合合理的管理策略,实现 Agent 的知识积累和跨会话连续性。


最后更新:2026年3月18日