当前位置: 首页 > article >正文

【由浅入深探究langchain】第十七集-构建你的首个 RAG 知识库助手(从文档索引到检索增强生成)

前言在大语言模型LLM爆火的今天我们常常会被 GPT 或 Claude 展现出的博学所惊叹。然而当你试着问它“我公司昨晚新发布的财务报表数据是多少”或者“我上周在笔记里写的某个私人计划是什么”时LLM 往往会陷入尴尬的沉默甚至开始一本正经地胡说八道。这种现象被称为模型幻觉Hallucination。究其原因是因为 LLM 的知识库被“冻结”在了训练数据结束的那一刻Knowledge Cut-off它并不具备实时获取外部私有数据的能力。为了填补这一鸿沟RAGRetrieval-Augmented Generation检索增强生成应运而生。简单来说RAG 就像是给大模型配了一本“实时查阅的字典”或“私人图书馆”打破知识边界让模型能够访问实时新闻、企业内网文档或个人笔记。降低幻觉风险强制模型根据检索到的“事实依据”来回答问题知之为知之不知则引用原文。数据隐私保护无需将私有数据送去重新训练模型只需在本地或私有云构建索引即可。具体介绍可以查看前几集的博文。接下来的内容中我将结合实际代码带大家拆解 RAG 的两大核心流程索引阶段和检索生成阶段核心架构RAG 的双螺旋结构Indexing索引阶段 数据如何变成向量并入库。Generation生成阶段 用户提问后如何检索并合成回答。第一阶段建立索引 (Indexing Pipeline)索引阶段的目标是将凌乱的非结构化数据如网页、PDF、文档转化为 LLM 可以理解并快速检索的结构化向量数据。正好最近DOTA2这款游戏更新了新的版本文本内容高达十几万字而大模型不联网搜索的话肯定还没有预训练这部分内容我们就把它拿来做演示。数据加载在代码中我通过设置os.environ[USER_AGENT]和header_template模拟了真实的浏览器行为并利用urllib3.disable_warnings绕过了部分站点的 SSL 验证确保能够稳定抓取数据。虽然我暂时注释掉了bs_kwargs过滤器但在实际应用中利用SoupStrainer针对性地抓取 HTML 中的div.article-content是过滤网页广告、导航栏噪音的关键。page_url https://www.dota2.com.cn/article/details/20260325/220462.html bs4_strainer bs4.SoupStrainer() # 修改 Loader 部分 loader WebBaseLoader( web_paths(page_url,), header_template{User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0}, verify_sslFalse, # 先注释掉特定的过滤器抓取全文看看 # bs_kwargs{parse_only: bs4.SoupStrainer(div, class_article-content)} ) docs loader.load() print(f1. 原始文档数量: {len(docs)}) if len(docs) 0: print(f2. 原始内容预览 (前100字): {docs[0].page_content[:100].strip()}) else: print(错误未能抓取到任何内容请检查 URL 是否有效。) docs loader.load()文本分割text_splitter RecursiveCharacterTextSplitter( chunk_size 300, #每块token/chunk size越小块越多 chunk_overlap 50, #重叠部分 add_start_index True ) all_splitstext_splitter.split_documents(docs)向量化与本地存储embeding OllamaEmbeddings(modelnomic-embed-text:v1.5) from langchain_chroma import Chroma vector_storeChroma( collection_namedota2, embedding_functionembeding, persist_directory./chroma_dota2_db ) ids vector_store.add_documents(documentsall_splits)完整代码如下from langchain_community.document_loaders import WebBaseLoader from langchain_ollama import OllamaEmbeddings from langchain_text_splitters import RecursiveCharacterTextSplitter import bs4 import os import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) os.environ[USER_AGENT] Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 page_url https://www.dota2.com.cn/article/details/20260325/220462.html bs4_strainer bs4.SoupStrainer() # 修改 Loader 部分 loader WebBaseLoader( web_paths(page_url,), header_template{User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0}, verify_sslFalse ) docs loader.load() print(f1. 原始文档数量: {len(docs)}) if len(docs) 0: print(f2. 原始内容预览 (前100字): {docs[0].page_content[:100].strip()}) else: print(错误未能抓取到任何内容请检查 URL 是否有效。) docs loader.load() # print(len(docs)) # 分割文本 text_splitter RecursiveCharacterTextSplitter( chunk_size 300, #每块token/chunk size越小块越多 chunk_overlap 50, #重叠部分 add_start_index True ) all_splitstext_splitter.split_documents(docs) # 向量库存储 embeding OllamaEmbeddings(modelnomic-embed-text:v1.5) from langchain_chroma import Chroma vector_storeChroma( collection_namedota2, embedding_functionembeding, persist_directory./chroma_dota2_db ) ids vector_store.add_documents(documentsall_splits) #add同步 aadd异步当看到项目路径下出现这个chroma_dota2_db说明已经完成的索引的建立第二阶段检索与增强生成 (Retrieval Generation)如果说索引阶段是“存书”那么生成阶段就是“看书考试”。在这一部分我采用了一种比传统 RAG 更灵活的架构基于 Agent 的动态检索。核心利器Tool-Calling (工具调用)传统的 RAG 通常是“先检索、后回答”的线性流程。但在我的代码中我将检索逻辑封装成了一个自定义工具tool这种做法的巧妙之处在于模型Kimi不再是被动接受上下文而是主动思考。如果它判断用户的问题需要外部知识如 DOTA2 魔方的数值改动它会主动调用这个工具去数据库中抓取最相关的 3 条内容。在retrieve_context中我不仅返回了拼接好的字符串还利用了response_formatcontent_and_artifact。这意味着模型在理解内容的同时程序依然能追踪到这些信息是从哪个 URL、哪一页读到的极大地增强了系统的可解释性。tool(response_formatcontent_and_artifact) def retrieve_context(query:str): Retrieve information to help answer a query # 相似度搜索逻辑 retrieve_docs vector_store.similarity_search(query, k3) # ... 格式化输出 ...智能体驱动create_agent通过create_agent我们将模型、工具箱和系统指令绑定在一起。当用户询问“魔方的数值改动”时Agent 会经历接收问题 - 识别意图 - 决定调用检索工具 - 获取 DOTA2 官网数据 - 总结回答这一完整闭环。agent create_agent( modelkimi_model, tools[retrieve_context], system_promptSYSTEM_PROMPT )完整代码from langchain.agents import create_agent from langchain_openai import ChatOpenAI from langchain_ollama import OllamaEmbeddings from langchain_chroma import Chroma from langchain.tools import tool #嵌入模型 embeding OllamaEmbeddings(modelnomic-embed-text:v1.5) #向量库 vector_storeChroma( collection_namedota2, embedding_functionembeding, persist_directory./chroma_dota2_db ) SYSTEM_PROMPT 你可以使用信息检索工具回答用户问题。 tool(response_formatcontent_and_artifact) def retrieve_context(query:str): Retrive information to help answer a query retrieve_docs vector_store.similarity_search(query,k3) content \n\n.join( (fSource:{doc.metadata}\nContent:{doc.page_content}) for doc in retrieve_docs ) return content,retrieve_docs kimi_model ChatOpenAI( modelkimi-k2.5, api_keysk-uQp****, base_urlhttps://api.moonshot.cn/v1, # 重点这里严格对应 Kimi 的 API 结构 extra_body{ thinking: {type: disabled} } ) agent create_agent( modelkimi_model, tools[retrieve_context], system_promptSYSTEM_PROMPT ) results agent.invoke( {messages:[{role:user,content:请告诉我魔方的数值改动?}]} ) messages results[messages] for message in messages : message.pretty_print()效果演示符合官网更新内容中的数据这个运行结果清晰地展示了一个ReActReasoning and Acting模式的智能体是如何工作的Kimi 模型先“思考”需要查资料发起tool_call拿到本地向量库的内容后再进行归纳总结。根据打印输出我们可以将整个黑盒过程拆解为以下 6 步意图识别 (Reasoning)当你输入“请告诉我魔方的数值改动?”时Kimi 模型并没有立即搜索脑海中的旧知识而是识别出这个问题涉及具体的、实时的游戏数值。触发工具 (Action)模型决定调用retrieve_context工具。你会看到日志中出现了Tool Calls这说明 Agent 已经把自然语言转化为了函数调用的参数query: 魔方的数值改动。向量检索 (Retrieval)Python 脚本执行vector_store.similarity_search。由于我们之前建立过索引系统会在本地chroma_dota2_db中寻找与“魔方”向量最接近的 3 个文本块Chunks。知识喂回 (Observation)检索到的原文Source 和 Content被拼接成字符串作为Tool Message返回给 Kimi。这就是你看到的Name: retrieve_context后面那一长串 DOTA2 官网内容。二次推理 (Summarization)Kimi 拿到检索回来的“参考资料”结合最初的问题进行信息提取。它过滤掉了无关的网页导航信息精准锁定了“25%状态抗性”等关键数值。结果输出 (Final Answer)最终Agent 以排版精美的 Markdown 格式回答了你的问题。总结通过这次实战我们深刻体会到RAG 的核心不在于 LLM 本身有多强而在于‘检索质量’和‘Agent 的调度’。当我们利用本地 Embedding 保证了隐私和速度再利用云端大模型保证了逻辑和文笔一个真正实用、专业的 AI 助手才算真正成型。

