LangChain-检索系统 (Retrieval)

news2025/4/18 21:33:02

检索系统 (Retrieval)

检索系统是LangChain的核心组件之一,它提供了从各种数据源获取相关信息的能力,是构建知识增强型应用的基础。本文档详细介绍LangChain检索系统的组件、工作原理和最佳实践。

概述

检索系统解决了大型语言模型知识有限和过时的问题,允许模型访问外部信息源。LangChain的检索框架包括以下主要组成部分:

  1. 文档加载:从各种来源加载文本数据
  2. 文档处理:分割、清理和预处理文档
  3. 嵌入和索引:将文本转换为向量并建立索引
  4. 检索:搜索并获取相关文档
  5. 上下文增强:将检索到的信息整合到模型输入中

文档加载器

LangChain提供了100多种文档加载器,用于从不同数据源获取文档。

常见文档加载器

from langchain_community.document_loaders import (
    TextLoader, PyPDFLoader, CSVLoader, 
    WebBaseLoader, YouTubeLoader, 
    DirectoryLoader, GitLoader
)

# 加载文本文件
text_loader = TextLoader("path/to/document.txt")
text_docs = text_loader.load()

# 加载PDF文件
pdf_loader = PyPDFLoader("path/to/document.pdf")
pdf_docs = pdf_loader.load()

# 加载CSV文件
csv_loader = CSVLoader("path/to/data.csv")
csv_docs = csv_loader.load()

# 加载网页内容
web_loader = WebBaseLoader(["https://www.example.com/page"])
web_docs = web_loader.load()

# 加载YouTube视频
youtube_loader = YouTubeLoader.from_youtube_url(
    "https://www.youtube.com/watch?v=example",
    add_video_info=True,
    language=["zh-cn"]
)
youtube_docs = youtube_loader.load()

# 加载整个目录
dir_loader = DirectoryLoader("./documents/", glob="**/*.pdf")
dir_docs = dir_loader.load()

# 加载Git仓库
git_loader = GitLoader(
    clone_url="https://github.com/username/repo",
    repo_path="./repos/example_repo",
    branch="main"
)
git_docs = git_loader.load()

文档结构

加载的文档通常包含以下属性:

from langchain_core.documents import Document

doc = Document(
    page_content="文档内容",
    metadata={"source": "example.txt", "page": 1, "author": "张三"}
)

文档处理

文本分割

将长文档分割成小块,以适应模型的上下文窗口:

from langchain_text_splitters import (
    RecursiveCharacterTextSplitter,
    CharacterTextSplitter,
    TokenTextSplitter,
    SentenceTransformersTokenTextSplitter
)

# 基于字符的递归分割(推荐)
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,  # 每块最大字符数
    chunk_overlap=200,  # 块之间的重叠字符数
    separators=["\n\n", "\n", "。", ",", " ", ""]  # 尝试优先在这些分隔符处拆分
)

# 基于令牌的分割(更精确控制token数量)
token_splitter = TokenTextSplitter(
    chunk_size=500,  # 每块最大token数
    chunk_overlap=50  # 块之间的重叠token数
)

# 中文分割优化(基于句子变换器的分词)
chinese_splitter = SentenceTransformersTokenTextSplitter(
    chunk_size=256,
    chunk_overlap=20
)

# 分割文档
doc = text_loader.load()[0]  # 假设已经加载了文档
chunks = text_splitter.split_documents([doc])
print(f"文档被分割成{len(chunks)}个块")

嵌入与向量存储

嵌入模型

将文本转换为向量表示:

from langchain_openai import OpenAIEmbeddings
from langchain_community.embeddings import HuggingFaceEmbeddings, ModelScopeEmbeddings

# OpenAI嵌入(高质量但需付费)
openai_embeddings = OpenAIEmbeddings()

# 开源嵌入选项(本地或免费)
huggingface_embeddings = HuggingFaceEmbeddings(
    model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"  # 多语言模型
)

# 使用中文模型(ModelScope)
chinese_embeddings = ModelScopeEmbeddings(
    model_id="iic/nlp_lawbert_text-embedding-chinese_base"
)

# 生成文本嵌入
text = "这是一段示例文本"
embedding = openai_embeddings.embed_query(text)

向量存储

存储和检索文档嵌入:

from langchain_community.vectorstores import FAISS, Chroma, Milvus

# 准备文档
docs = text_splitter.split_documents(text_loader.load())

# 使用FAISS(高效的开源向量库,适合本地使用)
faiss_db = FAISS.from_documents(docs, openai_embeddings)

# 使用Chroma(开源向量数据库,支持元数据过滤)
chroma_db = Chroma.from_documents(
    docs, 
    openai_embeddings,
    persist_directory="./chroma_db"  # 持久化存储路径
)

# 保存Chroma数据库
chroma_db.persist()

# 使用Milvus(分布式向量数据库,适合大规模部署)
milvus_db = Milvus.from_documents(
    docs,
    openai_embeddings,
    connection_args={"host": "localhost", "port": "19530"}
)

检索器

基本检索

从向量存储中检索文档:

# 将向量存储转换为检索器
retriever = chroma_db.as_retriever()

