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

【LLM实战】RAG初体验,两种实现方式

every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog

0. 前言

【LLM实战】RAG初体验,两种实现方式


# !pip install pypdf2
# !pip install dashscope
# !pip install langchain
# !pip install langchain-openai
# !pip install langchain-community
# !pip install faiss-cpu

1. 数据预处理

  1. 将pdf文件转换为txt文件
  2. 分块
  3. 生成向量
  4. 保存向量

文档:点击下载文档

import os
import logging
import pickle
from PyPDF2 import PdfReader
from langchain.chains.question_answering import load_qa_chain
from langchain_openai import OpenAI, ChatOpenAI
from langchain_openai import OpenAIEmbeddings
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.callbacks.manager import get_openai_callback
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from typing import List, Tupledef extract_text_with_page_numbers(pdf) -> Tuple[str, List[int]]:"""从PDF中提取文本并记录每行文本对应的页码参数:pdf: PDF文件对象返回:text: 提取的文本内容page_numbers: 每行文本对应的页码列表"""text = ""page_numbers = []for page_number, page in enumerate(pdf.pages, start=1):extracted_text = page.extract_text()if extracted_text:text += extracted_textpage_numbers.extend([page_number] * len(extracted_text.split("\n")))else:logging.warning(f"No text found on page {page_number}.")return text, page_numbersdef process_text_with_splitter(text: str, page_numbers: List[int], save_path: str = None) -> FAISS:"""处理文本并创建向量存储参数:text: 提取的文本内容page_numbers: 每行文本对应的页码列表save_path: 可选,保存向量数据库的路径返回:knowledgeBase: 基于FAISS的向量存储对象"""# 创建文本分割器,用于将长文本分割成小块text_splitter = RecursiveCharacterTextSplitter(separators = ["\n\n", "\n", ".", " ", ""],chunk_size = 512,chunk_overlap = 128,length_function = len,)# 分割文本chunks = text_splitter.split_text(text)# logging.debug(f"Text split into {len(chunks)} chunks.")print(f"文本被分割成 {len(chunks)} 个块。")# 创建嵌入模型,OpenAI嵌入模型,配置环境变量 OPENAI_API_KEY# embeddings = OpenAIEmbeddings()# 调用阿里百炼平台文本嵌入模型,配置环境变量 DASHSCOPE_API_KEYembeddings = DashScopeEmbeddings(model = "text-embedding-v2")# 从文本块创建知识库knowledgeBase = FAISS.from_texts(chunks, embeddings)print("已从文本块创建知识库...")# 存储每个文本块对应的页码信息page_info = {chunk: page_numbers[i] for i, chunk in enumerate(chunks)}knowledgeBase.page_info = page_info# 如果提供了保存路径,则保存向量数据库和页码信息if save_path:# 确保目录存在os.makedirs(save_path, exist_ok=True)# 保存FAISS向量数据库knowledgeBase.save_local(save_path)print(f"向量数据库已保存到: {save_path}")# 保存页码信息到同一目录with open(os.path.join(save_path, "page_info.pkl"), "wb") as f:pickle.dump(page_info, f)print(f"页码信息已保存到: {os.path.join(save_path, 'page_info.pkl')}")return knowledgeBasedef load_knowledge_base(load_path: str, embeddings = None) -> FAISS:"""从磁盘加载向量数据库和页码信息参数:load_path: 向量数据库的保存路径embeddings: 可选,嵌入模型。如果为None,将创建一个新的DashScopeEmbeddings实例返回:knowledgeBase: 加载的FAISS向量数据库对象"""# 如果没有提供嵌入模型,则创建一个新的if embeddings is None:embeddings = DashScopeEmbeddings(model="text-embedding-v2")# 加载FAISS向量数据库,添加allow_dangerous_deserialization=True参数以允许反序列化knowledgeBase = FAISS.load_local(load_path, embeddings, allow_dangerous_deserialization=True)print(f"向量数据库已从 {load_path} 加载。")# 加载页码信息page_info_path = os.path.join(load_path, "page_info.pkl")if os.path.exists(page_info_path):with open(page_info_path, "rb") as f:page_info = pickle.load(f)knowledgeBase.page_info = page_infoprint("页码信息已加载。")else:print("警告: 未找到页码信息文件。")return knowledgeBase# 读取PDF文件
pdf_reader = PdfReader('./浦发上海浦东发展银行西安分行个金客户经理考核办法.pdf')
# 提取文本和页码信息
text, page_numbers = extract_text_with_page_numbers(pdf_reader)
text
'百度文库  - 好好学习,天天向上  \n-1 上海浦东发展银行西安分行  \n个金客户经理管理考核暂行办法  \n \n \n第一章  总   则 \n第一条   为保证我分行个金客户经理制的顺利实施,有效调动个\n金客户经理的积极性,促进个金业务快速、稳定地发展,根据总行《上\n海浦东发展银行个人金融营销体系建设方案(试行)》要求,特制定\n《上海浦东发展银行西安分行个金客户经理管理考核暂行办法(试\n行)》(以下简称本办法)。  \n第二条   个金客户经理系指各支行(营业部)从事个人金融产品\n营销与市场开拓,为我行个人客户提供综合银行服务的我行市场人\n员。 \n第三条   考核内容分为二大类, 即个人业绩考核、 工作质量考核。\n个人业绩包括个人资产业务、负债业务、卡业务。工作质量指个人业\n务的资产质量。  \n第四条   为规范激励规则,客户经理的技术职务和薪资实行每年\n考核浮动。客户经理的奖金实行每季度考核浮动,即客户经理按其考\n核内容得分与行员等级结合,享受对应的行员等级待遇。  \n 百度文库  - 好好学习,天天向上  \n-2 第二章  职位设置与职责  \n第五条   个金客户经理职位设置为:客户经理助理、客户经理、\n高级客户经理、资深客户经理。  \n第六条   个金客户经理的基本职责:  \n(一)   客户开发。研究客户信息、联系与选择客户、与客户建\n立相互依存、相互支持的业务往来关系,扩大业务资源,创造良好业\n绩; \n(二)业务创新与产品营销。把握市场竞争变化方向,开展市场\n与客户需 求的调研,对业务产品及服务进行创新;设计客户需求的产\n品组合、制订和实施市场营销方案;  \n(三)客户服务。负责我行各类表内外授信业务及中间业务的受\n理和运作,进行综合性、整体性的客户服务;  \n(四)防范风险,提高收益。提升风险防范意识及能力,提高经\n营产品质量;  \n(五)培养人材。在提高自身综合素质的同时,发扬团队精神,\n培养后备业务骨干。  \n 百度文库  - 好好学习,天天向上  \n-3 第三章  基础素质要求  \n第七条   个金客户经理准入条件:  \n(一)工作经历:须具备大专以上学历,至少二年以上银行工作\n经验。  \n(二)工作能力:熟悉我行的各项业务,了解市场情况,熟悉各\n类客户的金融需求,熟悉个人理财工具,有一定的业务管理和客户管\n理能力。  \n(三)工作业绩:个金客户经理均应达到相应等级的准入标准。\n该标准可根据全行整体情况由考核部门进行调整。  \n(四)专业培训:个金客户经理应参加有关部门组织的专业培训\n并通过业务考试。  \n(五)符合分行人事管理和专业管理的要求。  \n第四章  个人业绩考核标准  \n第八条   个金客户经理个人业绩以储蓄季日均、季有效净增发卡\n量、季净增个贷余额 三项业务为主要考核指标,实行季度考核。具体\n标准如下:  \n \n    \n类别 行员级别 考核分值 准入标准  \n储蓄业务 个贷业务 卡业务 \n客户经理助理  5 90 300万  500张 \n4 95  百度文库  - 好好学习,天天向上  \n-4 3 100  \n2 105  \n1 110  \n客户经理 5 115 300万  500张 \n4 120  \n3 125  \n2 130  \n1 135  \n高级客户经理  5 140 500万 800万  \n4 145  \n3 150  \n2 155  \n1 160  \n资深客户经理  5 165 500万 800万  \n4 170  \n3 175  \n2 180  \n1 185  \n说明: 1.储蓄业务(季日均余额)为各类个金客户经理考核进入的最低标准。   \n2.卡业务(季新增发有效卡量)为见习、 D类、初级客户经理进入的最低标准。  \n3.有效卡的概念:每张卡月均余额为 100元以上。  \n4.个贷业务(季新增发放个贷)为中级以上客户经理考核进入的最低标准。  \n5.超出最低考核标准可相互折算,折算标准: 50万储蓄 =50万个贷 =50张有效卡 =5分(折算以 5分为单位)  \n \n 百度文库  - 好好学习,天天向上  \n-5 第五章  工作质量考核标准  \n第九条   工作质量考核实行扣分制。工作质量指个金客户经理在\n从事所有个人业务时出现投诉、差错及风险。该项考核最多扣 50分,\n如发生重大差错事故,按分行有关制度处理。  \n(一)服务质量考核:   \n1、工作责任心不强,缺乏配合协作精神;扣 5分 \n2、客户服务效率低,态度生硬或不及时为客户提供维护服务,\n有客户投诉的 ,每投诉一次扣 2分 \n3、不服从支行工作安排,不认真参加分(支)行宣传活动的,\n每次扣 2分; \n4、未能及时参加分行(支行)组织的各种业务培训、考试和专\n题活动的每次扣 2分; \n5、未按规定要求进行贷前调查、贷后检查工作的,每笔扣 5分; \n6、未建立信贷台帐资料及档案的每笔扣 5分; \n7、在工作中有不廉洁自律情况的每发现一次扣 50分。 \n(二)个人资产质量考核:  \n当季考核收息率 97%以上为合格,每降 1个百分点扣 2分;不\n良资产零为合格,每超一个个百分点扣 1分。 \nA.发生跨月逾期,单笔不超过 10万元,当季收回者,扣 1分。 \nB.发生跨月逾期, 2笔以上累计金额不超过 20万元,当季收回\n者,扣 2分;累计超过 20万元以上的,扣 4分。 百度文库  - 好好学习,天天向上  \n-6 C.发生逾期超过 3个月,无论金额大小和笔数,扣 10分。 \n \n第六章  聘任考核程序  \n第十条   凡达到本办法第三章规定的该技术职务所要求的行内职\n工,都可向分行人力资源部申报个金客户经理评聘。  \n第十一条   每年一月份为客户经理评聘的申报时间,由分行人力\n资源部、个人业务部每年二月份组织统一的资格考试。考试合格者由\n分行颁发个金客户经理资格证书,其有效期为一年。  \n第十二条   客户经理聘任实行开放式、浮动制,即:本人申报  —\n— 所在部门推荐  —— 分行考核  —— 行长聘任  —— 每年考评\n调整浮动。   \n第十三条   特别聘任:  \n(一)经分行同意录用从其他单位调入的个金客户经理,由用人\n单位按 D类人员进行考核, 薪资待遇按其业绩享受行内正式行员工同\n等待遇。待正式转正后按第十一条规定申报技术职务。  \n(二)对为我行业务创新、工作业绩等方面做出重大贡献的市场\n人员经支行推荐、分行行长 批准可越级聘任。  \n第十四条   对于创利业绩较高,而暂未入围技术职务系列,或所\n评聘技术职务较低的市场人员,各级领导要加大培养力度,使其尽快百度文库  - 好好学习,天天向上  \n-7 入围,并由所在行制定临时奖励办法。  \n \n第七章   考核待遇  \n第十五条   个人金融业务客户经理的收入基本由三部分组成: 客\n户经理等级基本收入、业绩奖励收入和日常工作绩效收入。  \n客户经理等级基本收入是指客户经理的每月基本收入, 基本分为\n助理客户经理、客户经理、高级客户经理和资深客户经理四大层面,\n在每一层面分为若干等级。  \n客户经理的等级标准由客户经理在上年的业绩为核定标准, 如果\n客户经理在我行第一次进行客户经理评级, 以客户经理自我评价为主\n要依据,结合客户经理以往工作经验,由个人金融部、人事部门共同\n最终决定客户经理的等级。  \n助理客户经理待遇按照人事部门对主办科员以下人员的待遇标\n准;客户经理待遇按照人事部门对主办科员的待遇标准;高级客户经\n理待遇按照人事部门对付科级的待遇标准; 资深客户经理待遇 按照人\n事部门对正科级的待遇标准。  \n业绩奖励收入是指客户经理每个业绩考核期间的实际业绩所给\n与兑现的奖金部分。  \n日常工作绩效收入是按照个金客户经理所从事的事务性工作进\n行定量化考核,经过工作的完成情况进行奖金分配。该项奖金主要由\n个人金融部总经理和各支行的行长其从事个人金融业务的人员进行\n分配,主要侧重分配于从事个金业务的基础工作和创新工作。  百度文库  - 好好学习,天天向上  \n-8 第十五条   各项考核分值总计达到某一档行员级别考核分值标\n准,个金客户经理即可在下一季度享受该级行员的薪资标准。下一季\n度考核时,按照已享受行员级别考核折算比值进行考核,以次类推。  \n第十六条   对已聘为各级客户经理的人员,当工作业绩考核达不\n到相应技术职务要求下限时,下一年技术职务相应下调 。 \n第十七条   为保护个人业务客户经理创业的积极性,暂定其收入\n构成中基础薪点不低于 40%。 \n \n第八章  管理与奖惩  \n第十八条   个金客户经理管理机构为分行客户经理管理委员会。\n管理委员会组成人员:行长或主管业务副行长,个人业务部、人力资\n源部、风险管理部负责人。  \n第十九条   客户经理申报的各种信息必须真实。分行个人业务部\n需对其工作业绩数据进行核实,并对其真实性负责;分行人事部门需\n对其学历、工作阅历等基本信息进行核实,并对其真实性负责。  \n第二十条   对因工作不负责任使资产质量产生严重风险或造成损\n失的给予降级直至开 除处分,构成渎职罪的提请司法部门追究刑事责\n任。 \n 百度文库  - 好好学习,天天向上  \n-9 第九章  附    则 \n第二十一条   本办法自发布之日起执行。  \n第二十二条   本办法由上海浦东发展银行西安分行行负责解释和\n修改。  \n '
print(f"提取的文本长度: {len(text)} 个字符。")# 处理文本并创建知识库,同时保存到磁盘
save_dir = "./vector_db"
knowledgeBase = process_text_with_splitter(text, page_numbers, save_path=save_dir)# 处理文本并创建知识库
knowledgeBase = process_text_with_splitter(text, page_numbers)
knowledgeBase
提取的文本长度: 3881 个字符。
文本被分割成 10 个块。
已从文本块创建知识库...
向量数据库已保存到: ./vector_db
页码信息已保存到: ./vector_db\page_info.pkl
文本被分割成 10 个块。
已从文本块创建知识库...<langchain_community.vectorstores.faiss.FAISS at 0x1e4e100c650>