相关文章:

【由浅入深探究langchain】第十七集-构建你的首个 RAG 知识库助手(从文档索引到检索增强生成)

前言在大语言模型(LLM)爆火的今天,我们常常会被 GPT 或 Claude 展现出的博学所惊叹。然而,当你试着问它“我公司昨晚新发布的财务报表数据是多少?”或者“我上周在笔记里写的某个私人计划是什么?”时&#…...

2025版等离子体期刊分区解析:从PRL到PPAP的投稿指南

1. 2025版等离子体期刊分区概览 对于从事等离子体研究的科研人员来说,选择合适的期刊投稿是研究成果传播的关键一步。2025版中科院期刊分区将等离子体相关期刊划分为三个主要层级,每个层级都有其独特的定位和特点。 先说说最顶级的中科院一区期刊。这个层…...

AIGC内容创作流水线:Qwen3-ASR-0.6B赋能语音素材自动化文本化

AIGC内容创作流水线:Qwen3-ASR-0.6B赋能语音素材自动化文本化 你有没有过这样的经历?录完一段精彩的课程讲解、一次深度的访谈对话,或者一段灵光乍现的语音随笔,看着长达几十分钟的音频文件,一想到要把它整理成文字稿…...

【忍者算法】394 字符串解码:遇到嵌套时,栈最像“现场保存器”

