langchain学习总结-Embedding 学习总结

OpenAI Embedding 学习总结

一、什么是 Embedding(嵌入)?

Embedding 是将文本转换为数值向量的技术,它能够:

  • 将文本映射到高维向量空间
  • 保留文本的语义信息
  • 使相似的文本在向量空间中距离更近

应用场景

  • 语义搜索
  • 文档相似度计算
  • 推荐系统
  • 文档聚类
  • 问答系统

二、LangChain 中的 Embedding

1. 基础嵌入模型

LangChain 提供了多种嵌入模型的统一接口,常用模型包括:

  • OpenAI Embeddings : text-embedding-3-small, text-embedding-3-large
  • 千帆 Embeddings : Embedding-V1
  • 其他本地模型

核心方法

方法 说明
embed_query(text) 将单个查询文本转换为向量
embed_documents(texts) 将多个文档文本批量转换为向量

三、示例代码与输出

示例 1:基础嵌入模型使用

python 复制代码
import dotenv
import numpy as np
from langchain_community.embeddings import QianfanEmbeddingsEndpoint
from numpy.linalg import norm

dotenv.load_dotenv()

# 计算两个向量的余弦相似度
def cosine_similarity(vec1, vec2):
    dot_product = np.dot(vec1, vec2)
    norm_vec1 = norm(vec1)
    norm_vec2 = norm(vec2)
    return dot_product / (norm_vec1 * norm_vec2)

# 创建文本嵌入模型
embeddings = QianfanEmbeddingsEndpoint(model="Embedding-V1")

# 嵌入单个查询
query_vector = embeddings.embed_query("你好,我是一名学生")
print("查询向量维度:", len(query_vector))

# 批量嵌入文档
documents_vectors = embeddings.embed_documents([
    "你好,我是一名学生",
    "你好,我是一名老师",
    "你好,我是一名学生",  # 重复文本
])

print("文档向量数量:", len(documents_vectors))

# 计算相似度
sim1 = cosine_similarity(documents_vectors[0], documents_vectors[1])
sim2 = cosine_similarity(documents_vectors[0], documents_vectors[2])

print("向量1和向量2的相似度:", sim1)
print("向量1和向量3的相似度:", sim2)
预期输出:
makefile 复制代码
查询向量维度: 1024
文档向量数量: 3
向量1和向量2的相似度: 0.9567
向量1和向量3的相似度: 1.0000

输出分析:

  • 向量维度为 1024(千帆 Embedding-V1 模型)
  • 相同文本的向量相似度为 1.0(完全相同)
  • 相似文本的向量相似度接近 1.0(语义相近)

四、CacheBackedEmbeddings(缓存嵌入)

是什么?

CacheBackedEmbeddings 是 LangChain 提供的带缓存功能的嵌入包装器,它能够:

  • 缓存已计算过的文本向量,避免重复调用 API
  • 节省时间和成本
  • 支持多种存储后端(本地文件、Redis 等)

有什么用?

优势 说明
节省成本 避免对相同文本重复调用付费 API
提升速度 从缓存读取比调用 API 快得多
离线可用 缓存后的文本可离线使用
一致性 相同文本始终得到相同的向量

核心参数

python 复制代码
CacheBackedEmbeddings.from_bytes_store(
    underlying_embeddings,    # 底层嵌入模型
    document_store,           # 存储后端
    namespace,                # 命名空间(区分不同缓存)
    query_embedding_cache=True # 是否缓存查询向量
)

五、示例代码与输出(带缓存)

示例 2:使用 CacheBackedEmbeddings

python 复制代码
import dotenv
import numpy as np
from langchain_community.embeddings import QianfanEmbeddingsEndpoint
from langchain_classic.embeddings import CacheBackedEmbeddings
from langchain_classic.storage import LocalFileStore
from numpy.linalg import norm

dotenv.load_dotenv()

def cosine_similarity(vec1, vec2):
    dot_product = np.dot(vec1, vec2)
    norm_vec1 = norm(vec1)
    norm_vec2 = norm(vec2)
    return dot_product / (norm_vec1 * norm_vec2)