# 自定义检索参数
custom_retriever = chroma_db.as_retriever(
    search_type="similarity",  # 相似度搜索
    search_kwargs={"k": 5}  # 返回前5个最相关文档
)

# 执行检索
query = "人工智能的应用场景有哪些?"
relevant_docs = retriever.get_relevant_documents(query)

# 显示检索结果
for i, doc in enumerate(relevant_docs):
    print(f"结果 {i+1}: {doc.page_content[:100]}...")
    print(f"来源: {doc.metadata.get('source', '未知')}\n")

检索增强生成 (RAG)

基础RAG实现

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI

# 创建检索链
def format_docs(docs):
    return "\n\n".join([doc.page_content for doc in docs])

# 创建RAG提示模板
template = """请根据以下上下文回答问题。如果上下文中没有提供足够的信息,就说你不知道。

上下文:
{context}

问题:{question}

回答:"""

prompt = ChatPromptTemplate.from_template(template)

# 创建RAG链
rag_chain = {
    "context": retriever | format_docs,
    "question": RunnablePassthrough()
} | prompt | ChatOpenAI(temperature=0) | StrOutputParser()

# 执行RAG查询
result = rag_chain.invoke("深度学习和机器学习有什么区别?")
print(result)

高级RAG模式

对话RAG
from langchain_core.prompts import MessagesPlaceholder
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory

# 创建带对话历史的RAG提示
conversational_rag_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个基于上下文的问答助手。使用提供的上下文回答用户问题。"),
    MessagesPlaceholder(variable_name="chat_history"),
    ("human", "{question}"),
    ("system", "上下文信息:\n{context}")
])

# 创建对话历史
chat_history = ChatMessageHistory()

# 对话RAG链
conversational_rag_chain = {
    "context": retriever | format_docs,
    "question": RunnablePassthrough(),
    "chat_history": lambda _: chat_history.messages
} | conversational_rag_prompt | ChatOpenAI() | StrOutputParser()

最佳实践

  1. 文档分割策略:根据文档类型选择适当的分割方法

    • 通用文本:使用RecursiveCharacterTextSplitter
    • 代码:使用专用代码分割器
    • 结构化文档:使用专用分割器如MarkdownHeaderTextSplitter
  2. 选择合适的块大小

    • 太大:检索精度低,但可能包含更完整信息
    • 太小:检索精度高,但可能缺乏上下文
    • 推荐:普通文本500-1000 tokens,技术文档300-500 tokens
  3. 中文检索优化

    • 使用专为中文优化的嵌入模型
    • 使用中文分词进行文本分割
    • 考虑检索更多文档以提高召回率
  4. 检索系统部署考虑

    • 小规模/本地测试:FAISS、Chroma
    • 中等规模/生产:Weaviate、Pinecone
    • 大规模/企业级:Milvus、Elasticsearch with vector search

总结

检索系统是LangChain中连接大语言模型与外部知识的关键组件。通过文档加载、文本处理、向量嵌入和检索,可以构建强大的知识增强型应用。RAG架构将检索系统与生成模型结合,创建了一种既有知识深度又能保持对话灵活性的AI应用框架。

后续学习

  • 模型输入输出 - 了解如何与语言模型交互
  • 链 - 学习如何将检索系统集成到复杂流程中
  • 智能体|后续更新 - 探索将检索系统与自主智能体结合

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2332475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Fast网络速度测试工具

目录 网站简介 功能特点 测试过程 为什么使用Fast 如果网络速度不达标 网站简介 Fast是一个由Netflix提供的网络速度测试工具,主要用来测试用户的互联网下载速度。它以其简洁的界面和快速的测试过程而受到用户的欢迎。 功能特点 下载速度测试:这是…

ubuntu20.04在mid360部署direct_lidar_odometry(DLO)

editor:1034Robotics-yy time:2025.4.10 1.下载DLO,mid360需要的一些...: 1.1 在工作空间/src下 下载DLO: git clone https://github.com/vectr-ucla/direct_lidar_odometry 1.2 在工作空间/src下 下载livox_ros_driver2&…

制造企业数据治理体系搭建与业务赋能实践

当下制造企业正面临着前所未有的机遇与挑战,从多环节业务协同的复杂性,到海量数据资源的沉睡与孤岛化;从个性化定制需求的爆发,到供应链效率优化的迫切性——如何通过数据治理将“数据包袱”转化为“数据资产”,已成为…

【LunarVim】解决which-key 自定义键位注册不成功问题

问题描述 LunarVim将which-key设置放在一个keymaps.lua中,然后config.lua调用reload “user.keymaps”,键位没用注册成功,而直接写在config.lua中,就注册成功 这暴露了LunarVim 插件和配置加载顺序的一些细节坑,下面解…

开源推荐#5:CloudFlare-ImgBed — 基于 CloudFlare Pages 的开源免费文件托管解决方案

大家好,我是 jonssonyan。 寻找一个稳定、快速、还最好是免费或成本极低的图床服务,一直是许多开发者、博主和内容创作者的痛点。公共图床可能说关就关,付费服务又增加成本。现在,一个名为 CloudFlare-ImgBed 的开源项目&#xf…

