0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何用个人数据知识库构建RAG聊天机器人?

冬至子 来源:思否AI 作者:思否AI 2023-10-26 15:43 次阅读

01.使用 BeautifulSoup4 抓取网页数据

所有机器学习(ML)项目的第一步都是收集所需的数据。本项目中,我们使用网页抓取技术来收集知识库数据。用 requests 库获取网页并使用 BeautifulSoup4.从网页中提取信息、解析 HTML 信息并提取段落。

导入 BeautifulSoup4 和 Requests 库进行网页抓取

运行 pip install beautifulsoup4 sentence-transformers安装 BeautifulSoup 和 Sentence Transformers。在数据抓取部分只需要导入requests和 BeautifulSoup。接下来,创建一个 dictionary,其中包含我们要抓取的 URL 格式。在本示例中,我们只从 Towards Data Science 抓取内容,同理也可以从其他网站抓取。

现在,用以下代码所示的格式从每个存档页面获取数据:

import requests
from bs4 import BeautifulSoup
urls = {
    'Towards Data Science': '< https://towardsdatascience.com/archive/{0}/{1:02d}/{2:02d} >'
    }

此外,我们还需要两个辅助函数来进行网页抓取。第一个函数将一年中的天数转换为月份和日期格式。第二个函数从一篇文章中获取点赞数。

天数转换函数相对简单。写死每个月的天数,并使用该列表进行转换。由于本项目仅抓取 2023 年数据,因此我们不需要考虑闰年。如果您愿意,可以根据不同的年份进行修改每个月天数。

点赞计数函数统计 Medium 上文章的点赞数,单位为 “K” (1K=1000)。因此,在函数中需要考虑点赞数中的单位“K”。

def convert_day(day):
    month_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    m = 0
    d = 0
    while day > 0:
        m += 1
        d = day
        day -= month_list[m-1]
    return (m, d)

def get_claps(claps_str):
    if (claps_str is None) or (claps_str == '') or (claps_str.split is None):
        return 0
    split = claps_str.split('K')
    claps = float(split[0])
    return int(claps*1000) if len(split) == 2 else int(claps)

解析 BeautifulSoup4 的网页抓取响应

现在已经设置好必要的组件,可以进行网页抓取。为了避免在过程中遇到 429 错误(请求过多),我们使用 time 库,在发送请求之间引入延迟。此外,用 sentence transformers 库从 Hugging Face 获取 embedding 模型—— MiniLM 模型。

如前所述,我们只抓取了 2023 年的数据,所以将年份设置为 2023。此外,只需要从第 1 天(1 月 1 日)到第 244 天(8 月 31 日)的数据。根据设定的天数进行循环,每个循环在第一次调用time.sleep()之前会首先设置必要的组件。我们会把天数转换成月份和日期,并转成字符串,然后根据 urls 字典组成完整的 URL,最后发送请求获取 HTML 响应。

获取 HTML 响应之后,使用 BeautifulSoup 进行解析,并搜索具有特定类名(在代码中指示)的div元素,该类名表示它是一篇文章。我们从中解析标题、副标题、文章 URL、点赞数、阅读时长和回应数。随后,再次使用requests来获取文章的内容。每次通过请求获取文章内容后,都会再次调用time.sleep()。此时,我们已经获取了大部分所需的文章元数据。提取文章的每个段落,并使用我们的 HuggingFace 模型获得对应的向量。接着,创建一个字典包含该文章段落的所有元信息。

