企业级RAG构建

RAG构建框架:

 

一.
langchain模型,Indexing工程化构建:

1.文档加载器(txt,word,pdf,json,md,网页)

2.文档解析

3.文档切分(chuncks):

  3.0.1)文档切割器:RecursiveCharacterTextSplitter,ChineseRecursiveTextSplitter等

  3.0.2)可重叠窗口的递归切分,chunk_size=500(块长度),chunk_overlap=20(重叠字符串长度),add_start_index=True

  3.0.3)记录元数据metadata:每一个切分块做元数据标记

  3.0.4)documents = text_splitter.split_documents(raw_documents)

  

3.1)chunks的作用

从检索相关性角度看,直接embedding大段的文章内容,是更有利于召回更相关的内容,这是因为它不仅可以考虑词组句子字面的意思,更能够关注到其上下文的信息,也要考虑文本中句子和短语之间的关系从而产生更全面的向量表征,捕捉文本更广泛的含义和主题。但同时,较大的文本又可能会引入噪音或削弱单个句子或短语的重要性,使得在查询索引时更难找到精确的匹配项。查询的长度也会影响embedding之间的关系。一个较短的查询,如一个句子或短语,将集中于具体内容,可能更适合与句子级向量匹配。跨度超过一个句子或段落的较长查询可能更适合与段落或文档级别的向量匹配,因为它可能在寻找更广泛的上下文或主题。可以看出,它和人类理解是有相似之处,背景信息既不能太少也不能太多。

同时,索引也可能是非同质的,包含不同大小的块的embedding。这可能会给查询结果的相关性带来挑战,但也可能会产生一些积极的影响。一方面,由于长内容和短内容的语义表征之间存在差异,查询结果的相关性可能会出现波动。另一方面,非同质索引有可能捕捉到更广泛的上下文和信息,因为不同的块大小代表了文本中不同的粒度。这可以更灵活地适应不同类型的查询。

除此之外,chunking对于简化工程实现复杂度,提升处理效率,比如可以减少内存消耗和提高并行度,以及结果可解释性等方面都有很重要的作用。

 

3.2)chunking策略:

1)文本类型及大小,比如是一篇文章博客还是一个推文,是markdown格式还是网页格式。

2)检索查询的长度和复杂程度,比如,是简短的问题,还是包含复杂的背景信息的描述。

3)具体使用的嵌入模型在何种大小的文本块上表现最佳。比如, sentence-transformer上模型在单个句子上效果很好,但像 text-embedding-ada-002 这样的模型在包含 256 或 512 个标记的块上效果更好。

4)具体使用场景,比如,是用于语义搜索、问题解答、摘要还是其他目的,以及最终检索的chunk会提交给大模型,其大模型的上下文窗口与之匹配情况。

5)资源的限制,比如在进行chunking时,算力及内存的一些约束,也会对chunking大小有限制。

 

3.3)常见的文本分块方法:

1)固定大小分块(FSC),这是最常见、最直接的分块方法:我们只需决定分块中token的数量,并选择它们之间是否应该有任何重叠。一般来说,我们会希望在分块之间保留一些重叠,以确保语义上下文不会在分块之间丢失。在大多数情况下,固定大小的分块是最佳选择。与其他形式的分块法相比,固定大小的分块法计算成本低,使用简单,因为它不需要使用任何 NLP 库。比如,下面使用langchain对文本进行分块,分块大小为256:

在此基础上,结合它们的优劣势衍生了内容定义分块算法(CDC)、滑动窗口分块算法(SWC)和两阈值两除法分块算法(TTTD)。FSC 将文本分割成大小相同的块,而不考虑内容。这种方法简单快捷,但由于边界偏移问题,重复数据删除效率较低。CDC 根据内容的某些特征(如标点符号或哈希值)分割文本。这种方法可以实现更高的重复数据删除效率,但需要更多的计算和存储。SWC 在文本上滑动一个窗口,并在窗口内满足特定条件时标记一个块边界。这种方法可以适应不同的数据特征,但可能会生成不同大小的块。TTTD 使用两个不同的阈值和除数将文本分成两个层次:粗粒度块和细粒度块。这种方法可以在重复数据删除效率和计算成本之间取得平衡。

2)句子级分块,以句子的粒度进行拆分,最简单的方法是用句号(".")和新行分割句子。虽然这种方法既快又简单,但却没有考虑到所有可能的边角问题。为了解决这一情况可以使用一些NLP的技术感知到文本内容语义,从而更好地保留所产生的语块的上下文。langchain中内置了很多句子拆分的工具包。比如NLTK和spaCy。

