测试 18 种 RAG 技术以找到最佳技术(1/2)

我们将从我们都知道的简单 RAG 方法开始,然后测试更先进的技术,如 CRAG、Fusion、HyDE 等!为了让一切简单……我没有使用 LangChain 或

今天给各位分享测试 18 种 RAG 技术以找到最佳技术(1/2) 的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

使一切变得简单.

我不使用兰班或faiss

但是,只需使用基本库以jupyter笔记本样式编写所有技术,以使其简单易于学习。

GitHub 仓库:https://github.com/FareedKhan-dev/all-rag-techniques

代码库的组织如下:

1_simple_rag.ipynb-2_semantic_chunking.ipynbismantic_ipynb-9_rse.ipynbismanbismant.10_contextual_compression.ipynb 17_graph_rag.ipynb.-18_hierarchy_rag.ipynb-I-19_hyde_rag.ipynbistrag.ipynb-20_crag.ipynbistar/data/data/lat.data/iston/iston/iston/son.jsonston-测试查询和最有效的llmStechnique!进口图书馆ragsemple ragsemistecontext富含检索的检索,检索副本块块标头介绍augmentationquery unmentationquery rankerrsectrationre-rankernsecontextualsementextualcompres剂我们需要四件事:

测试查询及其真实答案。将应用于抹布的PDF文档。嵌入生成模型。响应并验证LLM。使用Claude 3.5思维模型,我创建了一个16页的AI主题文档作为抹布的参考文档,而注意是您评估多模型抹布所需的所有论文。

对于响应生成和验证,我们将使用Llama-3.2-3B指示来测试小LLM在抹布任务中的表现。

为了嵌入,我们将使用Taylorai/GTE微型模型。

我们的测试查询很复杂,我们将在整个文档中使用它,其真正的答案是:

测试问题:人工智能如何依赖大规模数据集成为双刃剑?正确的答案:它推动了快速学习和创新的速度,同时也冒着放大固有的偏见的风险,因此将数据量与公平和质量平衡至关重要。

目录

在测试我们的测试查询中测试18种不同的抹布技术后,最好将其写在顶部,而不是在最后提供。

自适应抹布以0.86的最高得分获胜。

通过智能分类查询并为每种问题类型选择最合适的搜索策略,自适应抹布的性能比其他方法更好。它可以在事实,分析,观点和上下文策略之间动态切换,从而使其能够以惊人的准确性处理各种信息需求。

尽管诸如层次索引(0.84),融合(0.83)和CRAG(0.824)之类的技术也表现良好,但自适应抹布的灵活性使其在实际应用中具有优势。

测试查询和LLMs

让我们首先克隆我的存储库以安装所需的依赖项并开始。

#clone repo git克隆https://github.com/fareedkhan-dev/all-rag-techniques.git CD CD All-Rag-Techniques安装所需的依赖性。

安装所需的库pip install -r unigess.txt

(结论)最有效的技术!

让我们从最简单的抹布开始。首先,我们将了解它的工作原理,然后对其进行测试和评估。

简单的抹布工作流程

如图所示,简单的抹布管道的工作原理如下:

从PDF提取文本。将文本分为较小的块。将块转换为数字嵌入。根据查询搜索最相关的块。使用检索的块生成响应。将答案与正确答案进行比较以评估准确性。首先,让我们加载文档,获取文本并将其分为可管理的块:

定义PDF文件的路径pdf_path=\’data/ai_information.pdf\’从PDF文件中提取文本,并创建较小的重叠块。 extracted_text=extract_text_from_pdf(pdf_path) text_chunks=chunk_text(extracted_text, 1000 , 200 ) print (\’Number of text blocks:\’ , len (text_chunks)) ### Output ###Number of text blocks: 42 This code uses extract_text_from_pdf to extract all text from our PDF file.然后,chunk_text将大部分文本划分为较小的重叠片段,每个片段的长度约为1000个字符。

接下来,我们需要将它们变成数值表示(嵌入):

为文本块创建嵌入式响应=create_embeddings(text_chunks),create_embeddings获取我们的文本块列表,并使用我们的嵌入模型为每个块生成数字嵌入。这些嵌入捕获文本的含义。

现在,我们可以执行语义搜索并找到我们的测试查询最相关的块:

我们的测试查询并执行语义搜索。查询=\’\’\’人工智能如何依赖大规模数据集成为双刃剑? \’\’\’\’top_chunks=semantic_search(查询,text_chunks,嵌入,k=2),然后,Semantic_search将查询嵌入与块的嵌入式进行比较,从而返回大多数相似的块。

