首页 » 网站建设 » phpcatdoc技巧_构建一个运用 LlamaIndexQdrant 和 Render 进行进修的 Slack 机械人

phpcatdoc技巧_构建一个运用 LlamaIndexQdrant 和 Render 进行进修的 Slack 机械人

访客 2024-11-21 0

扫一扫用手机浏览

文章目录 [+]

在这篇文章中,我们将勾引您完成构建和支配一个 Slackbot 的过程,该 Slackbot 可以监听您的对话,从中学习,并利用这些知识回答有关 Slack 事情区正在进行的事情的问题。
我们还将在 Render 年夜将其支配莅临盆环境!

开始之前,您须要以下几样东西:对 LlamaIndex 的基本理解。
如果您还没有这个理解,我们文档中的入门教程将为您供应足够理解本教程所需的知识,而且只需几分钟。
对 Python 有一定的理解,并已安装 Python 3.11 或更高版本。
一个可以安装运用程序的 Slack 事情区(因此您须要是管理员)。
在本地机器上克隆我们 Slackbot 存储库的副本。
我们将在全体文章中引用该存储库中的文件。
步骤 1:创建一个 Slack 运用,并将其安装到您的事情区

这是最繁芜的一步,由于 Slack 对权限非常挑剔。

phpcatdoc技巧_构建一个运用 LlamaIndexQdrant 和 Render 进行进修的 Slack 机械人

您的 Slackbot 的第一个版本将只有大约 20 行代码。
它的全部功能是供应一个“challenge”端点,Slack 须要验证您的运用程序是否可用。
您可以在该存储库中的文件中查看此代码。
让我们一起来看一下 1_flask.py。

phpcatdoc技巧_构建一个运用 LlamaIndexQdrant 和 Render 进行进修的 Slack 机械人
(图片来自网络侵删)

首先,我们引入您的依赖项。
如果您尚未安装这些依赖项,您须要利用 pip 或 poetry 进行安装。

from flask import Flask, request, jsonify

现在,我们将创建您的 Flask 运用程序并设置它,以便它可以在开拓中运行。

flask_app = Flask(__name__)if __name__ == "__main__": flask_app.run(port=3000)

在这些行之间,我们将添加我们的基本路由:如果收到包含键的 JSON 工具的 POST 要求,我们将返回该键的值。
否则,我们将什么都不做。

@flask_app.route("/", methods=["POST"])def slack_challenge(): if request.json and "challenge" in request.json: print("Received challenge") return jsonify({"challenge": request.json["challenge"]}) else: print("Got unknown request incoming") print(request.json) return

这段代码的浸染是:如果收到包含 "challenge" 键的 JSON 工具的 POST 要求,它将返回该键的值。
否则,它将打印出未知要求的信息。

使您的运用对 Slack 可用

要配置 Slack 运用,它须要在 Slack 能够看到的地方运行。
让我们运行我们的 Slack 运用:

python 1_flask.py

然后,我们将设置它,以便全天下都能看到,利用 ngrok。
您须要下载并安装 ngrok 以完成此步骤。
安装完成后,运行以下命令,以便 ngrok 可以找到我们在端口 3000 上运行的运用程序:

ngrok http 3000

ngrok 将为您供应一个 HTTPS URL,例如 https://1bf6-64-38-189-168.ngrok-free.app。
记下它,由于我们须要将其供应给 Slack。
还请记住,如果您停滞 ngrok 并再次启动它,此 URL 将变动,您须要见告 Slack。
在开拓过程中,您只须要这个 URL。

在 Slack 中注册您的运用

转到 Slack API 网站,然后点击“创建新运用程序”。
您将看到一个类似于此的屏幕,您将选择“从头开始”:

选择一个友好的名称和要安装到的事情区。
您将看到类似于此的屏幕:

接下来,您将设置运用程序须要的权限。
点击右下角的“Permissions”链接:

这将带您进入“scopes”屏幕,在这里,您须要添加此图片中所见的所有范围,即:

channels:read — 许可您的运用查看可用的频道channels:join — 许可您的运用加入频道channels:history — 许可您的运用查看频道中的先前chat:write — 许可您的运用发送users:read — 许可您的运用查看用户的姓名

