大模型RAG (三)
·
一、文档的加载和分割
1、文档LLM回复系统搭建

2、把文本切分成chunks
把文本切分成chunks的方式有很多种:
1.按照句子来切分
2.按照字符数来切分
3.按固定字符数结合overlapping window
4. 递归方法 RecursiveCharacterTextSplitter
案例1: 按照句子来切分
import re
txts=("大语言模型是基于深度学习架构、通过海量文本数据训练而成的人工智能系统。它能够理解自然语言、生成连贯文本,并在对话、翻译、摘要、创作等多种任务中表现出接近人类的表达能力。模型的性能通常与其参数量、训练数据规模和优化算法密切相关。随着技术不断迭代,大模型已从单一文本生成,逐步走向多模态理解、逻辑推理与工具调用,成为新一代人工智能应用的重要基础。")
#正则表达式匹配中文句子结束的标点符合
sentences = re.split(r'(。| !|?|\...\...])', txts)
#重新组合句子和结尾的标点符合
chunks=[sentence +(puncutation if puncutation else '') for sentence, puncutation in zip(sentences[::2], sentences[1::2])]
for i ,chunk in enumerate(chunks):
print(f"chunk {i+1}:{len(chunk)}:{chunk}")

案例2:按照字符数来切分
import re
txts=("大语言模型是基于深度学习架构、通过海量文本数据训练而成的人工智能系统。它能够理解自然语言、生成连贯文本,并在对话、翻译、摘要、创作等多种任务中表现出接近人类的表达能力。模型的性能通常与其参数量、训练数据规模和优化算法密切相关。随着技术不断迭代,大模型已从单一文本生成,逐步走向多模态理解、逻辑推理与工具调用,成为新一代人工智能应用的重要基础。")
def split_fixed_count(text,count):
return [text[i:i+count] for i in range(0,len(text),count)]
#如果按照每50个字符来切分文本
chunks=split_fixed_count(txts,50)
for i ,chunk in enumerate(chunks):
print(f"chunk {i+1}:{len(chunk)}:{chunk}")

案例3:按固定字符数结合overlapping window
import re
txts=("大语言模型是基于深度学习架构、通过海量文本数据训练而成的人工智能系统。它能够理解自然语言、生成连贯文本,并在对话、翻译、摘要、创作等多种任务中表现出接近人类的表达能力。模型的性能通常与其参数量、训练数据规模和优化算法密切相关。随着技术不断迭代,大模型已从单一文本生成,逐步走向多模态理解、逻辑推理与工具调用,成为新一代人工智能应用的重要基础。")
#将文本切分成多个部分
def sliding_chunks(text,chunk_size,step):
return [text[i:i+chunk_size] for i in range(0,len(text),step)]
#如果按照每100个字符来切分文本,步长为50
chunks=sliding_chunks(txts,100,50)
for i ,chunk in enumerate(chunks):
print(f"chunk {i+1}:{len(chunk)}:{chunk}")

案例4: 递归方法 RecursiveCharacterTextSplitter
import re
from langchain_text_splitters import RecursiveCharacterTextSplitter
txts = (
"大语言模型是基于深度学习架构、通过海量文本数据训练而成的人工智能系统。它能够理解自然语言、生成连贯文本,并在对话、翻译、摘要、创作等多种任务中表现出接近人类的表达能力。模型的性能通常与其参数量、训练数据规模和优化算法密切相关。随着技术不断迭代,大模型已从单一文本生成,逐步走向多模态理解、逻辑推理与工具调用,成为新一代人工智能应用的重要基础。")
# 初始化分割器
# chunk_size: 每个块的最大长度
# chunk_overlap: 每个块之间的重叠长度
# length_function: 计算文本长度的函数,默认是len
# RecursiveCharacterTextSplitter会递归地尝试不同的分隔符(如段落、句子、单词等)来分割文本,确保分割后的文本块尽可能完整且有语义意义
text_splitter = RecursiveCharacterTextSplitter(chunk_size=50, chunk_overlap=10, length_function=len)
#一个文本块列表,每个文本块的长度不超过50个字符,且相邻文本块有10个字符的重叠部分。
chunks = text_splitter.split_text(txts)
for i, chunk in enumerate(chunks):
print(f"chunk {i + 1}:{len(chunk)}:{chunk}")
注意:
安装: pip install langchain
安装: pip install langchain-text-splitters
新版(1.2.15):from langchain_text_splitters import ...
LangChain 官方做了模块化拆分,文本分割器独立成包了。