3)递归分块,递归分块法使用一组分隔符,以分层和迭代的方式将输入文本分成较小的块。如果初次尝试分割文本时没有产生所需的大小或结构的分块,该方法就会使用不同的分隔符或标准对产生的分块进行递归调用,直到达到所需的分块大小或结构。这意味着,虽然分块的大小不会完全相同,但它们仍会倾向于达到相似的大小。

4.)特定格式的分块:针对特定格式的文本,如Markdown和LaTeX,保留内容的原始结构,例如识别Markdown语法或解析LaTeX命令和环境。

 

3.4)文本处理模型:

wikiextractor 能够从维基百科的数据转储(如XML文件)中提取出干净的文本数据,移除原始数据中的标记语言(如HTML和Wiki标记),用它将复杂的数据转储转化为易于处理的纯文本格式。
一旦有了干净的文本数据,接下来要考虑的就是如何去处理这庞大的原始文本。一种行之有效的解决方法是借助于预训练模型去处理,我们常用的是zh_core_web_lg 用来处理中文文本,其托管在spaCy平台。

spaCy 是一个高性能的自然语言处理(NLP)库,广泛应用于实业界和学术界,提供了多种语言的支持和许多强大的语言处理功能。spaCy 的设计重点在于速度和效率,在处理大规模文本数据时尤其出色。

 

3.5)非结构化文本处理(PDF)

解析 PDF 文档的挑战在于准确提取整个页面的布局并将内容(包括表格、标题、段落和图像)转换为文档的文本表示形式。该过程涉及处理文本提取、图像识别中的不准确以及表格中行列关系的混乱。
主流解析 PDF 的方法有以下三种:

3.5.1)基于规则的方法:每个部分的风格和内容根据文档的组织特征确定。然而,这种方法的通用性不是很强,因为 PDF 的类型和布局多种多样,不可能用预定义的规则涵盖所有类型和布局。

最具代表性的工具之一是pypdf,它是一种广泛使用的基于规则的解析器。它是LangChain和LlamaIndex中用于解析PDF文件的标准方法。
PyPDF识别的形式是将PDF中的字符序列序列化为单个长序列,而没有保留结构信息。换句话说,它将文档的每一行视为由换行符“ \n ”分隔的序列,最大的问题是会妨碍准确识别段落或表格。

3.5.2)基于深度学习模型的方法:例如当前流行的结合目标检测(yolox)和OCR模型的解决方案。

这种方法的优点是能够准确识别整个文档的布局,包括表格和段落。它甚至可以理解表内的结构。这意味着它可以将文档划分为定义明确、完整的信息单元,同时保留预期的含义和结构。

3.5.3)基于多模态大型模型传递复杂结构或提取 PDF 中的关键信息。

检索相关图像(PDF 页面)并将其发送到 GPT4-V 以响应查询。
检索相关图像(PDF 页面)并将其发送到 GPT4-V 以响应查询。
对裁剪后的表格图像应用 OCR 并将数据发送到 GPT4/GPT-3.5 以回答查询
 
4.Dataset数据集
 
5.embdding模型
  5.1)Openai或者hugging face都有有提供标准接口,集成在LangChain中
  5.2)付费Openai的text-embdding-3 ,开源的bge-base-zh-v1.5
  5.3)生成向量维度可以自定义1024,3072。text-embdding-3 中:文本对象的方法:embed_documents,query对应的方法:embed_query
  5.4)计算向量之间的相似度方法:
  点积(内积):两个向量的点积是一种衡量它们在同一方向上投影的大小的方法。如果两分向量是单位向量(长度为1),它们的点积等于它们之间夹角的余弦值。因此,点积经常被用来计算两个向量的相似度
  余弦相似度:这是一种通过测量两个向量之间的角度来确定它们相似度的方法。余弦相似度是两个向量点积和立的备画检度乘积的商。这个值的范围从-1到1,其中1表示完全相同的方向,-1表示完全相反,0表示正交。
  欧氏距离: 这种方法测量的是两个向量在n维空间中的实际距离。虽然它通常用于计算不相似度(即距离越大,不相似度越高),但可以通过某些转换(如取反数或用最大距离归化)将其用于相似度计算。

6.创建向量索引,存储所有向量的数据结构到向量数据库

  6.1)