保存这些范围后,滚动到“Install to workspace”以安装您的运用程序。

现在,您须要见告Slack您的运用程序在哪里,以便可以从中吸收。
单击左侧导航中的“Event Subscriptions”链接,并填写它,使其看起来像这样,详细而言:

将要求URL设置为ngrok先前供应的URL订阅message.channels事宜

如果您的运用程序正在运行且ngrok精确进行隧道连接,则您的要求URL该当是“已验证”的。

呼!
那真是够多的了。
您的Slack运用程序现在已注册,Slack将向其发送。
但要获取这些,您必须见告它加入一个频道。

第2步:加入频道,并回答 为此,我们须要扩展我们的运用程序。
您可以在2_join_and_reply.py中看到此步骤的终极结果。
让我们逐步理解我们添加了什么:

import dotenv, osdotenv.load_dotenv()

我们须要一些环境变量,因此您须要添加这些行并安装python-dotenv。
您还须要在项目的根目录中创建一个名为.env的文件,个中包含三个值:

OPENAI_API_KEY:您的OpenAI API密钥。
您现在不须要它,但最好在这里获取它。
SLACK_BOT_TOKEN:您可以在Slack运用程序的“OAuth and Permissions”部分找到此令牌。
SLACK_SIGNING_SECRET:您可以在Slack运用程序的“Basic Information”部分找到此署名密钥。

我们将利用Slack方便的Python SDK来构建我们的运用程序,因此实行pip install slack-bolt,然后更新所有我们的导入:

from slack_bolt import Appfrom flask import Flask, request, jsonifyfrom slack_bolt.adapter.flask import SlackRequestHandler

现在利用刚刚设置的那些机密初始化Slack Bolt运用程序:

app = App( token=os.environ.get("SLACK_BOT_TOKEN"), signing_secret=os.environ.get("SLACK_SIGNING_SECRET"))handler = SlackRequestHandler(app)

要侦听,机器人必须在一个频道中。
您可以让它加入任何公共频道,但出于测试的目的,我创建了一个名为#bot-testing的频道,并且这便是它在这里加入的:

channel_list = app.client.conversations_list().datachannel = next((channel for channel in channel_list.get('channels') if channel.get("name") == "bot-testing"), None)channel_id = channel.get('id')app.client.conversations_join(channel=channel_id)

app.client是Bolt框架的Slack WebClient,因此您可以直接从框架中实行WebClient可以实行的任何操作。
这里的末了一次添加是一个非常大略的监听器:

@app.message()def reply(message, say): print(message) say("Yes?")

在Bolt框架中,@app.message装饰器见告框架在收到事宜时触发此方法。
say参数是一个函数,将向发送的频道发送一条。
因此,每次吸收到时,此代码将向频道发送一条,内容为“Yes?”。

让我们试试吧!
停滞运行1_flask.py,然后运行python 2_join_and_reply.py。
您不须要重新启动ngrok,它将连续像以前一样将发送到端口3000。
以下是我考试测验的截图:

成功了!
我们有一个非常讨厌的机器人,会回答任何人说的每一句话。
我们可以做得更好!

第3步:只回答提到机器人的

表面上这是一个相称大略的变动,但Slack的传入格式有点繁芜,因此我们必须添加相称多的代码。
您可以在3_reply_to_mentions.py中看到终极的结果。

首先,为了知道我们的机器人被提及了,我们须要知道机器人的用户ID。
在幕后,Slack不该用用户名乃至不是@-handles,而是在所有Slack安装中都是全局唯一的ID。
我们必须获取它:

auth_response = app.client.auth_test()bot_user_id = auth_response["user_id"]

现在我们添加了一个非常繁芜的代码块,通过Slack的工具来查看哪个用户在传入中被提及。
如果是机器人,机器人会回答,否则它只是忽略。
随着我们的深入,我们将把发给机器人的视为“查询”,将任何其他视为它要存储的“事实”,但现在我们还不会存储。