import time
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("sentence-transformers/all-MiniLM-L12-v2")
data_batch = []
year = 2023
for i in range(1, 243):
    month, day = convert_day(i)
    date = '{0}-{1:02d}-{2:02d}'.format(year, month, day)
    for publication, url in urls.items():
        response = requests.get(url.format(year, month, day), allow_redirects=True)
        if not response.url.startswith(url.format(year, month, day)):
            continue
        time.sleep(8)
        soup = BeautifulSoup(response.content, 'html.parser')
        articles = soup.find_all("div","postArticle postArticle--short js-postArticle js-trackPostPresentation js-trackPostScrolls")
        for article in articles:
            title = article.find("h3", class_="graf--title")
            if title is None:
                continue
            title = str(title.contents[0]).replace(u'\xA0', u' ').replace(u'\u200a', u' ')
            subtitle = article.find("h4", class_="graf--subtitle")
            subtitle = str(subtitle.contents[0]).replace(u'\xA0', u' ').replace(u'\u200a', u' ') if subtitle is not None else ''
            article_url = article.find_all("a")[3]['href'].split('?')[0]
            claps = get_claps(article.find_all("button")[1].contents[0])
            reading_time = article.find("span", class_="readingTime")
            reading_time = int(reading_time['title'].split(' ')[0]) if reading_time is not None else 0
            responses = article.find_all("a", class_="button")
            responses = int(responses[6].contents[0].split(' ')[0]) if len(responses) == 7 else (0 if len(responses) == 0 else int(responses[0].contents[0].split(' ')[0]))
            article_res = requests.get(article_url)
            time.sleep(8)
            paragraphs = BeautifulSoup(article_res.content, 'html.parser').find_all("[class*="pw-post-body-paragraph"]")
            for i, paragraph in enumerate(paragraphs):
                embedding = model.encode([paragraph.text])[0].tolist()
                data_batch.append({
                    "_id": f"{article_url}+{i}",
                    "article_url": article_url,
                    "title": title,
                    "subtitle": subtitle,
                    "claps": claps,
                    "responses": responses,
                    "reading_time": reading_time,
                    "publication": publication,
                    "date": date,
                    "paragraph": paragraph.text,
                    "embedding": embedding
                })

最后一步是使用 pickle 处理文件。

filename = "TDS_8_30_2023"
with open(f'{filename}.pkl', 'wb') as f:
    pickle.dump(data_batch, f)

数据呈现

数据可视化十分有用。下面是在 Zilliz Cloud 中数据的样子。请注意其中的 embedding,这些数据表示了文档向量,也就是我们根据文章段落生成的向量。

02.将 TDS 数据导入到向量数据库中

获取数据后,下一步是将其导入到向量数据库中。在本项目中,我们使用了一个单独的 notebook 将数据导入到 Zilliz Cloud,而不是从 Towards Data Science 进行网页抓取。

要将数据插入 Zilliz Cloud,需按照以下步骤进行操作:

  • 连接到 Zilliz Cloud
  • 定义 Collection 的参数
  • 将数据插入 Zilliz Cloud

设置 Jupyter Notebook

运行 pip install pymilvus python-dotenv 来设置 Jupyter Notebook 并启动数据导入过程。用 dotenv 库来管理环境变量。对于pymilvus包,需要导入以下模块:

  • utility 用于检查集合的状态
  • connections 用于连接到 Milvus 实例
  • FieldSchema 用于定义字段的 schema
  • CollectionSchema 用于定义 collection schema
  • DataType 字段中存储的数据类型
  • Collection 我们访问 collection 的方式

然后,打开之前 pickle 的数据,获取环境变量,并连接到 Zilliz Cloud。

import pickle
import os
from dotenv import load_dotenv
from pymilvus import utility, connections, FieldSchema, CollectionSchema, DataType, Collection


filename="TDS_8_30_2023"
with open(f'{filename}.pkl', 'rb') as f:
    data_batch = pickle.load(f)

zilliz_uri = "your_zilliz_uri"
zilliz_token = "your_zilliz_token"
connections.connect(
    uri= zilliz_uri,
    token= zilliz_token
)

设置 Zilliz Cloud 向量数据库并导入数据

接下来,需要设置 Zilliz Cloud。我们必须创建一个 Collection 来存储和组织从 TDS 网站抓取的数据。需要两个常量:dimension(维度)和 collection name(集合名称),dimension 是指我们的向量具有的维度数。在本项目中,我们使用 384 维的 MiniLM 模型。

Milvus 的全新 Dynamic schema 功能允许我们仅为 Collection 设置 ID 和向量字段,无需考虑其他字段数量和数据类型。注意,需要记住保存的特定字段名称,因为这对于正确检索字段至关重要。

DIMENSION=384
COLLECTION_NAME="tds_articles"
fields = [
    FieldSchema(name='id', dtype=DataType.VARCHAR, max_length=200, is_primary=True),
    FieldSchema(name='embedding', dtype=DataType.FLOAT_VECTOR, dim=DIMENSION)
]
schema = CollectionSchema(fields=fields, enable_dynamic_field=True)
collection = Collection(name=COLLECTION_NAME, schema=schema)
index_params = {
    "index_type": "AUTO_INDEX",
    "metric_type": "L2",
    "params": {"nlist": 128},
}
collection.create_index(field_name="embedding", index_params=index_params)