【忍者算法】394 字符串解码:遇到嵌套时,栈最像“现场保存器” 接上题:这次栈里要存“上一层的现场” 前两题里,我们已经见过两种栈的用法: 《有效括号》:栈存“还没配对的左括号”。 《最小栈》:栈存数据,同时顺手维护“当前最小值”。 这一题会再往前走一步。 因为…...

大模型上下文长度的优化策略与应用场景

1. 大模型上下文长度的本质与挑战 当你和ChatGPT聊天时,有没有遇到过它突然"失忆"的情况?比如聊到第20轮对话时,它完全忘记了开头讨论的主题。这就是上下文长度限制导致的典型问题。所谓上下文长度,就是大模型能够记住和…...

KART-RERANK大模型实战:Python爬虫数据智能排序与相关性分析

KART-RERANK大模型实战:Python爬虫数据智能排序与相关性分析 你是不是也遇到过这种情况?用Python爬虫吭哧吭哧抓了一大堆数据,结果发现里面什么都有:有用的、没用的、相关的、跑题的、高质量的、纯广告的……看着满屏的文本&…...

分布式爬虫安全:构建高可用代理池的架构与实践指南

分布式爬虫安全:构建高可用代理池的架构与实践指南 【免费下载链接】scylla Intelligent proxy pool for Humans™ to extract content from the internet and build your own Large Language Models in this new AI era 项目地址: https://gitcode.com/gh_mirror…...

Protocol Buffer 入门:跨平台的高效序列化神器

&#x1f525;个人主页&#xff1a;Milestone-里程碑 ❄️个人专栏: <<力扣hot100>> <<C>><<Linux>> <<Git>><<MySQL>> &#x1f31f;心向往之行必能至 目录 一、什么是 Protobuf&#xff1f; 二、序列化与反…...

解决设计开发断层:Figma Code Connect的7个革新性实践

解决设计开发断层&#xff1a;Figma Code Connect的7个革新性实践 【免费下载链接】code-connect A tool for connecting your design system components in code with your design system in Figma 项目地址: https://gitcode.com/GitHub_Trending/co/code-connect 设计…...

终极美化指南:foobar2000如何通过foobox-cn打造你的专属音乐空间?

终极美化指南&#xff1a;foobar2000如何通过foobox-cn打造你的专属音乐空间&#xff1f; 【免费下载链接】foobox-cn DUI 配置 for foobar2000 项目地址: https://gitcode.com/GitHub_Trending/fo/foobox-cn 厌倦了千篇一律的音乐播放器界面&#xff1f;想让你的音乐体…...

新手零踩坑!微信搜一搜排名优化8大干货,14天轻松冲进前10

