• 主页
  • 架构
  • 编程语言
  • 数据存储
  • 网络
  • VMware
  • 服务器
  • 组网
  • AI
  • 算法系列
  • 设计模式
  • 读书笔记
  • 思考
  • 工具
  • 其它技术

  • 主页
  • 架构
  • 编程语言
  • 数据存储
  • 网络
  • VMware
  • 服务器
  • 组网
  • AI
  • 算法系列
  • 设计模式
  • 读书笔记
  • 思考
  • 工具
  • 其它技术

Memory向量记忆系统1-基础知识

2026-07-26

Agent Loop 每次循环结束后,其上下文窗口中的对话历史、推理过程、工具调用结果,都会随着会话的关闭而归零。这就像一个每天醒来都失忆的人——昨天你告诉他的项目背景、技术偏好、团队成员,今天他全忘了,你得从头再讲一遍。Memory 系统的存在意义,就是让 Agent 拥有跨会话的持久记忆能力,从“金鱼脑”进化为真正的智能助手。

一、文本变向量

一般使用embedding模型,如Doubao的Doubao-embedding,由字节跳动研发的语义向量化模型,主要面向向量检索的使用场景,支持中、英双语,最长 4K 上下文长度。向量维度 2048 维,支持 512、1024 降维使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
curl https://ark.cn-beijing.volces.com/api/v3/embeddings/multimodal \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ARK_API_KEY" \
-d $'{
"model": "doubao-embedding-vision-251215",
"encoding_format": "float",
"input": [
{
"type": "video_url",
"video_url": {
"url": "https://ark-project.tos-cn-beijing.volces.com/doc_video/ark_vlm_video_input.mp4"
}
}
]
}'

输出如下,向量就是embedding对应的数据,其实维度很多,我删除了一些方便展示。

1
{"created":1784698258,"data":{"embedding":[0.00482177734375,0.03955078125,-0.004180908203125,0.045654296875,-0.0031280517578125,0.019287109375,-0.0147705078125,-0.0133056640625,-0.0181884765625,-0.03125,0.0458984375],"object":"embedding"},"id":"021784698257058251fb4d9d2b64b7e0912e9d9de0a598cb39ec9","model":"doubao-embedding-vision-251215","object":"list","usage":{"prompt_tokens":10371,"prompt_tokens_details":{"image_tokens":10224,"text_tokens":147},"total_tokens":10371}}

这里真的要吐槽一下火山的模型广场,我用文本的embedding模型进行API调用,完全不通,反馈也反馈不了,醉了。

二、向量归一化

每个 embedding 向量都有两个属性:

属性 含义 类比
方向 向量指向哪里,代表语义 朝东还是朝西
长度(模长) 向量有多大,代表向量的长度,就是从坐标原点到向量端点的直线距离。 走了 1 米还是 10 米

归一化就是:把所有向量的长度都变成 1,让它们站在同一个起跑线上,只比方向。

❓ 为什么要做?

1. 相似度计算更纯粹

  • 语义相似 = 方向接近
  • 向量长度不应该影响相似度判断
  • 归一化后纯靠语义方向匹配,不受模长干扰

2. 计算更快(工程上最重要)

1
2
归一化前:余弦相似度 = 点积 / (|a| × |b|)  (要算两次模长)
归一化后:余弦相似度 = 直接点积 (一步到位)

向量数据库(FAISS、Milvus 等)对内积索引做了深度优化,归一化后用内积搜索 = 余弦搜索,但速度快很多。

3. 下游任务更稳定

  • 聚类、分类、RAG 检索等任务,归一化后效果通常更好
  • 避免 “长文本向量模长大、占优势” 这类不公平现象

🛠️ 怎么做?

最常用:L2 归一化(欧几里得归一化)

公式:每个元素 ÷ 向量的模长

1
2
3
4
5
import numpy as np

def l2_normalize(v):
norm = np.linalg.norm(v) # 算模长
return v / norm if norm > 0 else v

常见误区

