快速搭建自己的RAG应用(一)

906 阅读5分钟

github.com/hyy10086/zh…

如果你问我什么是明显的人工智能用例,可以提供价值的将是知识管理,不如你在哪里组织工作,每周都会有大量的文档留存或者是会议记录,这些文档不像图书馆的图书那样分类清晰,或者格式较为统一,任何人都可以阅读和消化这些信息,但是如果有强大的大预言模型,这个问题终于有了解决的办法,因为我们可以让语言模型来阅读各种不同的数据文档并为我们检索答案,这也就是一直以来有讨论为什么大ai即将颠覆搜索引擎,当你拥有一个强大的模型可以直接提供你答案,为什么还需要自己去检索并总结?

随着信息量的爆炸式增长,个人知识库的构建和管理变得愈发重要。除开开源的模型,还有像OpenAI,千问等产品提供的API,如同一座桥梁,降低了使用难度,连接了您的数据宝库与先进的自然语言处理能力。通过这些接口,您可以轻松实现文本的生成、理解、翻译和摘要,甚至是复杂问题的解答和智能对话的构建。

在本文的指导下。我们将一步步展示如何搭建一个基础的知识库系统,包括数据的收集、存储和检索,我们还将探讨如何优化您的知识库,使其更加智能准确。

初体验

智谱AI来说,开源了部分大模型,有条件的同学可以在自己的机器上部署,模型可以到魔搭社区自取,或者直接使用ollama即可在本地简单部署你想要的模型,又或者是使用官方的api接口,基于以上两者其一作为基石搭建自己文档助手。下面我就api接口的方式来做演示。

首先,我们先在智谱上注册,拿到开发api key,智谱也对新开发者赠送体验包100万tokens的体验礼包,这个肯定是够够的了。

    1. 参考开发者文档,我们可以接入接口看看效果。
#安装zhipu的sdk包
pip install --upgrade zhipuai
    1. 调用接口
from zhipuai import ZhipuAI

client = ZhipuAI(api_key="key--xx")  # 请填写您自己的APIKey
response = client.chat.completions.create(
    model="glm-4",  # 填写需要调用的模型名称
    messages=[
        {"role": "system", "content": "你是一个乐于解答各种问题的助手,你的任务是为用户提供专业、准确、有见地的建议。"},
        {"role": "user",
         "content": "马云生日是什么时候?"},
    ],
    stream=True,
)
for chunk in response:
    print(chunk.choices[0].delta.content,end='')

上下文理解

上面我们已经完成一次对话,询问了马云的生日,但是在现实场景中,对话一般都是连续的,假设接下来我再问gpt:他是哪里人?按照上面的代码,我们应该怎么改写呢?这里就带出一个名词:上下文。

"上下文"指的是模型在处理或生成文本时所依赖的先前信息。这些信息可以是之前的句子、段落,甚至是整个对话或文档。上下文对于理解语言的复杂性和细微差别至关重要,因为它帮助模型捕捉到语言中的连贯性、指代关系和语境含义。例如,在对话系统中,上下文可能包括对话的先前轮次,这样模型就能理解当前轮次中的代词(如“它”、“这个”)指的是什么,或者理解某个笑话或隐喻的背景。在文本生成任务中,上下文可能包括用户提供的提示或之前的文本,模型需要根据这些信息来生成连贯和相关的后续文本;

简单来说,就是每次的对话,都得先把之前所有的聊天记录重新喂给GPT,让GPT理解上下文,并针对新问题作出解答。

代入到上面的马云问题中,改写如下:

from zhipuai import ZhipuAI

client = ZhipuAI(api_key="key-xx")  # 请填写您自己的APIKey
response = client.chat.completions.create(
    model="glm-4",  # 填写需要调用的模型名称
    messages=[
        {"role": "system", "content": "你是一个乐于解答各种问题的助手,你的任务是为用户提供专业、准确、有见地的建议。"},
        {"role": "user","content": "马云生日是什么时候?"},
        {"role": "assistant", "content": "马云的生日是1964年9月10日。"},
        {"role": "user", "content": "他是哪里人?"},
    ],
    stream=True,
)
for chunk in response:
    print(chunk.choices[0].delta.content,end='')

这样,ai就能理解“他”指的马云了。这里面messages参数,从上到下表示和gpt的对话的过程内容,role参数用于标识每条消息的角色。它指示消息是由系统(AI助手)发送的还是由用户发送的

  1. "system":代表系统或AI助手发送的消息,通常包含系统提示、介绍或其他非用户生成的信息。
  2. "user":代表用户发送的消息,包含用户的查询或请求。
  3. "assistant":代表AI助手发送的消息,通常是对用户查询的响应或建议。

通过区分消息的角色,可以更好地理解对话的流程和每个参与者的作用。

我们希望对话之间是连续的,总不能每问一次,都得把gpt的回答记下来,在下次问的时候改代码带上吧,这时候我们可以使用集合记起来,

from typing import List

from zhipuai import ZhipuAI

from info import key

client = ZhipuAI(api_key=key)  # 请填写您自己的APIKey
# 用于保存聊天上下文
history: List = [
    {"role": "system", "content": "你是一个乐于解答各种问题的助手,你的任务是为用户提供专业、准确、有见地的建议。"}]

while True:
    user_input = input("请输入文字,按回车键确认:")
    # 检查用户是否想要退出
    if user_input.lower() == 'exit':
        print("程序退出。")
        break
    # 拼接问题
    history.append({"role": "user", "content": user_input})
    response = client.chat.completions.create(
        model="glm-4",
        messages=history,
        stream=True,
    )
    result = ""
    for chunk in response:
        word = chunk.choices[0].delta.content
        print(word, end='')
        result += word
    # 拼接回答
    history.append({"role": "assistant", "content": result}),
    print("")

好了,我们已经构建好了一个雏形,基于开放接口完成了一个基本的问答助手。问答助手现在都是基于互联网上的知识回答,下一章,我们将把个人知识库内容喂给他,让他可以根据知识库内容回答我们的问题。