智能AI文档管理新方式,手把手教你打造自己的文档聊天机器人

一个快速指南,为您构建一个聊天机器人网站,可以接受外部文档作为上下文。

0eefe4ba9064354530cf3693d284e7c3.jpeg

随着每天涌现的信息和知识在我的屏幕上呈现,我们面临着人类阅读和记忆自然限制的挑战,这使得跟上信息更新变得越来越困难。现在,像ChatGPT和Llama这样的大型语言模型(LLMs)提供了一种存储和处理大量信息的潜在解决方案,只需要简单的提示就可以快速直接地获得响应。然而,LLMs的表现取决于它们所训练的数据质量,尽管它们的大部分数据集已经非常庞大,但这些数据仍然属于“昨天”的数据。

我经常感到很困扰,因为我很难阅读用户手册或药品说明书,里面包含了大量陌生的信息,也很难在技术论文或报告中查找特定数据,即使一本新书非常吸引我,我也会很不耐烦地阅读。目前,ChatGPT或Bard无法直接帮助我获取我需要的信息。

364c7fcfe4e09a0bcb3e65ff7417f3b4.jpeg

在创建了多个基于GPT APIs和其他库的聊天机器人,如私人聊天、语音聊天和图像聊天之后,现在我正在考虑构建一个基于文档的聊天机器人,它可以从各种数据资源中学习新知识,并在我查询时提供准确有用的响应,而且成本可接受。

e00ee39b1aa370e2369362b0e204e168.jpeg

为了实现这个目标,有许多方法可以利用,其中一种是上下文学习,另一种是微调。由于学习领域非常多样化,上下文学习技术是我最好的选择。经过一些研究,我决定使用LlamaIndex作为我的文档聊天机器人的基础,以进行上下文学习,并继续使用OpenAI的完成和嵌入功能进行演示。

在本文中,我将向您介绍开发过程,确保您理解并能够复制您自己的文档聊天机器人。

1、Block Diagram(系统框图)

在这个简单的聊天机器人中,我们使用llama-index作为基础,并开发Streamlit Web应用程序,提供用户输入和文档查询交互的显示。使用llamaIndex工具包,我们不必担心OpenAI中的API调用,因为其内部数据结构和LLM任务管理很容易消除嵌入使用的复杂性或提示大小限制的问题。

cafc1f35509626732ef9d16aac317b4a.jpeg

2、OpenAI API密钥

LlamaIndex被设计为与各种LLMs兼容,默认情况下,它使用OpenAI的text-davinci-003模型和text-embedding-ada-002-v2进行嵌入操作。因此,当我们决定基于OpenAI GPT模型实现文档聊天机器人时,我们应该向程序提供我们的OpenAI API密钥。插入我们的密钥所需做的唯一事情是通过环境变量提供它:

import os
os.environ["OPENAI_API_KEY"] = '{my-openai_key}'

3、LlamaIndex

LlamaIndex是一个Python库,提供了用户私有数据与大型语言模型之间的中心接口。它提供以下功能:

  • 数据连接器:LlamaIndex可以连接各种数据源,包括API、PDF、文档和SQL数据库。这使得您可以在不实现额外代码的情况下,将现有数据与LLMs一起使用。这实际上是我选择它作为应用程序的关键原因。

  • 提示限制:LlamaIndex可以处理提示限制,如Davinci的4096个标记限制。这确保了即使上下文很大,您的LLMs仍然可以生成准确的结果。这节省了开发人员管理令牌计算和分割的大量时间。

  • 索引:LlamaIndex在原始语言数据上创建索引,使LLMs更快、更容易地访问。

  • 提示插入:LlamaIndex提供了一种将提示插入到数据中的方式。这使您可以管理LLMs与您的数据的交互。

  • 文本分割:LlamaIndex可以将文本分割成较小的块,这可以提高LLMs的性能。

  • 查询:LlamaIndex提供了一个查询索引的接口。这允许您从LLMs获得增强知识的输出。

LlamaIndex提供了一套全面的工具集,用于处理LLMs。这包括数据连接器、索引、提示插入、提示限制、文本分割和查询。您可以在这里找到完整的文档。

使用方法

以下是使用LlamaIndex的一般步骤:

安装LlamaIndex包。

!pip install llama-index

A)如果您的应用程序只需要一次加载某些文档文件并查询其内容,则以下几行Python代码就足够了。

步骤1-加载文档文件。

from llama_index import SimpleDirectoryReader

SimpleDirectoryReader = download_loader("SimpleDirectoryReader")
loader = SimpleDirectoryReader('./data', recursive=True, exclude_hidden=True)
documents = loader.load_data()