向量数据库,其解决的就是一个问题:更高效的实现搜索(Search)过程。传统数据库是先存储数据表,然后用查询语句(SQL)进行数据搜索,本质还是基于文本的精确匹配,这种方法对于关键字的搜索非常合适,但对于语义的搜索就非常弱。那么把传统数据库的索引思想引用到向量数据库中,同样是做搜索,在向量数据库的应用场景中就变成了:给定一个查询向量,然后在众多向量中找到最为相似的一些向量返回。这就不再是精确四配,而是具有一定的模糊性,这就是所谓的最近邻(Nearest Neighbors)问题,而能实现这一点的则称之为【最近邻馋臏龟…笥(搜索)算法】。

通过某种聚类算法先进行一轮训练,把相似向量划分到一个个不同的簇中,在实际执行搜索的时候,只需要找到和聚类向量中心点最近的那个向量,然后在这个簇中的执行搜索过程即可。但也会出现一些问题,比如下面这种情况:红色的点是查询向量落到的位置,它距离蓝色簇质心的距离最近,所以按照规则,它会去蓝色的簇中搜索向量,但实际上,与它最相近的向量是在黄色的簇中的红色点。  

这个时候我们就可以通过划分多个簇来尽可能的减少这种遗漏的情况,但需要说明的是,旦提高搜索质量通常会降低处理速度,这两者之间往往存在难以调和的矛盾。在实际应用中,几乎所有的算法都是在这两个指标之间寻求平衡。因此,除了暴力搜索之外,任何算法得到的都是一些近似的结果。这类算法也被称为“近似最近邻"(Approximate NearestNeighbors,简称ANN)

 

那除了聚类这种形式以外,减少搜索范围的方法还有很多,比如非常流行的哈希算法。哈希算法简单理解就是任何数据经过哈希函数计算后,都会输出一个固定的哈希值,那就会存在个问题:将无限可能的输入映射到有限的输出范围内,就一定会出现不同的输入数据产生相同的哈希值的这种情况,这种现象被称为“碰撞"。一个理想的哈希算法是尽可能的减少这种碰撞,但向量数据库的哈希函数设计却反其道而行,它会倾向于增大碰撞发生的可能性,因为当哈希值一样,那它就会认为这两个向量是相似的,然后把这些向量划分到一起,在哈希算法下就不叫簇了,而叫做桶:Bucket。

 

除了增加碰撞的概率外,在向量数据库中的哈希函数让越相似的向量,发生碰撞的概率越高高,通过这样的策略就会使得相似向量被分到同一个Bucket中的概率越大。,如此,在查询的时候,先通过哈希函数找到查询向量的哈希值,然后去对应的Bucket中查找,以此来减小搜索范围。我们把具有这种特性的哈希函数称之为:位置敏感哈希Locality Sensitive Hashing。当然,还有一些能够减低内存开销的搜索算法,比如有损压缩的PQ算法,基于图搜索的HNSW等,我们在后续使用时如果遇到,再开展给大家做详细的介绍。


总的来说,不同的向量数据库,底层实现的只是这种不同的逻辑,但核心都会搭建类似这样的流程。而在应用层面上,其展现出来将文本转换成向量,然后将向量存储在数据库中,当用户输入问题时,将问题转换成向量,然后在数据库中搜索最相似的向量和上下文,最后将文

  6.1)Milvus作为一个开源的向量相似度搜索引擎,专注于大规模向量数据的快速相似度搜索。它提供了高效的向量索引和搜索功能,支持多种向量数据类型和查询方式。作为一个专门设计用于处理输入向量查询的数据库,Milvus能够在万亿规模上对向量进行索引。与现有的关系数据库主要按照预定义的模式处理结构化数据不同,Milvus是从自底向上设计的,以处理从非结构化数据转换而来的嵌入向量。
  6.2)Faiss向量数据库:索引和量化算法
  6.3)Chramo向量数据库:
    db = Chroma.from_documents(document,embddings_model)
    query = 'asd'
    docs = db.similarity_search(query)

7.similarity_search_with_score_by_vector向量相似度检索方法

 

二.
RAG评估:

作用:RAG评估工具是用于测试和评估基于检索的文本生成系统的方法或框架,用来评估准确性、内容质量和相关性等指标。
方式:人工评估,RAG评估工具
对比:更加客观、准确、高效,可以通过自动化进行大规模评估。

常见的实体定义:
Question:指用户的询问,在某些工具中,也被称为Input或Query
Context:指检索到的文档上下文,有些工具称之为Retrieval Context
Answer:指生成的答案,可以使用不同的术语,例如:Actual Output 或 Response
Ground Truth:指手动标记的正确答案,它用于评估生成答案的准确性

