共计 1640 个字符,预计需要花费 5 分钟才能阅读完成。
为什么 Agent 需要记忆系统?
智能体的记忆就像人类的长期记忆,让对话不再像金鱼一样只有 7 秒有效期。它能记住用户偏好实现个性化服务,比如咖啡订单习惯;维持跨会话的上下文连续性,避免反复回答相同问题;更重要的是通过历史交互学习用户行为模式,像老友一样越用越懂你。

技术选型:数据库的三国演义
关系型数据库(如 PostgreSQL)
- 优点:事务支持完善,适合强一致性场景;成熟的索引优化
- 缺点:固定表结构难以适应动态记忆数据;相似度检索需要自定义函数
文档数据库(如 MongoDB)
- 适用场景:非结构化记忆存储(如聊天记录);JSON 原生支持
- 瓶颈:向量运算需额外插件,性能不如专用向量库
向量数据库(如 Pinecone)
- 杀招 :内置近似最近邻(ANN) 算法;毫秒级相似度查询
- 典型配置:768 维向量 +cosine 相似度,召回率 90%+(recall rate)
核心实现四步走
1. 记忆存储设计
// memory_schema.json
{
"timestamp": "2023-08-20T14:30:00Z",
"content": "用户喜欢冰美式不加糖",
"embedding": [0.12, -0.45, ..., 0.78], // 768 维向量
"metadata": {
"importance": 0.8, // 记忆权重
"expire_days": 30 // 过期时间
}
}
2. 记忆检索算法
# requirements.txt
# sentence-transformers==2.2.2
# numpy==1.24.3
from sentence_transformers import SentenceTransformer
import numpy as np
def search_memories(query: str, memory_pool: list[dict], top_k=3) -> list:
"""
基于余弦相似度的记忆检索
:param query: 查询文本
:param memory_pool: 记忆池
:param top_k: 返回最相关的 k 条记忆
"""model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
query_embed = model.encode(query)
similarities = []
for mem in memory_pool:
cos_sim = np.dot(query_embed, mem['embedding']) / (np.linalg.norm(query_embed) * np.linalg.norm(mem['embedding']))
similarities.append((mem, cos_sim))
return sorted(similarities, key=lambda x: x[1], reverse=True)[:top_k]
3. 记忆衰减机制
采用指数衰减公式:
当前权重 = 初始权重 * e^(-λ * 天数)
λ(lambda)是衰减系数,建议 0.01-0.1
4. 性能优化实战
| 优化策略 | 吞吐量(ops/s) | P99 延迟(ms) |
|---|---|---|
| 单条写入 | 120 | 45 |
| 批量写入(100 条) | 5800 | 8 |
| HNSW 索引 | – | 12 |
| 暴力搜索 | – | 310 |
避坑指南
记忆污染防护
- 设置输入过滤器:检测恶意输入(如长乱码)
- 实现置信度阈值:相似度 <0.6 的记忆不激活
分布式一致性
- 采用版本号乐观锁:
update ... where version=old_version - 最终一致性补偿:定期执行记忆同步任务
思考题时间
- 当用户换设备时,如何安全迁移记忆数据而不泄露隐私?
- 像 ” 用户今天心情不好 ” 这样的主观记忆,该用什么数据结构存储?
- 记忆数据增长到 TB 级时,哪些压缩算法能兼顾检索精度?
写在最后
实际部署时发现,简单的记忆衰减公式在复杂场景下可能失效——有次用户突然改变咖啡口味,系统却因为旧记忆权重过高迟迟不更新。后来我们加入了突变检测机制,当检测到用户行为模式剧烈变化时自动重置相关记忆权重。这提醒我们:再好的算法也需要留出人工干预的接口。
正文完