# 创建基础嵌入模型
embeddings = QianfanEmbeddingsEndpoint(model="Embedding-V1")

# 创建带缓存的嵌入模型
embeddings_with_cache = CacheBackedEmbeddings.from_bytes_store(
    embeddings,                      # 基础嵌入模型
    LocalFileStore("./cache/"),      # 本地文件存储
    namespace=embeddings.model,      # 使用模型名作为命名空间
    query_embedding_cache=True,      # 缓存查询向量
)

# 第一次调用 - 会请求 API 并缓存
query_vector = embeddings_with_cache.embed_query("你好,我是一名学生")
print("查询向量维度:", len(query_vector))

# 第二次调用相同文本 - 从缓存读取,不请求 API
query_vector_cached = embeddings_with_cache.embed_query("你好,我是一名学生")

# 批量嵌入(部分重复,会使用缓存)
documents_vectors = embeddings_with_cache.embed_documents([
    "你好,我是一名学生",  # 已缓存
    "你好,我是一名老师",  # 新文本
    "你好,我是一名学生",  # 已缓存
])

print("文档向量数量:", len(documents_vectors))

# 计算相似度
sim1 = cosine_similarity(documents_vectors[0], documents_vectors[1])
sim2 = cosine_similarity(documents_vectors[0], documents_vectors[2])

print("向量1和向量2的相似度:", sim1)
print("向量1和向量3的相似度:", sim2)
预期输出:
makefile 复制代码
查询向量维度: 1024
文档向量数量: 3
向量1和向量2的相似度: 0.9567
向量1和向量3的相似度: 1.0000
缓存目录结构:
bash 复制代码
./cache/
└── Embedding-V1/
    ├── <hash1>  # "你好,我是一名学生" 的缓存
    └── <hash2>  # "你好,我是一名老师" 的缓存

六、余弦相似度原理

公式

css 复制代码
cosine_similarity(A, B) = (A · B) / (||A|| × ||B||)

说明

  • A · B: 两个向量的点积
  • ||A||: 向量 A 的长度(模)
  • 取值范围 : [-1, 1]
    • 1.0: 完全相同方向
    • 0.0: 正交(无关)
    • -1.0: 完全相反方向

在文本嵌入中的应用

  • 值越接近 1,文本语义越相似
  • 值越接近 0,文本语义越不相关

七、最佳实践

  1. 生产环境务必使用缓存:可节省 50%+ 的 API 调用
  2. 选择合适的存储后端
    • 本地开发:LocalFileStore
    • 生产环境:Redis 或数据库
  3. 命名空间管理:使用模型名或项目名作为 namespace
  4. 批量处理 :优先使用 embed_documents 而非多次调用 embed_query
相关推荐
Anastasiozzzz12 分钟前
对抗大文件上传---分片加多重Hash判重
服务器·后端·算法·哈希算法
Vivienne_ChenW15 分钟前
DDD领域模型在项目中的实战
java·开发语言·后端·设计模式
女王大人万岁28 分钟前
Go标准库 sync 详解
服务器·开发语言·后端·golang
小高Baby@36 分钟前
session、cookie、Jwt-token
开发语言·后端·golang
露天赏雪38 分钟前
JDK8 的入门避坑指南
java·服务器·windows·spring boot·后端·spring·性能优化
爬山算法1 小时前
Hibernate(86)如何在性能测试中使用Hibernate?
java·后端·hibernate
菜鸟小杰子1 小时前
Spring Boot集成asyncTool:复杂任务的优雅编排与高效执行(实战优化版)
java·spring boot·后端
rannn_1111 小时前
【苍穹外卖|Day3】公共字段自动填充、新增菜品功能、菜品分页查询功能、删除菜品功能、修改菜品功能、起售停售菜品
java·spring boot·后端·学习·项目
无名-CODING1 小时前
SpringMVC处理流程完全指南:从请求到响应的完整旅程
java·后端·spring
BYSJMG1 小时前
计算机毕设推荐:基于大数据的共享单车数据可视化分析
大数据·后端·python·信息可视化·数据分析·课程设计