主流的评估框架:

2.1)TruLens 是一款软件工具,可以使用反馈功能客观地衡量基于 LLM 的应用程序的质量和有效性。反馈功能有助于以编程方式评估输入、输出和中间结果的质量,能够用于各种用例,包括问答、摘要、检索增强生成和基于代理的应用程序。
在 Trulens 的设计中,优先考虑了 RAG 应用程序的三个主要相关性评估:答案相关性、上下文相关性和依据性。

 

评估指标
中文描述
描述
Answer Relevance
答案相关性
评估 Answer 对 Question 的响应程度,衡量LLM的最终答案解决原始问题的程度,确保其有用且相关。
Context Relevance
上下文相关性
评估 Context 与 Question 的相关性,这一点至关重要,因为上下文构成了 LLM 答案的基础。
Groundedness
依据性
检查 Answer 是否与 Context 中呈现的事实相符,确保它不会夸大或偏离给定的信息。
Ground Truth
基准真值
将 Answer 与手动标记的 Ground Truth 进行比较,以确保准确性。

2.2)Ragas 是评估 RAG 应用程序的另一个框架。与 TruLens 相比,Ragas 提供了更详细的指标。

 

术语
中文描述
描述
Faithfulness
忠实度
评估 Question 和 Context 之间的一致性。
Answer Relevance
答案相关性
评估 Answer 和 Question 之间的一致性。
Context Precision
上下文精度
检查 Ground Truth 在 Context 中的排名是否较高。
Context Recall
上下文召回
评估 Ground Truth 和 Context 之间的一致性。
Context Entities Recall
上下文实体召回
评估 Ground Truth 和 Context 中实体之间的一致性。
Context Relevancy
上下文相关性
评估 Question 和 Context 之间的一致性。
Answer Semantic Similarity
答案语义相似度
评估 Answer 和 Ground Truth 之间的语义相似度。
Answer Correctness
答案正确性
评估 Answer 相对于 Ground Truth 的正确性。
Aspect Critique
方面批评
包括对其他方面的评价,如有害性、正确性等。
关键具体指标信息:
Faithfulness(忠实度):衡量了生成的答案与给定上下文的事实一致性。它是根据答案和检索到的上下文计算得出的。答案缩放到 (0,1) 范围。越高越好。
Answer Correctness(答案正确性)包含两个关键方面:生成的答案与基本事实之间的语义相似性,以及事实相似性。使用加权方案将这些方面结合起来以制定答案正确性分数。

整体工程化流程:
2.2.1).为RAG选择切分后的数据块(上下文)
2.2.2).使用大语言模型(GLM4等)基于块(问题)生成问题:基于传入的切分后文本块内容,首先让GLM4模型进行提出问题(question+context+metadata形式json),
2.2.3)使用上下文回答问题并使用大语言模型(Ground Truth Dataset)进行回答,然后基于提出的问题+文本块内容进行答案生成(question+contexts+ground truth)
2.2.4)运行RAG模型来检索和生成答案(answer):问题(2.2中构建的question)+上下文(context根据RAG流程检索出来的)+answer(RAG流程回答)
2.2.5)比较答案和真实情况并计算指标:question+answer+contexts+ground_truth

 

2.3)其它评估框架

2.3.1)A Workbench for Autograding Retrieve/Generate Systems

论文:https://arxiv.org/pdf/2405.13177
代码:https://github.com/TREMA-UNH/autograding-workbench

2.3.2)Evaluation of Retrieval-Augmented Generation: A Survey,提出了一个分析框架RAGR(检索、生成、额外要求)

论文:https://arxiv.org/pdf/2405.07437

2.3.3)DeepEval:是 LLMs 的开源评估框架,允许像单元测试一样运行评估任务。

Github地址:https://github.com/confident-ai/deepeval
 

3)自定义模型评估指标
3.1)F1分数
3.2)precision
3.3)recall
3.4)EM:预测生成的回答是否与真实的回答完全一致
3.5)SUB_EM:预测生成的回答是否包含了标准答案


三.
prompt template构建
3.1)构建基本的系统提示模板system_prompt和用户输入提示模板user_prompt


