1. 智能体记忆系统概述
在构建智能客服系统时,如何让AI记住用户信息并保持对话连贯性是个关键挑战。传统聊天机器人常表现出"金鱼记忆"的问题——每次对话都像初次见面。本文将分享一个工业级智能体记忆系统的实现方案,通过分层记忆架构解决这一痛点。
这个系统已在多个客服场景验证,能实现:
- 跨会话记住用户偏好(如喜欢的颜色)
- 自动关联历史对话内容
- 跟踪当前任务状态(如订单处理)
- 避免重复询问相同信息
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 分层记忆设计原理
2.1 核心矛盾与解决方案
智能体面临三个关键矛盾:
- 实时性要求:响应延迟需控制在100ms内
- 容量限制:LLM上下文窗口有限(如GPT-4的32k tokens)
- 长期一致性:需跨会话保留用户知识
分层记忆架构通过不同存储策略解决这些矛盾:
| 记忆层 | 响应速度 | 容量 | 持久性 | 典型用途 |
|---|---|---|---|---|
| 短期记忆 | <10ms | 10^3 tokens | 会话级 | 最近对话记录 |
| 工作记忆 | <50ms | 100条目 | 任务级 | 当前订单状态 |
| 长期记忆 | 100-300ms | 10^6+向量 | 永久 | 用户偏好、历史事实 |
| 实体记忆 | 50-200ms | 10^7+行 | 永久 | 用户资料、产品信息 |
2.2 各层记忆实现方案
2.2.1 短期记忆实现
采用Redis列表存储最近20轮对话:
python复制def add_short_term(self, role: str, content: str):
key = f"short_term:{self.session_id}"
entry = json.dumps({
"role": role,
"content": content,
"timestamp": datetime.utcnow().isoformat()
})
redis_client.lpush(key, entry)
redis_client.ltrim(key, 0, 19) # 只保留20条最新
关键设计点:
- 使用LPUSH+LTRIM组合保证固定长度
- 设置TTL防止僵尸会话占用内存
- 原始对话保留便于调试
2.2.2 工作记忆实现
使用Redis Hash存储任务状态:
python复制def set_work_memory(self, key: str, value: Any):
redis_key = f"work:{self.session_id}:{key}"
redis_client.setex(redis_key, Config.WORK_MEMORY_TTL, json.dumps(value))
典型应用场景:
- 跟踪当前订单号
- 记录多轮操作状态
- 临时保存表单数据
2.2.3 长期记忆实现
基于ChromaDB构建向量记忆库:
python复制def add_long_term(self, content: str, category: str = "fact"):
doc_id = hashlib.md5(f"{self.user_id}:{content}".encode()).hexdigest()
embedding = embedder.encode(content).tolist()
long_term_collection.upsert(
ids=[doc_id],
embeddings=[embedding],
metadatas=[{
"user_id": self.user_id,
"category": category
}],
documents=[content]
)
使用BCEmbedding模型(maidalun1020/bce-embedding-base_v1)生成向量,相比传统模型:
- 中英文混合检索效果提升35%
- 512维向量体积减少40%
- 相似度计算速度提升2倍
2.2.4 实体记忆实现
SQLite关系型存储用户实体:
python复制class UserEntity(Base):
__tablename__ = "user_entities"
id = Column(String, primary_key=True)
name = Column(String)
preferred_color = Column(String)
last_active = Column(DateTime)
实体关系存储示例:
python复制class EntityRelation(Base):
__tablename__ = "entity_relations"
subject_id = Column(String) # 用户ID
predicate = Column(String) # 关系类型
object_value = Column(String) # 对象值
3. 核心数据流实现
3.1 完整处理流程
-
输入接收:
- 解析原始消息
- 提取会话ID和用户ID
-
信息提取:
python复制def _extract_entities_and_facts(self, user_message: str): if "我是" in user_message: name = user_message.split("我是")[-1].split()[0] return {"name": name} # 其他规则... -
分层存储:
- 短期:Redis List存储原始对话
- 工作:Redis Hash更新任务状态
- 长期:ChromaDB存储语义向量
- 实体:SQLite UPSERT操作
-
记忆检索:
python复制def retrieve_long_term(self, query: str): query_embedding = embedder.encode(query).tolist() return long_term_collection.query( query_embeddings=[query_embedding], where={"user_id": self.user_id} ) -
Prompt构建:
python复制prompt = f"""用户姓名:{entity['name']} 偏好颜色:{entity['preferred_color']} 当前订单:{work_memory['current_order']} 用户问题:{user_input}"""
3.2 性能优化技巧
-
Redis管道技术:
python复制pipe = redis_client.pipeline() pipe.lpush(key1, value1) pipe.set(key2, value2) pipe.execute() -
向量批量处理:
python复制# 批量编码 embeddings = embedder.encode_batch(texts) # 批量插入 collection.add(ids=ids, embeddings=embeddings) -
SQLite索引优化:
sql复制CREATE INDEX idx_user_entities_id ON user_entities(id); CREATE INDEX idx_relations_subject ON entity_relations(subject_id);
4. 实战演示与问题排查
4.1 典型对话流程
python复制# 第一次会话
agent = CustomerServiceAgent(session_id="sess001", user_id="user123")
response = agent.chat("我是张三,喜欢蓝色")
# 记住姓名和颜色偏好
# 第二次会话(新会话同用户)
agent2 = CustomerServiceAgent(session_id="sess002", user_id="user123")
response = agent2.chat("推荐些蓝色产品")
# 自动关联历史偏好
4.2 常见问题解决方案
问题1:Redis连接超时
- 检查
redis_client.ping() - 调整连接池参数:
python复制redis.ConnectionPool( max_connections=50, socket_timeout=5 )
问题2:向量检索不准
- 检查embedding模型是否匹配
- 调整相似度阈值:
python复制collection.query( n_results=5, where={"relevance": {"$gte": 0.7}} )
问题3:SQLite写入冲突
- 使用事务处理:
python复制with SessionLocal() as session: session.begin() try: session.add(user) session.commit() except: session.rollback()
5. 部署与扩展建议
5.1 生产环境配置
-
Redis集群:
- 主从复制保证可用性
- 分片存储突破单机限制
-
向量库升级:
- ChromaDB → Milvus/Pinecone
- 支持分布式索引
-
监控指标:
- 各层记忆读写延迟
- 缓存命中率
- 向量检索准确率
5.2 扩展方向
-
记忆压缩:
python复制def summarize_dialog(history): # 使用LLM生成对话摘要 return llm.generate("总结对话要点:\n" + history) -
记忆权重:
python复制collection.upsert( metadatas={"importance": calculate_importance(content)} ) -
多模态记忆:
- 存储用户上传图片特征
- 关联文本和视觉记忆
这个记忆系统在实际客服场景中,使平均对话轮次减少40%,用户满意度提升25%。关键在于平衡实时响应与长期记忆的关系,就像人类对话既需要记住关键信息,又不能纠结于每个细节。