误区 真相
“API 输出已经归一化了吧?” 大部分没有(OpenAI、Cohere 等都是原始向量),自己再归一化一遍最稳妥
“归一化后不同模型就能混用了” ❌ 不行!归一化只统一长度,改变不了语义空间,不同模型的向量还是不能混
“所有场景都要归一化” 不一定,用欧氏距离的场景就不需要归一化
“归一化会损失信息” 确实丢了模长信息,但大部分 NLP 场景模长信息没用,方向才是关键

三、向量召回

向量召回的本质就是:拿 query 向量,跟库里向量算一次点积,分数最高的 K 个就是结果。

举例

用二维向量举个最直观的例子,我们有:

  • 1 个查询向量(用户的问题)
  • 3 个文档向量(库里的内容)
  • 都是 2 维,并且已经归一化(模长 = 1)
向量 x y 说明
query(查询) 0.8 0.6 用户问的问题
doc1 0.6 0.8 文档 1
doc2 1.0 0.0 文档 2
doc3 0.0 1.0 文档 3

画在坐标系里大概是这样:

1
2
3
4
5
6
7
8
9
10
     y ↑
|
doc3 ● | ● doc1
(0,1) | (0.6,0.8)
| ● query
| (0.8,0.6)
|
──────┼───────────→ x
| ● doc2
| (1,0)

🧮 点积怎么算?

公式:对应位置相乘,然后加起来。

a⋅b=ax×bx+ay×by

计算 query 和 doc1 的相似度:
1
2
3
query · doc1 = 0.8 × 0.6 + 0.6 × 0.8
= 0.48 + 0.48
= 0.96
计算 query 和 doc2 的相似度:
1
2
3
query · doc2 = 0.8 × 1.0 + 0.6 × 0.0
= 0.8 + 0
= 0.8
计算 query 和 doc3 的相似度:
1
2
3
query · doc3 = 0.8 × 0.0 + 0.6 × 1.0
= 0 + 0.6
= 0.6

📊 结果

表格

文档 点积(= 余弦相似度) 排名
doc1 0.96 🥇 最相似
doc2 0.8 🥈 第二
doc3 0.6 🥉 第三

所以召回 Top 2 的话,返回 doc1 和 doc2。

生产情况

实际工程上,数据量大了(百万、千万级),暴力算不起,所以用近似最近邻(ANN),牺牲一点点精度,换几百上千倍的速度。

不跟所有向量比,只跟 “可能相似” 的那一小撮比。

就像你在图书馆找书,不会从第一排第一本开始翻,而是先找到对应书架,再在那个书架里找。常见的索引算法

1. HNSW(最常用,效果最好)

层次化小世界图,现在的主流选择(FAISS、Milvus、Pinecone 默认基本都是它)。

原理:

  • 把所有向量建成一张图,相似的向量之间连边
  • 查询时从入口点出发,沿着边往 “更相似” 的方向跳
  • 跳几步就跳到最相似的附近了

类比: 像找朋友的朋友,通过人脉网络快速找到目标

特点:

  • 召回率高,速度快
  • 内存占用大(图结构占空间)
  • 适合对精度要求高的场景

2. IVF(倒排文件)

聚类分桶,先粗筛再精排。

原理:

  1. 建库时:把所有向量聚成 N 个簇(比如 1000 个簇),每个簇有一个中心点

  2. 查询时:

    • 第一步:先找 query 离哪几个簇最近(比如最近的 10 个簇)
    • 第二步:只在这 10 个簇里做精确计算
    • 不用跟全部 100 万条比,只跟几万条比

类比: 先找到对应书架,再在书架里找书

特点:

  • 速度快,内存占用比 HNSW 小
  • 精度略低于 HNSW
  • 适合数据量特别大的场景

3. PQ(乘积量化)

压缩向量,用空间换精度,适合超大规模数据。

原理:

  • 把高维向量切成几段,每段分别量化成一个小编码
  • 1536 维的 float 向量(6KB),可能压缩到几十字节
  • 计算相似度时用近似距离,不用算完整点积

特点:

  • 极度省空间,适合亿级数据
  • 精度损失较大,一般和 IVF 配合用(IVFPQ)

扫一扫,分享到微信

微信分享二维码
Memory向量记忆系统2-SQLite
© 2026 John Doe
Hexo Theme Yilia by Litten