很多新手运营者都有一个共同的困惑&#xff1a;明明做了公众号、小程序&#xff0c;也发了不少内容&#xff0c;可在微信搜一搜里搜相关关键词&#xff0c;却始终找不到自己的账号和内容&#xff0c;排名一直徘徊在百名之外&#xff0c;精准流量根本引不进来&#xff0c;更别提…...

3大核心技术解析:猫抓cat-catch如何实现浏览器媒体资源精准捕获

3大核心技术解析&#xff1a;猫抓cat-catch如何实现浏览器媒体资源精准捕获 【免费下载链接】cat-catch 猫抓 chrome资源嗅探扩展 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 猫抓cat-catch是一款专为技术爱好者和开发者设计的浏览器扩展工具&#xf…...

Z-Image-GGUF小程序开发:微信小程序前端调用云端AI绘画API

Z-Image-GGUF小程序开发&#xff1a;微信小程序前端调用云端AI绘画API 最近在折腾AI绘画&#xff0c;发现一个挺有意思的事儿&#xff1a;很多厉害的模型都部署在云端服务器上&#xff0c;但咱们平时用手机的时间可比用电脑多多了。要是能在微信里随手打开一个小程序&#xff…...

这次终于选对了!2026年最值得体验的专业AI论文软件

2026年AI论文写作工具已从“内容生成”进化为融合学术规范与智能优化的全流程解决方案&#xff0c;核心评价维度涵盖文献真实性、格式合规性、长文本逻辑、查重降重、AIGC合规等关键指标。本次测评覆盖6款主流工具&#xff0c;涵盖中英文、全流程与专项功能、免费与付费版本&am…...

三步解锁wxappUnpacker:从小白到高手的蜕变指南

三步解锁wxappUnpacker&#xff1a;从小白到高手的蜕变指南 【免费下载链接】wxappUnpacker 项目地址: https://gitcode.com/gh_mirrors/wxappu/wxappUnpacker 工具定位&#xff1a;小程序逆向工程的瑞士军刀 wxappUnpacker是一款专注于微信小程序解包的开源工具集&am…...

NUC 13 Pro装Ubuntu 20.04,WiFi图标消失?别急着换网卡,先试试这个BIOS固件更新法

NUC 13 Pro安装Ubuntu 20.04后WiFi图标消失的终极解决方案 当你满怀期待地在NUC 13 Pro上安装好Ubuntu 20.04&#xff0c;准备开始高效工作时&#xff0c;却发现系统托盘里那个熟悉的WiFi图标神秘消失了——这种挫败感我深有体会。更令人困惑的是&#xff0c;蓝牙功能却完全正…...

NVIDIA Orin AGX开发环境搭建避坑指南:从Ubuntu 22.04到ROS2完整配置流程

NVIDIA Orin AGX开发环境搭建实战&#xff1a;从系统部署到ROS2深度优化 第一次拿到NVIDIA Orin AGX开发套件时&#xff0c;我对着这块巴掌大的计算模块发呆了十分钟——它强大的AI算力与紧凑体积形成的反差令人震撼。但很快现实给了我一盆冷水&#xff1a;官方文档里轻描淡写的…...

OpenClaw三种方式安装:手把手保姆级教程

前置操作 【一】获取API Key 现在很多平台的API Key都有免费额度&#xff0c;阿里云和Kimi的优惠力度大些&#xff0c;大家按需索取。 阿里云百炼 Step01&#xff1a;注册/登录阿里云 Step02&#xff1a;创建并获取API Key 注意&#xff1a;我们要的是API Key&#xff0c;如…...

避坑指南:解决ROS2 Gazebo仿真中机械臂‘散架’或‘弹飞’问题(附惯性矩阵计算与dynamics参数调整)

ROS2 Gazebo仿真中机械臂物理异常问题深度解析与实战解决方案 当你在Gazebo仿真环境中看到精心设计的机械臂模型像积木一样散落一地&#xff0c;或是突然像火箭般腾空而起时&#xff0c;那种挫败感任何机器人开发者都能感同身受。这类物理异常问题不仅影响开发效率&#xff0c;…...

突破硬件限制的跨显卡AI增强方案:OptiScaler游戏画质优化全解析

突破硬件限制的跨显卡AI增强方案&#xff1a;OptiScaler游戏画质优化全解析 【免费下载链接】OptiScaler DLSS replacement for AMD/Intel/Nvidia cards with multiple upscalers (XeSS/FSR2/DLSS) 项目地址: https://gitcode.com/GitHub_Trending/op/OptiScaler OptiSc…...

