ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

LangChain向量检索指南:Retriever 使用、自定义与 RAG 项目落地

LangChain向量检索指南:Retriever 使用、自定义与 RAG 项目落地 我挖掘了一个巨牛的 人工智能 学习网站通俗易懂风趣幽默忍不住分享一下给大家。点击跳转到网站。1 相关概念1.1 检索系统 IR System定义信息检索系统Information Retrieval System面向大规模非结构化数据自动、高效完成信息查找、排序、返回核心目标在正确时间、用正确方式把正确信息交付用户。 最典型实例百度、Google 通用搜索引擎也是 RAG 大模型应用的核心底层组件。三类主流检索系统实现方案检索系统类型底层原理适用场景关系数据库SQL 精确匹配结构化行列存储表格结构化数据精确字段查询词法搜索索引倒排索引关键词词频匹配传统全文检索ES、Solr字面关键词搜索向量数据库嵌入模型文本向量化余弦相似度语义检索RAG、语义搜索支持同义、模糊语义匹配1.2 检索器 Retriever定位检索系统对外的标准统一组件接口屏蔽底层存储差异关系库 / 倒排索引 / 向量库。统一输入输出规范LangChain 强制标准输入单个查询字符串query: str输出标准化List[Document]文档对象列表核心优势 上层业务代码无需关心底层用什么数据库切换检索引擎仅修改底层实例上层调用逻辑完全不变。举例 关系数据库检索器接收问题 → 自动翻译成 SQL → 查表 → 封装成 Document 返回 向量数据库检索器接收问题 → 自动调用嵌入模型生成查询向量 → 向量库相似检索 → 封装文档返回。2 使用向量数据库作为检索器2.1 基础使用 as_retriever ()1. 核心逻辑任意向量存储实例调用.as_retriever()方法快速封装为标准检索器对象VectorStoreRetriever属于 LangChain 内置开箱即用检索器。 检索器本质是Runnable标准组件支持invoke()统一调用。完整示例RedisVectorStorefrom langchain_openai import OpenAIEmbeddings from langchain_redis import RedisConfig, RedisVectorStore # 1. 初始化嵌入模型 embeddings OpenAIEmbeddings(modeltext-embedding-3-large) # 2. Redis向量库配置 redis_url redis://192.168.100.238:6379 config RedisConfig( index_nameqa, redis_urlredis_url, metadata_schema[ {name: category, type: tag}, {name: num, type: numeric}, ], ) vector_store RedisVectorStore(embeddings, configconfig) # 3. 向量库转为标准检索器 retriever vector_store.as_retriever() # 4. 统一invoke调用检索 docs retriever.invoke(数据库表怎么设计的) for doc in docs: print(* * 30) print(doc.page_content[:30])2. as_retriever 核心配置参数search_type 三种检索模式重点考点similarity默认基础相似度检索 只按余弦相似度从高到低返回 Top-K 文档速度最快但结果容易内容重复。 适用常规问答、事实查询。similarity_score_threshold相似度阈值过滤检索 仅返回相似度分数大于score_threshold的文档低于阈值直接丢弃杜绝无关噪声。 适用知识库杂乱、严格避免幻觉、宁可少返回也不要错误内容。mmr最大边际相关性检索 兼顾相关性 结果多样性先批量召回一批候选文档再剔除高度重复内容返回多角度不重复资料。 适用总结、多维度分析、长文本生成场景。search_kwargs 配套控制参数k最终返回文档数量默认 4fetch_kMMR 专用先批量召回的候选文档总数默认 20大于 k用来筛选多样性score_threshold阈值检索专用0~1越接近 1 匹配越严格filter元数据过滤函数先缩小检索范围再做向量匹配。代码示例不同检索模式配置# 示例1基础相似度只返回2条文档 retriever vector_store.as_retriever(search_kwargs{k: 2}) # 示例2MMR多样性检索最终返回2条先捞10条候选 retriever vector_store.as_retriever( search_typemmr, search_kwargs{ k: 2, fetch_k: 10 } ) # 示例3阈值过滤只返回相似度大于0.7的文档 retriever vector_store.as_retriever( search_typesimilarity_score_threshold, search_kwargs{k: 3, score_threshold: 0.7} )3. 检索器流式特性说明检索器是同步阻塞组件不支持真正流式分片输出 调用.stream(query)只会一次性返回完整文档列表和invoke()行为无区别不会分块推送数据。chunks [] for chunk in retriever.stream(数据库表怎么设计的): chunks.append(chunk) print(chunk, end|, flushTrue) # 一次性输出全部文档无分段流式效果2.2 自定义检索器 chain 装饰器实现1. 自定义检索器标准约束必须同时满足两条规则属于 LangChainRunnable可运行对象输入为字符串 query输出为List[Document]文档列表。2. chain 快速自定义实现chain装饰器可将普通函数自动转为 Runnable快速实现自定义检索逻辑灵活性更高可自由增加元数据过滤、多库混合检索等逻辑。from langchain_core.runnables import chain from typing import List from langchain_core.documents import Document # 自定义检索器底层复用向量库similarity_search chain def retriever(query: str) - List[Document]: # 可自由增加过滤、多数据源拼接逻辑 return vector_store.similarity_search(query, k2) # 统一invoke调用和内置retriever用法完全一致 docs retriever.invoke(数据库表怎么设计的) for doc in docs: print(* * 30) print(doc.page_content[:30])3. 重要区分通过chain实现的只是具备检索输入输出规范的 Runnable 函数并非 LangChain 原生BaseRetriever检索器实体原生检索器继承标准基类支持检索专属回调、链路事件埋点自定义链式函数不具备这类专属能力。3.串联前文完整 RAG 链路复盘文档加载 → 文本分割 → 嵌入模型生成向量 → 存入向量库离线建库向量库通过as_retriever()封装为标准检索器用户提问调用retriever.invoke(query) 自动执行embed_query生成查询向量 → 向量库相似检索 → 返回相关 Document检索文档 用户问题一起送入 LLM生成最终回答完整 RAG 流程易混概念区分向量数据库 VectorStore底层存储载体负责向量持久化、相似度计算仅提供基础 search 方法检索器 Retriever上层标准接口封装层统一输入输出适配 LCEL 链式编排可灵活切换检索策略similarity/mmr/threshold嵌入模型 Embedding唯一负责文本↔向量转换检索器内部自动调用无需手动编码。可涵的问题List [Document] 里面的 document 是 python 自定义的类型吗Document是 LangChain 框架自定义的 Python 类不是 Python 内置类型。1. 来源from langchain_core.documents import DocumentLangChain 单独封装这个类用来统一承载所有文档数据实现全框架标准化。2. Document 类固定三个属性page_content: str文档正文、文本内容核心字段metadata: dict元数据记录来源、文件名、分类、时间、索引 ID 等附加信息id: Optional[str]文档唯一标识向量库入库时会自动生成 UUID。示例手动创建from langchain_core.documents import Document doc Document( page_content数据库分表可以提升查询性能, metadata{source: 租房平台QA.md, category: 数据库} ) print(doc.page_content) print(doc.metadata)3. List [Document] 含义解析ListPython 标准类型注解代表列表DocumentLangChain 自定义类 合起来List[Document]元素全部是 Document 对象的列表。检索器返回值retriever.invoke(query)输出就是List[Document]统一接口不管底层是向量库、ES、MySQL 检索器返回格式完全一致。4. 和 Python 原生类型区分Python 内置自带list、tuple、dict、set、str、int…… Document 不属于内置必须导入 langchain_core 才能使用脱离 LangChain 环境不存在这个类型。5. 为什么要自定义 Document统一标准加载 Markdown、PDF、数据库、网页等不同来源文件全部封装成同一种对象统一携带元数据方便过滤、溯源适配全链路文本分割、向量入库、检索、RAG 拼接提示词全程通用不用自己封装字典传递文本。4.RAG 案例RAG 是大语言模型应用领域的主流核心实现范式。用户向大模型发起提问时系统首先调用嵌入模型在知识库内完成语义检索筛选出关联性最高的文档片段随后将检索得到的上下文与用户原始问题一同送入大模型由大模型结合参考素材生成回答。该方案能够有效优化回答的准确度同时解决模型知识截止带来的时效性缺陷。LangChain 中的检索器本身属于 Runnable 可运行对象依托链式调用语法可以便捷完成整套 RAG 业务逻辑。下面实现一套最简 RAG 示例完整执行流程分为 4 步根据用户查询 Query检索知识库中相关性最高的 4 份文档将检索返回的文档对象拼接为文本字符串作为后续大模型的上下文输入把用户查询 Query 与拼接完成的上下文文本共同传入对话大模型大模型生成结果后通过输出解析器完成结果格式化输出from langchain_openai import OpenAIEmbeddings, ChatOpenAI from langchain_redis import RedisConfig, RedisVectorStore from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough # 初始化对话大模型 model ChatOpenAI(modelgpt-4o-mini) # 初始化嵌入模型用于文本向量化 embeddings OpenAIEmbeddings(modeltext-embedding-3-large) # Redis向量数据库连接配置 redis_url redis://192.168.100.238:6379 config RedisConfig( index_nameqa, redis_urlredis_url, metadata_schema[ {name: category, type: tag}, {name: num, type: numeric}, ], ) # 实例化Redis向量存储对象 vector_store RedisVectorStore(embeddings, configconfig) # 基于向量存储构建检索器默认返回top‑4相关性文档 retriever vector_store.as_retriever() # 构造RAG提示词模板 prompt ChatPromptTemplate.from_messages( [ ( human, 你是专业问答助手请利用下方检索得到的上下文片段回答用户问题。 如果上下文无法提供有效信息直接回复不知道。回答控制在三句话以内输出简洁精炼。 Question: {question} Context: {context} Answer:, ), ] ) # 工具函数把Document文档列表拼接成纯文本字符串 def format_docs(docs): return \n\n.join(doc.page_content for doc in docs) # 组装RAG执行链 rag_chain ( {context: retriever | format_docs, question: RunnablePassthrough()} | prompt | model | StrOutputParser() ) # 执行RAG链路开启流式逐块返回结果 for chunk in rag_chain.stream(数据库表怎么设计的): print(chunk, end|, flushTrue)程序运行后流式打印输出示例|数据库|表|设计|可以|通过|水平|分|表|来|优化|性能||特别|是|当|单|表|数据|量|过|大|时|可以|减少|锁|争用|和|提升|查询|效率|。|实现|方式|是|将|状态|字段|独立|存储|在|house_status|表|中|并|通过|house_id|进行|关联|查询|。|使用|MySQL|和|MyBatis|进行|数据|存储|与|访问|同时|可以|利用|Redis|缓存|来|进一步|提高|性能|。|||补充说明检索器本身不支持流式读取检索属于同步阻塞 IO 操作。但整条 RAG 链路可以开启流式输出整条链路可以拆分为两个执行阶段准备阶段同步阻塞接收用户输入、执行向量检索、拼接文档、渲染提示词模板。这一步会完整执行完毕之后才会调用大模型生成阶段支持流式调用 LLM 服务大模型逐 token 返回生成内容。流式输出返回的仅仅是大模型生成的最终回答检索、文档拼接这类中间步骤不会产生流式分片。
返回列表