四.
向量检索器构建原理:
4.1)Sparse Retrieval:稀疏检索,(pyserini库构建的索引BM25检索器,实现向量稀疏检索)
信息检索在过去依赖于基于单词统计的稀疏技术。在传统方法中,文档由词袋模型表示,其中特定单词的存在或不在决定了文档与查询的相关性。词袋模型将每个文档表示为整个词汇表大小的向量,其中每个维度代表一个唯一的词。对于大型文本数据集,这个词汇表可以非常庞大(通常达到成千上万或更多的独立词汇)。因此大多数维度都是0,导致向量非常稀疏。所以我们将这种传统的方法称之为:Sparse Retrieval

评分函数(例如 BM25 和 TF-IDF)使用词频对文档进行评分,平衡关键字在文档中出现的频率与该词的普遍流行程度其中BM25通过量化查询词与文档之间的相关性来对文档进行排序,基于逆文档频率(IDF)和文档中词项的频率来计算得分,从而评估一个文档对于给定搜索查询的相关性。是TF-IDF(词频-逆文档频率)方法的一个改进。

4.2)Dense Retrieval:稠密检索,(faiss向量数据库构建的索引的密集检索器)
随着自然语言处理和机器学习的进步,信息检索已经转向使用嵌入的更密集的表示。嵌入捕获单词和短语的语义,从而可以更细致地理解内容;这使得查询与相关文档能够更准确地匹配,因为嵌入可以捕获传统单词统计无法捕获的微妙语义相似性。从稀疏表示到密集表示的转变显着提高了检索系统的性能和精度。对于密集检索-Dense Retievers,基本上支持各种基于BERT的嵌入模型,如DPR、E5 和BGE。使用语义搜索来查找相关文档。语义搜索意味着我们使用文本的密集表示来测量给定查询和潜在相关文档之间的相似性。使用不同的方法来存储文档向量并测量查询和文档之间的相似性。

那这个过程就变成了:由知识库(KB)、检索器和生成器(LLM)组成,它“读取“查询和检索到的文档,并生成输出。可以尝试不同的架构、模型,对性能和延迟的结果进行基准测试。这种基准称为自然问题(NQ)。

 

五.Re-ranking
基于RAG 的问题系统遵循数据科学的旧原则:垃圾输入,垃圾输出。如果文档检索失败,LLM 模型就没有机会提供好的答案。在简单的 RAG 方法中(Navie RAG),可以检索大量上下文,但并非所有上下文都一定与问题相关。所以,对Navie RAG 改进是使用重新排序器。重新排序器将用户的问题和所有最初检索到的文档作为输入,并根据这些文档与问题的匹配程度对这些文档进行重新排序。将相关文档置于最前面,从而提高RAG的有效性。

5.1)付费在线模型 Cohere ,可以通过 API 访问
5.2)开源模型, bge-reranker-base 和 bge-reranker-large 
5.3)Bi-Encoder+交叉编码器进行重排序:
给定用户查询,我们将查询转换为嵌入向量,然后在查询嵌入和所有存储的块嵌入之间执行向量相似性搜索。这种类型的编码器模型也称为Bi-Encoder(双向编码器),它将所有输入独立地转换为嵌入向量。
首先使用双编码器和嵌入相似性搜索来检索候选文档。然后我们使用更慢但更准确的方法对这些文档进行重新排序。例如,使用重新排序器,我们可以将检索到的 top_k1 = 25 文档块缩小到最相关的 top_k2 = 3 块。
交叉编码器可用于信息检索:给定一个查询,用所有检索到的文档对其进行编码。然后,按降序对它们进行排序。得分高的文档是最相关的文档。
Bi-Encoder双向编码器:

 交叉编码器:

整体架构:

 5.4)

提升RAG检索质量的三个高级技巧(查询扩展、交叉编码器重排序和嵌入适配器)
1.查询扩展
1) 使用生成的答案进行查询扩展
给定输入查询后,这种方法首先会指示 LLM 提供一个假设答案,无论其正确性如何。然后,将查询和生成的答案合并在一个提示中,并发送给检索系统。这个方法的效果很好。基本目的是希望检索到更像答案的文档。
2)用多个相关问题扩展查询
利用 LLM 生成 N 个与原始查询相关的问题,然后将所有问题(加上原始查询)发送给检索系统。通过这种方法,可以从向量库中检索到更多文档。不过,其中有些会是重复的,因此需要进行后处理来删除它们。

