2026年7月9日 周四晚上19:30,报名腾讯会议了解“如何构建自进化的动态知识库(Brain)”(限30人)
免费POC, 零成本试错
FDE知识库

FDE知识库

学习大模型的前沿技术与行业落地应用


收藏

使用 Easysearch 打造企业内部知识问答系统 | 征文系列

发布日期:2024-07-30 19:15:24 浏览次数: 2788
作者:SearchKit

微信搜一搜,关注“SearchKit”


活动预告



【7月31日】第1期 | 2024 搜索客社区 Meetup 线上直播活动,主题:《Easysearch 结合大模型实现 RAG》


以下是正文



大家可能都有这样的经历,刚入职一家企业时,同事往往会给你分享一些文档资料,有可能是产品信息、规章制度等等。这些文档有的过于冗长,很难第一时间找到想要的内容。有的已经有了新版本,但员工使用的还是老版本。


基于这种背景,我们可以利用 Easysearch 加 LLM 实现一个内部知识的 QA 问答系统。这个系统将利用 LangChain 框架调用本地部署的大模型和 Easysearch,实现理解员工的提问,并基于最新的文档,给出精准答案。


开发框架



整个框架分为四个部分:

  • 数据源:数据可以有很多种,可以是非结构化的,比如 PDF、docx、txt 等。也可以是结构化的数据,甚至代码也行。在本次示例中,我们使用 PDF 的非结构化数据。

  • 大模型应用:应用与大模型交互,生成我们需要的答案。

  • 大模型:系统执行相关任务需要用到的大模型,可以有多个。

  • Q&A 场景:基于大模型为引擎的 QA 场景,使用 web 框架,构建一个交互界面。


数据准备


本次我们使用的资料是 “INFINI 产品安装手册.pdf” ,文档部分内容展示如下:



首先我们使用 LangChain 的 document_loaders 来加载文件。document_loaders 集成了数百种数据源格式,可以很方便的加载数据。我们的数据的 pdf 格式的,导入 PyPDFLoader 类来进行处理。代码如下:

import os
# 导入 Document Loadersfrom langchain_community.document_loaders import PyPDFLoader
# Load Pdfbase_dir = '.\\easysearch' # 文档的存放目录docs = []for file in os.listdir(base_dir):    file_path = os.path.join(base_dir, file)    if file.endswith('.pdf'):        loader = PyPDFLoader(file_path)        documents.extend(loader.load())


上面的代码将 pdf 文件的内容存储在 docs 这个列表中,以便后续进行处理。


文本分割


一个文件的文本内容可能很大,无法适应许多模型的上下文窗口,也不利于检索和存储。因此,通常我们会将文本内容分割成更小的块,这将帮助我们在运行时只检索文档中最相关的部分。LangChain 提供了工具来进行处理文本分割,非常方便。我们将把文档分割成 1000 个字符的块,每个块之间有 200 个重叠字符。这种重叠有助于减少将语句与相关的重要上下文分离的可能性。

# 2.将Documents切分成块from langchain.text_splitter import RecursiveCharacterTextSplittertext_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=20)chunked_documents = text_splitter.split_documents(docs)


上面的代码将 docs 的内容按 1000 字符大小进行切分,存储在 chunked_documents 中,以便后续进行处理。


注意,实际运行中,切分及重叠的大小,都会影响应用效果,需自行调试。


向量库 Easysearch


接下来,我们将这些文本块转换成向量的形式,并存储在一个向量数据库中。在本示例中,我们使用 mxbai-embed-large 模型来生成向量,然后将向量和原始内容存入 easysearch 。


本地部署模型,我使用的是 ollama ,大家可以使用自己喜欢的工具。

# 3. 定义embedding模型from langchain_community.embeddings import OllamaEmbeddingsollama_emb = OllamaEmbeddings(    model="mxbai-embed-large",)
# 4. 定义 easysearch 集群的信息,以及存放向量的索引名称 infinifrom langchain_community.vectorstores import EcloudESVectorStoreES_URL = "https://192.168.56.3:9200"USER = "admin"PASSWORD = "e5ac1b537785ae27c187"indexname = "infini"
docsearch = EcloudESVectorStore.from_documents(    chunked_documents,    ollama_emb,    es_url=ES_URL,    user=USER,    password=PASSWORD,    index_name=indexname,    verify_certs=False,)


通过上面的步骤,我们成功将文本块转换成了向量,并存入到了 easysearch 集群的 infini 索引中。



我们看看 infini 索引内容是怎样的



text 字段存放了文本块的原始内容,vector 字段存放着对应的向量表示。


检索及生成答案


在这一步,我们会定义一个生成式大模型。然后创建一个 RetrievalQA 链,它是一个检索式问答模型,用于生成问题的答案。


在 RetrievalQA 链中有下面两大重要组成部分。


  • LLM 是大模型,负责回答问题。

  • retriever(vectorstore.as_retriever())负责根据用户的问题检索相关的信息。先是找最近似的“向量块”,再把”向量块“对应的“文档块”作为知识信息,和问题一起传递进入大模型。之所以要先检索,是因为从互联网信息训练而来的大模型不可能拥有一个私营企业的内部知识。

