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

LangChain实现简易版-----PDF 文档问答机器人

文档加载器 + 文本分割器 + PromptTemplate + LLM

原理(极简版,不学向量也能懂)

  1. 加载 PDF 全部文本
  2. 分割成多个语义完整文本块
  3. 用户提问 → 简单匹配最相关的文本块
  4. 把「相关文档片段 + 用户问题」塞进提示词
  5. 强制 LLM只能看给的文档片段回答,不准瞎编

第一步 安装依赖

pip install -U langchain langchain-openai langchain-community pypdf python-dotenv

第二步 完整可运行代码(纯基础知识点,无 RAG 无向量库)

# 文档问答机器人 import os from dotenv import load_dotenv from langchain_core import documents from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_community.document_loaders import PyPDFLoader from langchain_text_splitters import RecursiveCharacterTextSplitter # 加载环境变量 load_dotenv() # ====================== 1. 配置 ================================= PDF_PATH = "Dubbo面试.pdf" CHUNK_SIZE = 1200 # 单个块最大的字符数(推荐1000 - 2000) CHUNK_OVERLAP = 200 # 相邻块的重叠字符数(推荐200 - 400) 保留上下文 # 初始化大模型 LLM llm = ChatOpenAI( api_key=os.getenv("QWEN_API_KEY"), base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", model='qwen3-max', # 必须用 pro模型,支持工具调用 temperature=0 ) # ======================2, 加载PDF ================================= def load_PDF(pdf_path: str): """ 加载本地 PDF 文档 :param pdf_path: PDF 文件路径 :return: Document 对象列表(每个元素是 PDF 的一页) """ print(f'📄 正在加载,PDF:{PDF_PATH}...') # 初始化PDF加载器 loader = PyPDFLoader(pdf_path) #加载PDF 每个元素 对应pdf一页 documents = loader.load() print(f'✅️PDF文档加载完成!共{len(documents)}页 \n') return documents # ======================= 3. 文本语义分割 =============================== def split_documents(documents): """ 用 RecursiveCharacterTextSplitter 进行语义完整的文本分割 :param documents: 加载后的 Document 对象列表 :return: 分割后的文本块列表 """ print("✂️ 正在进行语义完整的文本分割...") # ✅️ 核心:初始化 RecursiveCharacterTextSplitter (最推荐的分割器) text_splitter = RecursiveCharacterTextSplitter( chunk_size=CHUNK_SIZE, chunk_overlap=CHUNK_OVERLAP, # 分割优先级(按顺序,优先保留段落、句子) separators=["\n\n", "\n", "。", "!", "?", " ", ""], ) # 执行分割 split_chunks = text_splitter.split_documents(documents) print(f"✅ 文本分割完成!共生成 {len(split_chunks)} 个文本块\n") return split_chunks # ====================== 4. 简单的文本匹配 ========================== def get_relevant_chunk(question, chunks): """ 简易关键词匹配:找出和问题最相关的文档块 不用向量,纯字符串包含匹配 """ # 提取问题关键词 (简单按空格拆分) q_words = set(question.replace(",", " ").replace("。", " ").split()) print(f'q_words: {q_words}') best_chunk = None max_score = 0 for chunk in chunks: content = chunk.page_content # 统计命中关键词数量 hit = sum(1 for word in q_words if word in content) if hit > max_score: max_score = hit best_chunk = content # 没有任何匹配 返回空 if max_score == 0: return None return best_chunk # ============================ # 5,构建问答prompt + 普通chain ============================== # 强约束 只能用文档内容 不能编造 prompt = ChatPromptTemplate.from_template(""" 你是文档专属问答助手,**严格遵守以下规则**: 1. 只能依据【文档内容】回答用户问题 2. 文档里没有相关信息,直接回复:文档中没有相关内容 3. 绝对不能自己编造、不能使用外部知识 4. 回答简洁准确 【文档内容】 {context} 【用户问题】 {question} """) # 普通链式组装 chain = prompt | llm | StrOutputParser() # ===================== 6. 对话主循环 ========================================== def main(): print("===== 📚 简易PDF文档问答机器人(无向量库、无RAG)=====") print("正在加载并处理文档...\n") # 加载+分割 documents = load_PDF(PDF_PATH) chunks = split_documents(documents) print("🤖 文档加载完毕,可以开始提问,输入 q 退出\n") while True: question = input("你:").strip() if question.lower() == "q": print("🤖 再见!") break if not question: continue # 匹配相关文档片段 context = get_relevant_chunk(question, chunks) if not context: print("🤖:文档中没有相关内容\n") continue # 传入文档片段+问题,让LLM回答 ans = chain.invoke({ "context": context, "question": question }) print(f"🤖:{ans}\n") if __name__ == "__main__": main()

第三步 .env 文件配置

DOUBAO_API_KEY=你的豆包密钥

四、用到的知识点(全是你学过的)

  1. PyPDFLoader文档加载器
  2. RecursiveCharacterTextSplitter语义文本分割器
  3. ChatPromptTemplate提示词模板
  4. ChatOpenAI大模型调用
  5. LCEL 链式调用|
  6. StrOutputParser输出解析器

五、运行效果

  • 问文档里有的内容 → 精准基于文档回答
  • 问文档里没有的 → 自动回复:文档中没有相关内容
  • 不会瞎编、不会扯外面知识
