网站开发建设账务处理程序,汕头 网站设计,旅游开发公司网站建设方案书,定制做网站平台如果你正在构建基于大语言模型#xff08;LLMs#xff09;的 AI 应用#xff0c;那么用你的特定数据来“锚定”生成的文本响应#xff0c;是获得准确答案的关键。检索增强生成#xff08;RAG#xff09; 将大语言模型与外部知识源#xff08;如向量数据库#xff09;连…如果你正在构建基于大语言模型LLMs的 AI 应用那么用你的特定数据来“锚定”生成的文本响应是获得准确答案的关键。检索增强生成RAG将大语言模型与外部知识源如向量数据库连接起来。这使得模型在生成回复之前能够找到相关的事实依据。检索过程的质量是影响应用程序性能的最大因素之一。许多开发者专注于挑选合适的向量数据库或嵌入模型Embedding Model但最重要的一步往往是你如何准备数据本身。这就是分块Chunking发挥作用的地方。接下来我们将回顾一些基本的分块策略从基础到高级技术分析它们的权衡取舍并提供为你的 RAG 应用选择正确方法的建议。什么是分块简单来说分块是将大型文档分解为更小、更易于管理的片段称为“块”或 chunks的过程。这是准备数据以供大语言模型使用时的关键第一步。主要原因是 LLM 具有有限的上下文窗口context window这意味着它们一次只能处理一定量的文本。如果上下文窗口中的文本过多重要的细节就会丢失从而导致答案不完整或不准确。分块通过创建更小、更聚焦的内容片段来解决这个问题使 LLM 能够利用这些片段回答用户的查询而不会迷失在无关的信息中。每个块的大小、内容和语义边界都会影响检索性能因此决定使用哪种技术会对 RAG 系统的下游性能产生巨大的影响。为什么分块对 RAG 如此重要分块可以说是 RAG 性能中最重要的因素。你如何拆分文档会直接影响系统找到相关信息并给出准确答案的能力。当一个 RAG 系统表现不佳时问题往往不在于检索器而在于块。如果是在准备得很糟糕的数据上进行搜索即使是完美的检索系统也会失败。这就产生了一个根本性的挑战你的分块既要便于向量搜索找到又要给 LLM 提供足够的上下文来生成有用的答案。1. 优化检索准确性第一步是确保你的系统能够在向量数据库中找到正确的信息。向量搜索通过比较用户查询与分块的嵌入向量来实现这一点。分块过大的问题在于它们通常混合了多种观点子主题可能会丢失或变得模糊。这就好比试图通过平均所有章节的内容来描述一本书。这会产生一个嘈杂的、“平均化”的嵌入向量无法清晰地代表任何单一主题从而使向量检索步骤难以找到所有相关的上下文。分块小而聚焦则能捕捉到一个清晰的观点。这会产生一个精确的嵌入向量能够编码内容的细微差别。这使得系统更容易找到正确的信息。2. 为生成保留上下文当系统找到最佳的分块后它们会被传递给 LLM。这就是上下文质量决定输出响应质量的地方。这有一个简单的测试方法如果一个分块单独阅读时对你来说有意义那么它对 LLM 来说也会有意义。分块过小无法通过这个测试。想象一下从一篇研究论文的中间读一个单独的句子——如果没有更多的上下文即使是人类也很难理解发生了什么。分块过大则会产生另一个问题。由于注意力稀释attention dilution和“迷失在中间lost in the middle”效应LLM 的性能会随着上下文输入的变长而下降。也就是说模型很难访问埋藏在长上下文中间的信息尽管它能较好地处理开头和结尾的信息。随着上下文长度的增加模型的注意力在所有输入上变得过于分散使其在寻找相关信息时变得不那么准确导致推理错误增多并增加了产生幻觉hallucinating的可能性。分块的最佳平衡点 (The Sweet Spot)你希望在保留作者的**“思路train of thought”的同时创建足够小的分块以进行精确检索但又足够完整以给 LLM 提供全部上下文。这是上下文工程context engineering**的一部分以一种 LLM 能够理解并据此生成准确响应的方式准备输入。当你找准了这个平衡点几件事会得到改善提高检索质量通过创建聚焦的、语义完整的分块你使检索系统能够精确定位查询最相关的上下文。管理 LLM 的上下文窗口有效的分块确保只有相关数据被传递给 LLM有助于避免过长的上下文长度混淆模型。减少幻觉通过向模型提供小的、高度相关的分块你将模型的回答锚定在事实数据中最大限度地降低了它编造信息的风险。提高效率并降低成本处理较小的分块速度更快计算效率更高这能带来更快的响应时间和更低的 LLM 使用成本。预分块 (Pre-Chunking) vs 后分块 (Post-Chunking)既然我们已经涵盖了分块的基本困境我们可以探讨在 RAG 管道中何时执行分块步骤。这个决定导致了两种主要策略标准的预分块和一种更先进的替代方案后分块。预分块是最常见的方法。它异步处理文档在嵌入和存储到向量数据库之前将它们分解成更小的部分。这种方法需要预先决定分块的大小和边界但由于所有分块都是预先计算和建立索引的因此能够在查询时实现快速检索。后分块采取了不同的方法它首先嵌入整个文档然后仅在实际检索到文档后才在查询时进行分块。分块结果可以被缓存因此随着频繁访问的文档积累起缓存的块系统会随着时间的推移变得更快。这种方法避免了对可能永远不会被查询的文档进行分块同时允许根据具体查询采用更动态、上下文感知的分块策略。然而它在首次访问时会引入延迟并需要额外的基础设施决策。分块策略最好的分块策略取决于你正在处理的文档类型以及你的 RAG 应用的需求。以下方法主要针对基于文本的文档。对于其他格式如 PDF需要额外的步骤将其转换为干净的文本。关于处理 PDF在对 PDF 进行分块之前你需要干净、结构化的文本。PDF 是一种视觉格式因此提取文本可能很棘手。分栏、表格、页眉或扫描页面会使文本提取变得不可靠。对于扫描文档需要光学字符识别 (OCR)来获取文本。专家建议最可靠的方法是首先将 PDF 转换为结构化格式如 Markdown。这个预处理步骤确保你在应用以下任何分块策略之前拥有干净、逻辑有序的文本。简单分块技术固定大小分块 (Fixed-Size Chunking / Token Chunking)固定大小分块是最简单、最直接的方法。它将文本分割成预定大小的块通常以 Token模型处理文本的单位或字符来衡量。这种方法易于实现但不尊重文本的语义结构。因此它可能会在句子甚至单词的中间切断导致尴尬的断裂。一个常见的解决方案是**分块重叠 (Chunk Overlap)**即一个分块末尾的一些 Token 会在下一个分块的开头重复出现。这保留了原本可能在分块边界处丢失的上下文。关键考虑因素分块大小 (Chunk Size)一个常见的起点是与嵌入模型的上下文窗口对齐的大小。较小的分块可能更适合捕捉细粒度的细节而较大的分块可能更适合理解更广泛的主题。分块重叠 (Chunk Overlap)典型的重叠比例是分块大小的 10% 到 20%。适用场景快速原型设计以及获取 RAG 系统性能的基准线。这是最简单的起点特别是当你处理结构不一致的文档或尚不确定正在处理什么内容时。只要确保使用适当的重叠10-20%这样你就不会因信息被分割到不同块中而丢失重要上下文。代码示例from typing import Listimport re# Split the text into units (words, in this case)def word_splitter(source_text: str) - List[str]: source_text re.sub(\s, , source_text) # Replace multiple whitespces return re.split(\s, source_text) # Split by single whitespacedef get_chunks_fixed_size_with_overlap(text: str, chunk_size: int, overlap_fraction: float 0.2) - List[str]: text_words word_splitter(text) overlap_int int(chunk_size * overlap_fraction) chunks [] for i in range(0, len(text_words), chunk_size): chunk_words text_words[max(i - overlap_int, 0): i chunk_size] chunk .join(chunk_words) chunks.append(chunk) return chunks递归分块 (Recursive Chunking)递归分块是一种更细致的方法。它使用优先级的常用分隔符列表来分割文本例如双换行符用于段落或单换行符用于句子。它首先尝试用优先级最高的分隔符段落来分割文本。如果产生的任何分块仍然太大算法会对该特定分块递归地应用下一个分隔符句子。这种方法适应文档的结构尽可能保持结构相关的单元在一起。它避免了固定大小分块的突然切断并确保分块保留其原始格式的结构。推荐用于非结构化文本文档如文章、博客文章和研究论文。这通常是一个可靠的默认选择因为它尊重文本的自然组织而不是随机分割。代码示例from typing import Listdef recursive_chunking(text: str, max_chunk_size: int 1000) - List[str] # Base case:if text is small enough, returnas single chunk if len(text) max_chunk_size: return [text.strip()] if text.strip() else [] # Try separators in priority order separators [\n\n, \n, . , ] for separator in separators: if separator in text: parts text.split(separator) chunks [] current_chunk for part in parts: # Check if adding this part would exceed the limit test_chunk current_chunk separator part if current_chunk else part if len(test_chunk) max_chunk_size: current_chunk test_chunk else: # Save current chunk and start new one if current_chunk: chunks.append(current_chunk.strip()) current_chunk part # Add the final chunk if current_chunk: chunks.append(current_chunk.strip()) # Recursively process any chunks that are still too large final_chunks [] for chunk in chunks: if len(chunk) max_chunk_size: final_chunks.extend(recursive_chunking(chunk, max_chunk_size)) else: final_chunks.append(chunk) return [chunk for chunk in final_chunks if chunk] # Fallback: split by character limit if no separators work return [text[i:i max_chunk_size] for i in range(0, len(text), max_chunk_size)]基于文档的分块 (Document-Based Chunking)基于文档的分块利用文档的内在结构。它不是依赖通用的分隔符而是根据文档特定格式的元素来解析文档。例如Markdown:按标题#, ##分割以捕获章节或子章节。HTML:按标签p,div分割以保留逻辑内容块。PDF:预处理后如 OCR 或转换为 Markdown按页眉、段落、表格或其他结构元素分割。程序代码:按函数或类例如 Python 中的def分割以保持代码的逻辑单元。使用这种方法分块保持与文档逻辑组织的对齐这种组织通常也与语义含义相关联。LangChain 和 LlamaIndex 都为各种文档类型包括 Markdown、代码和 JSON提供了专门的分割器。适用场景高度结构化的文档其格式可以轻松定义逻辑分隔。非常适合 Markdown、HTML、源代码或任何具有清晰结构标记的文档。代码示例from typing import Listimport redef markdown_document_chunking(text: str) - List[str]: # Split by markdown headers (# ## ### etc.) header_pattern r^#{1,6}\s.$ lines text.split(\n) chunks [] current_chunk [] for line in lines: # Check if this line is a header if re.match(header_pattern, line, re.MULTILINE): # Save previous chunk if it has content if current_chunk: chunk_text \n.join(current_chunk).strip() if chunk_text: chunks.append(chunk_text) # Start new chunk with this header current_chunk [line] else: # Add line to current chunk current_chunk.append(line) # Add final chunk if current_chunk: chunk_text \n.join(current_chunk).strip() if chunk_text: chunks.append(chunk_text) return chunks高级分块技术语义分块 (Semantic Chunking / Context-Aware Chunking)语义分块从传统的基于规则的分割转变为基于意义的分割。这种更高级的技术不是依赖字符数或文档结构而是根据语义相似性来划分文本。该过程包括句子分割将文本分解为单独的句子。嵌入生成将每个句子转换为向量嵌入。相似度分析比较嵌入向量以检测语义断点主题发生变化的地方。分块形成在这些断点之间创建新的分块。结果是一组高度连贯的语义块每个块包含一个独立的想法或主题。这种方法非常适合密集的非结构化文本在这些文本中你希望保留论点或叙述的逻辑流。推荐用于密集的非结构化文本以保留一个想法的完整语义上下文。这种方法非常适合学术论文、法律文件或长篇故事。这些文本并不总是使用清晰的分隔符如段落来显示主题变化。当你处理复杂的内容且语义边界与文档结构不完全一致时这种方法非常棒。基于 LLM 的分块 (LLM-Based Chunking)基于 LLM 的分块使用大语言模型 (LLM)来决定如何分割文本。LLM 不是依赖固定规则或基于向量的相似度分数而是处理文档并生成语义连贯的分块通常还会添加额外的上下文、摘要或其他信息。这可以通过以下方式完成识别命题 (Identifying propositions)将文本分解为清晰、逻辑的陈述。部分摘要 (Summarizing sections)归纳成更小的、保留原意的分块。突出关键点 (Highlighting key points)确保捕获最相关的信息。结果是一组比传统方法更准确地保留语义意义的分块。这使得基于 LLM 的分块成为检索增强生成 (RAG) 最强大的策略之一。适用场景检索质量至关重要且预算不是主要顾虑的高价值、复杂文档。非常适合法律合同、研究论文、合规文件或企业知识库。这种方法可以生成概括或突出关键思想的分块但也伴随着权衡。与其他分块技术相比它是计算成本最高且速度最慢的方法。代理式分块 (Agentic Chunking)代理式分块将基于 LLM 的分块概念更进一步。AI 代理不是应用单一方法而是动态决定如何分割你的文档。它会查看整个文档包括其结构、密度和内容。然后它决定使用最佳的分块策略或策略组合。例如代理可能会看到一个文档是 Markdown 文件然后按标题分割文件。它也可能发现一个更密集的文档需要命题式的方法。它甚至可以用元数据标签丰富分块以实现更高级的检索。这些“LLM 驱动的方法”可以创建非常清晰且内容丰富的分块。然而它们需要大量的计算能力成本更高。通常每个文档需要多次调用强大的模型。适用场景高风险的 RAG 系统你需要尽可能最好的分块且成本不是决定性因素。当你需要针对每个文档的独特特征量身定制自定义分块策略时这是完美的选择。后期分块 (Late Chunking)后期分块是一种略有不同的技术旨在解决其他分块策略中的一个常见问题上下文丢失。在其他分块技术中当你先分割文档然后创建嵌入时每个分块都会变得孤立。这可能导致分块内的上下文模棱两可或丢失而这些上下文是在文档前面的部分解释或引用的。后期分块反其道而行之。你不是先分割而是首先将整个文档输入到一个长上下文嵌入模型中。这创建了详细的、Token 级别的嵌入能够理解全貌。只有在那之后你才将文档分割成块。当你为每个分块创建嵌入时你使用的是已经包含完整上下文的 Token 嵌入。你只需平均该分块的相关 Token 嵌入。这意味着每个分块都保留了关于整个文档的上下文。适用场景在检索质量依赖于理解分块与整个文档之间关系的 RAG 系统中使用。这对技术文档、研究论文 or 法律文本非常有用。这些文档的章节经常引用其他地方提到的想法、方法或定义。这有助于捕捉常规分块方法会错过的文档不同部分之间的联系。分层分块 (Hierarchical Chunking)分层分块对于非常大和复杂的文档来说可能是一个游戏规则改变者。这个想法非常直接你在不同的细节层级上创建多层分块。在顶层你创建大的分块总结广泛的章节或主题如标题和摘要。在下一层你将这些章节分割成逐渐变小的分块以捕捉更精细的细节如论点、例子或定义。这让你的 RAG 系统可以从高层概览开始然后在用户需要更多细节时深入到具体内容。LlamaIndex 的HierarchicalNodeParser使这种方法的实现变得容易。适用场景非常大和复杂的文档如教科书、法律合同或广泛的技术手册。当你需要回答高层总结性问题和高度具体、细节性查询时此策略非常理想。它为你提供了广阔上下文和细粒度访问之间的良好中间地带虽然比基本分割方法更复杂但没有完全的代理式分块那么复杂。自适应分块 (Adaptive Chunking)自适应分块技术根据文档的内容动态调整关键参数如分块大小和重叠。这种方法不是对整个文档应用单一、固定的规则而是将文本视为变化的景观。它可能会使用机器学习模型来分析不同部分的语义密度和结构。例如它可以自动为复杂、信息丰富的段落创建更小、更细粒度的分块以捕捉细节同时为更一般的介绍性部分使用更大的分块。目标是创建大小和边界针对其包含的具体内容量身定制的分块从而实现更精确和上下文感知的检索。这与代理式分块不同后者由代理决定使用哪种分块策略而不仅仅是调整一种策略的参数。适用场景具有变化和不一致内部结构的文档。想象一份长报告其中包含密集的技术段落和稀疏的叙述部分。自适应策略在这里表现出色因为它避免了“一刀切”的问题。它可以在同一文档中为复杂部分创建细小的颗粒状分块以捕捉每个细节并为较简单的文本创建较大的分块以保留上下文。如何选择最佳分块策略没有单一的“最佳”分块方法最优策略始终取决于你的具体用例。但在深入研究不同技术之前要问的最重要的问题是“我的数据真的需要分块吗”分块旨在分解长的、非结构化的文档。如果你的数据源已经包含小的、完整的信息片段如常见问题解答FAQ、产品描述或社交媒体帖子通常不需要对它们进行分块。分块甚至可能引起问题。目标是创建有意义的语义单元如果你的数据已经是这种格式你就已经准备好进入嵌入阶段了。一旦你确认文档足够长可以从分块中受益你可以使用以下问题来指导你选择策略我的文档性质是什么它们是高度结构化的如代码或 JSON还是非结构化的叙述性文本我的 RAG 系统需要什么级别的细节它需要检索具体的、细粒度的事实还是总结更广泛的概念我使用的是哪种嵌入模型输出向量的大小是多少维度越多存储更细粒度信息的能力越强用户查询会有多复杂它们是需要小的、目标明确的分块的简单问题还是需要更多上下文的复杂问题分块策略工作原理复杂度最佳适用场景示例固定大小 (Fixed-Size)按 Token 或字符计数分割。低小型或简单文档或当速度最重要时。会议记录、短博文、邮件、简单 FAQ递归 (Recursive)重复分割文本直到符合所需大小通常保留一些结构。中需要保持一定结构但速度仍然重要的文档。研究文章、产品指南、简短报告基于文档 (Document-Based)将每个文档视为一个分块或仅在文档边界分割。低短小、独立的文档集合。新闻文章、客户支持工单、短合同语义 (Semantic)在自然意义边界主题、想法处分割文本。中-高技术、学术或叙述性文档。科学论文、教科书、小说、白皮书基于 LLM (LLM-Based)使用语言模型根据上下文、意义或任务需求决定边界。高意义感知分块能改善下游任务如摘要或问答的复杂文本。长报告、法律意见书、医疗记录代理式 (Agentic)让 AI 代理根据意义和结构决定如何分割。非常高需要自定义策略的复杂、微妙文档。监管文件、多章节合同、公司政策后期 (Late)先嵌入整个文档然后从中推导分块嵌入。高分块需要感知完整文档上下文的用例。案例研究、综合手册、长篇分析报告分层 (Hierarchical)将文本分解为多个层级章节 → 段落 → 句子。保持结构完整。中大型、结构化文档如手册、报告或合同。员工手册、政府法规、软件文档自适应 (Adaptive)使用 ML 或启发式方法动态调整分块大小和重叠。高结构和长度各异的混合数据集。来自多源的数据博客、PDF、邮件、技术文档代码 (Code)按逻辑代码块函数、类、模块分割同时保留语法。中源代码、脚本或编程文档。Python 模块、JavaScript 项目、API 文档分块工具和库在为 RAG 应用程序设置数据摄取管道时你经常面临分块的经典权衡你可以依赖专用库以获得速度和易用性或者自己构建逻辑以获得完全控制。使用库幸运的是你不必从头开始。LLM 社区经常使用两个强大的开源库LangChain和LlamaIndex每一个都有不同的分块方法LangChain:一个用于构建 LLM 应用程序的广泛框架。其灵活的TextSplitters使其易于将分块集成为更大系统如多步 AI 代理的一部分。最适合模块化工作流其中分块只是拼图的一块。LlamaIndex:专为 RAG 管道设计。其复杂的NodeParsers生成针对摄取和检索进行优化的“节点Nodes”。最适合高性能、以数据为中心的检索系统。chonkie:一个轻量级、专用的分块库专注于分割文本。它提供各种分块策略如SemanticChunker并且易于与其他 RAG 库集成。最适合那些你想要简单、专注的解决方案而不需要大型框架开销的项目。手动实现使用库的替代方案是自己实现分块逻辑。像固定大小或递归分块这样的策略在 Python 中很容易编写代码这让你对数据处理方式拥有完全的权威并避免在项目中添加外部依赖。最适合那些希望避免添加大型库、需要实现高度自定义分块策略或需要数据管道完全透明的项目。如何在生产环境中优化 RAG 的分块大小在生产环境中优化分块大小需要大量的测试和审查。以下是你可以采取的一些步骤从通用的基准策略开始例如固定大小分块。一个好的起点是 512 个 Token 的分块大小和 50-100 个 Token 的重叠。这为你提供了一个稳固的基准易于复现并与其他分块策略进行比较。尝试不同的分块方法通过调整分块大小和重叠等参数找到最适合你数据的方法。测试检索效果通过运行典型的查询并检查命中率 (hit rate)、精确率 (precision) 和召回率 (recall)等指标看看哪种策略效果最好。引入人工审查检查检索到的分块和 LLM 生成的回复——他们的反馈会捕捉到指标可能遗漏的问题。持续监控生产环境中 RAG 系统的性能并准备好根据需要迭代你的分块策略。如何学习大模型 AI 由于新岗位的生产效率要优于被取代岗位的生产效率所以实际上整个社会的生产效率是提升的。但是具体到个人只能说是“最先掌握AI的人将会比较晚掌握AI的人有竞争优势”。这句话放在计算机、互联网、移动互联网的开局时期都是一样的道理。我在一线互联网企业工作十余年里指导过不少同行后辈。帮助很多人得到了学习和成长。我意识到有很多经验和知识值得分享给大家也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限很多互联网行业朋友无法获得正确的资料得到学习提升故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。第一阶段10天初阶应用该阶段让大家对大模型 AI有一个最前沿的认识对大模型 AI 的理解超过 95% 的人可以在相关讨论时发表高级、不跟风、又接地气的见解别人只会和 AI 聊天而你能调教 AI并能用代码将大模型和业务衔接。大模型 AI 能干什么大模型是怎样获得「智能」的用好 AI 的核心心法大模型应用业务架构大模型应用技术架构代码示例向 GPT-3.5 灌入新知识提示工程的意义和核心思想Prompt 典型构成指令调优方法论思维链和思维树Prompt 攻击和防范…第二阶段30天高阶应用该阶段我们正式进入大模型 AI 进阶实战学习学会构造私有知识库扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架抓住最新的技术进展适合 Python 和 JavaScript 程序员。为什么要做 RAG搭建一个简单的 ChatPDF检索的基础概念什么是向量表示Embeddings向量数据库与向量检索基于向量检索的 RAG搭建 RAG 系统的扩展知识混合检索与 RAG-Fusion 简介向量模型本地部署…第三阶段30天模型训练恭喜你如果学到这里你基本可以找到一份大模型 AI相关的工作自己也能训练 GPT 了通过微调训练自己的垂直大模型能独立训练开源多模态大模型掌握更多技术方案。到此为止大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗为什么要做 RAG什么是模型什么是模型训练求解器 损失函数简介小实验2手写一个简单的神经网络并训练它什么是训练/预训练/微调/轻量化微调Transformer结构简介轻量化微调实验数据集的构建…第四阶段20天商业闭环对全球大模型从性能、吞吐量、成本等方面有一定的认知可以在云端和本地等多种环境下部署大模型找到适合自己的项目/创业方向做一名被 AI 武装的产品经理。硬件选型带你了解全球大模型使用国产大模型服务搭建 OpenAI 代理热身基于阿里云 PAI 部署 Stable Diffusion在本地计算机运行大模型大模型的私有化部署基于 vLLM 部署大模型案例如何优雅地在阿里云私有部署开源大模型部署一套开源 LLM 项目内容安全互联网信息服务算法备案…学习是一个过程只要学习就会有挑战。天道酬勤你越努力就会成为越优秀的自己。如果你能在15天内完成所有的任务那你堪称天才。然而如果你能完成 60-70% 的内容你就已经开始具备成为一名大模型 AI 的正确特征了。这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】