# 5. Retrieval 准备模型和Retrieval链import logging# MultiQueryRetriever工具from langchain.retrievers.multi_query import MultiQueryRetriever# RetrievalQA链from langchain.chains import RetrievalQA
# # 设置Logginglogging.basicConfig()logging.getLogger('langchain.retrievers.multi_query').setLevel(logging.INFO)
# # 实例化一个大模型工具from langchain_community.chat_models import ChatOllamallm = ChatOllama(model="qwen2:latest")
from langchain.prompts import PromptTemplatemy_template = PromptTemplate(    input_variables=["question"],    template="""You are an AI language model assistant. Your task is    to generate 3 different versions of the given user    question in Chinese to retrieve relevant documents from a vector  database.    By generating multiple perspectives on the user question,    your goal is to help the user overcome some of the limitations    of distance-based similarity search. Provide these alternative    questions separated by newlines. Original question: {question}""",)
# # 实例化一个MultiQueryRetrieverretriever_from_llm = MultiQueryRetriever.from_llm(retriever=docsearch.as_retriever(), llm=llm,prompt=my_template,include_original=True)
# # 实例化一个RetrievalQA链qa_chain = RetrievalQA.from_chain_type(llm,retriever=retriever_from_llm)


这里我们使用 ollama 在本地部署一个 qwen2 大模型,负责问题改写和生成答案。


启动 qwen2 大模型:ollama run qwen2



我们获取到用户问题后,先通过 MultiQueryRetriever 类调用大模型 qwen2 进行改写,生成 3 个同样语义的问题,然后再调用 easyearch 进行向量检索,搜索相关内容。


最后把所有相关内容,合并、去重后,与原始问题一起提交给大模型 qwen2,进行答案生成。


虽然这里使用的是向量检索,但实际上我们可以同时使用全文检索和向量检索。这也是使用 easysearch 作为检索库的优势之一。


前端展示


这一步我们创建一个 Flask 应用(需要安装 Flask 包)来接收用户的问题,并生成相应的答案,最后通过 index.html 对答案进行渲染和呈现。


在这个步骤中,我们使用了之前创建的 RetrievalQA 链来获取相关的文档和生成答案。然后,将这些信息返回给用户,显示在网页上。

# 6. Q&A系统的UI实现from flask import Flask, request, render_templateapp = Flask(__name__) # Flask APP
@app.route('/', methods=['GET', 'POST'])def home():    if request.method == 'POST':
       # 接收用户输入作为问题        question = request.form.get('question')
       # RetrievalQA链 - 读入问题,生成答案        result = qa_chain({"query": question})
       # 把大模型的回答结果返回网页进行渲染        return render_template('index.html', result=result)
   return render_template('index.html')
if __name__ == "__main__":    app.run(host='0.0.0.0',debug=True,port=5000)


效果演示


我们模仿用户进行提问。



Q&A 系统进行回答,回答速度取决于本地的计算资源。



内容校验,在原始文档内用 ctrl+F 搜索关键字 LOGGING_ES_ENDPOINT 得到如下内容。



嗯,回答的还不错,达到预期目的。如果还有其他要求,可修改 my_template 中的提示词或者替换成别的大模型也是可以的。


总结


通过这次示例,我们演示了如何基于 LangChain 和 easysearch 以及大模型,快速开发出一个内部知识问答系统。怎么样,是不是觉得整个流程特别简单易懂?


如有任何问题,请随时联系我,期待与您交流!




正文完





INFINI Labs 首期征文活动来袭!


无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。


点击 图片 查看活动详情!


嗨,互动起来吧!

喜欢这篇文章么?欢迎留下你的评论!

搜索客 公众号长期征稿,如果您有搜索领域技术相关文章,也欢迎投稿至本公众号,一起进步! 投稿请添加微信:searchkit-org


招聘信息

Job board






社区招聘栏目是为帮助社区的小伙伴找到心仪的职位,也帮助企业找到所需的人才,为伯乐和千里马牵线搭桥。有招聘需求的企业和正在求职的社区小伙伴,可以联系微信 searchkit-org 提交招聘需求和发布个人简历信息。

搜索客公众号 (SearchKit)

“搜索人自己的社区” ,为广大搜索领域从业者提供更为丰富便捷的学习和交流平台。


欢我们的内容就点“在看”分享给小伙伴哦

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询

扫码登录
登录即表示您同意《53AI网站服务协议》
服务协议

欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。

在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。

一、 定义

本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。

会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。

知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。

二、 账号注册与登录

登录方式:本网站支持以下登录方式,您可根据实际情况选择:

微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。

手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。

账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。

实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。

未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。

三、 服务内容与规范

知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。

服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。

禁止行为:您在使用服务时不得实施以下行为:

利用技术手段批量爬取、下载、转存知识库内容;

将知识库内容用于商业目的或未经授权地向第三方传播;

干扰本网站正常运行或侵犯其他用户合法权益;

发布违法违规信息或从事违反公序良俗的活动。

四、 知识产权声明

权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。

有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。

侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。

五、 个人信息保护

我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。

您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。

您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。

六、 免责声明

内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。

不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。

第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。

七、 违约责任

如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。

如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。

八、 法律适用与争议解决

本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。

因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。

九、 其他

本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。

本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。

我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。


已查阅