本系列想学习如何从零开始搭建一个multi-agent系统并融入到应用中,这篇文章主要写其中的LLM-agent的核心模块RAG和向量数据库,以及Camel系统中是如何使用RAG。
1.为什么要用RAG(检索增强生成)
先聊下什么是RAG,为什么我们要用RAG:
RAG和向量数据库本身不是很新的技术,传统的搜广推里也用的比较成熟了,但是今年 LLM和Agent大火,同样也带火了向量数据库,不少细分领域创业公司也有在这块商业化做的不错的。
当开箱即用的预训练LLM解答问题不佳时,如何提高LLM应用的性能一直是我们讨论的焦点,一般我们会使用检索增强生成(RAG)或者模型微调这两种方法来改善结果。
RAG:这种方法将检索(或搜索)的能力集成到LLM文本生成中。它结合了一个检索系统和一个法学硕士,前者从大型语料库中获取相关文档片段,后者使用这些片段中的信息生成答案。本质上,RAG 帮助模型“查找”外部信息以改进其响应。
微调:这是采用预先训练的 LLM 并在较小的特定数据集上对其进行进一步训练的过程,以使其适应特定任务或提高其性能。通过微调,我们根据数据调整模型的权重,使其更适合我们应用程序的独特需求。
至于RAG和微调哪个好,以下是读到的一位大神的原话:
"从 RAG 开始,评估其性能,如果发现不足,则转向微调。然而,我的观点后来发生了变化。我认为,将 RAG 和微调视为实现相同结果的两种技术过于简单化,只是其中一种技术比另一种更便宜、更简单。它们从根本上是不同的——它们实际上是正交的,而不是共线的——并且满足LLM应用的不同要求。"
微调的优势在于能够使LLM的行为适应特定的细微差别。如果我们希望模型听起来更像专业人士,以诗意的风格写作,或者使用特定行业的术语,那么对特定领域的数据进行微调可以让我们实现这些定制。这种影响模型行为的能力对于与特定风格或领域专业知识保持一致至关重要的应用程序至关重要。
RAG 虽然在整合外部知识方面功能强大,但主要侧重于信息检索,并且本身并不根据检索到的信息来调整其语言风格或领域特异性。它将从外部数据源提取相关内容,但可能不会展现微调模型可以提供的定制细微差别或领域专业知识。
LLM的缺点之一是他们容易产生幻觉——编造没有现实依据的事实或细节。在准确性和真实性至关重要的应用中,这可能会产生很大的问题。
通过将模型基于特定领域的训练数据进行微调,可以在一定程度上帮助减少幻觉。然而,当面对不熟悉的输入时,模型仍然可能会做出响应。需要对新数据进行再训练,以不断减少虚假捏造。
相比之下,RAG 系统本质上不太容易产生幻觉,因为它们将每个响应都基于检索到的证据。在生成器构建答案之前,检索器从外部知识源中识别相关事实。此检索步骤充当事实检查机制,降低模型的虚构能力。生成器被限制为合成由检索到的上下文支持的响应。
2.什么是向量数据库
向量数据库顾名思义是一个用于查询的数据库,它是RAG框架的核心之一,它提供了一个可供高效处理和存储向量化数据的数据库,这些数据库能够处理高维度数据,也能提供ANN查询,如今向量数据库被看作Ai infra的关键一环,专门用于存储,索引和查询向量的数据库系统。
以下是是经典的基于向量数据库的应用框图:
拆解一下可以分为几个步骤:
首先,我们使用嵌入模型为我们想要索引的内容创建向量嵌入。
将向量嵌入插入向量数据库,并引用创建嵌入的原始内容。
当应用程序发出查询请求时,我们使用相同的嵌入模型为查询创建嵌入,并使用这些嵌入查询数据库中的相似向量嵌入。
3.camel与RAG
camel正在探索Native RAG经典方法和Advance RAG先进方法在multi-agent框架中的应用,在Native RAG中,camel引入了qdrant库作为核心组件,并同时集成了unstructured, SentenceTransformers等热门开源组件。
3.1 向量数据库qdrant
qdrant的常用元素:
集合(collections):一组点(points),可以在这些点之间搜索,同一集合中每个点的向量必须具有相同的维度,并由单一的度量标准进行比较。
度量标准 (Metric):用于测量向量之间的相似性,在创建集合时选择,度量标准就是我们选择的向量相似度算法
点(points):点是Qdrant操作的核心实体,由向量、可选的id和负载组成。
3.2 camel中RAG的使用
下图转载自camel RAG Roadmap,这个流程非常清晰,并且根据Roadmap,图数据库也会引入,不过本文只讨论向量数据库。
3.2.1 Unstructured模块
是一个针对非结构化数据的预处理开源工具,可以从多种文件类型中提取表格,图像,文本等信息类型。
3.2.2 SentenceTransformers库
是一个可以用于句子、文本和图像嵌入的Python库,该库提供了大量针对各种任务的预训练模型。
可用于Embeddings,Semantic Clustering,Semantic Similarity等大量任务,camel引入SentenceTransformers主要用于通过输入文本给模型生成embedding。
以下是SentenceTransformers的测试用例:
def test_embed_list_with_valid_input():
embedding = SentenceTransformerEncoder()
test_texts = ['Hello world', 'Testing sentence embeddings']
embeddings = embedding.embed_list(test_texts)
assert isinstance(embeddings, list)
assert len(embeddings) == 2
for e in embeddings:
assert len(e) == embedding.get_output_dim()
3.2.3 QdrantStorage
Camel的向量数据库QdrantStorage里主要围绕collection进行操作(create, delete, add, check和clear), 并定义了distance_map(用于向量相似度的度量):
distance_map = {
VectorDistance.DOT: Distance.DOT,
VectorDistance.COSINE: Distance.COSINE,
VectorDistance.EUCLIDEAN: Distance.EUCLID,
}
其中add和create的区别在于create是创建一个新的集合,而add是在集合里加入新的point list, delete也是根据对应的IDs来删除相应的point list。
而query函数是根据要查询的对象通过计算向量相似度来检索出需要的vector list。
3.2.4 RetrievalModule模块
RetrievalModule模块实现了整个RAG的工作流,它可以处理非结构化数据,将其嵌入到向量空间中,并根据查询检索相关信息。
embed_and_store_chunks函数主要作用是将从内容分割出来的内容块存储到向量数据库中,并调用vector_storage对象的add方法,将向量和负载添加到向量存储中:
vector = self.embedding_model.embed(obj=str(chunk))
combined_dict = {**content_path_info, **chunk_metadata, **chunk_text}
vector_storage.add(records=[VectorRecord(vector=vector, payload=combined_dict)])
query_and_compile_results函数是搜索的核心部分:
使用 embedding_model 将查询字符串转换为向量表示。
创建一个 VectorDBQuery 对象,包含查询向量和 top_k 参数。
调用 vector_storage 的 query 方法执行查询,并传入额外的 kwargs 参数。
query_vector = self.embedding_model.embed(obj=query)
db_query = VectorDBQuery(query_vector=query_vector, top_k=top_k)
query_results = vector_storage.query(query=db_query, **kwargs)
以上是本篇文章的学习笔记,图片来自转载,若有侵权告知我,我会删除的哈
资料参考:
Camel社区: https:// www.camel-ai.org
https://zhuanlan.zhihu.com/p/64
标签:RAG,multi,camel,数据库,vector,query,向量 From: https://www.cnblogs.com/huangjinxiaomiaomiao/p/18150873