算法训练之动态规划(三)

♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨ 个…

xv6-labs-2024 lab2

lab-2 0. 前置 课程记录 操作系统的隔离性,举例说明就是,当我们的shell,或者qq挂掉了,我们不希望因为他,去影响其他的进程,所以在不同的应用程序之间,需要有隔离性,并且&#xff0…

基于FPGA实现BPSK 调制

目录 一、 任务介绍二、基本原理三、基于FPGA实现BPSK 调制四、源码 一、 任务介绍 BPSK 调制在数字通信系统中是一种极重要的调制方式,它的抗干扰噪声性能及通频带的利用率均优先于 ASK 移幅键控和 FSK 移频键控。因此,PSK 技术在中、高速数据传输中得…

在排序数组中查找元素的第一个和最后一个位置 --- 二分查找

目录 一:题目 二:算法原理分析 三:代码实现 一:题目 题目链接: 34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode) 二:算法原理分析 三:代码实现 c…

631SJBH中小型企业的网络管理模式的方案设计

1.1、研究现状 我国很多企业信息化水平一直还处在非常初级的阶段,有关统计表明,真正实现了计算机较高应用的企业在全国1000多万中小企业中所占的比例还不足10%幢3。大多数企业还停留在利用互联网进行网上查询(72.9%)、…

LangChain4j(1):初步认识Java 集成 LLM 的技术架构

LangChain 作为构建具备 LLM 能力应用的框架,虽在 Python 领域大放异彩,但 Java 开发者却只能望洋兴叹。LangChain4j 正是为解决这一困境而诞生,它旨在借助 LLM 的强大效能,增强 Java 应用,简化 LLM 功能在Java应用中的…

【C++算法】53.链表_重排链表

文章目录 题目链接:题目描述:解法C 算法代码: 题目链接: 143. 重排链表 题目描述: 解法 模拟 找到链表的中间节点 快慢双指针 把后面的部分逆序 双指针,三指针,头插法 合并两个链表 合并两个有…

多卡分布式训练:torchrun --nproc_per_node=5

多卡分布式训练:torchrun --nproc_per_node=5 1. torchrun 实现规则 torchrun 是 PyTorch 提供的用于启动分布式训练作业的实用工具,它基于 torch.distributed 包,核心目标是简化多进程分布式训练的启动和管理。以下是其主要实现规则: 进程启动 多进程创建:torchrun 会…

Elasticsearch:加快 HNSW 图的合并速度

作者:来自 Elastic Thomas Veasey 及 Mayya Sharipova 过去,我们曾讨论过搜索多个 HNSW 图时所面临的一些挑战,以及我们是如何缓解这些问题的。当时,我们也提到了一些计划中的改进措施。本文正是这项工作的成果汇总。 你可能会问…

图片中文字无法正确显示的解决方案

图片中文字无法正确显示的解决方案 问题描述 在 Linux 系统中生成图片时,图片中的文字(如中文)未能正确显示,可能表现为乱码或空白。这通常是由于系统缺少对应的字体文件(如宋体/SimSun),或者…

ISP--Demosaicking

文章目录 前言算法解释简单的线性插值代码实现 色差法和色比法基于方向加权的方法RB缺失的G通道的插值RB缺失的BR的插值G缺失的BR的插值代码实现 基于边缘检测的方法计算缺失的G计算缺失的RB值/计算缺失的G值 前言 人眼之所以有能感受到自然界的颜色,是因为人眼的感…

国标GB28181协议EasyCVR视频融合平台:5G时代远程监控赋能通信基站安全管理

一、背景介绍 随着移动通信行业的迅速发展,无人值守的通信基站建设规模不断扩大。这些基站大多建于偏远地区,周边人迹罕至、交通不便,给日常的维护带来了极大挑战。其中,位于空旷地带的基站设备,如空调、蓄电池等&…

模拟-与-现实协同训练:基于视觉机器人操控的简单方法

25年3月来自 UT Austin、Nvidia、UC Berkeley 和纽约大学的论文“Sim-and-Real Co-Training: A Simple Recipe for Vision-Based Robotic Manipulation”。 大型现实世界机器人数据集在训练通才机器人模型方面拥有巨大潜力,但扩展现实世界人类数据收集既耗时又耗资…

WRS-PHM电机智能安康系统:为浙江某橡胶厂构筑坚实的生产防线

以行业工况为背景 一、顾客工厂的背景 浙江某橡胶厂以电机为中心生产设备必须连续平稳运行。但由于缺乏有效的故障预警体系,电机故障就像潜伏着的“不定时炸弹”,不但不时地造成生产流程的中断,也使对生产进行管理异常艰难,对持续安全生产提…

将 CrewAI 与 Elasticsearch 结合使用

作者:来自 Elastic Jeffrey Rengifo 学习如何使用 CrewAI 为你的代理团队创建一个 Elasticsearch 代理,并执行市场调研任务。 CrewAI 是一个用于编排代理的框架,它通过角色扮演的方式让多个代理协同完成复杂任务。 如果你想了解更多关于代理…