2.查询

2.1 方法一:OpenAI接口

# 设置查询问题
query = "客户经理被投诉了,投诉一次扣多少分"
# query = "客户经理每年评聘申报时间是怎样的?"
if query:# 执行相似度搜索,找到与查询相关的文档docs = knowledgeBase.similarity_search(query)# 初始化对话大模型chatLLM  = ChatOpenAI(# 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx",api_key = os.getenv("DASHSCOPE_API_KEY"),base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1",model = "deepseek-v3")# 加载问答链chain = load_qa_chain(chatLLM, chain_type="stuff")# 准备输入数据input_data = {"input_documents": docs, "question": query}# 使用回调函数跟踪API调用成本with get_openai_callback() as cost:# 执行问答链response = chain.invoke(input=input_data)print(f"查询已处理。成本: {cost}")print(response["output_text"])print("来源:")# 记录唯一的页码unique_pages = set()# 显示每个文档块的来源页码for doc in docs:text_content = getattr(doc, "page_content", "")source_page = knowledgeBase.page_info.get(text_content.strip(), "未知")if source_page not in unique_pages:unique_pages.add(source_page)print(f"文本块页码: {source_page}")
C:\Users\13010\AppData\Local\Temp\ipykernel_16536\3842879030.py:17: LangChainDeprecationWarning: This class is deprecated. See the following migration guides for replacements based on `chain_type`:
stuff: https://python.langchain.com/docs/versions/migrating_chains/stuff_docs_chain
map_reduce: https://python.langchain.com/docs/versions/migrating_chains/map_reduce_chain
refine: https://python.langchain.com/docs/versions/migrating_chains/refine_chain
map_rerank: https://python.langchain.com/docs/versions/migrating_chains/map_rerank_docs_chainSee also guides on retrieval and question-answering here: https://python.langchain.com/docs/how_to/#qa-with-ragchain = load_qa_chain(chatLLM, chain_type="stuff")查询已处理。成本: Tokens Used: 1255Prompt Tokens: 1201Prompt Tokens Cached: 0Completion Tokens: 54Reasoning Tokens: 0
Successful Requests: 1
Total Cost (USD): $0.0
根据提供的考核标准:在服务质量考核部分第2条明确规定:
"客户服务效率低,态度生硬或不及时为客户提供维护服务,有客户投诉的,每投诉一次扣2分。"因此,客户经理被投诉一次将被扣2分。
来源:
文本块页码: 1

