如何手撸一个自有知识库的RAG系统

如何手撸一个自有知识库的RAG系统RAG通常指的是\”Retrieval-Augmented Generation\”,即“检索增强的生成”。这是一种结合了检索(Retrieval)和生成&#xff08

RAG 通常指“检索增强生成”。它是一种结合搜索和生成的机器学习模型,通常用于文本生成和问答系统等自然语言处理任务。

根据京东云官网文档,按照以下步骤完成RAG系统。

数据采集、知识库构建、向量搜索、提示词和模型

数据收集

数据收集可以说是整个RAG实施过程中最耗费人力的过程,包括收集、清洗、格式化、分段等过程。我们将使用京东云的官方文档作为我们知识库的基础。文档的格式大约是:

复制快捷代码{
\’content\’: \’DDoS IP 高防与Web 应用防火墙组合方案说明\\n=======================\\n\\n\\nDDoS IP 高防+ Web应用防火墙提供3-7层安全防护体系,应用场景包括游戏、金融、电商、互联网、政府、企业等多种类型的应用,涵盖京东云内外的用户。 \\n\\n\\n部署架构\\n====\\n\\n\\n[![\\\’部署架构\\\’](\\\’https://jdcloud-portal.oss.cn-north-1.jcloudcs.com/cn/image/Advanced%20Anti-DDoS/Best-Practice02.png\\\’)](\\\’https://jdcloud-portal.oss.cn-north-1.jcloudcs.com/cn/image/Advanced%20Anti-DDoS/Best-Practice02 . png\\\’) \\n\\nDDoS IP防御+Web应用防火墙的最佳部署架构为: \\n\\n\\n* 京东云安全调度中心通过DNS解析CNAME将用户域名解析为DDoS IP防御。 \\n* 常规用户访问流量和DDoS攻击流量由DDoS IP高防清理并返回到Web应用防火墙的源头。 \\n* 攻击者的恶意请求被Web应用防火墙过滤并返回到用户原始站点。 \\n* Web应用防火墙可以保护任何公网服务器,包括但不限于京东云、其他厂商的云、IDC等。 \\n\\n\\n方案优势\\n====\\n\\n\\n1.用户源站位于DDoS IP高防和Web应用防火墙后面,隐藏源站IP即可实现。 \\n2. CNAME访问,配置简单,减少运维人员的工作量。 \\n\\n\\n\’,
\’title\’: \’DDoS IP高级防御与Web应用防火墙组合方案说明\’,
\’产品\’: \’DDoS IP 防御高\’,
\’url\’: \’https://docs.jdcloud.com/cn/anti-ddos-pro/anti-ddos-pro-and-waf\’
}

每个数据都是包含四个字段的JSON。这四个字段是“内容”:文档的标题、“产品”:关联的产品和“URL”:文档的在线地址。

向量数据库的选择与Retriever实现

矢量数据库是RAG系统的存储中心。市面上有很多开源的向量库,哪个向量库更好是见仁见智的问题。对于这个项目,作者选择Clickhouse 作为矢量数据库。选择ck 时的主要考虑因素包括:

ckzailangchain社区的集成实现不错,入库也比较顺利,向量查询支持SQL,学习成本低,而且京东云有相关产品和专业团队支持,所以很容易上手。信心

文档向量化及入库过程

为了简化文档矢量化和检索过程,我们使用了Longchain 的Retriever 工具集。
首先,对文档进行矢量化。这是代码:

从ini libs.jd_doc_json_loader 复制代码导入JD_DOC_Loader
从langchain_community.document_loaders 导入DirectoryLoader
root_dir=\’/root/jd_docs\’
加载器=目录加载器(
\’/root/jd_docs\’, glob=\’**/*.json\’, loader_cls=JD_DOC_Loader)
文档=loader.load()

为此,由于langchain社区没有提供具体格式的loader,我们自定义了JD_DOC_Loader来实现加载过程。

复制代码并在Python 中导入JSON
导入日志
从pathlib导入路径
从输入导入迭代器、可选、联合
从langchain_core.documents 导入文档
从langchain_community.document_loaders.base 导入BaseLoader
从langchain_community.document_loaders.helpers 导入detector_file_encodings
记录器=logging.getLogger(__name__)
类JD_DOC_Loader(BaseLoader):
\’\’加载文本文件。
参数:
file_path: 要加载的文件的路径。
coding: 要使用的文件编码。如果“无”,则将加载该文件。
使用默认的系统编码。
autoDetect_encoding: 是否自动检测文件编码
如果指定的编码失败。
””
def __init__(
自己,
file_path: 联合[str, 路径],
编码: 选项[str]=无,
autoDetect_encoding: 布尔=假,
):
“使用文件路径初始化。”
self.filepath=文件路径
self.encoding=编码
self.autoDetect_encoding=自动检测_编码
def Lazy_load(self) – 迭代器[文档] :
“从文件路径加载。”
文本=\’\’
来自网址=\’\’
尝试:
使用open(self.file_path,encoding=self.encoding) 作为f:
doc_data=json.load(f)
文本=doc_data[\’内容\’]
标题=doc_data[\’标题\’]
产品=doc_data[\’产品\’]
from_url=doc_data[\’url\’]
# 文本=f.read()
除了UnicodeDecodeError 为e:
如果self.autoDetect_encoding:
检测编码=检测文件编码(self.file_path)
用于使用detector_encodings: 进行编码
logger.debug(f\’编码: {encoding.encoding}\’)
尝试:
使用open(self.file_path,encoding=encoding.encoding) 作为f:
文本=f.read()
休息
UnicodeDecodeError: 除外
继续
: 其他
从e 引发RuntimeError(f\’读取{self.file_path} 时出错\’)
除了e:
从e 引发RuntimeError(f\’读取{self.file_path} 时出错\’)
# 元数据={\’source\’: str(self.file_path)}
元数据={\’source\’: from_url,\’title\’: 标题,\’product\’: 产品}
产量文档(page_content=文本,元数据=元数据)

上面代码的主要功能是解析json文件并填充文档的page_content和metadata字段。

接下来,使用langchain 的clickhouse 矢量工具集将文档保存到数据库。

复制ini代码并将langchain_community.vectorstores.clickhouse导入为clickhouse
从langchain.embeddings 导入HuggingFaceEmbeddings
model_kwargs={\’设备\’: \’cuda\’}
嵌入=HuggingFaceEmbeddings(
model_name=\’/root/models/moka-ai-m3e-large\’, model_kwargs=model_kwargs)
设置=clickhouse.ClickhouseSettings(
表=\’jd_docs_m3e_with_url\’,用户名=\’默认\’,密码=\’xxxxx

x\’, 主机=\’10.0.1.94\’)

docsearch=clickhouse.Clickhouse.from_documents(

文档、嵌入、配置=设置)

正常存放后,我们会进行检查

复制ini代码并将langchain_community.vectorstores.clickhouse导入为clickhouse

从langchain.embeddings 导入HuggingFaceEmbeddings

model_kwargs={\’device\’: \’cuda\’}~~~~

嵌入=HuggingFaceEmbeddings(

model_name=\’/root/models/moka-ai-m3e-large\’, model_kwargs=model_kwargs)

设置=clickhouse.ClickhouseSettings(

表=\’jd_docs_m3e_with_url_splited\’,用户名=\’默认\’,密码=\’xxxx\’,主机=\’10.0.1.94\’)

ck_db=clickhouse.Clickhouse(嵌入,config=config)

ck_retriever=ck_db.as_retriever(

search_type=\’similarity_score_threshold\’, search_kwargs={\’score_threshold\’: 0.9})

ck_retriever.get_relevant_documents(\’如何创建mysql rds\’)

一旦有了知识库,您就可以构建简单的RESTful 服务。这里我们使用fastapi。

从ini fastapi 复制代码导入FastAPI

从pydantic 导入BaseModel

从singleton_decorator 导入单例

从langchain_community.embeddings 导入HuggingFaceEmbeddings

将langchain_community.vectorstores.clickhouse 导入为clickhouse

进口独角兽

导入json

应用程序=FastAPI()

应用程序=FastAPI(docs_url=无)

应用程序主机=\’0.0.0.0\’

model_kwargs={\’设备\’: \’cuda\’}

嵌入=HuggingFaceEmbeddings(

model_name=\’/root/models/moka-ai-m3e-large\’, model_kwargs=model_kwargs)

设置=clickhouse.ClickhouseSettings(

表=\’jd_docs_m3e_with_url_splited\’,用户名=\’默认\’,密码=\’xxxx\’,主机=\’10.0.1.94\’)

ck_db=clickhouse.Clickhouse(嵌入,config=config)

ck_retriever=ck_db.as_retriever(

search_type=\’相似度\’, search_kwargs={\’k\’: 3})

类问题(BaseModel):

内容: str

@app.get(\’/\’)

异步默认root():

返回{\’确定\’}

@app.post(\’/retriever\’)

异步默认检索器(问题: 问题) :

全局ck_retriever

结果=ck_retriever.invoke(问题.内容)

返回结果

如果__name__==\’__main__\’:

uvicorn.run(app=\’retriever_api:app\’, 主机=\’0.0.0.0\’,

端口=8000,重新加载=True)

返回值的结构如下所示:

复制快捷代码[

{

\’page_content\’: \’云缓存Redis — Redis 迁移解决方案\\n###RedisSyncer 说明\\n####数据验证\\n“\\nwget https://github.com/TraceNature/rediscompare/releases/download/v1.0/rediscompare-1.0.0-linux-amd64.tar.gz\\nrediscompare 比较single2single –saddr \\\’10.0.1.101:6479\\\’ –spassword \\\’redistest0102\\\’ –taddr \\\’10.0.1.102:6479\\\’ – -tpassword \\ \’ redistest0102\\\’ –comparetimes 3\\n\\n“`\\n**Github 地址:** [https://github.com/TraceNature/redissyncer-server](\\\’https://github.com/TraceNature/redissyncer-server \\\’ )\’ ,

\’元数据\’: {

\’产品\’: \’云缓存Redis\’,

\’来源\’: \’https://docs.jdcloud.com/cn/jcs-for-redis/doc-2\’,

\’title\’: \’Redis迁移方案\’

},

\’类型\’: \’文档\’

},

{

\’page_content\’: \’云缓存Redis — Redis 迁移解决方案\\n###RedisSyncer 说明\\n####数据验证\\n“\\nwget https://github.com/TraceNature/rediscompare/releases/download/v1.0/rediscompare-1.0.0-linux-amd64.tar.gz\\nrediscompare 比较single2single –saddr \\\’10.0.1.101:6479\\\’ –spassword \\\’redistest0102\\\’ –taddr \\\’10.0.1.102:6479\\\’ – -tpassword \\ \’ redistest0102\\\’ –comparetimes 3\\n\\n“`\\n**Github 地址:** [https://github.com/TraceNature/redissyncer-server](\\\’https://github.com/TraceNature/redissyncer-server \\\’ )\’ ,

\’元数据\’: {

\’产品\’: \’云缓存Redis\’,

\’来源\’: \’https://docs.jdcloud.com/cn/jcs-for-redis/doc-2\’,

\’title\’: \’Redis迁移方案\’

},

\’类型\’: \’文档\’

},

{

\’page_content\’: \’云缓存Redis — Redis 迁移解决方案\\n###RedisSyncer 说明\\n####数据验证\\n“\\nwget https://github.com/TraceNature/rediscompare/releases/download/v1.0/rediscompare-1.0.0-linux-amd64.tar.gz\\nrediscompare 比较single2single –saddr \\\’10.0.1.101:6479\\\’ –spassword \\\’redistest0102\\\’ –taddr \\\’10.0.1.102:6479\\\’ – -tpassword \\ \’ redistest0102\\\’ –comparetimes 3\\n\\n“`\\n**Github 地址:** [https://github.com/TraceNature/redissyncer-server](\\\’https://github.com/TraceNature/redissyncer-server \\\’ )\’ ,

\’元数据\’: {

\’产品\’: \’云缓存Redis\’,

\’来源\’: \’https://docs.jdcloud.com/cn/jcs-for-redis/doc-2\’,

\’title\’: \’Redis迁移方案\’

},

\’类型\’: \’文档\’

}

]

返回具有最小向量距离的列表。

结合模型和prompt,回答问题

为了节省计算资源,v100卡选择了Qwen 1.8B模型,只能支持Qwen模型和m3e-large嵌入式模型。

接听服务

从ini fastapi 复制代码导入FastAPI

从pydantic 导入BaseModel

从langchain_community.llms 导入VLLM

从变压器导入AutoTokenizer

从langchain.prompts 导入PromptTemplate

导入请求

进口独角兽

导入json

导入日志

应用程序=FastAPI()

应用程序=FastAPI(docs_url=无)

应用程序主机=\’0.0.0.0\’

记录器=logging.getLogger()

logger.setLevel(logging.INFO)

to_console=logging.StreamHandler()

logger.addHandler(to_console)

# 加载模型

# model_name=\’/root/models/Llama3-Chinese-8B-Instruct\’

模型名称=\’/root/models/Qwen1.5-1.8B-Chat\’

tokenizer=AutoTokenizer.from_pretrained(model_name)

llm_llama3=VLLM(

型号=型号名称,

分词器=分词器,

任务=\’文本生成\’,

温度=0.2,

do_sample=真,

重复罚分=1.1,

return_full_text=False,

最大新令牌=900,

迅速的

提示模板=\’\’

您是云技术专家吗?

请使用下面获得的上下文回答问题。

如果你不知道答案,就说你不知道。

请用中文回答问题。

问题: {问题}

Context: {上下文}

答复:

””

提示=提示模板(

input_variables=[\’上下文\’, \’问题\’],

模板=提示_模板,

def get_context_list(q: str)

:
url = \”http://10.0.0.7:8000/retriever\”
payload = {\”content\”: q}
res = requests.post(url, json=payload)
return res.text
class question(BaseModel):
content: str
@app.get(\”/\”)
async def root():
return {\”ok\”}
@app.post(\”/answer\”)
async def answer(q: question):
logger.info(\”invoke!!!\”)
global prompt
global llm_llama3
context_list_str = get_context_list(q.content)
context_list = json.loads(context_list_str)
context = \”\”
source_list = []
for context_json in context_list:
context = context+context_json[\”page_content\”]
source_list.append(context_json[\”metadata\”][\”source\”])
p = prompt.format(context=context, question=q.content)
answer = llm_llama3(p)
result = {
\”answer\”: answer,
\”sources\”: source_list
}
return result
if __name__ == \’__main__\’:
uvicorn.run(app=\’retriever_api:app\’, host=\”0.0.0.0\”,
port=8888, reload=True)

代码通过使用Retriever接口查找与问题相似的文档,作为context组合prompt推送给模型生成答案。
主要服务就绪后可以开始画一张脸了,使用gradio做个简易对话界面

gradio 服务
ini复制代码import json
import gradio as gr
import requests
def greet(name, intensity):
return \”Hello, \” + name + \”!\” * int(intensity)
def answer(question):
url = \”http://127.0.0.1:8888/answer\”
payload = {\”content\”: question}
res = requests.post(url, json=payload)
res_json = json.loads(res.text)
return [res_json[\”answer\”], res_json[\”sources\”]]
demo = gr.Interface(
fn=answer,
# inputs=[\”text\”, \”slider\”],
inputs=[gr.Textbox(label=\”question\”, lines=5)],
# outputs=[gr.TextArea(label=\”answer\”, lines=5),
# gr.JSON(label=\”urls\”, value=list)]
outputs=[gr.Markdown(label=\”answer\”),
gr.JSON(label=\”urls\”, value=list)]
)
demo.launch(server_name=\”0.0.0.0\”)

如何学习AI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

四、AI大模型商业化落地方案

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

#以上关于如何手撸一个自有知识库的RAG系统的相关内容来源网络仅供参考,相关信息请以官方公告为准!

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91315.html

(0)
CSDN's avatarCSDN
上一篇 2024年6月21日 下午6:07
下一篇 2024年6月21日 下午6:48

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注