现在,我们可以执行语义搜索以找到与我们的测试查询最相关的块:

系统提示System_prompt=\’您是AI助手,它严格根据给定上下文回答。如果无法直接从提供的上下文中得出答案,请回答:‘我没有足够的信息来回答这个问题。 \’\’创建基于顶部块的用户提示并生成AI响应。USER_PROMPT=\’\\ n\’.join([f\’Context {i + 1} : \\ n {chunk} \\ n====================================\\ n\’for I,for I,n e e e e e e e e e e e e eumerate(top_chunks)user_promprompt \\ nquestion: {query}\’ai_response=generate_response(system_prompt,user_prompt)print(ai_response.choices.choices.choices.choices.message.content)此代码格式格式,将检索到的块作为大型语言模型的提示(LLM)。

最后,让我们看看抹布的表现如何:

定义评估系统的系统提示evaluate_system_prompt=“您是一个智能评估系统,负责评估AI助手的答案。如果答案非常接近真实的答案,则得分为1。如果答案不正确或不满意,则与真实的答案是0.5。 创建一个评估提示并生成一个ession_prompt=f\’user query: {query} \\ nai响应: \\ n {ai_response.choices [0] .message.content.content} \\ ntrue wenders} evaluation_response=generate_response(evaluate_system_prompt,evaluation_prompt)print(evaluation_response.choices [0] .message.content)### output ### .因此,得分0.3的分数不是很近,并且不太接近实际响应,并且不是完全一致的。好吧……简单的抹布的回应低于平均水平

让我们继续采用下一种方法。

导入库

在我们简单的抹布方法中,我们只需将文本切成固定尺寸的块即可。这很粗糙!它可能会将句子分为一半,或者团体无关紧要的句子在一起。

语义块设计为更聪明。它没有采用固定尺寸,而是试图通过其含义和组语义相关的句子将文本分开。

语义分解工作流程

这个想法是,如果句子在谈论类似的事情,那么它们应该在同一块中。我们将使用相同的嵌入模型来确定句子的相似程度。

测试 18 种 RAG 技术以找到最佳技术(1/2)

将文本分为句子(基本上是拆分)=extract_text.split(\’。\’)为每个句子嵌入的嵌入量=[句子中的句子] print(f\’generated {f\’generated {len(embeddings)}句子}句子。然后为每个句子创建一个嵌入。

现在,让我们计算连续句子之间的相似性:

计算连续句子相似性之间的相似性=[cosine_simarility(嵌入[i],嵌入[i + 1])i在范围内(len(embeddings)-1)]这个cosine_sibility函数(我们之前定义了)告诉我们两个嵌入两个嵌入方式。得分为1表示它们非常相似,而0表示它们完全不同。我们计算每对相邻句子的分数。

语义块是将文本分成块的地方。我们将使用“断点”方法。我们在这里使用百分位方法来寻找相似性的大量下降:

使用百分位方法计算断点,阈值为90个断点=compute_breakpoints(相似之处,方法=\’perstalile\’,阈值\’,阈值=90)compute_breakpoints函数,并使用“百分位”方法识别句子之间相似度明显较低的点。这些是我们的块边界。

现在我们可以创建语义块:

# Create blocks with the split_into_chunks function text_chunks=split_into_chunks(sentences, breakpoints) print ( f\’Number of semantic blocks: { len (text_chunks)} \’ ) ### OUTPUT ### Number of semantic blocks: 145split_into_chunks Get our sentence list and the breakpoints we found and group the sentences into chunks.

接下来,我们需要为这些块创建嵌入:

创建块嵌入chunk_embeddings=create_embeddings(text_chunks)生成响应:

从顶部块创建用户提示\\ n==========================================================================。=============================================================================================================================================================================================================================================================================================] .message.content)最后,评估:

# Create evaluation prompts evaluation_prompt=f\’User query: {query} \\nAI response:\\n {ai_response.choices[ 0 ].message.content} \\nReal response: {data[ 0 ][ \’ideal_answer\’ ]} \\n {evaluate_system_prompt} \’ # Generate evaluation response using evaluation system prompts and评估提示evaliuation_Response=generate_response(esture_system_prompt,evaluation_prompt)打印评估响应响应打印(evaluation_response.choices.choices.choices [0] .message.content)### ###输出根据评估标准,我将给AI助手助手ai助手a 0.2分。评估者仅给出0.2分