@app.message()def reply(message, say): if message.get('blocks'): for block in message.get('blocks'): if block.get('type') == 'rich_text': for rich_text_section in block.get('elements'): for element in rich_text_section.get('elements'): if element.get('type') == 'user' and element.get('user_id') == bot_user_id: for element in rich_text_section.get('elements'): if element.get('type') == 'text': query = element.get('text') print(f"Somebody asked the bot: {query}") say("Yes?") return # otherwise do something else with it print("Saw a fact: ", message.get('text'))

哎呀。
这花了一些韶光才搞清楚!
但现在我们的机器人只在被提及时回答:

第4步:利用LlamaIndex存储事实和回答问题

我们一贯到第4步,我们还没有利用LlamaIndex做任何事情!
但现在是时候了。
在4_incremental_rag.py中,您将看到一个演示大略命令行Python脚本的地方,该脚本利用LlamaIndex存储事实并回答问题。
我不会逐行为您讲解(脚本中有有用的注释),但让我们重视视要的部分。
记得要安装llama-index!

首先,我们创建一个新的VectorStoreIndex,这是一个内存中的向量存储,我们将在个中存储我们的事实。
一开始它是空的。

index = VectorStoreIndex([])

接下来,我们创建3个Document工具,并将它们插入我们的索引。
真实的文档可以是弘大的文本块,全体PDF,乃至是图像,但这些只是一些大略的、适宜Slack大小的事实。

doc1 = Document(text="Molly is a cat")doc2 = Document(text="Doug is a dog")doc3 = Document(text="Carl is a rat")index.insert(doc1)index.insert(doc2)index.insert(doc3)

末了,我们从我们的索引中创建一个查询引擎并讯问它一个问题:

# 运行一个查询query_engine = index.as_query_engine()response = query_engine.query("Who is Molly?")print(response)

结果是“Molly是一只猫”,还有很多喧华的调试信息,由于我们在4_incremental_rag.py中打开了喧华的调试。
您可以看到我们发送给LLM的提示,它从索引中检索到的高下文,以及它天生并发送回给我们的相应。

第5步:在Slack中利用LlamaIndex存储事实和回答问题

在5_rag_in_slack.py中,我们将之前的两个东西结合在一起:脚本3,我们回答查询的地方,以及脚本4,我们存储事实并回答问题的地方。
再次,我们不会逐行讲解,但以下是主要的变动:

首先,如果您还没有安装llama-index,请利用pip install llama-index,并在进行初始化时引入您的依赖项:

from llama_index import VectorStoreIndex, Documentindex = VectorStoreIndex([])

在以前我们只是回答“是的?”(第73行),现在让我们向查询引擎发送一个查询并用相应回答:

query = element.get('text')query_engine = index.as_query_engine()response = query_engine.query(query)say(str(response))

以前我们只是把稳到我们看到了一个事实(第82行),现在让我们将其存储在索引中:

index.insert(Document(text=message.get('text')))

结果是一个能够回答关于它所听到的事情的问题的Slackbot:

了不起!
您可以轻松想象一个机器人,它听取所有人的对话,并能够回答关于人们几周或几个月前说过的事情的问题,为所有人节省韶光和精力,而不必搜索旧。

第6步:持久化我们的影象

然而,我们的机器人有一个关键的毛病:索引仅存储在内存中。
如果我们重新启动机器人,它会忘却所有内容:

在6_qdrant.py中,我们引入了Qdrant,一个开源确当地向量数据库,它将这些事实存储在磁盘上。
这样,如果我们重新启动机器人,它就记得以前说过的话。
利用pip install qdrant-client并引入一些新的依赖项:

import qdrant_clientfrom llama_index.vector_stores.qdrant import QdrantVectorStore

现在我们将初始化Qdrant客户端,将其附加到存储高下文,并在初始化索引时将该存储高下文供应给我们的索引:

client = qdrant_client.QdrantClient( path="./qdrant_data")vector_store = QdrantVectorStore(client=client, collection_name="slack_messages")storage_context = StorageContext.from_defaults(vector_store=vector_store)index = VectorStoreIndex([],storage_context=storage_context)

这便是这一步!
您的机器人现在可以在重新启动时存活,并记得我在截图中拼错了“Doug”为“Dough”,而我

第7步:使最近的更主要