Collection 有两种插入数据的选项:

  • 遍历数据并逐个插入每个数据
  • 批量插入数据

在插入所有数据之后,重要的是刷新集合以进行索引并确保一致性,导入大量数据可能需要一些时间。

for data in data_batch:
    collection.insert([data])
collection.flush()

03.查询 TDS 文章片段

一切准备就绪后,就可以进行查询了。

获取 HuggingFace 模型并设置 Zilliz Cloud 查询

注意,必须获取 embedding 模型并设置向量数据库以查询 Towards Data Science 知识库。这一步使用了一个单独的笔记本。我们将使用dotenv库来管理环境变量。此外,还需要使用 Sentence Transformers 中的 MiniLM 模型。这一步中,可以重用 Web Scraping 部分提供的代码。

import os
from dotenv import load_dotenv
from pymilvus import connections, Collection


zilliz_uri = "your_zilliz_uri"
zilliz_token = "your_zilliz_token"


from sentence_transformers import SentenceTransformer


model = SentenceTransformer("sentence-transformers/all-MiniLM-L12-v2")

执行向量搜索查询

连接到向量数据库并执行搜索。在本项目中,我们将连接到一个 Zilliz Cloud 实例,并检索之前创建的集合 tds_articles,用户要先输入他们的查询问题。

接下来,使用 Hugging Face 的 embedding 模型对查询进行编码。这个过程将用户的问题转换为一个 384 维的向量。然后,使用这个编码后的查询向量来搜索向量数据库。在搜索过程中,需要指定进行 ANN 查询字段(anns_field)、索引参数、期望的搜索结果数量限制以及我们想要的输出字段(output fields)。

之前,我们用了 Milvus 的 Dynamic Schema 特性来简化字段 Schema 定义流程。搜索向量数据库时,包括所需的动态字段在搜索结果中是必要的。这个特定的场景涉及请求paragraph字段,其中包含文章中每个段落的文本。

connections.connect(uri=zilliz_uri, token=zilliz_token)
collection = Collection(name="tds_articles")
query = input("What would you like to ask Towards Data Science's 2023 publications up to September? ")
embedding = model.encode(query)
closest = collection.search([embedding],
    anns_field='embedding',
    param={"metric_type": "L2",
        "params": {"nprobe": 16}},
    limit=2,
    output_fields=["paragraph"])
print(closest[0][0])
print(closest[0][1])

比如,我在应用中查询大语言模型相关的信息,返回了以下两个回答。尽管这些回答提到了“语言模型”并包含一些相关信息,但它们没有提供关于大型语言模型的详细解释。第二个回答在语义上相似,但是不足够接近我们想要的内容。

04.给向量数据库知识库添加内容

到目前为止,我们使用 Zilliz Cloud 作为向量数据库在 TDS 文章上创建了一个知识库。虽然能够轻松地检索语义上相似的搜索结果,但还没有达到我们的期望。下一步是通过加入新的框架和技术来增强我们的结果。

05.总结

教程介绍了如何基于 Towards Data Science 文章构建聊天机器人。我们演示了网页爬取的过程,创建了知识库,包括将文本转换成向量存储在 Zilliz Cloud 中。然后,我们演示了如何提示用户进行查询,将查询转化为向量,并查询向量数据库。

不过,虽然结果在语义上相似,但并不完全符合我们的期望。在本系列的下一篇中,我们将探讨使用 LlamaIndex 来优化查询。除了这里讨论的步骤之外,大家也可以结合 Zilliz Cloud 尝试替换模型、合并文本或使用其他数据集。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编码器
    +关注

    关注

    45

    文章

    3576

    浏览量

    134027
  • URL
    URL
    +关注

    关注

    0

    文章

    139

    浏览量

    15299
  • 机器学习
    +关注

    关注

    66

    文章

    8357

    浏览量

    132336
  • TDS
    TDS
    +关注

    关注

    0

    文章

    14

    浏览量

    14367
  • 聊天机器人
    +关注

    关注

    0

    文章

    331

    浏览量

    12283