SimpleDirectoryReader是LlamaIndex工具集中的文件加载器之一。它支持加载用户提供的文件夹下的多个文件,在本例中是子文件夹'./data/'。这个神奇的加载器函数可以支持解析各种文件类型,如.pdf、.jpg、.png、.docx等,因此您不必自己将文件转换为文本。

步骤2-构建索引。

from llama_index import LLMPredictor, GPTSimpleVectorIndex, PromptHelper, ServiceContext
from langchain import OpenAI

...

# define LLM
llm_predictor = LLMPredictor(llm=OpenAI(temperature=0, model_name="text-davinci-003"))

max_input_size = 4096
num_output = 256
max_chunk_overlap = 20
prompt_helper = PromptHelper(max_input_size, num_output, max_chunk_overlap)

service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor, prompt_helper=prompt_helper)

index = GPTSimpleVectorIndex.from_documents(
    documents, service_context=service_context
)

在调用这个方法时,LlamaIndex将与您定义的LLM交互以构建索引,在这个演示中,LlamaIndex通过OpenAI API调用嵌入方法。

步骤3-查询索引

有了索引,查询非常简单,直接输入没有上下文数据的查询即可。

response = index.query("How to use Keytruda in cervical cancer cases?")
print(response)

Step1.ex — 加载各种数据资源

除了SimpleDirectoryReader读取本地文档文件的方法外,还有许多在llamahub.ai上列出的开源阅读器可以通过download_loader函数加载。它们的使用非常简单。例如,如果我想从维基百科加载《三体》系列第二部《黑暗森林》的整个页面,代码将如下所示:

from llama_index import download_loader

WikipediaReader = download_loader("WikipediaReader")
loader = WikipediaReader()
documents = loader.load_data(pages=['The_Dark_Forest'])

在索引构建的过程中,由于需要使用 LLM 来处理大量数据,所以在索引建立后,应该将其存储在本地磁盘上,这样如果未来的查询仍然基于相同的文档,则从磁盘加载索引是最经济和时间最有效的做法。

Step2.ex —保存和加载生成的索引

在索引构建的过程中,由于需要使用 LLM 来处理大量数据,所以在索引建立后,应该将其存储在本地磁盘上,这样如果未来的查询仍然基于相同的文档,则从磁盘加载索引是最经济和时间最有效的做法。

# save to disk
index.save_to_disk('index.json')
# load from disk
index = GPTSimpleVectorIndex.load_from_disk('index.json')

Step3.ex — 设置响应模式

在调用index.query()方法时,可以使用有用的参数response_mode来指定响应样式以考虑提示成本。

  1. default(默认) — 适合详细的回答

  2. compact(紧凑型) — 适合成本敏感的情况

  3. tree-summarize(树状概述) — 适合汇总回答

response = index.query("...", response_mode="default")

4. Web 应用开发

作为我之前文章中的项目的延续,我们将继续使用方便的Streamlit库来构建文档聊天机器人应用程序。

df44324469807a84d137d8667241ca5c.jpeg

Streamlit是一个开源的Python库,使得创建交互式Web应用程序变得容易。它旨在供数据科学家和机器学习工程师使用,用于与其他人分享他们的工作。Streamlit应用程序可以仅用几行代码创建,并且可以使用单个命令部署到Web上。

它提供了多种小部件,可以用于创建交互式应用程序。这些小部件包括按钮、文本框、滑块和图表。你可以在其官方文档中找到所有小部件的用法:
https://docs.streamlit.io/library/api-reference

一个典型的用于Web应用程序的Streamlit代码可以非常简单,如下所示:

!pip install streamlit
import streamlit as st

st.write("""
# My First App
Hello *world!*
""")

然后只需输入以下命令,即可在线运行网站:

!python -m streamlit run demo.py

如果成功运行,会打印出用户可以访问的URL。

You can now view your Streamlit app in your browser.

  Network URL: http://xxx.xxx.xxx.xxx:8501
  External URL: http://xxx.xxx.xxx.xxx:8501

整个 Doc ChatBot 的实现包括以下功能:

  • 通过 Streamlit st.file_uploader() 方法创建文件上传小部件,以接受用户上传的文档文件。

  • 成功上传后,将文件保存在 ./data/ 文件夹中,并使用 LlamaIndex 生成文档对象,然后调用 st.sidebar() 方法在左侧区域打印转换后的内容,供用户参考。

  • 调用 llamaIndex 方法针对 ./data/ 文件夹中的文档文件生成索引对象,并将其存储在网站根目录 ./ 中。

  • 如果在 ./ 网站根目录中存在索引文件 (index.json),则一对 Streamlit 小部件 st.text_input() 和 st.button() 将被激活,允许用户对当前正在加载的文档进行查询。

  • 每次打开网站而没有上传新文档时,现有的索引文件将被加载,等待用户的查询。