我们现在有一个相称强大的机器人!
但它有一个奇妙的问题:人们可能会说出相互抵牾的事情,而它没有办法决定谁是“精确的”,比如当我改变对狗名字的意见时:

在真实的Slack对话中,随着情形的发展,人们可能会从说项目“正在方案”到“进行中”再到“已启动”。
因此,我们须要一种方法见告机器人,最近的比旧的更主要。

为了实现这一点,我们必须进行相称多的重构,终极结果可以在7_recency.py中看到。
首先,我们须要一堆新的依赖项:

import datetime, uuidfrom llama_index.schema import TextNodefrom llama_index.prompts import PromptTemplatefrom llama_index.postprocessor import FixedRecencyPostprocessorfrom llama_index import set_global_handler

为了使最近的更主要,我们必须知道何时发送。
为此,我们将停滞将文档插入索引,而是插入节点,我们将在个中附加韶光戳作为元数据(在幕后,我们的文档始终被转换为节点,因此这并没有太多改变):

dt_object = datetime.datetime.fromtimestamp(float(message.get('ts')))formatted_time = dt_object.strftime('%Y-%m-%d %H:%M:%S')# 获取消息文本text = message.get('text')# 创建一个带有元数据的节点node = TextNode( text=text, id_=str(uuid.uuid4()), metadata={ "when": formatted_time })index.insert_nodes([node])

我还将回答逻辑从处理等分离出来到它自己的函数,answer_question,只是为了使事情看起来更随意马虎阅读一些。
我们要变动的第一件事是我们给LLM的提示:我们必须见告它最近的很主要。
为此,我们创建了一个提示模板:

template = ( "Your context is a series of chat messages. Each one is tagged with 'who:' \\\\n" "indicating who was speaking and 'when:' indicating when they said it, \\\\n" "followed by a line break and then what they said. There can be up to 20 chat messages.\\\\n" "The messages are sorted by recency, so the most recent one is first in the list.\\\\n" "The most recent messages should take precedence over older ones.\\\\n" "---------------------\\\\n" "{context_str}" "\\\\n---------------------\\\\n" "You are a helpful AI assistant who has been listening to everything everyone has been saying. \\\\n" "Given the most relevant chat messages above, please answer this question: {query_str}\\\\n")qa_template = PromptTemplate(template)

与LLM一起事情的有趣之处在于,您常常会用英语描述您正在做的事情,然后将其发送给LLM。
提示模板将自动从查询引擎获取context_str和query_str。
但我们必须将此模板设置在我们的查询引擎上,像这样:

query_engine.update_prompts( {"response_synthesizer:text_qa_template": qa_template})

现在有两件事情要变动。
我们将得到从向量存储获取的结果,并按最近的韶光对它们进行排序,LlamaIndex有一个内置的类叫做FixedRecencyPostprocessor。
我们见告它保存韶光戳的键(我们在上面的节点中定义的)以及它该当返回多少结果:

