尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

RAG23-RAG28

RAG23-RAG28 RAG23LangChain 文档加载器 DocumentLoader CSVLoader 笔记一、核心概念1. 文档加载器作用提供标准接口读取 PDF/CSV/JSON 等不同来源数据统一转为 LangChain 的Document对象做到一致化处理。所有加载器内置 / 自定义都继承实现BaseLoader接口。2. Document 类文档统一载体所有文档加载器最终返回Document实例from langchain_core.documents import Document doc Document( page_contentHello, world!, # ✅文档正文内容 metadata{source: https://example.com} # ✅元数据字典格式记录来源、行号等信息 )page_content文档文本内容metadata元数据记录来源文件、行号、页码等附加信息3. BaseLoader 的两个核心方法表格方法说明适用场景load()一次性全部加载返回List[Document]小文件全部读到内存lazy_load()延迟流式加载返回生成器for 循环迭代获取超大文件防止内存溢出所有加载器都具备这两个方法。4. CSVLoader专门用来读取 csv 文件每一行 csv 生成一个Document对象。每一行 csv → 一个 Document 实例page_content该行各个字段拼接文本metadata记录文件 source、row 行号关键参数file_path文件路径encoding文件编码一般utf‑8csv_args字典底层传给 python csv 库可配置分隔符delimiter、引号quotechar、无表头时指定fieldnames字段名⚠️fieldnames无表头 csv 才使用如果 csv 自带表头不要配置否则会把表头当成数据行。二、完整可运行代码示例 1基础 CSVLoader load () 一次性加载from langchain_community.document_loaders.csv_loader import CSVLoader # 1. 创建加载器 loader CSVLoader( file_path./data/stu.csv, encodingutf-8 ) # 2. load()一次性全部加载到内存返回Document列表 documents loader.load() # 遍历打印查看每一个Document对象 for doc in documents: print(type(doc)) print(page_content:\n, doc.page_content) print(metadata:, doc.metadata) print(- * 50)示例 2自定义 csv 解析参数 csv_argsfrom langchain_community.document_loaders.csv_loader import CSVLoader loader CSVLoader( file_path./data/stu.csv, encodingutf-8, csv_args{ delimiter: ,, # 指定字段分隔符 quotechar: , # 字符串包裹引号 # fieldnames: [name,age,gender] # 无表头csv才打开这个配置 } ) documents loader.load() for d in documents: print(d)示例 3lazy_load () 流式大文件加载生成器节省内存from langchain_community.document_loaders.csv_loader import CSVLoader loader CSVLoader( file_path./data/stu.csv, encodingutf-8 ) # lazy_load 返回生成器不会一次性全部载入内存适合超大csv for doc in loader.lazy_load(): print(doc.page_content) print(doc.metadata) print(*40)三、运行注意事项目录结构P3_LangChainRAG开发 ├─ data │ └─ stu.csv └─ 22CSVLoader的使用.py安装依赖pip install langchain langchain-community langchain-corestu.csv 示例内容name,age,gender 王梓涵,25,男 刘若曦,22,女 陈俊宇,20,男 赵思瑶,28,女 黄浩然,15,男 林雨桐,20,女 周博文,20,男 吴诗琪,24,女 马子轩,22,男 孙悦然,27,女输出效果每一行 csv 生成一个 Document 对象metadata包含source文件路径和row行号。四、面试简答速记Document 有哪两个核心属性page_content文档正文metadata元数据字典。load()和lazy_load()区别load()一次性加载全部文档返回列表小文件大文件会内存溢出。lazy_load()生成器流式迭代读取边读边处理适合大文件避免内存爆掉。CSVLoader 读取 csv一行 csv 对应几个 Document 一行 csv 生成一个 Document 对象。官方文档地址https://docs.langchain.com/oss/python/integrations/document_loadersRAG24、LangChain JSONLoader 笔记一、概述JSONLoader把 JSON 文件加载为 LangChain 的Document文档对象用于 RAG 知识库构建。⚠️ 依赖第三方库jq需要手动安装pip install jq底层依靠 jq 做 JSON 解析通过jq_schema语法抽取 JSON 里面的数据。jq_schema 抽取语法规则表格语法含义.代表 JSON 根对象[]代表数组.name抽取根下 name 字段.hobby[1]抽取 hobby 数组的第 2 个元素下标从 0 开始.other.addr嵌套对象取值取 other 里面 addr.[]遍历数组取出数组中每一个字典对象.[].name遍历数组取出数组每个对象的 name 字段三种 JSON 文件格式普通对象 stu.json{ name: 周杰伦, age: 11, hobby: [唱, 跳, RAP], other: { addr: 深圳, tel: 12332112321 } }数组 JSON stus.json外层[]包裹内部多个对象[ {name: 周杰伦, age: 11, gender: 男}, {name: 蔡依临, age: 12, gender: 女}, {name: 王力宏, age: 11, gender: 男} ]JsonLines 文件 stu_json_lines.jsonjson_linesTrue每行一个独立 json 对象整体没有外层数组{name: 周杰伦, age: 11, gender: 男} {name: 蔡依临, age: 12, gender: 女} {name: 王力宏, age: 11, gender: 男}二、JSONLoader 构造参数from langchain_community.document_loaders import JSONLoader loader JSONLoader( file_pathxxx.json, # 必填json文件路径 jq_schema., # 必填jq抽取表达式 text_contentTrue, # 可选默认True抽取结果转为字符串作为page_contentFalse保留dict对象 json_linesFalse # 可选默认FalseTrue代表文件是JsonLines格式每行一个json )file_path文件路径必填jq_schemajq 抽取语法必填text_contentTrue把抽取内容转字符串放到page_contentFalse则page_content为字典对象json_lines是否是 JsonLines 文件每行一条 json默认 False调用loader.load()返回List[Document]。三、完整可运行代码文件目录./data/下放三个 json 文件from langchain_community.document_loaders import JSONLoader print(案例1读取普通对象stu.json抽取name字段) loader1 JSONLoader( file_path./data/stu.json, jq_schema.name ) docs1 loader1.load() for doc in docs1: print(doc.page_content) print(doc.metadata) print(\n案例2读取stu.json抽取hobby数组第二个元素) loader2 JSONLoader( file_path./data/stu.json, jq_schema.hobby[1] ) docs2 loader2.load() print(docs2[0].page_content) print(\n案例3读取数组 stus.json遍历数组取出全部对象) loader3 JSONLoader( file_path./data/stus.json, jq_schema.[] ) docs3 loader3.load() for idx, doc in enumerate(docs3): print(f{idx1}: {doc.page_content}) print(\n案例4读取数组 stus.json只抽取所有name) loader4 JSONLoader( file_path./data/stus.json, jq_schema.[].name ) docs4 loader4.load() for doc in docs4: print(doc.page_content) print(\n案例5读取JsonLines格式 stu_json_lines.json) loader5 JSONLoader( file_path./data/stu_json_lines.json, jq_schema., json_linesTrue ) docs5 loader5.load() for doc in docs5: print(doc.page_content)四、重点总结RAG25必须安装依赖pip install jq否则报错jq_schema是核心控制提取哪些内容.代表根.[]遍历数组json_linesTrue专门处理每行一个独立 JSON的文件不要用于普通数组 jsontext_contentFalsepage_content是字典True会自动序列化为字符串RAG 场景一般保持默认 Trueload()返回List[Document]每个 Document 包含page_content和metadata会自带 source、seq_num 元数据五、常见坑jq 语法写错返回空文档注意数组下标从 0 开始混淆普通数组 json 和 json‑lines 文件数组 json 不要设置json_linesTrue文件路径错误相对路径注意 py 文件执行位置没有安装 jq 库直接运行直接抛出异常RAG25、课程笔记TextLoader 和 RecursiveCharacterTextSplitter1、TextLoader 文本加载器作用读取.txt文本文件把整个文件全部内容封装成 1 个 Document 对象返回[Document]所以len(docs)1。导入from langchain_community.document_loaders import TextLoader参数文件路径file_pathencoding文件编码中文 txt 一般填utf-8防止乱码方法.load()加载文档返回 Document 列表注意TextLoader 不会做文本切分不管 txt 多大全部塞进一个 Document大文件必须配合文本分割器做分片。2、RecursiveCharacterTextSplitter 递归字符文本分割器LangChain官方默认推荐的分割器开箱即用效果最好。核心特点递归按照separators分隔符列表依次切割优先按换行、句号等自然语义切割兼顾上下文完整性 控制分片大小。chunk_size每个分片最大字符数chunk_overlap分片之间重叠字符解决被切到句子中间丢失上下文的问题。separators分割优先级列表优先用前面符号切割切完还超长度就用下一个符号。length_functionlen使用 len 函数统计字符长度。方法.split_documents(docs)对 loader 加载出来的 Document 列表做分片返回多个小 Document。依赖安装pip install langchain-text-splitters完整可运行代码from langchain_community.document_loaders import TextLoader from langchain_text_splitters import RecursiveCharacterTextSplitter # 1. 加载txt文本文件 loader TextLoader( file_path./data/Python基础语法.txt, encodingutf-8 ) # 得到完整文档只有1个Document docs loader.load() print(f加载后原始文档数量: {len(docs)}) # 2. 创建递归字符分割器 splitter RecursiveCharacterTextSplitter( chunk_size500, # 每一块最大字符数 chunk_overlap50, # 块与块重叠字符 # 分割优先级优先双换行其次单换行再句号、感叹号等 separators[\n\n, \n, 。, , , ., !, ?, , ], length_functionlen # 使用len统计字符长度 ) # 3. 执行文档切分 split_docs splitter.split_documents(docs) print(f切分之后分片数量{len(split_docs)}) # 遍历打印每一个分片 for idx, doc in enumerate(split_docs): print( * 30 f 分片{idx1} * 30) print(doc.page_content) print( * 70)知识点总结TextLoader只负责读取 txt输出单个 Document 对象的列表不做分片。RecursiveCharacterTextSplitterRAG 开发最常用分片工具按自然语义递归切割不是暴力按字符截断chunk_overlap重叠很关键保证语义不会因为切割丢失separators 有优先级优先用列表靠前的符号分割RAG 标准流水线Loader加载文档 → TextSplitter切分文档 → 向量化存入向量库。面试高频问题Q为什么要设置 chunk_overlap A防止一个完整语义句子被切分到两个 chunk检索的时候上下文断裂分片之间保留一部分重叠文本保证语义连续性。QRecursiveCharacterTextSplitter 和普通 CharacterTextSplitter 区别 A普通分割器只用一个分隔符切割递归分割器是一组分隔符递归尝试优先用大粒度分隔符保证尽可能在语义边界切分效果更好。RAG26、课程笔记PyPDFLoader PDF 文档加载器1、简介PyPDFLoaderLangChain 社区提供的 PDF 文件加载器底层依赖pypdf库只提取 PDF 里面的文本内容不能解析图片、扫描版 PDF。安装依赖pip install pypdf导入from langchain_community.document_loaders import PyPDFLoader构造参数表格参数说明file_path必填pdf 文件路径mode读取模式page默认每一页生成 1 个 Document 对象single把整个 PDF 全部内容合并为1 个 Documentpassword可选加密 PDF 的访问密码两种加载方法.load()一次性全部加载返回List[Document]小文件用大 PDF 会占用较多内存。.lazy_load()惰性加载迭代器一页一页读取不会一次性把全部内容载入内存处理大 PDF 推荐使用。Document 对象的metadata元数据会自动携带页码信息{page: 页码}。完整可运行代码from langchain_community.document_loaders import PyPDFLoader # 1.实例化加载器 loader PyPDFLoader( file_path./data/pdf1.pdf, modepage, # 默认page模式一页一个Document # password # 如果pdf加密填写密码 ) # ----------------方式1load() 一次性全部加载---------------- docs loader.load() print(f总页数/文档数量{len(docs)}) for idx, doc in enumerate(docs): print( * 40 f 第{doc.metadata[page]1}页 *40) print(doc.page_content) # ----------------方式2lazy_load() 惰性加载大文件推荐---------------- i 0 for doc in loader.lazy_load(): i 1 print( * 30, i) print(f页码元数据{doc.metadata}) print(doc.page_content)结合 RecursiveCharacterTextSplitter 完整 RAG 流水线PDF → 分片PDF 一页的文本依然很长实际 RAG 项目中PDF 加载完成后仍然要交给分割器做语义分片from langchain_community.document_loaders import PyPDFLoader from langchain_text_splitters import RecursiveCharacterTextSplitter # 1.加载PDF loader PyPDFLoader(file_path./data/pdf1.pdf) pdf_docs loader.load() # 2.初始化分割器 splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap50, separators[\n\n, \n, 。, , , ., !, ?, , ], length_functionlen ) # 3.对PDF文档做切分 split_docs splitter.split_documents(pdf_docs) print(f原始pdf页数{len(pdf_docs)}切分后分片总数{len(split_docs)}) # 查看分片 for chunk in split_docs[:3]: print(-*50) print(chunk.page_content) print(f来源页码{chunk.metadata[page]})重点总结modepage一页对应一个 Documentmetadata 自带页码方便溯源single模式全部合并成 1 个 Document。.load()一次性加载.lazy_load()惰性迭代读取大 PDF 优先用 lazy_load降低内存占用。局限只能解析可复制文本的 PDF扫描件、图片型 PDF 无法提取文字此时要用 PyMuPDFLoader / UnstructuredLoader 或者 OCR 工具。项目流程PyPDFLoader加载PDF → RecursiveCharacterTextSplitter分片 → 向量化存入向量库。面试小问题Qload()和lazy_load()的区别 Aload()把所有文档全部读到内存返回完整列表小文件方便大 PDF 内存开销大。lazy_load()返回迭代器按需一页一页读取不会一次性加载全部内容内存友好适合大体积 PDF 文件。QPyPDFLoader 可以处理扫描版 PDF 吗 A不行。扫描 PDF 本质是图片没有文本流PyPDF 拿不到文字需要 OCR 识别方案。RAG27、Vector stores 向量存储 课程笔记这节课是 RAG 的核心向量存储就是用来保存文本转出来的向量做相似度检索。分为内存版InMemoryVectorStore和持久化磁盘版Chroma一、RAG 向量存储完整流程分为两大阶段索引 / 存储阶段把文档入库原始文档 → Embedding嵌入模型 → 嵌入向量 → 存入向量数据库查询 / 检索阶段用户提问用户查询文本 → Embedding嵌入模型 → 查询向量 → 相似度搜索 → 返回Top‑k最相似文档通俗理解 把一堆文档变成一堆数字数组向量存起来用户提问也转成向量计算和库里哪个向量最接近把对应的原文拿出来给大模型参考。二、LangChain 向量存储统一 3 个接口所有向量库都有这 3 套方法add_documents(documents, ids)新增文档指定 iddelete(ids[...])根据 id 删除文档similarity_search(query, kN)相似度检索k代表返回几条最相似的结果k4就是取匹配度最高的 4 条文档三、第一种内存向量存储 InMemoryVectorStore✅特点数据放在内存程序关闭数据全部丢失只适合练习、测试不能生产环境使用。完整可运行代码from langchain_core.vectorstores import InMemoryVectorStore from langchain_community.embeddings import DashScopeEmbeddings from langchain_community.document_loaders import CSVLoader # 1.初始化内存向量存储指定阿里百炼的嵌入模型 vector_store InMemoryVectorStore(embeddingDashScopeEmbeddings()) # 2.加载csv文档 info.csv loader CSVLoader( file_path./data/info.csv, encodingutf-8, source_columnsource # metadata里标记数据来源 ) documents loader.load() # 3.把文档写入向量库手动生成id vector_store.add_documents( documentsdocuments, ids[idstr(i) for i in range(1, len(documents)1)] ) # 4.根据id删除文档 vector_store.delete(ids[id1,id2]) # 5.相似度检索 k3 返回3条结果 result vector_store.similarity_search( queryPython是不是简单易学, k3 ) # 打印检索结果 for doc in result: print(page_content, doc.page_content) print(metadata, doc.metadata) print(-*50)运行输出解读返回的是list[Document]对象page_content原始文本内容metadata元数据记录来源、行号 row、文档 id 等信息exit code 0代表代码无报错执行成功。内存版坑点程序一旦停止运行内存释放所有向量全部消失。重启代码需要重新加载文档、重新向量化。四、第二种Chroma 外部持久化向量存储✅特点向量数据保存到本地磁盘文件sqlite 数据库程序关闭数据不会丢下次启动可以直接读取适合做项目开发。需要先安装依赖pip install langchain-chroma chromadb完整可运行代码from langchain_chroma import Chroma from langchain_community.embeddings import DashScopeEmbeddings from langchain_community.document_loaders import CSVLoader # 1.初始化Chroma向量库 vector_store Chroma( collection_nametest, # 集合名相当于表名 embedding_functionDashScopeEmbeddings(), # 嵌入模型 persist_directory./chroma_db # 磁盘文件夹数据保存在这里 ) # 2.加载csv文档 loader CSVLoader( file_path./data/info.csv, encodingutf-8, source_columnsource ) documents loader.load() # 3.写入向量库 vector_store.add_documents( documentsdocuments, ids[idstr(i) for i in range(1, len(documents)1)] ) # 4.删除文档 vector_store.delete(ids[id1,id2]) # 5.相似度检索 result vector_store.similarity_search( queryPython是不是简单易学, k3 ) for doc in result: print(doc.page_content) print(doc.metadata) print(-*50)Chroma 底层原理运行之后项目目录生成chroma_db文件夹里面是chroma.sqlite3数据库文件。embeddings 表存放二进制格式向量数组segments 表存放原始文本片段可以直接用数据库工具打开 sqlite 文件查看底层表结构。Chroma 重点注意持久化关闭程序向量还保存在磁盘再次运行代码不需要重新 add_documents直接 new Chroma 读取文件夹就可以检索。如果重复执行add_documents会重复插入相同文档产生重复向量。五、内存版 vs Chroma 对比表表格对比项InMemoryVectorStore内存Chroma磁盘持久化数据存储位置内存本地 sqlite 磁盘文件程序重启数据全部丢失数据保留适用场景课程练习、demo 快速测试本地 RAG 项目开发接口方法add_documents / delete / similarity_search完全一模一样的 API✨LangChain 设计思想两套向量存储对外 API 完全统一你写好业务代码想切换存储只需要改初始化那一行后面增删查代码不用改动。六、常见看不懂的知识点通俗解释什么是 Embedding 向量一段文字交给嵌入模型输出一串浮点数数字数组语义越接近的文本向量数字越接近。相似度搜索本质在计算向量之间的距离。k 参数是什么similarity_search(xxx,k3)k 就是我要从向量库里拿出语义匹配度最高的 k 条文档给大模型做参考。k 不能太大会把无关内容带进来。ids 参数干嘛用每一条文档给一个唯一字符串 id后续想删除哪条数据直接传 id 列表就可以精准删除对应向量和文本。Document 对象是什么LangChain 封装文档对象page_content存正文metadata存附加信息来源、行号所有 loader 加载完文件输出都是list[Document]。CSVLoader 参数source_columncsv 文件有一列叫 source这一列的值自动保存到 Document 的 metadata用来标记这条数据来自哪里。七、踩坑清单InMemoryVectorStore跑完程序数据就没了不要拿来做正式项目。Chroma 如果重复运行 add_documents会重复导入产生重复向量。DashScopeEmbeddings 需要配置环境变量DASHSCOPE_API_KEY否则向量化会报错。csv 文件必须保存 utf‑8 编码否则 CSVLoader 读取中文乱码。八、面试简答巩固QInMemoryVectorStore 和 Chroma 有什么区别 AInMemoryVectorStore 数据存内存程序退出丢失适合练习Chroma 持久化到本地 sqlite 磁盘重启数据保留。LangChain 提供统一接口增删检索代码完全一致。Qsimilarity_search 的 k 参数含义 Ak 代表返回相似度最高的文档数量。Q向量存储在 RAG 中起到什么作用 A存储文档对应的 embedding 向量用户提问时把提问文本转为向量做相似度检索召回相关原文交给大模型参考生成答案。RAG28、课程向量检索构建提示词课程核心理解通俗大白话这就是极简版 RAG 完整流程先把一些参考文档放到内存向量库InMemoryVectorStore内存版程序关掉数据就消失不用磁盘文件适合上课练习用户输入问题怎么减肥向量库做相似度检索拿出最相关的 2 条参考文本把检索出来的参考资料塞到 Prompt 模板的{context}占位符用户问题塞到{input}占位符交给大模型你只能参考我给你的资料来回答不要瞎编通过 LangChain 的管道符|组装 chain 链路执行拿到回答重点InMemoryVectorStore内存向量库不会保存到硬盘程序关闭所有数据清空只适合学习测试生产用 Chroma/Milvus。完整可直接运行代码 28 向量检索构建提示词.py 提示词用户的提问 向量库中检索到的参考资料 极简RAG演示 InMemoryVectorStore内存向量库 from langchain_community.chat_models import ChatTongyi from langchain_core.vectorstores import InMemoryVectorStore from langchain_community.embeddings import DashScopeEmbeddings from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser # 1.初始化大模型 model ChatTongyi(modelqwen3-max) # 2.构建提示词模板 prompt ChatPromptTemplate.from_messages( [ (system, 以我提供的已知参考资料为主简洁和专业的回答用户问题。参考资料:{context}。), (user, 用户提问: {input}) ] ) # 3.初始化内存向量库指定阿里embedding向量化模型 vector_store InMemoryVectorStore(embeddingDashScopeEmbeddings(modeltext-embedding-v4)) # 4.add_texts把参考文本列表存入向量库内部自动做embedding vector_store.add_texts([ 减肥就是要少吃多练, 在减脂期间吃东西很重要清淡少油控制卡路里摄入并运动起来, 跑步是很好的运动哦 ]) # 用户问题 input_text 怎么减肥 # 5.相似度检索 k2取出最匹配的2条文档 result vector_store.similarity_search(input_text, k2) # 6.循环拼接检索出来的文档内容组装参考上下文 reference_text [ for doc in result: # doc.page_content 就是原始文本内容 reference_text doc.page_content reference_text ] # 小工具函数打印中间生成的prompt方便调试看传给大模型的完整消息 def print_prompt(prompt_value): print(prompt_value.to_string()) print(*20) return prompt_value # 7.使用LCEL管道 | 组装执行链 chain prompt | print_prompt | model | StrOutputParser() # 8.invoke传入参数字典填充模板里面两个占位符 context、input res chain.invoke({input: input_text, context: reference_text}) print(大模型最终回答) print(res)课程笔记1. InMemoryVectorStore 内存向量库特点全部数据在内存程序退出全部丢失不会生成本地文件适合课堂快速实验不用管理 chroma_db 文件夹方法add_texts(字符串列表)批量存入文本内部自动调用 Embedding 转为向量similarity_search(query, kN)相似度检索返回 Top‑k 最相似的 Document 对象返回值 result 是 Document 对象列表doc.page_content原始文本内容doc.metadata元数据信息2. RAG 在这里完整执行步骤向向量库写入知识库文本用户提问similarity_search检索获取相关文档片段循环遍历检索结果拼接成reference_text参考上下文提示词模板有两个占位符{context}放向量库检索出来的参考资料{input}放用户真实问题LCEL 链路prompt | print_prompt | model | StrOutputParser()prompt填充占位符生成完整消息print_prompt自定义中间函数打印中间 prompt调试神器看你到底传给模型什么文字model通义千问大模型StrOutputParser()把 ChatMessage 对象提取成普通字符串chain.invoke({input:xxx, context:xxx})传入字典给两个占位符赋值3. 容易看不懂的地方拆解①reference_text [循环拼接reference_text [ for doc in result: reference_text doc.page_content reference_text ]通俗讲把检索出来 2 段文字拼在一起外面包[ ]作为完整参考资料丢进 prompt 的{context}。②print_prompt自定义函数为什么可以放进管道|LCEL 管道|支持放入普通函数输入是上一步输出return 给下一级。 作用调试运行时控制台打印出完整发给大模型的 prompt 字符串方便排查为什么模型回答不对。③ invoke 传参字典chain.invoke({input: input_text, context: reference_text})模板里面有几个占位符invoke 字典就要传几个 key。模板写了{context}和{input}字典就必须带上这两个 key。4. 和 Chroma 向量库区别对比表格项目InMemoryVectorStoreChroma存储位置内存本地磁盘文件夹 persist_directory持久化❌关闭程序数据消失✅保存到磁盘下次运行还在适用场景上课快速 demo真实 RAG 项目开发5. 常见踩坑点忘记配置DASHSCOPE_API_KEY环境变量运行 Embedding 直接报错similarity_search(k2)k 不能大于向量库里面文档总条数invoke 字典 key 名必须和模板占位符名字完全一致大小写敏感InMemoryVectorStore 重启代码必须重新执行add_texts添加数据内存清空了6. 本节课 RAG 核心逻辑简答题面试常考向量存储检索匹配相关参考信息将用户提问、检索出来的参考资料一起填入提示词模板将组装完整提示词交给大模型得到回答核心思想不修改模型权重外部给资料让模型基于给的资料回答。运行前确认环境变量配置好DASHSCOPE_API_KEY已经安装依赖包pip install langchain langchain-community langchain-core dashscope
返回列表