虽然语义块在理论上听起来不错,但这对我们没有帮助。实际上,与简单的固定尺寸块相比,我们的分数下降了!

这表明仅仅改变块策略并不能保证胜利。我们需要采用更复杂的方法。让我们在下一节中尝试其他方法。

简单的 RAG

我们发现语义块原则上是个好主意,但实际上并不能改善我们的结果。

一个问题是,即使是语义定义的块也可能太集中了。他们可能缺乏周围文本中的关键背景。

上下文丰富的工作流程

上下文丰富的搜索通过抓住最匹配的块及其邻居来解决此问题。

让我们看看它在代码中的工作方式。我们需要一个新功能Context_enriched_search来处理检索:

def context_enriched_search(查询,text_chunks,embeddeds,k=1,context_size=1):\’\’\’\’检索最相关的块及其相邻块。 \’\’\’将查询转换为嵌入的矢量query_embedding=create_embeddings(QUERY).data [0] .embeding samelity_scores=[]计算查询和i,每个文本块嵌入I,chunk_embedding中的每个文本块之间的相似度分数cosine_similarity(np.array(query_embedding), np.array(chunk_embedding.embedding)) # Store the index and similarity scores as tuples similar_scores.append((i, Similarity_score)) # Sort the similarity scores in descending order (the highest similarity is preferred) similarity_scores.sort(key=lambda x: x[ 1 ],反向=true)获取最相关块的索引top_index=samelity_scores [0] [0]定义上下文包含的范围,请确保它不小于0或超过text_chunks的长度,text_chunks start=max start=max(0,top_index -top_index -top_index -contect_size) [text_chunks [i] for In Range(start,end)]核心逻辑类似于我们以前的搜索,但它不仅仅是返回单个最佳块,而是在其“窗口”周围爬行。控制我们在双方都包含多少块。

让我们在抹布管道中使用它。我们将跳过文本提取和块步,因为它们与简单的抹布相同。

我们将使用固定尺寸的块,就像在简单的抹布部分中一样,我们将Chunk_size=1000和Override=200保持。

现在产生响应,与以前一样:

从顶部块创建用户提示\\ n==========================================================================。=============================================================================================================================================================================================================================================================================================] .message.content)最后,评估:

创建一个评估提示并生成评估响应评估_PROMPT=f\’user query: {query} \\ nai响应: \\ n {ai_response.choices.choices [0] .message.content} {evaliuate_system_prompt}\’evaluituy_response=generate_response(everuate_system_prompt,evaluation_prompt)print(evaluation_response.choices.choices.choices.choices [0] .Message.content)### utut ### utut ### evaliation Criteria,我将为AI助理提供0.6标记。这次,我们得到的评估得分是0.6!

这是对简单抹布(0.5)和语义块(0.1)的显着改善。

通过包括相邻的块,我们为LLM提供了更多的工作背景,并提供了更好的答案。

我们仍然不是完美的,但是我们肯定正在朝着正确的方向前进。这显示了上下文对检索的重要性。

语义分块

我们已经看到,通过包括相邻块来添加上下文是有帮助的。但是,如果块本身缺乏重要信息怎么办?

通常,文档具有清晰的结构化标题,标题和字幕,可提供关键背景信息。上下文块标头(CCH)利用了此结构。

上下文块标头

这个想法很简单:在创建嵌入之前,我们首先在每个块之前添加一个描述性标题。这个标题就像一个迷你夏令部,为检索系统(和LLM)提供了更多可用信息。

GENTATE_CHUNK_HEADER函数分析每条文本,并生成简洁而有意义的标题以总结其内容。这有助于有效地组织和检索相关信息。

碎片提取的文本,生成标题text_chunks_with_headers=chunk_text_with_headers(extracted_text,1000,200)打印样本以查看它的外观(\’带有header3:\’示例块的header:\’)print(\’header:\’,header:\’,text_chunks_with_headsefter_headers newn 33\’\’ text_chunks_with_headers [0] [\’text\’])###输出###带header: header3: AI的影响的示例块:人工智能的描述自从…以来一直是社会的重要组成部分。看到每个块现在都有一个标题和原始文本?这是我们将要使用的增强数据。

让我们现在看一下嵌入。我们将为标题和文本创建嵌入:

为tqdm中的每个块嵌入=[]生成嵌入式(标题和文本)(tex_chunks_with_headers,desc=\’生成嵌入\’): text_embedding=create_embeddings(create_embeddings) :块[\’header\’],\’text\’:块[\’text\’],\’嵌入\’: text_embedding,\’header_embedding\’:\’: header_embedding})我们通过块循环,将标题和文本的嵌入并存储在一起。这提供了两种方法,使块与检索系统查询的查询相匹配。