二、向量检索
1、检索的方式
- 关键字搜索:通过用户输入的关键字来查找文本数据。
- 语义搜索:不仅考虑关键词的匹配,还考虑词汇之间的语义关系,以提供更准确的搜索结果。
2、关键字搜索
我们需要把相关的信息存储在Redis中。我们需要先安装一个Redis。先下载再直接解压缩。

然后cmd进入到对应的目录。然后输入redis-server.exe

再安装一个RDM工具来查看导入的数据

连接到Redis服务器,默认有16个数据库

(1) 将json中的数据存入到Redis数据库中

python安装 pip install redis
import redis # pip install redis
from openai import OpenAI
from dotenv import load_dotenv
import json
# 默认加载项目根目录下的 .env 文件
load_dotenv()
# 1. 获取client对象,OpenAI类对象
client=OpenAI()
#2. 获取redis对象
#localhost:指定Redis服务器地址为本地主机
#6379:指定Redis服务器端口为6379
#db=0:指定Redis数据库索引为0;(Redis默认有16个数据库(0-15))
#decode_responses=True:指定Redis返回的数据类型为字符串
r = redis.Redis(host='localhost', port=6379, db=0,decode_responses=True)
#3.读取数据
with open('train_zh.json', 'r', encoding='utf-8') as f:
data = json.load(f)
#4.取出问题
instrutions= [item['instruction'] for item in data[0:800]]
#5.输出数据
outputs=[item['output'] for item in data[0:800]]
#6.将数据存入redis
for instrution,output in zip(instrutions,outputs):
#存入Redis,值序列化为JSON
r.set(instrution,output) #key为问题,value为答案
#7.查询数据:根据关键字搜索instruction中包含该关键字的条目
def search_instrutions(keyword,top=3):
# 通过模糊匹配
keys=r.keys(pattern='*'+keyword+'*')
data=[]
#遍历通过模糊匹配找到的所有键
for key in keys:
data.append(r.get(key))
return data[:top]

(2)从Redis中提取数据进行大模型使用
>>>使用LLM接口封装
#2. 封装openai接口
# qwen-turbo阿里自研模型(对标 gpt-3.5-turbo)
def get_completion(prompt,model="qwen-turbo"):
response=client.chat.completions.create(
model=model,
messages=[
{"role": "user", "content": prompt}
],
temperature=0, #模型输出的随机性,0表示随机性小
)
return response.choices[0].message.content
>>>构建Prompt
#8 Prompt模板
# user_query="玩手机"
user_query="时间管理"
#1.检索
search_results=search_instrutions(user_query,3)
search_results='\n'.join(search_results)
#2.构建Prompt
prompt=f"""
你是一个问答机器人。
你的任务是根据下述给定的己知信息回答用户问题。
确保你的回复完全依据下述已知信息。不要编造答案。
如果下述己知信息不足以回答用户的问题,请直接回复“我无法回答您的问题
已知信息:
{search_results}
用户问:
{user_query}
请用中文回答用户问题。
"""
print("=======Prompt=======")
print(prompt)
print("=======Prompt=======")
#3.调用模型 LLM
response=get_completion(prompt)
print("=======回复=======")
print(response)
>>>整合(1)中,运行效果如下:


更多推荐
所有评论(0)