===== 📚 简易PDF文档问答机器人(无向量库、无RAG)===== 正在加载并处理文档... 📄 正在加载,PDF:Dubbo面试.pdf... ✅️PDF文档加载完成!共15页 ✂️ 正在进行语义完整的文本分割... ✅ 文本分割完成!共生成 16 个文本块 🤖 文档加载完毕,可以开始提问,输入 q 退出 你:Dubbo 支持哪些协议,每种协议的应用场景,优缺点 q_words: {'支持哪些协议,每种协议的应用场景,优缺点', 'Dubbo'} 🤖:Dubbo 支持以下协议,每种协议的应用场景和优缺点如下: - **dubbo**:单一长连接和 NIO 异步通讯,适合大并发小数据量的服务调用,以及消费者远大于提供者。传输协议 TCP,异步,Hessian 序列化。 - **rmi**:采用 JDK 标准的 rmi 协议实现,传输参数和返回参数对象需实现 Serializable 接口,使用 java 标准序列化机制,使用阻塞式短连接,传输数据包大小混合,消费者和提供者个数差不多,可传文件,传输协议 TCP。多个短连接,TCP 协议传输,同步传输,适用常规的远程服务调用和 rmi 互操作。在依赖低版本的 Common-Collections 包时,java 序列化存在安全漏洞。 - **webservice**:基于 WebService 的远程调用协议,集成 CXF 实现,提供和原生 WebService 的互操作。多个短连接,基于 HTTP 传输,同步传输,适用系统集成和跨语言调用。 - **http**:基于 Http 表单提交的远程调用协议,使用 Spring 的 HttpInvoke 实现。多个短连接,传输协议 HTTP,传入参数大小混合,提供者个数多于消费者,需要给应用程序和浏览器 JS 调用。 - **hessian**:集成 Hessian 服务,基于 HTTP 通讯,采用 Servlet 暴露服务,Dubbo 内嵌 Jetty 作为服务器时默认实现,提供与 Hessian 服务互操作。多个短连接,同步 HTTP 传输,Hessian 序列化,传入参数较大,提供者大于消费者,提供者压力较大,可传文件。 - **memcache**:基于 memcached 实现的 RPC 协议。 - **redis**:基于 redis 实现的 RPC 协议。 你:q 🤖 再见!

🔴 先预判一下你的问题

这个报错ValueError: Invalid input type <class 'dict'>是 LangChain 里最经典的链结构错误,大概率是这 3 种情况之一:

  1. 直接把字典传给了大模型你可能写了llm.invoke({"question": "xxx"}),但大模型只接受字符串或消息列表。

  2. 链的顺序写错了你可能写了{...} | llm,但正确的应该是prompt | llm

  3. PromptTemplate 后面没接 llm,或者接错了你可能在链里混用了不同类型的 Runnable,导致输出格式不对。

http://www.jsqmd.com/news/725704/

相关文章:

  • BetterJoy终极指南:5分钟让你的Switch手柄变身PC游戏神器
  • 通用汽车将为400万辆车升级谷歌Gemini,可规划省油路线!
  • 2026年新疆隐形车衣市场深度横评:乌鲁木齐汽车漆面保护膜选购指南 - 企业名录优选推荐
  • 如何快速构建现代化中后台系统:RuoYi-Vue3-FastAPI终极指南
  • 闲置天猫超市卡别浪费!可可收实测指南,3步轻松回收 - 可可收
  • 2026年软床厂家推荐:深圳市慕格寝具有限公司简约软床/网红软床/轻奢软床/双人软床专业供应 - 品牌推荐官
  • Turnitin检测实战:亲测将英文论文AI率从80%降到10%的3款工具
  • 涡街流量计品牌怎么选?2026 采购必看榜单 - 陈工日常
  • 2026年武汉短视频代运营与AI搜索推广五大服务商深度横评指南 - 年度推荐企业名录
  • Free-NTFS-for-Mac:让NTFS设备在macOS上重获自由的技术革新
  • 深圳市建永防水装饰:深圳卫生间厨房免砸砖施工哪个好 - LYL仔仔
  • Java企业级工程化·终极完整版背诵手册(无遗漏、全覆盖、面试+落地通用)
  • 别再乱改 resolv.conf 了!理解 Ubuntu 20.04 中 systemd-resolved 的 DNS 管理机制
  • 2026年武汉短视频代运营与AI搜索推广完全指南:湖北企业获客转化全链路解决方案 - 年度推荐企业名录
  • 智启千行数赋未来|火山引擎天扬智能,以AI实战赋能中小企业破局增长 - 速递信息
  • Momenta 校招 C++ 考试题到底怎么考?它筛的不是刷题机器,是能把算法和系统一起落地的人
  • 终极指南:1分钟解决iPhone USB网络共享驱动问题,Apple-Mobile-Drivers-Installer让你告别iTunes臃肿安装
  • 旧笔记本别扔!用U盘做个OpenWrt软路由,保姆级安装教程(含DiskGenius分区指南)
  • 3分钟解决Minecraft英文界面困扰:Masa Mods全家桶汉化包完全指南
  • 终极抖音批量下载解决方案:开源无水印下载器完全指南
  • 当编程成为积木游戏:MIT App Inventor如何重新定义移动应用开发
  • 推荐一些可以用于论文降重的软件(附高效论文降重方案:TOP10平台功能对比与选择建议) - nut-king
  • 2026北京车展智驾竞争维度生变,五一视界SimOne 4.0重构端到端智驾仿真平台
  • Jellyfin Bangumi插件完整指南:打造智能动漫库的终极解决方案
  • 释放NVIDIA显卡色彩潜能:novideo_srgb专业色彩校准全攻略
  • VLC for Android:你的口袋影院,从此告别“格式不兼容“烦恼
  • 后浪用90+就业率支撑变现,打通设计副业增收全路径 - 速递信息
  • 上海泽固新型建材:嘉定灌浆料批发怎么联系 - LYL仔仔
  • 终极指南:HS2-HF_Patch汉化补丁如何彻底改变你的Honey Select 2体验
  • AI率居高不下怎么办?2026年实测10款降AI率工具,附免费降AI率工具 - 降AI实验室