2.2 方法二:Tongyi接口

from langchain_community.llms import Tongyi# 设置查询问题
# query = "客户经理被投诉了,投诉一次扣多少分?"
query = "客户经理每年评聘申报时间是怎样的?"
if query:# 示例:如何加载已保存的向量数据库# 注释掉以下代码以避免在当前运行中重复加载# 创建嵌入模型embeddings = DashScopeEmbeddings(model="text-embedding-v2")# 从磁盘加载向量数据库loaded_knowledgeBase = load_knowledge_base("./vector_db", embeddings)# 使用加载的知识库进行查询docs = loaded_knowledgeBase.similarity_search(query)# 初始化对话大模型DASHSCOPE_API_KEY = os.getenv("DASHSCOPE_API_KEY"),llm = Tongyi(model_name="deepseek-v3", dashscope_api_key=DASHSCOPE_API_KEY)# 加载问答链chain = load_qa_chain(llm, chain_type="stuff")# 准备输入数据input_data = {"input_documents": docs, "question": query}# 使用回调函数跟踪API调用成本with get_openai_callback() as cost:# 执行问答链response = chain.invoke(input=input_data)print(f"查询已处理。成本: {cost}")print(response["output_text"])print("来源:")# 记录唯一的页码unique_pages = set()# 显示每个文档块的来源页码for doc in docs:text_content = getattr(doc, "page_content", "")source_page = knowledgeBase.page_info.get(text_content.strip(), "未知")if source_page not in unique_pages:unique_pages.add(source_page)print(f"文本块页码: {source_page}")
向量数据库已从 ./vector_db 加载。
页码信息已加载。
查询已处理。成本: Tokens Used: 0Prompt Tokens: 0Prompt Tokens Cached: 0Completion Tokens: 0Reasoning Tokens: 0
Successful Requests: 1
Total Cost (USD): $0.0
客户经理每年评聘申报时间是**每年一月份**。
来源:
文本块页码: 1
http://www.dtcms.com/a/320990.html