由于Semantic_search可以使用嵌入,因此我们只需要确保正确嵌入标题和文本块即可。这样,当我们执行搜索时,模型可以同时考虑高级摘要(标题)和详细信息(块文本)以找到最相关的信息。

测试 18 种 RAG 技术以找到最佳技术(1/2)

现在,让我们修改搜索步骤,不仅返回匹配块,而且还要修改其标题以获得更好的上下文并生成响应。

使用查询和新嵌入来执行语义搜索top_chunks=smantic_search(查询,嵌入式,k=2)基于顶部块创建用户提示。注意:无需添加标题,因为上下文创建了user_prompt=\’\\ n\’。 \\ N=============================================================================================================================================================================================================================================================================================================================================================================(ai_response.choices [0] .message.content)###输出###评估得分:0.5这次我们的评估得分为0.5!

通过添加这些上下文标题,我们为系统提供了一个更好的机会,可以找到正确的信息,并为LLM提供更好的机会来生成完整而准确的答案。

这显示了在进入检索系统之前增强数据的力量

。我们没有改变核心 RAG 管道,但我们让数据本身更具信息量。

Document Augmentation 文档增强

我们已经了解了在块周围添加上下文(使用邻居或标题)可以带来哪些帮助。现在,让我们尝试一种不同的增强方法:从文本块中生成问题。

这个想法是,这些问题可以作为替代“查询”,可能比原始文本块本身更符合用户的意图。

文档增强工作流程

我们在分块和嵌入创建之间添加这一步。我们可以简单地为此使用 generate_questions 函数。它需要 text_chunk 并返回许多可以使用它生成的问题。

让我们首先看看如何通过问题生成实现文档增强:

# 处理文档(提取文本、创建块、生成问题、构建向量存储) text_chunks, vector_store = process_document( pdf_path, chunk_size= 1000 , chunk_overlap= 200 , questions_per_chunk= 3 ) print ( f\”Vector store contains { len (vector_store.texts)} items\” ) ### 输出 ### Vector store 包含214 个项目在这里,process_document函数可以完成所有工作。它接受pdf_path、chunk_size、overlap和questions_per_chunk,并返回vector_store。

现在,vector_store不仅包括文档的嵌入,还包括生成的问题的嵌入。

现在,我们可以像以前一样使用这个进行语义搜索vector_store。我们在这里使用一个简单的函数来查找相似的向量。

# 执行语义搜索,找到相关内容search_results = semantic_search(query, vector_store, k= 5 ) print ( \”Query:\” , query) print ( \”\\nSearch Results:\” ) # 按类型组织结果chunk_results = [] question_results = [] for result in search_results: if result[ \”metadata\” ][ \”type\” ] == \”chunk\” : chunk_results.append(result) else : question_results.append(result这里最重要的变化是我们如何处理搜索结果。现在我们的向量存储中有两种类型的项目:原始文本块和生成的问题。此代码将它们分开,因此我们可以看到哪种类型的内容与查询最匹配。

最后的步骤,生成上下文然后进行评估:

# 从搜索结果准备上下文context = prepare_context(search_results) # 生成响应response_text = generate_response(query, context) # 从验证数据中获取参考答案reference_answer = data[ 0 ][ \’ideal_answer\’ ] # 评估响应evaluation = assesse_response(query, response_text, reference_answer) print ( \”\\nEvaluation:\” ) print (evaluation) ### OUTPUT ###根据评估标准,我会给AI 助手的回答分配0.8分。我们的评估显示分数在0.8左右!

生成问题并将其添加到我们的可搜索索引中使我们的性能再次得到提升。

有时候,问题似乎比原始文本块更能表达信息需求。

Query Transformation 查询转换

到目前为止,我们一直专注于改进 RAG 系统使用的数据。但是查询本身呢?

通常,用户提出问题的方式并不是搜索知识库的最佳方式。查询转换旨在解决此问题。我们将探索三种不同的方法:

查询重写:使查询更加具体和详细。后退提示:创建更广泛、更通用的查询来检索背景内容。子查询分解:将复杂的查询分解为多个更简单的子查询。查询转换工作流

让我们看看这些转换的实际效果。我们将使用标准测试查询:

# 查询重写rewritten_query = rewrite_query(query) # 后退提示step_back_query = generate_step_back_query(query)generate_step_back_query与重写相反:它创建一个更广泛的查询,可能会检索有用的背景信息。

测试 18 种 RAG 技术以找到最佳技术(1/2)

最后,子查询分解:

# 子查询分解sub_queries = decompose_query(query, num_subqueries= 4 )decompose_query将原始查询分解为几个更小、更集中的问题。其理念是,这些子查询组合在一起,可能比任何单个查询更好地涵盖原始查询的意图。

现在,为了了解这些转换如何影响我们的 RAG 系统,让我们使用一个结合了所有以前方法的函数:

def rag_with_query_transformation ( pdf_path, query, transformation_type= None ): \”\”\” 使用可选的查询转换运行完整的 RAG 管道。Args : pdf_path(str):PDF 文档的路径 query(str):用户查询 transformation_type(str):转换类型(无、\’rewrite\’、\’step_back\’ 或 \’decompose\’) 返回: Dict:包括查询、转换后的查询、上下文和响应的结果 \”\”\” # 处理文档以创建向量存储 vector_store = process_document(pdf_path) # 应用查询转换和搜索 if transformation_type: # 使用转换后的查询执行搜索 results = formed_embeddings(query, vector_store, transformation_type) else: # 执行不进行转换的常规搜索 query_embeddings = create_embeddings(query) results = vector_store.similarity_search(query_embedding, k= 3 ) # 从搜索结果中合并上下文 context = \”\\n\\n\” .join([ f\”PASSAGE {i+ 1 } :\\n {result[ \’text\’ ]} \” for i, result in enumerate (results)]) # 根据查询和组合上下文生成响应 response = generate_response(query, context) # 返回包括原始查询、转换类型、上下文和响应的结果 return { \”original_query\” : query, \”transformation_type\” : transformation_type, \”context\” : context, \”response\” : response }evaluate_transformations函数通过不同的查询转换技术(重写、后退和分解)运行原始查询,然后比较它们的输出。

这有助于我们了解哪种方法可以检索最相关的信息以获得更好的响应。

# 运行评估evaluation_results = assesse_transformations(pdf_path, query, reference_answer) print (evaluation_results) ### 输出 ###评估分数:0.5评估分数为0.5。

这表明我们的查询转换技术并不总是优于简单的方法。

虽然查询转换功能非常强大,但它们并不是灵丹妙药。有时,原始查询已经是格式正确的,试图“改进”它实际上可能会让事情变得更糟。

Reranker 重排器

我们尝试改进数据(使用分块策略)和查询(使用转换)。现在,让我们关注检索过程本身。简单的相似性搜索通常会返回相关和不相关的结果。

Reranker

重新排序是第二遍,对最初检索到的结果进行重新排序,将最佳结果放在最上面。

该rerank_with_llm函数获取初始检索到的块并使用 LLM 根据相关性对其进行重新排序。这有助于确保最有用的信息首先出现。

重新排序后,我们称之为的最终函数将generate_final_response获取重新排序的块,将其格式化为提示,然后将其发送到 LLM 以生成最终响应。

def rag_with_reranking ( query, vector_store, reranking_method= \”llm\” , top_n= 3 , model= \”meta-llama/Llama-3.2-3B-Instruct\” ): \”\”\” 完成包含重新排名的 RAG 管道。 \”\”\” # 创建查询嵌入 query_embedding = create_embeddings(query) # 初始检索(获取比重新排名所需更多的数据) initial_results = vector_store.similarity_search(query_embedding, k= 10 ) # 应用重新排名 if reranking_method == \”llm\” : reranked_results = rerank_with_llm(query, initial_results, top_n=top_n) elif reranking_method == \”keywords\” : reranked_results = rerank_with_keywords(query, initial_results, top_n=top_n) # 我们不使用它。 else : # 不重新排名,只使用初始检索中的顶级结果 reranked_results = initial_results[:top_n] # 结合重新排名结果中的上下文 context = \”\\n\\n===\\n\\n\” .join([result[ \”text\” ] for result in reranked_results]) # 根据上下文生成响应 response = generate_response(query, context, model) return { \”query\” : query, \”reranking_method\” : reranking_method, \”initial_results\” : initial_results[:top_n], \”reranked_results\” : reranked_results, \”context\” : context, \”response\” : response }它需要一个query、一个vector_store(我们已经创建了)和一个reranking_method。我们使用“llm”进行基于 LLM 的重新排序。该函数执行初始检索,调用rerank_with_llm以重新排序结果,然后生成响应。

