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的解决方案

  1. 【离线准备】将公司文档向量化存入数据库
    "2024年销售政策:..." → [0.1, 0.2, 0.3, ...] → 存储

  2. 【用户提问】
    用户:"2024年销售政策是什么?"

  3. 【问题向量化】
    "2024年销售政策是什么?" → [0.15, 0.25, 0.35, ...]

  4. 【向量检索】
    在数据库中找到最相似的文档:
    SELECT content FROM embeddings
    ORDER BY embedding <-> [0.15, 0.25, 0.35, ...]
    LIMIT 3;

  5. 【生成回答】
    AI基于检索到的文档内容生成准确回答

4. 整个系统架构

┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 用户文档 │───▶│ 向量化模型 │───▶│ PostgreSQL │
│ (PDF/Word) │ │ (nomic-embed) │ │ + pgvector │
└─────────────────┘ └──────────────────┘ └─────────────────┘

┌─────────────────┐ ┌──────────────────┐ │
│ 用户提问 │───▶│ 向量化模型 │───────────┘
│ "销售政策?" │ │ (nomic-embed) │ │
└─────────────────┘ └──────────────────┘ ▼
┌─────────────────┐
┌─────────────────┐ ┌──────────────────┐ │ 相似度检索 │
│ AI回答 │◀───│ 大语言模型 │◀───│ (向量距离) │
│ "根据文档..." │ │ (ChatGPT) │ └─────────────────┘
└─────────────────┘ └──────────────────┘

这个地方架构容易有点误区,并不是有两个nomic-embed,而是同一个模型的两次使用:

第一次使用(离线处理):
用户文档 → nomic-embed模型 → 向量 → 存储到pgvector

第二次使用(实时查询):
用户问题 → nomic-embed模型 → 向量 → 在pgvector中检索

详细流程

【离线阶段 - 建立知识库】

  1. 公司上传文档:"2024销售政策.pdf"
  2. 系统调用 nomic-embed-text 模型
  3. 文档内容 → [0.1, 0.2, 0.3, ...] (384维向量)
  4. 存储到 PostgreSQL 的 embeddings 表

【在线阶段 - 用户查询】

  1. 用户问:"销售政策是什么?"
  2. 系统调用 同一个 nomic-embed-text 模型
  3. 问题 → [0.15, 0.25, 0.35, ...] (384维向量)
  4. 在 embeddings 表中找相似向量
  5. 返回相关文档内容给大模型

为什么必须用同一个模型?

❌ 错误做法:
文档用 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长度相同但方向不同

posted @ 2025-12-29 11:28  烈酒清茶  阅读(4)  评论(0)    收藏  举报