2.交叉编码器重排序
这种方法会根据输入查询与检索到的文档的相关性的分数对文档进行重排序。为了计算这个分数,将会使用到交叉编码器。
交叉编码器是一种深度神经网络,它将两个输入序列作为一个输入进行处理。这样,模型就能直接比较和对比输入,以更综合、更细致的方式理解它们之间的关系。
交叉编码器可用于信息检索:给定一个查询,用所有检索到的文档对其进行编码。然后,将它们按递减顺序排列。得分高的文档就是最相关的文档。
交叉编码器重新排序可与查询扩展一起使用:在生成多个相关问题并检索相应的文档(比如最终有 M 个文档)后,对它们重新排序并选出前 K 个(K < M)。这样,就可以减少上下文的大小,同时选出最重要的部分。

3.嵌入适配器 
这是一种功能强大但使用简单的技术,可以扩展嵌入式内容,使其更好地与用户的任务保持一致,利用用户对检索文档相关性的反馈来训练适配器。
适配器是全面微调预训练模型的一种轻量级替代方法。目前,适配器是以小型前馈神经网络的形式实现的,插入到预训练模型的层之间。训练适配器的根本目的是改变嵌入查询,从而为特定任务产生更好的检索结果。嵌入适配器是在嵌入阶段之后、检索之前插入的一个阶段。可以把它想象成一个矩阵(带有经过训练的权重),它采用原始嵌入并对其进行缩放。

 

 

六.实时联网检索+Rerank+RAG检索整体架构

 

6.1)Serper,该服务是一个高性能的 Google 搜索 API,提供快速且成本效益高的方式访问 Google 搜索结果。在目前的应用落地产品中广泛被用于增强聊天机器人、进行搜索引擎优化(SEO)分析和简化金融科技项目等多种场景。该API具备:
- 执行实时搜索
- 自定义查询位置
- 快速访问 Google 的搜索引擎结果——通常在1-2秒内
1. 计算相似度:我们需要通过某种相似度计算方法,去衡量检索到的网页和用户实际提出的query是不是相关的。
2. 排序:根据计算得到的相似度分数,对所有文档进行排序,得分最高的文档被认为与查询最相关。
3. 选择:选取得分最高的一定数量的文档进行深入处理。具体数量可以根据系统需求和性能考虑进行调整。
 
过程:
6.2.1)获取到Serper API Key后,我们可以使用 Python 的 requests 库来调用 Serper API,从返回的JSON 数据中提取 "organic" 键对应的值,其内容代表了搜索引擎返回的自然(非广告)搜索结果。
6.2.2)接下来,我们需要进行进一步处理,增加两个新的属性:一个是用于唯一标识每个搜索结果的 UUID,另一个是初始化搜索结果的得分。
  6.2.2.1) 使用 hashlib.md5() 生成基于搜索结果链接的 MD5 哈希值。这里,对每个结果的 link 字段进行编码并哈希处理,用于生成一个唯一的标识符(UUID)。MD5 哈希用于确保每个搜索结果都有一个独一无二的标识码。
  6.2.2.2)给每个搜索结果添加一个 "score" 键,并初始化其值为 0.00。这个得分用于后续的评分算法,目的是在进入RAG过程前做进一步的筛选。
6.2.3) 进一步转换成 Document 对象,并存储在一个列表中,包含了一个文档的内容及其元数据。metadata={'uuid': '07ec36227ed79525b4c7d82434e8a3e6', 'title': '2024年NBA总决赛 - 维基百科',
6.2.4)对于每个检索到的网页,使用 normalizedLevenshtein.similarity() 方法计算query与网页摘要 (x.page_content) 的相似度。标准化后的距离值(Score)介于 0(完全不相似)和 1(完全相同)之间。
6.2.5)根据 score 的分数决定要对Top N 篇文档进行提取页面主体信息-切分chunks-存入向量数据-检索与query最相关的chunks等一系列后续数据处理工作。那么首先要做的就是:提取URL列表,用于获取页面内容。
  6.2.5.1)第一步,我们需要提取出每个网页信息的metadata字典里的link键对应的值。
  6.2.5.2)第二步,遍历url_list列表中的每一个URL,使用requests.get(url)函数向每个URL发送HTTP GET请求。html_reponse列表包含了从每个访问的链接返回的HTML响应。
  6.2.5.3)第三步,将HTML响应转换成Markdown格式,并对最终的Markdown文本进行一些额外的格式化处理
6.2.6)构建content_maps字典。这个字典现在包含了键为URL和值为对应Markdown格式化内容的键值对。这样做的好处是可以通过URL快速查找到相应的Markdown内容,提高数据检索的效率,尤其在需要根据URL快速获取或显示内容的应用中非常有用。

 

posted @ 2025-05-18 14:46  修心的博客  阅读(163)  评论(0)    收藏  举报