在笔记本中定义了rerank_with_keywords但我在这里没有使用它。

让我们运行它并看看它是否能改善我们的结果:

# 使用基于 LLM 的重新排名运行 RAGllm_reranked_result = rag_with_reranking(query, vector_store, reranking_method= \”llm\” ) # 评估。evaluation_prompt = f\”用户查询:{query} \\nAI 响应:\\n {llm_reranked_result[ \’response\’ ]} \\nTrue 响应:{reference_answer} \\n {evaluate_system_prompt} \”evaluation_response = generate_response(evaluate_system_prompt, evaluation_prompt) print (evaluation_response.choices[ 0 ].message.content) ### OUTPUT ###评估分数为 0.7我们的评估分数现在约为0.7!

重新排序为我们带来了显著的改进。通过使用 LLM 直接对每个检索到的文档的相关性进行评分,我们能够优先考虑用于生成响应的最佳信息。

这是一项强大的技术,可以显著提高 RAG 系统的质量。

用户评论


余笙南吟

这篇博客看起来很有趣!我一直在想尝试RAG技术,看看能不能提升我的项目效率。你们是怎么选取这18 种技术的?有什么评判标准吗?

    有12位网友表示赞同!


命里缺他

我以前也试用过很多RAG技术,但总是感到不太理想,不知道你们的测试结果会让我眼前一亮吗?期待看到最终结果!

    有16位网友表示赞同!


花开丶若相惜

真是太棒了!能详细说明一下每个技术点位的优劣势吗?这样我们更容易理解和选择合适的RAG技术!

    有12位网友表示赞同!


。婞褔vīp

这18 种RAG技术名字听起来有点眼花缭乱,感觉测试比较复杂。希望作者能给出更清晰的解释,方便对新手友好一点!

    有20位网友表示赞同!


残花为谁悲丶

我也在找合适的RAG技术,想了解一下哪些技术更适用于自然语言理解的任务?也许这篇测试结果能帮我找到答案! 期待看到第二部分内容!

    有9位网友表示赞同!


满心狼藉

我感觉这篇文章的内容太过主观了,没有给出具体的评价指标和对比数据。希望作者能够提供更多的数据支撑来证明技术的优劣!

    有18位网友表示赞同!


莫阑珊

标题说“最佳技术”,我觉得这个结论很武断。不同的RAG技术适用于不同的场景,应该注重实际应用效果而不是简单排名

    有11位网友表示赞同!


ˉ夨落旳尐孩。

非常期待这篇博客的第二部分!很想了解最终结果是哪种RAG技术最出色,以及它在哪些场景下表现最好!

    有14位网友表示赞同!


怀念·最初

我最近也在研究RAG技术,对你们测试的结果非常感兴趣!希望能看到更详细的技术分析和案例应用实例!

    有5位网友表示赞同!


聽風

这篇文章很全面地介绍了18 种RAG技术,对新手朋友来说很有帮助。但我个人觉得,文章可以加入一些图表的对比来更直观地展示技术差异。

    有9位网友表示赞同!


冷眼旁观i

我非常同意作者的观点,选择合适的RAG技术对于项目成功至关重要!希望这篇文章能帮助大家找到适合自己的最佳技术!

    有16位网友表示赞同!


陌上蔷薇

我有点好奇,这些RAG技术的应用场景是什么? 比如是用于客服、搜索引擎还是其他领域? 可以多加一些解释吗?

    有19位网友表示赞同!


苏樱凉

我一直在用开源的 RAG 技术,不知道有哪些商业化的解决方案更优秀。这篇博文能介绍一些吗?

    有14位网友表示赞同!


全网暗恋者

希望作者未来能分享更多关于RAG技术的应用案例,这样更容易理解它的实际价值!

    有8位网友表示赞同!


清原

这篇博客写的真的太好了! 我一直在找寻合适的RAG技术来提升我的项目, 期待看到第二部分的内容!

    有18位网友表示赞同!


莫失莫忘

感觉这篇测试只停留在理论层面,缺乏更具体的实践案例分析。能不能在后续文章中分享一些实战经验呢?

    有14位网友表示赞同!


孤廖

希望第二部分能介绍一下如何搭建及配置这些RAG技术,方便新手学习和应用!

    有14位网友表示赞同!

原创文章,作者:匿名,如若转载,请注明出处:https://www.xinyuspace.com/20049.html

(0)
匿名匿名
上一篇 3小时前
下一篇 3小时前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注