pgVector学习总结
pgVector学习资料
目前经过这一次ai开发,了解到了相关知识
1、PgVector是什么?
我对pgVector的理解就是向量数据库,首先Vector就是向量的意思
而这个pgVector其实是pgsql的一个扩展,用来存储向量的
2、那么我们就会衍生出新的概念,Vector是什么?
通俗易懂的来说,Vector是向量
拿个例子举
"苹果很甜" 和 "苹果味道不错"
计算机无法直接理解这两句话的相似性,因为它们没有相同的词汇。
向量化的解决方案
向量就是把文字转换成数字数组,让计算机能"理解"语义:
"苹果很甜" → [0.2, 0.8, 0.1, 0.9, ...] (384个数字)
"苹果味道不错" → [0.3, 0.7, 0.2, 0.8, ...] (384个数字)
2. 为什么是384维?
维度的含义
- 1维:一条线上的点(只有长度)
- 2维:平面上的点(长度+宽度)
- 3维:空间中的点(长度+宽度+高度)
- 384维:384个特征的"超空间"中的点
384维的来源
这是nomic-embed-text模型的输出维度:
- 每个维度代表文本的一个"特征"
- 比如:第1维可能代表"情感倾向"
- 第2维可能代表"主题类别"
- 第3维可能代表"时态信息"
- ...以此类推到第384维
注意:
维度是模型决定的,不是随意规定
不同的向量化模型有不同的输出维度:
- nomic-embed-text: 384维
- OpenAI text-embedding-ada-002: 1536维
- sentence-transformers/all-MiniLM-L6-v2: 384维
- BERT-base: 768维
可以是38个数字吗?
理论上可以,但效果会很差:
- 维度越高 = 能表达的语义信息越丰富
- 维度越低 = 语义信息丢失严重
类比理解:
- 38维 = 用38种颜色画画(信息有限)
- 384维 = 用384种颜色画画(信息丰富)
为什么选择384维?
这是模型训练时的平衡点:
- 太低(如38维):语义表达不够准确
- 太高(如3840维):计算成本太高,存储占用大
- 384维:准确性和效率的最佳平衡
3、我们还在PGVector中创建了一张表叫 embeddings
那么为什么要创建这张表呢?首先我们要知道的是这张表作用是什么:
CREATE TABLE embeddings (
id SERIAL PRIMARY KEY, -- 唯一标识
content TEXT NOT NULL, -- 原始文本内容
metadata JSONB, -- 文档元信息(来源、作者等)
embedding vector(384), -- 384维向量表示
created_at TIMESTAMP -- 创建时间
);
这张表的每一条数据,代表着文档的一段内容、文档的向量表示、相关的元数据等等
也就是说,我们将文档内容,存储到这张表之后,就可以通过各种pgvector里面自带的各个公式
来计算文档的相识内容,然后就可以衍生到RAG了
RAG的解决方案
-
【离线准备】将公司文档向量化存入数据库
"2024年销售政策:..." → [0.1, 0.2, 0.3, ...] → 存储 -
【用户提问】
用户:"2024年销售政策是什么?" -
【问题向量化】
"2024年销售政策是什么?" → [0.15, 0.25, 0.35, ...] -
【向量检索】
在数据库中找到最相似的文档:
SELECT content FROM embeddings
ORDER BY embedding <-> [0.15, 0.25, 0.35, ...]
LIMIT 3; -
【生成回答】
AI基于检索到的文档内容生成准确回答
4. 整个系统架构
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 用户文档 │───▶│ 向量化模型 │───▶│ PostgreSQL │
│ (PDF/Word) │ │ (nomic-embed) │ │ + pgvector │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│
┌─────────────────┐ ┌──────────────────┐ │
│ 用户提问 │───▶│ 向量化模型 │───────────┘
│ "销售政策?" │ │ (nomic-embed) │ │
└─────────────────┘ └──────────────────┘ ▼
┌─────────────────┐
┌─────────────────┐ ┌──────────────────┐ │ 相似度检索 │
│ AI回答 │◀───│ 大语言模型 │◀───│ (向量距离) │
│ "根据文档..." │ │ (ChatGPT) │ └─────────────────┘
└─────────────────┘ └──────────────────┘
这个地方架构容易有点误区,并不是有两个nomic-embed,而是同一个模型的两次使用:
第一次使用(离线处理):
用户文档 → nomic-embed模型 → 向量 → 存储到pgvector
第二次使用(实时查询):
用户问题 → nomic-embed模型 → 向量 → 在pgvector中检索
详细流程
【离线阶段 - 建立知识库】
- 公司上传文档:"2024销售政策.pdf"
- 系统调用 nomic-embed-text 模型
- 文档内容 → [0.1, 0.2, 0.3, ...] (384维向量)
- 存储到 PostgreSQL 的 embeddings 表
【在线阶段 - 用户查询】
- 用户问:"销售政策是什么?"
- 系统调用 同一个 nomic-embed-text 模型
- 问题 → [0.15, 0.25, 0.35, ...] (384维向量)
- 在 embeddings 表中找相似向量
- 返回相关文档内容给大模型
为什么必须用同一个模型?
❌ 错误做法:
文档用 nomic-embed-text 向量化 → [0.1, 0.2, 0.3]
问题用 OpenAI-embed 向量化 → [0.8, 0.9, 0.7]
结果:两个向量空间不同,无法比较!
✅ 正确做法:
文档用 nomic-embed-text → [0.1, 0.2, 0.3]
问题用 nomic-embed-text → [0.15, 0.25, 0.35]
结果:同一空间,可以计算相似度
🏗️ 5. 系统架构的完整理解
【一次性部署】
Ollama容器 → 包含 nomic-embed-text 模型
PostgreSQL容器 → 包含 pgvector 扩展
【离线处理】
PDF文档 → Ollama(nomic-embed) → 向量 → PostgreSQL存储
【在线查询】
用户问题 → Ollama(nomic-embed) → 向量 → PostgreSQL检索 → 相关文档 → ChatGPT → 回答
关键点:
- pgvector = 数据库扩展(存储和检索向量)
- nomic-embed = AI模型(文本转向量)
- 两者配合 = 完整的向量搜索系统
科普一下计算公式:
2. L2、余弦、内积的区别
三种距离计算方式
L2距离(欧几里得距离)
计算公式:√[(a₁-b₁)² + (a₂-b₂)² + ... + (aₙ-bₙ)²]
特点:计算实际的"空间距离"
适用:向量长度有意义的场景
余弦相似度
计算公式:(A·B) / (|A|×|B|)
特点:只关心方向,不关心长度
适用:文本相似度(最常用)
内积(点积)
计算公式:a₁×b₁ + a₂×b₂ + ... + aₙ×bₙ
特点:同时考虑方向和长度
适用:推荐系统
实际例子
向量A:[3, 4] (长度=5)
向量B:[6, 8] (长度=10)
向量C:[4, 3] (长度=5)
L2距离:
A到B = √[(3-6)² + (4-8)²] = 5
A到C = √[(3-4)² + (4-3)²] = √2 ≈ 1.4
余弦相似度:
A和B = 完全相同方向 = 1.0(最相似)
A和C = 不同方向 = 0.96
结论:B和A方向相同但长度不同,C和A长度相同但方向不同

浙公网安备 33010602011771号