首页 > 其他分享 >基于langchain和文心一言的检索增强生成(RAG)初级实验

基于langchain和文心一言的检索增强生成(RAG)初级实验

时间:2024-01-16 18:01:57浏览次数:30  
标签:检索 RAG 模型 langchain 车次 时间 文心 出发

一、什么是RAG?

RAG的架构如图中所示,简单来讲,RAG就是通过检索获取相关的知识并将其融入Prompt,让大模型能够参考相应的知识从而给出合理回答。因此,可以将RAG的核心理解为“检索+生成”,前者主要是利用向量数据库的高效存储和检索能力,召回目标知识;后者则是利用大模型和Prompt工程,将召回的知识合理利用,生成目标答案。

基于langchain和文心一言的检索增强生成(RAG)初级实验_数据库

RAG架构

完整的RAG应用流程主要包含两个阶段:

  • 数据准备阶段:数据提取——>文本分割——>向量化(embedding)——>数据入库
  • 应用阶段:用户提问——>数据检索(召回)——>注入Prompt——>LLM生成答案

技术细节和注意事项:

1、数据准备阶段:

数据准备一般是一个离线的过程,主要是将私域数据向量化后构建索引并存入数据库的过程。主要包括:数据提取、文本分割、向量化、数据入库等环节。

基于langchain和文心一言的检索增强生成(RAG)初级实验_向量化_02

数据准备

  • 数据提取
  • 数据加载:包括多格式数据加载、不同数据源获取等,根据数据自身情况,将数据处理为同一个范式。
  • 数据处理:包括数据过滤、压缩、格式化等。
  • 元数据获取:提取数据中关键信息,例如文件名、Title、时间等 。
  • 文本分割
    文本分割主要考虑两个因素:1)embedding模型的Tokens限制情况;2)语义完整性对整体的检索效果的影响。一些常见的文本分割方式如下:
  • 句分割:以”句”的粒度进行切分,保留一个句子的完整语义。常见切分符包括:句号、感叹号、问号、换行符等。
  • 固定长度分割:根据embedding模型的token长度限制,将文本分割为固定长度(例如256/512个tokens),这种切分方式会损失很多语义信息,一般通过在头尾增加一定冗余量来缓解。
  • 向量化(embedding)

向量化是一个将文本数据转化为向量矩阵的过程,该过程会直接影响到后续检索的效果。目前常见的embedding模型如表中所示,这些embedding模型基本能满足大部分需求,但对于特殊场景(例如涉及一些罕见专有词或字等)或者想进一步优化效果,则可以选择开源Embedding模型微调或直接训练适合自己场景的Embedding模型。

模型名称
描述
获取地址

ChatGPT-Embedding
ChatGPT-Embedding由OpenAI公司提供,以接口形式调用。
https://platform.openai.com/docs/guides/embeddings/what-are-embeddings

ERNIE-Embedding V1
ERNIE-Embedding V1由百度公司提供,依赖于文心大模型能力,以接口形式调用。
https://cloud.baidu.com/doc/WENXINWORKSHOP/s/alj562vvu

M3E
M3E是一款功能强大的开源Embedding模型,包含m3e-small、m3e-base、m3e-large等多个版本,支持微调和本地部署。
https://huggingface.co/moka-ai/m3e-base

BGE
BGE由北京智源人工智能研究院发布,同样是一款功能强大的开源Embedding模型,包含了支持中文和英文的多个版本,同样支持微调和本地部署。
https://huggingface.co/BAAI/bge-base-en-v1.5

  • 数据入库:

数据向量化后构建索引,并写入数据库的过程可以概述为数据入库过程,适用于RAG场景的数据库包括:FAISS、Chromadb、ES、milvus等。一般可以根据业务场景、硬件、性能需求等多因素综合考虑,选择合适的数据库。

2、应用阶段:

在应用阶段,我们根据用户的提问,通过高效的检索方法,召回与提问最相关的知识,并融入Prompt;大模型参考当前提问和相关知识,生成相应的答案。关键环节包括:数据检索、注入Prompt等。

基于langchain和文心一言的检索增强生成(RAG)初级实验_向量化_03

数据检索

  • 数据检索

常见的数据检索方法包括:相似性检索、全文检索等,根据检索效果,一般可以选择多种检索方式融合,提升召回率。

  • 相似性检索:即计算查询向量与所有存储向量的相似性得分,返回得分高的记录。常见的相似性计算方法包括:余弦相似性、欧氏距离、曼哈顿距离等。
  • 全文检索:全文检索是一种比较经典的检索方式,在数据存入时,通过关键词构建倒排索引;在检索时,通过关键词进行全文检索,找到对应的记录。
  • 注入Prompt