收藏 人收藏

    评论

    相关推荐

    聊天机器人+微信平台检测环境,方案分享啦

    聊天机器人+微信平台检测环境,方案分享回馈论坛的帮助,也顺便给自己拉拉票,第一季创客作品征集大赛,求点赞!!这是链接,有项目介绍:https://www.elecfans.com/project
    发表于 02-22 19:46

    聊天机器人在国内为什么只能做客服?

    还不是那么智能的聊天机器人们找到一个发挥所长的新工作,那就是客服。细数一下,这一年来空降而来的机器人客服真是络绎不绝。 百度推出的虚拟个人助理“度秘”,通过人机互动完成搜索、买票、订餐票等服务。 淘宝
    发表于 06-20 16:50

    聊天机器人的自动问答技术实现

    【原创】聊天机器人与自动问答技术
    发表于 06-03 08:47

    如何利用Python+ESP8266 DIY 一个智能聊天机器人

    如何利用Python+ESP8266 DIY 一个智能聊天机器人
    发表于 02-14 06:16

    五步诠释聊天机器人

    。从某种意义上来说,正是语音控制的聊天机器人促成了个人助手如Siri出现在我们手机上,促成了亚马逊Echo智能音箱出现在我们的客厅里。这一切足以让你相信聊天机器人已开始渗透到了我们的日常生活中。 只不过,它们还没有变成主流。推动
    发表于 09-20 08:32 10次下载

    聊天机器人的作用分析

    著名的网络媒体BackChanel日前撰文称,聊天机器人作为一项热门的技术,将会颠覆手机应用(APP),在个人生活、公司客服、政府服务方面都有很好的应用。 文章将此称为即将到来的真正革命。未来,聊天机器人
    发表于 09-20 10:21 2次下载

    如何避免聊天机器人的5个错误策略

    聊天机器人正迅速成为客户和最终用户沟通的通用解决方案。但许多聊天机器人策略都没有达到其目的。
    的头像 发表于 12-06 16:24 3723次阅读

    一个基于Microsoft聊天机器人Tay的示例

    当意料之外的事情浮出水面时,我们可以期望的最好的办法就是减少有效应对负担的基础设施。让我们谈谈为AI构建该基础架构。互联网喜欢聊天机器人无处不在,所以让我们看一个基于Microsoft聊天机器人Tay的示例。
    的头像 发表于 04-09 14:18 2919次阅读

    智能聊天机器人的会话式应用平台日趋成熟化

    聊天机器人正在变得越来越好,更重要的是,非开发人员更容易使用构建聊天机器人和会话代理所需的工具。
    发表于 04-29 17:19 932次阅读

    构建聊天机器人需要哪些资源?

    我问新客户的第一个问题是:“为什么需要聊天机器人,并且该聊天机器人如何解决您的问题或为您的组织带来价值?”,“您的客户正在寻找什么答案?”,“您的客户服务是否经常收到重复的问题?”
    的头像 发表于 10-27 14:59 2404次阅读

    GoGlobal 推出全新 AI 聊天机器人 – ChatGoGlobal

        立即提问,即时回应 全球领先的国际人力资源和名义雇主(EOR)服务提供商 GoGlobal,近日宣布推出其全新的 AI 聊天机器人ChatGoGlobal。 这款生成式 AI 聊天机器人旨在
    的头像 发表于 04-20 14:56 1133次阅读
    GoGlobal 推出全新 AI <b class='flag-5'>聊天机器人</b> – ChatGoGlobal

    聊天机器人开源分享

    电子发烧友网站提供《聊天机器人开源分享.zip》资料免费下载
    发表于 06-20 15:07 1次下载
    <b class='flag-5'>聊天机器人</b>开源分享

    何用AI聊天机器人写出万字长文

    何用AI聊天机器人写出万字长文
    的头像 发表于 12-26 16:25 1020次阅读

    英伟达推出全新AI聊天机器人

    近日,英伟达(Nvidia)宣布推出其全新的AI聊天机器人——“Chat With RTX”。这款聊天机器人被视为英伟达版的ChatGPT,为用户提供了一个全新的、本地化的AI交互体验。
    的头像 发表于 02-19 11:09 847次阅读

    ChatGPT 与传统聊天机器人的比较

    随着人工智能技术的飞速发展,聊天机器人已经成为我们日常生活中不可或缺的一部分。从简单的客服助手到复杂的个人助理,这些虚拟助手正在逐渐改变我们与技术的互动方式。在众多聊天机器人中,ChatGPT无疑是
    的头像 发表于 10-25 16:16 382次阅读