从零实现AI代理的长期记忆

大多数开发人员认为"记忆"只是存储聊天日志。这是一个根本性的误解。

如果你想构建一个能够真正了解你的 AI 代理——一个能够根据你的整个对话历史、目标、健身水平和偏好提供个性化建议的系统——那么你就需要超越简单的聊天日志存储。

1、为什么当前的聊天机器人会失败

每次你刷新页面时,聊天机器人都忘记了你是谁。它必须从头开始了解你。

这会:

  • 烧毁 token(每次重新阅读整个对话)
  • 增加延迟(搜索数据库减慢响应)
  • 提供糟糕的用户体验(机器人重复问相同的问题)

为了解决这个问题,我们需要分离两种记忆

1) 非结构化记忆(The Stream)

  • 持续的对话流
  • 允许快速查询(不扫描整个表)
  • 适合:一般聊天、最近上下文

2) 结构化事实(The Facts)

  • 用户档案:年龄、性别、目标、健身水平
  • 稳定的信息:不经常变化
  • 适合:个性化推荐、设置更新

2、设置数据库

让我们使用 SQLite,因为:

  • 轻量级(与 Python 代理完美集成)
  • 内置(无需外部依赖)
  • 完美适配演示环境

数据库架构:

CREATE TABLE IF NOT EXISTS profiles (
    session_id TEXT PRIMARY KEY,
    gender TEXT,
    age INTEGER,
    fitness_level TEXT,
    goals TEXT,
    updated_at TEXT DEFAULT CURRENT_TIMESTAMP
);

这个表是我们的"真相来源"——它包含不会随每次对话重新计算的稳定事实。

3、记忆提取层

在源代码中,我们实现一个轻量级提取函数:

def extract_profile_updates(message: str) -> Optional[dict]:
    """从用户消息中提取个人资料更新。"""
    # 示例 - 提取年龄、健身水平和目标
    import re
    age_match = re.search(r'\b(\d+)\b', message)
    fitness_match = re.search(r'fitness level[:\s]+', message)
    goal_match = re.search(r'goal[:\s]+', message)
    
    if age_match or fitness_match or goal_match:
        return {
            'age': int(age_match.group(1)) if age_match else None,
            'fitness_level': fitness_match.group(1) if fitness_match else None,
            'goals': goal_match.group(1) if goal_match else None
        }
    return None

这个函数在后台运行,确保用户档案保持最新。

4、提示注入层(代理的大脑)

这是真正的魔法发生的地方。我们的代理需要能够访问这些记忆来做出智能决策。

我们使用 系统提示注入来组合查询:

# 伪代码示例
context = {
    "stream_summary": get_recent_stream(),      # 非结构化:最近消息
    "user_profile": get_user_profile(),         # 结构化:用户事实
    "goals": get_user_goals()              # 从档案中读取
}

prompt = f"""
根据以下上下文,做出适当的回复:

**流记忆(非结构化):**
{context['stream_summary']}

**用户档案(结构化):**
- 年龄:{context['user_profile']['age'] if 'age' in context['user_profile'] else '未知'}
- 健身水平:{context['user_profile']['fitness_level'] if 'fitness_level' in context['user_profile'] else '未知'}
- 目标:{context['user_profile']['goals'] if 'goals' in context['user_profile'] else '无'}
- 偏好:根据健身水平和历史记录
- 更新时间:{datetime.now().strftime('%Y-%m-%d')}

**要求:**
- 提供个性化建议
- 参考健身目标和水平
- 如果涉及健身计划,调整建议
- 保持对话连贯性
- 不要假设信息,总是从档案中读取

**你的回复风格:**
- 专业且友好
- 如果需要更多上下文,说明你将从流记忆中查找
- 使用用户的名字(如果已知)
"""

这确保我们的代理不会做出奇怪的假设,而是基于真实数据。

5、技术实现细节

源代码可在 Fabio Hiroki 的 GitHub**

这是一个完整的、生产就绪的实现,包含:

  • 双重记忆架构
  • SQLite 数据库集成
  • 提取和提示注入系统
  • Gradio Web 界面

关键技术:

  • 会话管理(session_id
  • 异步更新(避免阻塞)
  • 上下文组合(Stream + Facts)
  • 智能提示(避免重复查询)

6、实际应用场景

场景 1:健身指导

用户:"我最近开始去健身房"

代理响应:

  • 检索用户档案 → 年龄:28, 健身水平:初级
  • 检索最近目标 → "每周锻炼 3 次"
  • 生成个性化建议:"根据您的健身水平,建议从每周 2 次开始,关注基础动作"
  • 引用用户档案更新:"记得你是从上次对话开始的"

7、未来展望

下一代 AI 代理不会只是"更聪明的聊天机器人"——它们将具有深度持久记忆,能够理解用户在多个对话中的意图、目标和偏好。

随着 世界模型的发展,我们有更多机会将记忆与推理相结合,创造出真正个性化的 AI 助手。


原文链接: Build an AI agent with long-term memory

汇智网翻译整理,转载请标明出处