相关文章:

  • wstool的一个完整的工作流解析
  • 安全合规1--实验:ARP欺骗、mac洪水攻击、ICMP攻击、TCP SYN Flood攻击
  • 【Day 19】Linux-网站操作
  • mac笔记本如何重新设置ssh key
  • 使用 ECharts GL 实现 3D 中国地图点位飞线效果
  • GoLand 项目从 0 到 1:第六天 —— 权限接口开发与问题攻坚
  • 笔试——Day32
  • pycharm常见环境配置和快捷键
  • 微软XBOX游戏部门大裁员
  • vue项目常见BUG和优化注意事项
  • HTTP 请求返回状态码和具体含义?200、400、403、404、502、503、504等
  • OpenBMC中libgpio架构与驱动交互全解析:从硬件映射到应用控制
  • 智能厨具机器人的革命性升级:Deepoc具身模型外拓板技术解析
  • 【Rust】多级目录模块化集成测试——以Cucumber为例
  • 服务器登上去,显示 failed to send WATCHDOG 重启有效吗?
  • 当服务器多了时,如何管理?
  • 机柜内部除了服务器还有哪些组件?
  • 防火墙概述
  • 手动开发一个TCP服务器调试工具(四):构建完整的UI与功能联合的TCP服务器应用
  • 脚本统计MongoDB集合结构信息
  • 从0开始的中后台管理系统-5(userList动态展示以及上传图片和弹出创建用户表单)
  • 【MongoDB学习笔记1】MongoDB的常用命令介绍-数据库操作、集合操作、文档操作、文档分页查询、高级查询
  • 操作系统: 线程(Thread)
  • Lazada东南亚矩阵营销破局:指纹手机如何以“批量智控+数据中枢”重构运营生态
  • Android 之 OOM的产生和解决办法
  • Android 之 ANR问题的全面解析与优化方案
  • 综合项目记录:自动化备份全网服务器数据平台
  • 日本站群服务器与普通日本服务器对比
  • 深入解析C++流运算符(>>和<<)重载:为何必须使用全局函数与友元机制
  • [论文阅读] 人工智能 + 软件工程 | LLM协作新突破:用多智能体强化学习实现高效协同——解析MAGRPO算法