如何用SlopeCraft实现Minecraft地图艺术创作:5个实用技巧

如何用SlopeCraft实现Minecraft地图艺术创作&#xff1a;5个实用技巧 【免费下载链接】SlopeCraft Map Pixel Art Generator for Minecraft 项目地址: https://gitcode.com/gh_mirrors/sl/SlopeCraft 在Minecraft的方块世界中&#xff0c;将现实图像转化为立体地形艺术曾…...

3步掌握Buzz字幕智能分割:从杂乱时间戳到专业级字幕的技术实现

3步掌握Buzz字幕智能分割&#xff1a;从杂乱时间戳到专业级字幕的技术实现 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Trending/buz/buzz Bu…...

告别硬件!用Proteus8.9和VSPD虚拟串口,5分钟搞定51单片机串口通信仿真

零成本玩转51单片机串口通信&#xff1a;Proteus与VSPD虚拟串口实战指南 记得刚接触单片机开发时&#xff0c;最头疼的就是硬件问题——买开发板要钱&#xff0c;买USB转串口模块要钱&#xff0c;连杜邦线都得精打细算。直到发现ProteusVSPD这对黄金组合&#xff0c;才明白原来…...

wxappUnpacker:让微信小程序源代码重见天日的开发者利器

wxappUnpacker&#xff1a;让微信小程序源代码重见天日的开发者利器 【免费下载链接】wxappUnpacker 项目地址: https://gitcode.com/gh_mirrors/wxappu/wxappUnpacker 在微信小程序开发过程中&#xff0c;开发者常常面临源代码被打包加密的困境&#xff0c;特别是当需…...

RK3568开发板烧录避坑指南:Maskrom和Loader模式切换失败?手把手教你排查(附串口调试技巧)

RK3568开发板烧录模式切换全攻略&#xff1a;从原理到实战排查 刚拿到RK3568开发板的开发者们&#xff0c;往往会在第一个环节就遭遇"拦路虎"——开发板死活进不了Maskrom或Loader模式。看着官方文档里简单的按键操作说明&#xff0c;实际操作时却像在玩一场没有规则…...

拒绝手动排版!用Word域代码+样式库打造自动化技术文档(含GitHub模板)

拒绝手动排版&#xff01;用Word域代码样式库打造自动化技术文档&#xff08;含GitHub模板&#xff09; 技术文档工程师的日常往往被格式调整、编号校对这类重复劳动占据。我曾见过团队因为手动调整200页需求文档的标题格式&#xff0c;导致版本发布时间延误三天。其实&#x…...

如何利用Outline构建现代化团队知识管理体系

如何利用Outline构建现代化团队知识管理体系 【免费下载链接】outline Outline 是一个基于 React 和 Node.js 打造的快速、协作式团队知识库。它可以让团队方便地存储和管理知识信息。你可以直接使用其托管版本&#xff0c;也可以自己运行或参与开发。源项目地址&#xff1a;ht…...

AviatorScript函数扩展避坑指南:固定参数vs可变参数的选择与实现差异

AviatorScript函数扩展避坑指南&#xff1a;固定参数vs可变参数的选择与实现差异 在AviatorScript的深度开发中&#xff0c;函数扩展是提升脚本灵活性的核心手段。但许多开发者在面对固定参数&#xff08;AbstractFunction&#xff09;和可变参数&#xff08;AbstractVariadicF…...

C++实战:用代码构建你的斗罗大陆武魂觉醒系统

1. 从零开始搭建武魂觉醒系统 第一次看到斗罗大陆的武魂觉醒桥段时&#xff0c;我就被这个充满想象力的设定吸引了。作为程序员&#xff0c;我总忍不住思考&#xff1a;如果用代码实现这个系统会怎样&#xff1f;去年带新人培训时&#xff0c;我尝试用C还原了这个过程&#xff…...

GIL Free ≠ Thread Safe:从Linux futex源码到Python对象头重定义,解构无锁环境下的引用计数崩溃根因(含gdb逆向调试录屏脚本)

第一章&#xff1a;GIL Free ≠ Thread Safe&#xff1a;核心命题与崩溃现象全景Python 的全局解释器锁&#xff08;GIL&#xff09;长期被视为多线程性能的桎梏&#xff0c;而 PyPy、Jython 乃至最新 CPython 3.13 的实验性 GIL-free 构建&#xff0c;常被误读为“天然支持安全…...