以下是整个演示代码,供您参考:

import os
os.environ["OPENAI_API_KEY"] = '{my_api_key}'

import streamlit as st
from llama_index import download_loader
from llama_index.node_parser import SimpleNodeParser
from llama_index import GPTSimpleVectorIndex
from llama_index import LLMPredictor, GPTSimpleVectorIndex, PromptHelper, ServiceContext
from langchain import OpenAI

doc_path = './data/'
index_file = 'index.json'

if 'response' not in st.session_state:
    st.session_state.response = ''

def send_click():
    st.session_state.response  = index.query(st.session_state.prompt)

index = None
st.title("Yeyu's Doc Chatbot")

sidebar_placeholder = st.sidebar.container()
uploaded_file = st.file_uploader("Choose a file")

if uploaded_file is not None:

    doc_files = os.listdir(doc_path)
    for doc_file in doc_files:
        os.remove(doc_path + doc_file)

    bytes_data = uploaded_file.read()
    with open(f"{doc_path}{uploaded_file.name}", 'wb') as f: 
        f.write(bytes_data)

    SimpleDirectoryReader = download_loader("SimpleDirectoryReader")

    loader = SimpleDirectoryReader(doc_path, recursive=True, exclude_hidden=True)
    documents = loader.load_data()
    sidebar_placeholder.header('Current Processing Document:')
    sidebar_placeholder.subheader(uploaded_file.name)
    sidebar_placeholder.write(documents[0].get_text()[:10000]+'...')

    llm_predictor = LLMPredictor(llm=OpenAI(temperature=0, model_name="text-davinci-003"))

    max_input_size = 4096
    num_output = 256
    max_chunk_overlap = 20
    prompt_helper = PromptHelper(max_input_size, num_output, max_chunk_overlap)

    service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor, prompt_helper=prompt_helper)

    index = GPTSimpleVectorIndex.from_documents(
        documents, service_context=service_context
    )

    index.save_to_disk(index_file)

elif os.path.exists(index_file):
    index = GPTSimpleVectorIndex.load_from_disk(index_file)

    SimpleDirectoryReader = download_loader("SimpleDirectoryReader")
    loader = SimpleDirectoryReader(doc_path, recursive=True, exclude_hidden=True)
    documents = loader.load_data()
    doc_filename = os.listdir(doc_path)[0]
    sidebar_placeholder.header('Current Processing Document:')
    sidebar_placeholder.subheader(doc_filename)
    sidebar_placeholder.write(documents[0].get_text()[:10000]+'...')

if index != None:
    st.text_input("Ask something: ", key='prompt')
    st.button("Send", on_click=send_click)
    if st.session_state.response:
        st.subheader("Response: ")
        st.success(st.session_state.response, icon= "")

结束

在完成开发后,我进行了一些快速尝试。

我上传了《黑暗森林》这本书的维基百科页面,并问了一个问题,通常需要我读几遍才能回答,令我惊讶的是,这个聊天机器人通过组合几个情节完美地回答了我的问题。

ffeafd6c5d3ab52e0c371fd00bf359e3.jpeg

我随后让 ChatBot 读取了一份关于 Keytruda(一种治疗癌症的人源抗体药物)的医疗说明书,询问其在治疗某种癌症时的用法。回答看起来非常全面,涉及了不同方面的信息。在领域知识难以理解的情况下,这样的学习支持绝对可以节省大量时间并提供更准确的信息。

11b171fb3d2a4fcf704d0e61adb37b97.jpeg

希望本文对你有所帮助,感谢阅读!通过使用LlamaIndex和Streamlit,我们成功地创建了一个文档聊天机器人应用。它能够读取多种数据资源并生成索引,然后通过用户的查询提供有用的答案。这个应用程序不仅简单易用,而且能够极大地提高工作效率,成为我的个人助手。

在文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。

原文:
https://levelup.gitconnected.com/how-to-create-a-doc-chatbot-that-learns-everything-for-you-in-15-minutes-364fef481307

作者:Yeyu Huang

非直接翻译,有自行改编和添加部分,翻译水平有限,难免有疏漏,欢迎指正

猜你喜欢

转载自blog.csdn.net/Ed7zgeE9X/article/details/130376800
今日推荐