Ragish - RAG的轻量级替代品

B站影视 2024-12-02 12:22 2

摘要:我甚至不知道 RAG 是什么,直到我构建了整个东西后才知道它是什么!我在一家早期的 AI 初创公司(即 2024 年的每一家初创公司)实习,并被交给了安然电子邮件数据集,这只是一个有趣的 1.5 GB 的电子邮件,用于创建一些使处理电子邮件更容易的东西。对于第

Ragish 是 RAG 的轻量级替代品,表现超出预期!

RAG(检索增强生成)工具基本上允许将大量非结构化数据转换为可查询的内容,并通过自然语言从中检索信息。

我甚至不知道 RAG 是什么,直到我构建了整个东西后才知道它是什么!我在一家早期的 AI 初创公司(即 2024 年的每一家初创公司)实习,并被交给了安然电子邮件数据集,这只是一个有趣的 1.5 GB 的电子邮件,用于创建一些使处理电子邮件更容易的东西。对于第一个原型,我们决定制作一个界面来“与你的电子邮件对话”。

最简单的解决方案往往是最好的。——奥卡姆剃刀

这是一个罕见的轶事,我没有过多考虑技术复杂性,只是专注于解决问题。事实上,如果我知道 RAG 是什么,我甚至不会发现这种方法,并且会像往常一样立即跳上 AI 列车。

问题是我所知道的只是 SQL、一点 AI/ML 和大量的 Python,令人惊讶的是,这就是我制作 ragish 所需要的全部!

RAG 典型流程:

检索相关文档使用检索到的上下文增强查询使用 LLM 生成响应

Ragish 流程:

Ragish 的一般流程

提取立即可用的相关数据并将其全部添加到你选择的数据库中。(我用 SQL 获得了最好的结果)从你的数据中选择关键数据字段(对我来说是电子邮件的正文),然后提取命名实体并使用你选择的模型为该字段提供类别,并将其也添加到你的数据库中。训练 LLM 从自然语言中为该 DB 的模式生成 SQL 查询,并确保给出如何使用 NER 数据和类别的示例!。从 SQL 查询中检索数据并使用 LLM 生成响应。

但是你会问,这怎么会比典型的 RAG 更好呢?嗯,RAG有两个主要问题:

在对数据进行矢量化时,你通常会得到一个带有矢量嵌入的大型数据库,其中每个嵌入都有 3-6 KB 的数据,最终仅用于嵌入就加起来有 GB 的数据。至于 RAG 中的增强部分:更高的计算成本、更容易产生幻觉、结果更不可预测NER 和文本分类器只需添加几个字节的数据,因为它们本质上只是一个很小的 JSON 和一个文本短语。从 LLM 生成 SQL 查询:由于减少了令牌消耗,计算成本大大降低;更具确定性和精确性;而且它显然要快得多……它是 SQL!

如果你有大量小块数据或可以分成小块的东西,这种方法效果最好,这就是它在电子邮件数据集上如此有效的原因。它还可以处理法律文件、宗教经文、国际疾病分类等医学数据,所有这些要么已经是小块​​,要么可以转换成小块,同时保持其唯一性。

这种方法的缺点是,当单个数据点的大小达到 NER 和文本类别不足以准确确定底层数据的大小时,该方法无法工作。

让我们来看看一些糟糕的代码,看看我是如何实现的,以及它是如何工作的

2、检索

首先,我使用正则表达式解析电子邮件数据集以获取标题,如姓名、电子邮件、发件人、收件人等,并将其添加到类对象中。

为了获取命名实体,我使用了 en_core_web_sm 模型附带的 Spacy NER :

# Take in the Half filled data objectdef process_features(obj_list):nlp = spacy.load('en_core_web_sm')i=0for objs in obj_list:#NLP object of the bodydoc = nlp(objs.body) #get the word countobjs.word_count=sum(1 for token in doc if token.text.isalnum)# add all the Named entities to a Dictionary named_entity_lists={}for ent in doc.ents:if ent.label_ not in named_entity_lists:ent_list = ent_list.append(str(ent))named_entity_lists[ent.label_] = ent_listelse:named_entity_lists[ent.label_].append(str(ent))objs.named_entities = named_entity_lists print(i)i+=1

如果你想知道所有可能的命名实体是什么,请看这里!

最后在检索阶段,classy classification库!

分类所需的所有数据

classy 所做的非常令人印象深刻,每个类别只需 3 个示例,你就可以使用 classy 获得非常好的结果。我为我的数据使用了 12 个类别,这已经足够了

注意:据我所知,使用像 classy 这样的分类器时,拥有更多类别总是更好的,尝试类别的质量和数量以获得最佳结果!

classy 的配置和代码:

nlp = spacy.blank("en")nlp.add_pipe("classy_classification",config={"data": data,"model": "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2","device": "gpu",},)def categorize_mail(obj):doc = nlp(obj.body)cats = doc._.catspredicted_category = max(cats, key=cats.get)print(f"{predicted_category}")return predicted_category

太好了,现在我们得到了准备好了所有需要的上下文的对象,我使用了 psycopg2 并将其推送到 postgreSQL

3、增强

想象一下,你正在寻找一封关于与 Allen 会面的特定电子邮件。在传统的 RAG 系统中,你将拥有:

在大量嵌入中进行模糊搜索可能不相关的结果计算成本高

在 Ragish 的增强中,你将拥有:

精确分类:电子邮件预先标记为“会议安排”;已提取命名实体“Allen”SQL 查询生成:直接针对“会议”类别;“Allen”的过滤器;精确、快速检索

我们使用 Mistral 的 Codestral 模型来生成 SQL 查询。

Claude LLm

当此文本传递给 SQL 查询机器人时:

来自 LLM 提示的 SQL 查询

10 个电子邮件正文和 SQL 返回的其余列,我只需复制粘贴到 claude 中,这就是响应。

最终响应

目前我还没有将其全部连接到一个不错的应用程序中,但那是以后的事了,这有效的证据显而易见!

我想说的一点是,你不需要 1000 维向量来对数据进行分类,然后使用向量数据库来检索相关数据,相反,如果你很了解你的数据,你可以自己将其矢量化为较少的维度,然后自己命名和创建。当然,矢量化有其自身的优势,例如更好的语义映射,但你仍然可以在不使用传统方式的情况下走很长的路

它仍在进行中。我一定会更新此方法的统计数据

作为一名在 AI 初创公司摸爬滚打的实习生,我无意中创造了一些很酷的东西。这不是什么总体规划——只是我试图用我所知道的工具解决问题。

“需要是发明之母”——柏拉图

Ragish 证明了你不需要博士学位或尖端基础设施来构建创新的东西。有时,你所需要的只是 SQL、一些 Python 和尝试不同事物的勇气。

下一步涉及扩展其多功能性——从企业通信到医疗记录、法律文件等等。

想加入混乱吗?

让我们构建一个开源库,让整个过程更容易。

没有废话,只有代码!

来源:汽车任谈

相关推荐