postprocessor = FixedRecencyPostprocessor( top_k=20, date_key="when", # the key in the metadata to find the date service_context=ServiceContext.from_defaults())

然后我们须要利用附加的后处理器创建我们的查询引擎:

query_engine = index.as_query_engine(similarity_top_k=20, node_postprocessors=[postprocessor])

在这个过程中,我们还做了末了一件事,即通报similarity_top_k=20,这意味着向量存储将为我们供应20条Slack作为高下文(默认值仅为2,由于常日节点中的文本块要大得多)。

大功告成!
现在机器人知道将更近的声明视为事实。

第8步:画出猫头鹰的别的部分 这个机器人现在运作得相称不错,但我在构建它时玩得太愉快了,我加了两个更多的功能:

我附加了关于说话者是谁的元数据,这样机器人就可以回答问题,比如“Logan对项目说了什么?”与机器人互动的同事考试测验在线程中提出后续问题,就像我们彼此一样。
因此,我添加了一种让机器人理解它在一个线程中的方法,并将在线程中的回答视为后续问题,即利用户没有直接提到机器人:

使这两者发生的代码在8_rest_of_the_owl.py中,但我不会逐行讲解它。
我们必须将这个东西支配!

第9步:支配到Render

到目前为止,我们一贯在利用通过ngrok隧道运行确当地脚本,但纵然最专注的程序员有时也会关闭他们的条记本电脑。
让我们将这个东西放到一个真正的做事器上。

登录到Render

我们将支配到Render,这是一个对小型项目免费的Python友好的托管做事。
注册一个帐户(我建议利用GitHub登录)。

创建一个新的GitHub存储库

Render从GitHub存储库支配东西,因此您须要创建一个新的存储库,并将我们现有存储库中的2个文件复制到个中:

pyproject.toml8_rest_of_the_owl.py,我们将其大略地重命名为“app.py”。
提交这些文件并将它们推送到GitHub。
创建一个新的Render Web做事

在Render中,创建一个新的Web做事。
将其连接到您刚刚创建的GitHub存储库:

Render可能会自动检测到这是一个Python运用程序,但您该当确保以下设置是精确的:

名称:您选择的任何名称区域:任何区域都可以分支:main根目录:(空缺,表示根目录)运行时:Python 3构建命令:poetry install启动命令:gunicorn app:flask_app(这肯定须要设置)

您还须要向下滚动并设置一些环境变量:

PYTHON_VERSION:3.11.6(或您利用的任何版本)OPENAI_API_KEY:您的OpenAI API密钥SLACK_BOT_TOKEN:您的Slack机器人令牌SLACK_SIGNING_SECRET:之前从Slack获取的署名密钥

然后点击支配,就可以了!

您现在拥有一个生产中的Slack机器人,监听,记住,学习和回答。
恭喜!

下一步做什么呢?

有许多功能可以添加到这个机器人中,大致按难度递增的顺序:

加入每个频道,而不仅仅是一个频道,显然!
添加一种见告机器人忘却事物(删除节点)的方法给机器人添加利用多个索引的能力,比如文档索引,或连接到您的电子邮件,或您的日历为机器人添加“标签”,以便它可以将元数据附加到节点,并仅利用(或忽略)以某种办法标记的内容来回答问题添加多模式功能,使机器人能够阅读图像,乃至用天生的图像回答还有很多!

这个机器人非常有趣,玩起来也很有趣。
希望您享受学习有关Slack机器人和LlamaIndex的知识,就像我写这篇教程一样有趣!

点赞关注 二师兄 talk 获取更多资讯,并在 头条 上阅读我的短篇技能文章

标签:

相关文章

介绍皮肤设置,如何打造理想肌肤状态

随着科技的发展和人们对美的追求,皮肤设置已成为美容护肤的重要一环。如何根据皮肤类型、肤质、年龄等因素进行合理设置,已成为众多爱美人...

网站建设 2025-01-03 阅读0 评论0

介绍盖章制作,传承文化,彰显权威

自古以来,盖章在我国文化中具有重要的地位。从古代的官印、私印到现代的公章、合同章,盖章已成为一种独特的文化符号,承载着丰富的历史内...

网站建设 2025-01-03 阅读0 评论0

介绍监控破坏,技术手段与法律风险并存

随着科技的飞速发展,监控设备已遍布大街小巷,成为维护社会治安的重要手段。一些不法分子为了逃避法律制裁,开始研究如何破坏监控设备。本...

网站建设 2025-01-03 阅读0 评论0

介绍登录不上之谜,技术故障还是人为疏忽

随着互联网的普及,登录已成为人们日常生活中不可或缺的一部分。在享受便捷的登录不上这一问题也困扰着许多用户。本文将深入剖析登录不上之...

网站建设 2025-01-03 阅读0 评论0

介绍电脑键盘调出方法,让操作更高效

随着科技的发展,电脑已经成为了我们日常生活中不可或缺的工具。而电脑键盘,作为电脑输入设备,更是我们与电脑进行交流的桥梁。你是否知道...

网站建设 2025-01-03 阅读0 评论0

介绍磁力链,高效便捷的文件下载利器

在互联网高速发展的今天,文件下载已成为日常生活中不可或缺的一部分。而磁力链作为一种新型的文件下载方式,凭借其高效、便捷的特点,受到...

网站建设 2025-01-03 阅读0 评论0