本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!
ChatGPT面向对话格式的文本理解很好,但如果要把网络上的文章让ChatGPT直接分析则会有格式的问题。文本清洗是个大课题,讲起来需要很多篇幅,优化起来前路漫漫。
本文基于稍微加工后的文本内容,使用LangChain的CharacterTextSplitter 和 RecursiveCharacterTextSplitter两个文本切割方法做效果对比,因为文本切割的效果直接影响知识库方向ChatGPT反馈的效果。
先说结论,CTS比RTCS稍好,利用明确的段落分隔符可以避免一些初级问题发生,一些高级的问题两者都会发生。
以下文本内容来自大爆发:最后一波上半年能开标的50多个项目,预算超50亿元,标黄的内容是测试关键数据。
直接贴出运行结果,红框是出错的地方都是来自RTCS(RecursiveCharacterTextSplitter):
CTS 返回结果是使用CharacterTextSplitter做text_splitter,它是基于符号做段落切割,本文选择####作为段落的分割符。
RTCS 返回结果是使用RecursiveCharacterTextSplitter,它是基于固定大小做段落切分。
再次总结结论,CTS比RTCS稍好,可以避免一些初级问题发生。
接下来贴出源代码,分为两部分:input.py和output.py。
以下是Input.py的源码,是很关键很关键很关键的地方,用embedding和切割存数据到向量数据库:
import os
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
# 1 定义embedding
os.environ["OPENAI_API_TYPE"] = "azure"
os.environ["OPENAI_API_KEY"] = "xxxxxxxxxxxxx"
os.environ["OPENAI_API_BASE"] = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002", deployment="lk-text-embedding-ada-002", chunk_size=1)
# 2 定义文件
loader = TextLoader(".\\单文件\\项目信息.txt", "utf-8")
pages = loader.load_and_split()
# 3 重要!!!初始化加载器
# 按符号切分段落
text_splitter_CTS = CharacterTextSplitter(
separator = "####",
chunk_size = 500, #chunk_size = 1000,
chunk_overlap = 0
)
split_docs_CTS = text_splitter_CTS.split_documents(pages)
print(f'CharacterTextSplitter documents:{len(split_docs_CTS)}')
#print(split_docs_CTS)
#写入向量数据库
print(f'写入CTS向量数据库')
vectordb = Chroma.from_documents(split_docs_CTS, embedding=embeddings, persist_directory="./CTS/")
vectordb.persist()
# 按固定尺寸切分段落
text_splitter_RCTS = RecursiveCharacterTextSplitter(
chunk_size = 500, #chunk_size = 1000,
chunk_overlap = 200
)
split_docs_RCTS = text_splitter_RCTS.split_documents(pages)
print(f'RecursiveCharacterTextSplitter documents:{len(split_docs_RCTS)}')
#print(split_docs_RCTS)
#写入向量数据库
print(f'写入RCTS向量数据库')
vectordb = Chroma.from_documents(split_docs_RCTS, embedding=embeddings, persist_directory="./RTCS/")
vectordb.persist()
以下是Output.py的源码,调用ChatGPT基于向量数据库搜索出来的文字片段组织文字来回答:
import os
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain import OpenAI,VectorDBQA
from langchain.chains import RetrievalQA
from typing import Dict, Any
os.environ["OPENAI_API_TYPE"] = "azure"
os.environ["OPENAI_API_KEY"] = "xxxxxxxxxxxxxxxxxxxx"
os.environ["OPENAI_API_BASE"] = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
dict: Dict[str, Any] = {
"deployment_id": "lk-gpt-35-turbo"
}
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002", deployment="lk-text-embedding-ada-002", chunk_size=1)
openAiLLm = OpenAI(temperature=0.9, model_name="gpt-35-turbo", model_kwargs=dict, max_tokens=100)
db_CTS = Chroma(persist_directory="./CTS/", embedding_function=embeddings)
db_RTCS = Chroma(persist_directory="./RTCS/", embedding_function=embeddings)
print('----------------')
question_list=["介绍一下重庆市新型数字交通物联网大数据服务平台的金额、截止时间",
"介绍一下广州城市职业学院项目的金额、截止时间",
"介绍一下吴中区智慧教育项目的预算、截止时间",
"介绍一下之江实验室项目的预算、截止时间"]
for i in range(0,len(question_list)):
question_text=question_list[i]
qa_CTS = RetrievalQA.from_chain_type(llm=openAiLLm, chain_type="stuff", retriever=db_CTS.as_retriever(), return_source_documents=False)
# 进行问答
result = qa_CTS({"query": question_text})
print("CTS 返回结果:" + str(result))#.split('\n')[0])
print('------')
qa_RTCS = RetrievalQA.from_chain_type(llm=openAiLLm, chain_type="stuff", retriever=db_RTCS.as_retriever(), return_source_documents=False)
# 进行问答
result = qa_RTCS({"query": question_text})
print("RTCS 返回结果:" + str(result))#.split('\n')[0])
print('***********************************************')