基于langchain和文心一言的检索增强生成(RAG)初级实验_向量化_04

LLM生成

Prompt作为大模型的直接输入,是影响模型输出准确率的关键因素之一。在RAG场景中,Prompt一般包括任务描述、背景知识(检索得到)、任务指令(一般是用户提问)等,根据任务场景和大模型性能,也可以在Prompt中适当加入其他指令优化大模型的输出。一个简单知识问答场景的Prompt如下所示:

 

【任务描述】
假如你是一个专业的客服机器人,请参考【背景知识】,回
【背景知识】
{content} // 数据检索得到的相关文本
【问题】
石头扫地机器人P10的续航时间是多久?

Prompt的设计只有方法、没有语法,比较依赖于个人经验,在实际应用过程中,往往需要根据大模型的实际输出进行针对性的Prompt调优。

二、跑通一个例子

在环境已经安装、embeded模型和文心正确部署的情况下,编写代码。这里待处理的对象是小学课文《观潮》

钱塘江大潮,自古以来被称为天下奇观。

农历八月十八是一年中传统的观潮日。这一天早上,我们来到了海宁市的盐官镇,据说这里是观潮最好的地方。我们随着观潮的人群,登上了海塘大堤。宽阔的钱塘江横卧在眼前。江面很平静,越往东越宽,在雨后的阳光下,笼罩着一层蒙蒙的薄雾。镇海古塔、中山亭和观潮台屹立在江边。远处,几座小山在云雾中若隐若现。江潮还没有来,海塘大堤上早已人山人海。大家昂首东望,等着,盼着。

午后一点左右,从远处传来隆隆的响声,好像闷雷滚动。顿时人声鼎沸,有人告诉我们,潮来了!我们踮着脚往东望去,江面还是风平浪静,看不出有什么变化。过了一会儿,响声越来越大,只见东边水天相接的地方出现了一条白线,人群又沸腾起来。

那条白线很快地向我们移来,逐渐拉长,变粗,横贯江面。再近些,只见白浪翻滚,形成一堵两丈多高的水墙。浪潮越来越近,犹如千万匹白色战马齐头并进,浩浩荡荡地飞奔而来;那声音如同山崩地裂,好像大地都被震得颤动起来。

霎时,潮头奔腾西去,可是余波还在漫天卷地般涌来,江面上依旧风号浪吼。过了好久,钱塘江才恢复了平静。看看堤下,江水已经涨了两丈来高了。

 

from langchain import LLMChain
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings import HuggingFaceBgeEmbeddings
from langchain.vectorstores import Chroma
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
from langchain.prompts.chat import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate
from langchain_wenxin.llms import Wenxin
#读取领域信息
loader = TextLoader("./knowledge/观潮.txt")
documents = loader.load()
#文本分割
text_splitter = CharacterTextSplitter(chunk_size=128, chunk_overlap=0)
documents = text_splitter.split_documents(documents)
# 向量化 embedding model: m3e-base
model_name = "./m3e-base"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': True}
embedding = HuggingFaceBgeEmbeddings(
                model_name=model_name,
                model_kwargs=model_kwargs,
                encode_kwargs=encode_kwargs,
                query_instruction="为文本生成向量表示用于文本检索"
            )
# load data to Chroma db
db = Chroma.from_documents(documents, embedding)
# LLM选型
llm = Wenxin(model="ernie-bot", baidu_api_key= baidu_api_key, baidu_secret_key= baidu_secret_key)

retriever = db.as_retriever()
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
qa = ConversationalRetrievalChain.from_llm(llm, retriever, memory=memory)
ret = qa({"question": "什么时间去哪里观潮比较合适?"})
print(ret)

  

返回结果:

{'question': '什么时间去哪里观潮比较合适?',

'chat_history': [HumanMessage(content='什么时间去哪里观潮比较合适?'), AIMessage(content='根据原文信息得出,农历八月十八去海宁市的盐官镇观潮比较合适。')], 'answer': '根据原文信息得出,农历八月十八去海宁市的盐官镇观潮比较合适。'}

再提问:

{'question': '钱塘江大潮分为那几个过程?',

'chat_history': [HumanMessage(content='钱塘江大潮分为那几个过程?'), AIMessage(content='钱塘江大潮分为三个过程:

1. 远处传来闷雷滚动的声音,人群沸腾,但江面依旧平静;

2. 东边水天相接的地方出现一条白线,白线逐渐拉长、变粗、横贯江面,形成一堵两丈多高的水墙,浩浩荡荡地飞奔而来;

3. 潮头奔腾西去,余波涌来,江面上依旧风号浪吼,过了好久,钱塘江才恢复了平静。')],

'answer': '钱塘江大潮分为三个过程:\n1. 远处传来闷雷滚动的声音,人群沸腾,但江面依旧平静;\n2. 东边水天相接的地方出现一条白线,白线逐渐拉长、变粗、横贯江面,形成一堵两丈多高的水墙,浩浩荡荡地飞奔而来;\n3. 潮头奔腾西去,余波涌来,江面上依旧风号浪吼,过了好久,钱塘江才恢复了平静。'}

这里的对原文的理解和解析,还是很到位的。

三、对民法典进行分析

法典是规范性文件,但是一千多条很专业,如果能够使用RAG来加快理解,应该是有帮助的:

'question': '处理民事纠纷应该注意哪些要点?'

'answer': '处理民事纠纷应该注意以下要点:

1. 当事人的姓名或者名称和住所。

2. 标的。

3. 数量。

4. 质量。

5. 价款或者报酬。

6. 履行期限、地点和方式。

7. 违约责任。

8. 解决争议的方法。

9. 内容与公序良俗的关联性。

10. 受害人名誉受贬损的可能性。

11. 核实能力和核实成本。

'question': '签订合同的时候需要注意哪些?'

AIMessage(content='在签订合同时,应该注意以下方面:

1. 确保合同内容具体确定,包括双方的权利和义务、交易条件等。

2. 如果采用格式条款订立合同,提供格式条款的一方应当遵循公平原则确定当事人之间的权利和义务,并采取合理的方式提示对方注意免除或者减轻其责任等与对方有重大利害关系的条款,按照对方的要求,对该条款予以说明。如果提供格式条款的一方未履行提示或者说明义务,致使对方没有注意或者理解与其有重大利害关系的条款的,对方可以主张该条款不成为合同的内容。

3. 合同成立地点:采用数据电文形式订立合同的,收件人的主营业地为合同成立的地点;没有主营业地的,其住所地为合同成立的地点。当事人另有约定的,按照其约定。

4. 合同组成部分:与履行合同有关的技术背景资料、可行性论证和技术评价报告、项目任务书和计划书、技术标准、技术规范、原始设计和工艺文件,以及其他技术文档,按照当事人的约定可以作为合同的组成部分。')],

question='法人和自然人有哪些区别?'),

AIMessage(content='法人和自然人的区别主要有以下几点:

1. 法律地位:法人是一个组织,具有法律上的独立人格,可以独立享有权利和承担义务。而自然人是指有生命的个人,是权利和义务的主体。

2. 成立条件和程序:法人必须依法成立,具备相应的条件和程序,如名称、组织机构、住所、财产或经费等。而自然人无需经过任何法定程序即可成为权利主体。

3. 民事权利和义务:法人和自然人在民事权利和义务方面有所不同。法人主要享有名称权、名誉权和荣誉权等权利,而自然人则享有生命权、身体权、健康权、姓名权、肖像权、名誉权、荣誉权、隐私权、婚姻自主权等权利。此外,法人的民事权利能力和民事行为能力从法人成立时产生,到法人终止时消灭,而自然人的民事权利能力和民事行为能力则伴随其一生。\n4. 财产责任:法人以其全部财产独立承担民事责任,而自然人的财产责任则根据具体情况而定。')],

四、对新闻进行分析

鉴于大模型的知识库中可能存在历史的信息,所以用最新的新闻来进行以上流程。这里我特地在提问的时候写了错别字,应该被文心看出来了。


五、表格数据分析

随机生成100条简化版的列车时刻表信息。每条信息包括车次和出发时间。使用RAG进行问询:

1. 车次:G12345,出发时间:08:00
2. 车次:D67890,出发时间:09:30
3. 车次:K12345,出发时间:10:00
4. 车次:T67890,出发时间:11:30
5. 车次:G12346,出发时间:12:00
6. 车次:D67891,出发时间:13:30
7. 车次:K12346,出发时间:14:00
8. 车次:T67891,出发时间:15:30
9. 车次:G12347,出发时间:16:00
10. 车次:D67892,出发时间:17:30
11. 车次:K12347,出发时间:18:00
12. 车次:T67892,出发时间:19:30
13. 车次:G12348,出发时间:20:00
14. 车次:D67893,出发时间:21:30
15. 车次:K12348,出发时间:22:00
16. 车次:T67893,出发时间:23:30
17. 车次:G12349,出发时间:00:00
18. 车次:D67894,出发时间:01:30
19. 车次:K12349,出发时间:02:00
20. 车次:T67894,出发时间:03:30
21. 车次:G12350,出发时间:04:00
22. 车次:D67895,出发时间:05:30
23. 车次:K12350,出发时间:06:00
24. 车次:T67895,出发时间:07:30
25. 车次:G12351,出发时间:08:00
26. 车次:D67896,出发时间:09:30
27. 车次:K12351,出发时间:10:00
28. 车次:T67896,出发时间:11:30
29. 车次:G12352,出发时间:12:00
30. 车次:D67897,出发时间:13:30
31. 车次:K12352,出发时间:14:00
32. 车次:T67897,出发时间:15:30
33. 车次:G12353,出发时间:16:00
34. 车次:D67898,出发时间:17:30
35. 车次:K12353,出发时间:18:00
36. 车次:T67898,出发时间:19:30
37. 车次:G12354,出发时间:20:00
38. 车次:D67899,出发时间:21:30
39. 车次:K12354,出发时间:22:00
40. 车次:T67899,出发时间:23:30
41. 车次:G12355,出发时间:00:00
42. 车次:D67900,出发时间:01:30
43. 车次:K12355,出发时间:02:00
44. 车次:T67900,出发时间:03:30
45. 车次:G12356,出发时间:04:00
46. 车次:D67901,出发时间:05:30
47. 车次:K12356,出发时间:06:00
48. 车次:T67901,出发时间:07:30
49. 车次:G12357,出发时间:08:00
50. 车次:D67902,出发时间:09:30
51. 车次:K12357,出发时间:10:00
52. 车次:T67902,出发时间:11:30
53. 车次:G12358,出发时间:12:00
54. 车次:D67903,出发时间:13:30
55. 车次:K12358,出发时间:14:00
56. 车次:T67903,出发时间:15:30
57. 车次:G12359,出发时间:16:00
58. 车次:D67904,出发时间:17:30
59. 车次:K12359,出发时间:18:00
60. 车次:T67904,出发时间:19:30
61. 车次:G12360,出发时间:20:00
62. 车次:D67905,出发时间:21:30
63. 车次:K12360,出发时间:22:00
64. 车次:T67905,出发时间:23:30
65. 车次:G12361,出发时间:00:00
66. 车次:D67906,出发时间:01:30
67. 车次:K12361,出发时间:

 

提问:出发最早的车是哪个?
RAG回答: 出发最早的车是车次G12345,出发时间是08:00。【这个答案是错误的】

 

提问:我下午2点出发,最好坐那班车?
RAG回答: 要确定下午2点哪个车次最适合你乘坐,需要找到所有出发时间在2点之后的车次,然后从中选择最适合的车次。以下是符合要求的所有车次:
1. 车次:G12351,出发时间:14:00
2. 车次:K12352,出发时间:14:00
3. 车次:T67897,出发时间:15:30
4. 车次:G12353,出发时间:16:00
5. 车次:K12353,出发时间:16:00
6. 车次:T67898,出发时间:17:30
7. 车次:G12354,出发时间:18:00
8. 车次:K12354,出发时间:18:00
9. 车次:T67899,出发时间:19:30
10. 车次:G12355,出发时间:20:00
11. 车次:D67903,出发时间:20:00
12. 车次:K12355,出发时间:20:00
13. 车次:T67903,出发时间:21:30
14. 车次:G12356,出发时间:22:00
15. 车次:D67904,出发时间:22:00
16. 车次:K12356,出发时间:22:00
17. 车次:T67904,出发时间:23:30
在这些车次中,你可以选择出发时间最早的车次G12351。

 

提问:有哪些以K开头的车?
RAG回答: 以K开头的车次有:
1. K12345,出发时间:10:00
2. K12346,出发时间:14:00
3. K12347,出发时间:18:00
4. K12348,出发时间:22:00
5. K12349,出发时间:02:00
6. K12350,出发时间:06:00
7. K12351,出发时间:10:00
8. K12352,出发时间:14:00
9. K12353,出发时间:18:00
10. K12354,出发时间:22:00
11. K12355,出发时间:02:00
12. K12356,出发时间:06:00
13. K12357,出发时间:10:00
14. K12358,出发时间:14:00
15. K12359,出发时间:18:00
16. K12360,出发时间:22:00
17. K12361,出发时间:

标签:检索,RAG,模型,langchain,车次,时间,文心,出发
From: https://blog.51cto.com/jsxyhelu2017/9275869

相关文章

  • 文心一言 VS 讯飞星火 VS chatgpt (180)-- 算法导论13.4 3题
    三、用go语言,在练习13.3-2中,将关键字41、38、31、12、19、8连续插入一棵初始的空树中,从而得到一棵红黑树。请给出从该树中连续删除关键字8、12、19、31、38、41后的红黑树。文心一言,代码不能运行:为了解决这个问题,我们首先需要构建一棵红黑树,然后依次删除给定的关键字。以下......
  • 神经网络优化篇:详解指数加权平均的偏差修正(Bias correction in exponentially weighte
    指数加权平均的偏差修正\({{v}_{t}}=\beta{{v}_{t-1}}+(1-\beta){{\theta}_{t}}\)在上一个博客中,这个(红色)曲线对应\(\beta\)的值为0.9,这个(绿色)曲线对应的\(\beta\)=0.98,如果执行写在这里的公式,在\(\beta\)等于0.98的时候,得到的并不是绿色曲线,而是紫色曲线,可以注意到紫色曲线......
  • localStorage、sessionStorage和cookie的使用
    vue-cookies的使用首先需要安装vue-cookiescnpminstallvue-cookies-S 具体使用方法如下:设置cookie://key,value形式、过期时间为7天cookie.set('name','zeng','7d') 获取cookie://打印key值为name的cookieconsole.log(cookie.get('name')) 删除......
  • 基于文心大模型的AI机器人画画实现
    在过去的几年里,人工智能(AI)已经取得了巨大的进步,特别是在自然语言处理(NLP)领域。文心大模型是NLP领域的一种重要技术,它通过学习大量文本数据来理解人类语言,并能够生成自然、流畅的语言输出。基于文心大模型的AI机器人画画实现,就是利用文心大模型的语言生成能力,结合画画技术,创作出具有......
  • 从飞桨PPDE到文心布道师
    随着深度学习技术的不断发展,大模型已经成为了业界的热点话题。在大模型时代,如何高效地开发、训练和应用模型成为了众多开发者面临的问题。为了帮助开发者更好地应对这一挑战,飞桨PPDE和文心布道师这两个平台应运而生。飞桨PPDE(PaddlePaddleDeveloperExperience)是飞桨平台为开发者......
  • AI遇上传统文化,文心一言上央视带来跨时空访古体验
    从先秦七子到唐宋八大家,千年前的先贤们为后人留下了弥足珍贵的思想瑰宝。在科技发展飞速的后世,先贤的思想传承方式能否借助科技推陈出新呢?在近期CCTV-10科教频道播出的《寻迹先贤》中,文心一言就通过AI互动的形式,给观众带来了一场现代科技与传统文化融合的精神盛宴。在节目中,文心一......
  • 神经网络优化篇:理解指数加权平均数(Understanding exponentially weighted averages)
    理解指数加权平均数回忆一下这个计算指数加权平均数的关键方程。\({{v}_{t}}=\beta{{v}_{t-1}}+(1-\beta){{\theta}_{t}}\)\(\beta=0.9\)的时候,得到的结果是红线,如果它更接近于1,比如0.98,结果就是绿线,如果\(\beta\)小一点,如果是0.5,结果就是黄线。进一步地分析,来理解如何计......
  • 文心一言 VS 讯飞星火 VS chatgpt (178)-- 算法导论13.4 1题
    一、用go语言,在执行RB-DELETE-FIXUP之后,证明:树根一定是黑色的。文心一言:在证明RB-DELETE-FIXUP之后,树根一定是黑色的的过程中,我们首先需要理解红黑树的性质。红黑树是一种自平衡二叉搜索树,它的每个节点都有一个颜色属性,可以是红色或黑色。红黑树的性质包括:节点是红色或黑色。......
  • 文心一言 VS 讯飞星火 VS chatgpt (178)-- 算法导论13.4 1题
    一、用go语言,在执行RB-DELETE-FIXUP之后,证明:树根一定是黑色的。文心一言:在证明RB-DELETE-FIXUP之后,树根一定是黑色的的过程中,我们首先需要理解红黑树的性质。红黑树是一种自平衡二叉搜索树,它的每个节点都有一个颜色属性,可以是红色或黑色。红黑树的性质包括:节点是红色或黑色......
  • 开发篇1:使用原生api和Langchain调用大模型
    对大模型的调用通常有以下几种方式:方式一、大模型厂商都会定义http风格的请求接口,在代码中可以直接发起http请求调用;方式二、在开发环境中使用大模型厂商提供的api;方式三、使用开发框架Langchain调用,这个就像java对数据库的调用一样,可以直接用jdbc也可以使用第三方框架,第三方框架......