【人工智能】RAG分块

在RAG(检索增强生成)系统中,文档分块(Chunking)是决定系统性能的核心环节,直接影响检索精度和生成质量。分块需平衡语义完整性检索效率上下文保留三大目标。

一、分块的核心标准

1.1 分块基础知识

1. 块大小(Chunk Size)​

  • 推荐范围​:200-500字(通用场景)或1000-2000字(专业文档)。

  • 权衡原则​:

    • 小分块​(<500字):提升检索精确性,但可能丢失上下文连贯性(如技术文档的完整逻辑链)。

    • 大分块​(>1000字):保留丰富上下文,但增加噪声和检索延迟(如法律条文需完整条款)。

2. 块重叠(Chunk Overlap)​

  • 比例​:10%-20%的块大小(如500字块设置50-100字重叠)。

  • 作用​:避免语义断裂(例如句子被切分时,重叠部分携带关键过渡信息)。

3. 切分依据(Splitting Criteria)​

方法

原理

适用场景

固定大小分块

按字符数/词数均匀分割,简单高效

舆情监控、日志分析(速度优先)

语义分块

计算相邻句子嵌入的余弦相似度,相似度骤降处切分(需调阈值)

法律合同、医学报告(高精度需求)

递归分块

先按段落/章节分割,超限块再递归细分

技术手册、企业年报(结构复杂文档)

基于结构分块

按标题/段落标记切分(如Markdown的#,HTML的<section>

API文档、论文(格式规范)

基于LLM的分块

由大模型动态生成语义连贯的块,智能度高

跨领域非结构化文本(资源充足场景)

 ​语义完整性验证​:切分后需确保每个块独立表达完整语义单元(如一个论点或事件描述)。


1.1.1 分块算法的数学原理

1. ​语义相似度计算(核心模型)​
  • 余弦相似度​:衡量文本块间语义关联性
    \text{sim}(A, B) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|}
    • 其中 \mathbf{A}, \mathbf{B} 为句子嵌入向量(如 SBERT 生成)
  • 阈值判定​:当相邻段落相似度低于阈值 \theta(通常 0.7-0.8)时切分新块
2. ​递归分块的空间复杂度
  • 动态规划实现,空间复杂度 O(m+n)m, n 为序列长度)
  • 分割公式:基于文档结构递归划分
    \text{chunk}(D) = \begin{cases} 
    D & \text{if } \text{len}(D) \leq L \\
    \text{chunk}(D_{\text{left}}) \cup \text{chunk}(D_{\text{right}}) & \text{else}
    \end{cases}
    • L 为预设块大小上限
3. ​主题模型分块(LDA)​
  • 潜在狄利克雷分布(Latent Dirichlet Allocation):
    P(\text{topic}_k | \text{chunk}) \propto \prod_{w \in \text{chunk}} P(w | \text{topic}_k)
  • 按主题概率分布聚类句子

1.1.2、五大分块策略的算法实现

1.1.2.1. ​固定大小分块(Fixed-Size Chunking)​
  • 原理​:按字符/词数均匀切分,重叠区缓解语义割裂
  • 数学方法​:滑动窗口均值分割
  • 代码实现​(Python):
    def fixed_chunk(text, chunk_size=500, overlap=50):words = text.split()chunks = []for i in range(0, len(words), chunk_size - overlap):chunk = " ".join(words[i:i + chunk_size])chunks.append(chunk)return chunks
1.1.2.2. ​语义分块(Semantic Chunking)​
  • 原理​:计算相邻句子嵌入的余弦相似度,低于阈值时切分
  • 数学方法​:动态调整块边界以最大化簇内相似度
  • 代码实现​(使用 Sentence-BERT):
    from sentence_transformers import SentenceTransformer
    import numpy as npmodel = SentenceTransformer('all-MiniLM-L6-v2')
    def semantic_chunk(text, threshold=0.75):sentences = [sent.text for sent in nlp(text).sents]embeddings = model.encode(sentences)chunks, current_chunk = [], [sentences[0]]for i in range(1, len(sentences)):cos_sim = np.dot(embeddings[i-1], embeddings[i]) / (np.linalg.norm(embeddings[i-1]) * np.linalg.norm(embeddings[i]))if cos_sim < threshold:chunks.append(" ".join(current_chunk))current_chunk = []current_chunk.append(sentences[i])chunks.append(" ".join(current_chunk))return chunks
1.1.2.3. ​递归分块(Recursive Chunking)​
  • 原理​:按分隔符(段落 > 句子 > 单词)层级切分
  • 数学方法​:贪心算法优先选择最大语义单元
  • 代码实现​(LangChain 内置):
    from langchain_text_splitters import RecursiveCharacterTextSplitter
    text_splitter = RecursiveCharacterTextSplitter(separators=["\n\n", "\n", "。", "?", "!", ". "],  # 优先级降序chunk_size=300,chunk_overlap=30
    )
    chunks = text_splitter.split_text(text)
1.1.2.3.1、递归分块原理与实现

1. 算法原理

递归分块采用分层分割策略,按优先级迭代使用分隔符切分文本:

  • 分隔符优先级​:从大粒度(章节)到小粒度(句子)逐级切分
    \text{Separators} = [\text{"\n\n"}, "\n", "。", ". ", "?", "!", " "]
  • 终止条件​:块长度 ≤ chunk_size(通常512-2000字符)

  • 数学表示​:
    \text{split}(text) = \begin{cases} 
    [text] & \text{if } len(text) \leq \text{chunk\_size} \\
    \text{split}(part_1) \cup \text{split}(part_2) & \text{else}
    \end{cases}

    其中 part_1, part_2 为按最高优先级分隔符切分的子文本

2. 代码实现

LangChain 标准实现

from langchain_text_splitters import RecursiveCharacterTextSplittersplitter = RecursiveCharacterTextSplitter(separators=["\n\n", "\n", "。", "?", "!", ". ", " "],  # 优先级降序chunk_size=500,chunk_overlap=50,      # 块间重叠字符数keep_separator=True    # 保留分隔符
)
chunks = splitter.split_text(long_text)

底层Python实现(递归核心)​

def recursive_split(text, separators, chunk_size, overlap=0):if len(text) <= chunk_size:return [text]# 按当前最高优先级分隔符切分for sep in separators:if sep in text:parts = text.split(sep)chunks = []current_chunk = ""for part in parts:# 添加分隔符(保留语义连贯性)candidate = current_chunk + sep + part if current_chunk else partif len(candidate) > chunk_size:if current_chunk: chunks.append(current_chunk)current_chunk = part  # 开启新块else:  # 单个部分超长chunks.extend(recursive_split(part, separators, chunk_size))else:current_chunk = candidateif current_chunk: chunks.append(current_chunk)return chunks# 无分隔符时强制切分return [text[i:i+chunk_size] for i in range(0, len(text), chunk_size)]

1.1.2.3.2、风险与漏洞分析

1. 核心风险

风险类型

成因

影响案例

语义割裂

在关键逻辑点切分(如“但是”后)

法律条款被分割:“甲方有权...<切分>...但乙方免责” → 曲解原意

敏感信息暴露

重叠区包含隐私数据(如身份证号跨越两分块)

通过重叠区拼接还原完整敏感信息

递归深度爆炸

无分隔符的超长文本(如Base64编码)导致栈溢出

Python递归深度限制(通常1000层)崩溃

注入攻击

恶意构造分隔符(\n\nDROP TABLE users;--

数据库被清空

2. 漏洞场景

  • 医疗报告漏洞​:患者过敏史被分割到两个块:“青霉素过敏” + “史(严重休克)”,生成建议忽略风险。

  • 金融欺诈​:合同条款“不得提前还款”被切分为“不得”+“提前还款”,模型解读为允许提前还款。

  • 资源耗尽攻击​:提交无分隔符的10MB文本,触发递归深度爆炸(CVE-2025-32711)。


1.1.2.3.3、系统集成方案

1. 全链路调用架构

sequenceDiagramparticipant Frontend as 前端participant API as 服务APIparticipant Chunker as 递归分块participant VectorDB as 向量数据库participant LLM as 大模型Frontend->>API: 上传文档API->>Chunker: 调用分块Chunker->>VectorDB: 存储分块+元数据Frontend->>API: 发送查询API->>VectorDB: 检索相关块VectorDB->>LLM: 发送查询+相关块LLM->>API: 返回生成结果API->>Frontend: 答案+溯源信息

2. 关键组件调用

  • 推理引擎调用​(vLLM示例):
    from vllm import SamplingParams
    params = SamplingParams(max_tokens=500, temperature=0.3)
    outputs = llm.generate([f"基于上下文:{retrieved_chunks}\n问题:{query}"], params)
  • 向量数据库操作​(ChromaDB):
    import chromadb
    client = chromadb.HttpClient()
    collection = client.create_collection("docs", metadata={"hnsw:space": "cosine"})# 存储分块(添加位置元数据)
    collection.add(ids=["chunk1", "chunk2"],documents=[chunk1_text, chunk2_text],metadatas=[{"start_char": 0}, {"start_char": 480}]
    )

1.1.2.3.4、前端系统需求

1. 核心功能模块

模块

功能

技术方案

分块可视化器

文档分块高亮展示 + 块边界标记

Monaco Editor + 字符坐标映射

风险扫描面板

检测敏感数据暴露(如身份证号跨越两分块)

正则匹配 + 大模型语义分析

溯源交互

点击答案跳转到原文分块位置

关联元数据中的start_char字段

递归深度监控

实时显示分块树深度,预警栈溢出风险

树形结构可视化(D3.js)

2. 交互流程设计

graph TBA[用户上传合同文档] --> B(递归分块引擎)B --> C{前端渲染分块}C --> D[用户调整分块参数]D --> E[保存至向量库]E --> F[用户提问“违约责任”]F --> G[检索相关块]G --> H[生成答案+标记来源位置]H --> I[前端高亮原文对应段落]

1.1.2.3.5、风险缓解策略
  1. 语义连续性保护​:

    • 动态重叠区​:在逻辑转折词(但/然而)处增加重叠(从50→150字符)

    • 禁忌分隔符​:禁止在关键短语(如“不可抗力”)后切分

  2. 安全加固​:

    • 输入清洗​:过滤危险分隔符(DROPDELETE等SQL关键词)

    • 递归深度限制​:设定最大递归深度(如100层),超长文本转线性分割

    • 隐私检测​:扫描重叠区是否含敏感信息(身份证/银行卡号)

  3. 资源优化​:

    • 尾递归优化​:改写递归为循环,避免栈溢出

    • 流式分块​:对超长文档分段加载处理,内存占用降低80%


总结建议

  1. 参数调优优先​:

    • 中文文档分隔符:["\n\n", "\n", "。", "?", "!", ";", ",", " "]

    • 推荐chunk_size=800(平衡检索精度与上下文完整性)

  2. 混合分块策略​:
    # 先结构分块(保留章节)→ 超长章节递归分块
    if is_structured(doc):chunks = markdown_chunk(doc)
    else:chunks = recursive_chunk(doc)
  3. 前端必备能力​:

    • 分块边界可视化 + 答案溯源定位 + 实时风险扫描

1.1.2.4. ​文档结构分块(Structure-Based Chunking)​
  • 原理​:按标题/章节等 Markdown/LaTeX 标签切分
  • 数学方法​:树形结构解析(DOM 树遍历)
  • 代码实现​(Markdown 示例):
    import re
    def markdown_chunk(text):pattern = r"(#+\s+.+?)(?=#|\Z)"chunks = re.findall(pattern, text, re.DOTALL)return [chunk.strip() for chunk in chunks]
​1.1.2.4.1、算法原理与底层实现

1. 核心原理

文档结构分块利用文档固有逻辑结构​(如标题、章节、表格、代码块)作为分块边界,确保语义和格式的完整性:

  • 结构解析​:通过HTML/Markdown标签(如<h1>##)、LaTeX环境或PDF布局树识别逻辑单元。

  • 元数据继承​:为每个块附加结构标签(如{"Header 1": "引言"}),增强检索时的上下文关联。

  • 数学表示​:
    \text{chunk}(D) = \bigcup_{s \in S} \text{extract}(s, D)
    其中 S 是预定义的结构标记集合(如章节标题),\text{extract} 是标签内容提取函数。

2. 代码实现

LangChain高级API

from langchain.text_splitter import MarkdownHeaderTextSplitterheaders = [("#", "Header 1"), ("##", "Header 2"), ("###", "Header 3")]
splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers)
chunks = splitter.split_text(md_content)  # 返回带元数据的文本块

纯Python底层实现(DOM解析)​

from bs4 import BeautifulSoupdef html_structure_chunk(html):soup = BeautifulSoup(html, 'html.parser')chunks = []for section in soup.find_all(['h1', 'h2', 'section']):title = section.get_text()content = section.find_next_sibling('div').get_text()  # 提取关联内容chunks.append({"text": content,"metadata": {"title": title, "tag": section.name}})return chunks
 ​​1.1.2.4.2、风险与漏洞分析

1. 技术风险

风险类型

成因

影响

缓解方案

格式依赖漏洞

非标文档(扫描PDF/OCR错误)导致结构识别失败

分块错乱,关键信息丢失

OCR预处理 + 混合分块策略

权限越界漏洞

结构标签携带敏感元数据(如<admin_only>),被未授权检索

数据泄露(如CVE-2025-32711)

元数据脱敏 + 向量库权限过滤

上下文割裂

表格/公式被错误分割(如分块1含表头,分块2含表体)

模型误解数据结构,生成错误结论

特殊结构识别 + 自定义分块规则

注入攻击

恶意结构标签(如<!-- DELETE FROM users -->)污染知识库

数据库被篡改或数据泄露

输入清洗 + 安全沙箱执行

2. 安全漏洞案例

  • 微软Copilot漏洞(CVE-2025-32711)​​:攻击者通过邮件注入恶意HTML标签,诱骗系统检索越权数据。

  • 简历搜索系统攻击​:篡改简历中的<skills>标签注入钓鱼链接,模型生成带恶意链接的推荐。

​1.1.2.4.3、系统集成方案

1. 全链路调用关系

2. 关键组件调用方式

  • 推理引擎调用​:
    # 使用vLLM加速生成
    from vllm import LLM
    llm = LLM(model="qwen2:1.5b", tensor_parallel_size=2)
    outputs = llm.generate(prompts, sampling_params={"max_tokens": 500})
  • 向量数据库操作​:
    from pymilvus import Collection
    collection = Collection("structured_chunks")
    # 插入分块(含结构元数据)
    data = [[chunk_ids], [chunk_embeddings], [{"title": "引言", "section": "2.1"}]]
    collection.insert(data)
    # 检索时过滤敏感标签
    results = collection.search(query_vec, filter="section != 'confidential'", limit=3)

​1.1.2.4.4、前端系统需求与交互设计

1. 必备功能模块

模块

功能

技术方案

分块调试器

可视化文档结构解析结果,标注分块边界

D3.js树状图 + 块高亮

安全审计面板

标记敏感块(如含PII)、注入攻击风险

正则匹配 + 大模型敏感词扫描

溯源交互界面

点击答案显示来源块,关联元数据(章节/标题)

React + 块ID映射

动态分块配置

用户调整分块参数(如最小块大小、标签过滤)

配置中心 + 实时重分块

2. 交互流程示例


​1.1.2.4.5、风险缓解最佳实践
  1. 结构验证层​:

    • 使用XML Schema/JSON Schema校验文档结构完整性。

  2. 动态混合分块​:

    • 先结构分块 → 超长表格/代码块启用语义分块(如SemanticChunker)。

  3. 零信任安全​:

    • 输入层​:清洗HTML标签(移除<script><!-->)。

    • 输出层​:LLM生成前扫描敏感词(如身份证号、API密钥)。

  4. 权限控制​:

    • 向量库按角色过滤元数据(如filter="security_level <= user_level")。


总结

文档结构分块通过尊重文档逻辑关系显著提升RAG精度,但需警惕格式依赖、权限漏洞、结构割裂三大风险。生产环境中建议:

  1. 技术选型​:结构化文档用LangChain分块器,非结构化数据混合递归分块。

  2. 安全加固​:输入清洗 → 向量库权限过滤 → 输出审计三层防护。

  3. 前端协同​:实现分块调试器 + 安全面板,提升系统可解释性。

1.1.2.5. ​主题分块(Topic-Based Chunking)​
  • 原理​:用 LDA/k-means 聚类主题相似的句子
  • 数学方法​:期望最大化(EM)算法迭代优化主题分布
  • 代码实现​(Scikit-learn):
    from sklearn.decomposition import LatentDirichletAllocation
    from sklearn.feature_extraction.text import CountVectorizerdef topic_chunk(text, n_topics=3):sentences = text.split('. ')vectorizer = CountVectorizer(stop_words='english')X = vectorizer.fit_transform(sentences)lda = LatentDirichletAllocation(n_components=n_topics)lda.fit(X)topic_labels = lda.transform(X).argmax(axis=1)chunks = {}for i, label in enumerate(topic_labels):chunks.setdefault(label, []).append(sentences[i])return list(chunks.values())
1. 算法原理

主题分块旨在将语义连贯的文本单元聚合成块,关键技术包括:

  • 主题建模​:通过 LDA(Latent Dirichlet Allocation)或 BERTopic 识别文本主题分布,公式表示为:
    P(\text{topic}_k | \text{chunk}) \propto \prod_{w \in \text{chunk}} P(w | \text{topic}_k) \cdot P(\text{topic}_k)
  • 语义边界检测​:计算相邻句子嵌入的余弦相似度,低于阈值 \theta(通常 0.6-0.8)时切分:
    \text{split if } \cos(\vec{s_i}, \vec{s_{i+1}}) < \theta
  • LLM 增强分块​:利用大模型动态识别主题边界(如 GPT-4 生成分割建议)。
2. 代码实现

LangChain 语义分块示例​:

from langchain_experimental.text_splitter import SemanticChunker
from langchain.embeddings import HuggingFaceEmbeddings# 加载嵌入模型(调用本地推理引擎)
embed_model = HuggingFaceEmbeddings(model_name="BAAI/bge-small-zh")# 初始化语义分块器
text_splitter = SemanticChunker(embeddings=embed_model,breakpoint_threshold_type="percentile",  # 动态阈值threshold_multiplier=1.5,               # 宽松阈值=μ-1.5σadd_start_index=True                     # 保留原始位置
)# 执行分块
docs = text_splitter.create_documents([long_text])

底层 LDA 分块实现​:

from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import CountVectorizerdef topic_chunk(text, n_topics=3, max_chunk_size=500):sentences = text.split('. ')vectorizer = CountVectorizer(stop_words='english')X = vectorizer.fit_transform(sentences)# LDA 主题聚类lda = LatentDirichletAllocation(n_components=n_topics)lda.fit(X)topic_labels = lda.transform(X).argmax(axis=1)# 合并同主题句子chunks = []current_chunk = []last_topic = topic_labels[0]for i, topic in enumerate(topic_labels):if topic == last_topic and len(current_chunk) < max_chunk_size:current_chunk.append(sentences[i])else:chunks.append(" ".join(current_chunk))current_chunk = [sentences[i]]last_topic = topicreturn chunks

风险与漏洞分析
1. 技术风险
风险类型成因影响
主题漂移长文档中主题渐变,硬切分导致语义断裂块内信息不连贯,生成答案偏离事实
敏感信息泄露分块时未过滤隐私字段(如医疗记录中的身份证号)违反 GDPR/ HIPAA,法律风险
对抗攻击恶意注入误导性文本(如“青霉素安全”被篡改为“青霉素无害”)模型生成危险建议
计算资源瓶颈LDA/LLM 分块需高频计算,高并发时延迟飙升系统响应超时,用户体验下降
2. 安全漏洞
  • 向量数据库污染​:攻击者注入带恶意指令的文本块(如 <!-- DELETE FROM users -->),检索后触发 SQL 注入 。
  • 越狱漏洞​:无害知识块组合触发模型有害生成(如“制作炸弹”+“厨房用品清单”=危险配方)。
  • 元数据篡改​:修改块关联的标题/章节信息,导致检索结果偏离上下文 。

系统集成方法
1. 调用推理引擎与大模型
  • 本地推理​(Ollama + vLLM):
    # 通过 Ollama 调用本地模型
    import ollama
    response = ollama.chat(model='llama3:8b', messages=[{'role':'user', 'content': prompt}])# 通过 vLLM 加速生成
    from vllm import LLM
    llm = LLM(model="meta-llama/Llama-3-8B", tensor_parallel_size=4)
    outputs = llm.generate([prompt])
  • 云 API 调用​(OpenAI/Dashscope):
    # Dashscope 示例(国内低延迟)
    from dashscope import Generation
    response = Generation.call(model="qwen-plus", prompt=prompt, api_key="YOUR_KEY")
2. 向量数据库操作
  • 存储与检索​(Milvus/Chroma):
    from pymilvus import Collection
    collection = Collection("medical_records")  # 连接集合# 插入分块向量
    data = [[chunk_ids], [chunk_embeddings], [chunk_metadata]]
    collection.insert(data)# 语义检索
    results = collection.search(query_embedding, anns_field="vector", limit=3)
3. 前端输出与交互
前端产品需求
  • 可视化调试面板​:展示分块边界、主题聚类、检索来源(如 Streamlit + UMAP 降维图)。
  • 安全审计模块​:标记敏感字段、对抗样本检测结果。
  • 实时反馈环​:用户对答案评分,反向优化分块阈值。
交互设计


风险缓解策略
  1. 动态分块加固​:
    • 医疗/金融领域采用 ​LGMGC 算法​(滑动窗口 + 主题连续性校验)。
    • 敏感字段(如过敏史)强制单块存储,避免分割。
  2. 安全防护层​:
    • 输入过滤​:正则表达式匹配隐私字段(身份证/银行卡号)。
    • 输出过滤​:LLM 生成结果经规则引擎校验(如禁止药品组合)。
  3. 资源优化​:
    • 层叠式分块:先递归分块 → 仅对复杂段落调用 LLM 分块,计算量降低 50%+ 。

前端系统实现示例

Streamlit 可视化面板​:

import streamlit as st
import umap
import pandas as pd# 主题分块可视化
reducer = umap.UMAP()
chunk_embeddings = model.encode(chunks)
embedding_2d = reducer.fit_transform(chunk_embeddings)# 绘制分块聚类
df = pd.DataFrame(embedding_2d, columns=['x','y'])
df['topic'] = chunk_topics  # 主题标签
st.scatter_chart(df, x='x', y='y', color='topic')
  • 算法选型​:通用场景用语义分块(LangChain),高危领域用 LGMGC 分块。
  • 架构设计​:
    graph LR
    文档 --> 主题分块 --> 向量数据库 --> 检索服务 --> LLM生成 --> 前端溯源
  • 合规要点​:分块阶段脱敏处理,生成阶段添加审计日志。

1.1.2.6 基于LLM的分块
 1.1.2.6.1 基于LLM的分块方法原理

1. ​核心思想

通过LLM理解文本语义边界,动态划分语义连贯的文本块:

  • 主题一致性​:识别文本中的主题转换点(如段落逻辑分隔)

  • 上下文感知​:利用LLM预训练的语言模式捕捉长程依赖关系

  • 边界识别​:检测语义转折词(如“然而”、“综上所述”)作为切分点

2. ​数学模型

  • 主题概率模型​(基于LDA扩展):
    P(\text{chunk}|d) \propto \prod_{s \in \text{chunk}} P(s|\text{topic}_k) \cdot P(\text{topic}_k|d)

    LLM通过隐狄利克雷分布(LDA)优化主题划分

  • 语义相似度阈值​:
    \text{split if } \cos(\vec{s_i}, \vec{s_{i+1}}) < \theta \quad (\theta \in [0.7,0.9])

    相邻句子嵌入相似度骤降时切分


1.1.2.6.2、实现流程与代码解析

1. ​分层处理流程

graph TD
A[原始文本] --> B(句子分割)
B --> C{LLM生成句嵌入}
C --> D[计算相邻句相似度]
D --> E{相似度<阈值?}
E -->|是| F[创建新块]
E -->|否| G[并入当前块]
F/G --> H[输出语义块]

2. ​关键代码实现​(Python示例)

# 基于LangChain的LLM分块实现
from langchain_experimental.text_splitter import SemanticChunker
from langchain.embeddings import HuggingFaceEmbeddings# 1. 加载嵌入模型(实际调用推理引擎)
embed_model = HuggingFaceEmbeddings(model_name="BAAI/bge-small-zh")# 2. 初始化语义分块器
text_splitter = SemanticChunker(embeddings=embed_model,breakpoint_threshold_type="percentile",  # 动态阈值buffer_size=3  # 重叠句子数
)# 3. 执行分块
docs = text_splitter.create_documents([long_text])

3. ​底层计算逻辑

# 相似度计算核心代码(简化版)
import torch
from transformers import AutoModel, AutoTokenizermodel = AutoModel.from_pretrained("bert-base-chinese")
tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")def get_sentence_embedding(sentence):inputs = tokenizer(sentence, return_tensors="pt", padding=True, truncation=True)outputs = model(**inputs)return torch.mean(outputs.last_hidden_state, dim=1)  # 池化为句向量def semantic_split(text, threshold=0.8):sentences = text.split('。')  # 初步分句embeddings = [get_sentence_embedding(s) for s in sentences]chunks, current_chunk = [], [sentences[0]]for i in range(1, len(sentences)):cos_sim = torch.cosine_similarity(embeddings[i-1], embeddings[i], dim=0)if cos_sim < threshold:chunks.append("。".join(current_chunk))current_chunk = []current_chunk.append(sentences[i])chunks.append("。".join(current_chunk))return chunks

1.1.2.6.3 系统集成方案

1. ​与推理引擎交互

  • LLM调用方式​:

    • 本地部署​:通过Ollama API调用本地模型:
      import ollama
      response = ollama.chat(model='qwen2:1.5b', messages=[{'role':'user','content':prompt}])
    • 云服务​:使用vLLM加速推理(支持张量并行):
      from vllm import LLM
      llm = LLM(model="meta-llama/Llama-3-8B", tensor_parallel_size=4)
      outputs = llm.generate(prompts)

2. ​向量数据库集成

  • 数据流架构​:
    graph LR
    A[原始文档] --> B(LLM分块)
    B --> C{嵌入模型}
    C --> D[向量数据库]
    D --> E[相似性检索]
    E --> F((RAG系统))
  • 代码示例​(ChromaDB):
    import chromadb
    from chromadb.utils.embedding_functions import OllamaEmbeddingFunction# 1. 连接向量库
    client = chromadb.HttpClient(host="localhost", port=8000)
    collection = client.get_or_create_collection(name="docs", embedding_function=OllamaEmbeddingFunction())# 2. 存储分块数据
    collection.add(documents=chunks, ids=[f"id_{i}" for i in range(len(chunks))])# 3. 检索相关块
    results = collection.query(query_texts=["用户问题"], n_results=3)

3. ​端到端RAG工作流

  1. 文档加载​:用PyPDF提取PDF文本

  2. LLM分块​:动态划分语义块

  3. 向量化存储​:BGE模型生成嵌入 → 存入Milvus/Chroma

  4. 检索增强​:
    retrieved = vector_db.similarity_search(query, k=3)
    prompt = f"基于上下文:{retrieved},回答:{query}"
  5. 生成响应​:通过vLLM调用LLM生成答案


1.1.2.6.4、工程挑战与优化
问题解决方案技术要点
计算成本高层叠式分块:先递归分块 → 仅对复杂段落调用LLM分块减少LLM调用次数50%+
长文档处理效率低流式处理 + 滑动窗口内存占用降低80%
主题漂移引入注意力掩码:Attention(Q,K,V) = \text{softmax}(\frac{QK^T}{\sqrt{d_k}} \odot M)V屏蔽无关句子
向量检索精度不足混合索引:语义块 + 结构元数据(标题/章节)HNSW索引 + 元数据过滤
实时性要求高GPU加速分块:NVIDIA RAPIDS cuML实现并行LDA10倍速度提升

1.1.2.6.5、参数调优建议
# LangChain最佳配置参考
optimized_splitter = SemanticChunker(embeddings=OpenAIEmbeddings(model="text-embedding-3-small"),breakpoint_threshold_type="standard_deviation", threshold_multiplier=1.8,  # 宽松阈值=μ-1.8σadd_start_index=True,      # 保留原始位置max_chunk_size=1000        # 安全截断
)

关键参数​:

  • 阈值类型​:结构化文本用percentile,非结构化用standard_deviation
  • 块大小​:技术文档≤800字,文学文本≤1500字
  • 重叠量​:主题切换频繁时设15%重叠

1.1.3、分块策略的适用场景对比

策略最佳场景缺陷数学约束
固定大小分块日志分析/高吞吐批处理语义割裂块大小方差=0
语义分块医疗法律文档/强上下文依赖问答计算开销大相似度阈值 \theta 敏感
递归分块技术手册/多层级文档递归深度影响性能分隔符优先级排序
文档结构分块API文档/Markdown论文依赖格式规范性树形结构深度 O(\log n)
主题分块新闻聚合/跨领域知识库LDA训练成本高主题数 k 需预设

1.1.4、工程优化建议

  1. 动态块大小调整​:
    • 根据查询复杂度动态扩展块大小(简单查询→300字,多跳推理→1500字)
  2. 混合分块策略​:
    • 先按结构分块,超长块再用语义分块细分
  3. 元数据继承​:
    • 为每个块添加标题/章节号等上下文标记,提升LLM理解力
  4. 量化评估指标​:
    • 检索召回率(Recall@K)和生成事实准确性(Factuality Score)


二、分块策略选型指南

1. 按文档类型选择
文档类型推荐策略案例说明
技术文档/手册递归分块 + 结构标记先按章节分割,超长节递归细分(保留代码块完整性)
法律/医疗文本语义分块(阈值0.7-0.8)合同条款需完整,避免分割责任条款
新闻/社交媒体固定大小分块 + 15%重叠500字分块,重叠75字(兼顾效率与连贯性)
学术论文结构分块(标题层级)Abstract/Introduction/Method切分
2. 按业务需求优化
  • 高检索精度场景​(如QA问答):
    • 小分块(300字) + 语义分块 → 精准匹配问题关键词。
  • 强上下文依赖场景​(如报告生成):
    • 大分块(1500字) + 块重叠 → 保留论证逻辑链。
3. 避免常见陷阱
  • 阈值敏感性问题​:语义分块需动态调整相似度阈值(不同领域文档阈值差异可达0.2)。
  • 结构依赖风险​:非标格式文档(如扫描PDF)需预处理OCR,否则结构分块失效。
  • 资源开销平衡​:LLM分块计算成本高,仅建议关键业务使用(如金融风控报告)。

三、工具与实施建议

1. 分块工具链
  • LangChain集成​:
    • RecursiveCharacterTextSplitter:通用递归分割
    • SemanticChunker:基于嵌入相似度分块(需调breakpoint_threshold
    • MarkdownHeaderTextSplitter:结构化分块(自动继承标题元数据)
  • 自定义流程​:
    # 语义分块示例(Sentence-BERT嵌入)
    from sentence_transformers import SentenceTransformer
    model = SentenceTransformer('all-MiniLM-L6-v2')
    sentences = ["sentence1", "sentence2", ...]  # 输入句子列表
    embeddings = model.encode(sentences)
    # 计算相邻句子相似度,低于阈值则切分
2. 调优与验证
  • A/B测试指标​:
    • 检索召回率(Recall@K)、生成答案的事实准确性(Factuality Score)。
  • 动态调整​:
    • 监控长尾查询的失败率,反向优化分块大小(如失败率>20%时增大块尺寸)。

四、总结:分块黄金法则

  1. 先分类后分块​:根据文档类型(结构化/非结构化)和业务目标(精度/上下文)选择策略。
  2. 小步快跑验证​:从固定大小分块(500字+20%重叠)起步,逐步升级到语义/结构分块。
  3. 资源效率平衡​:
    • 90%文档用递归分块(LangChain默认),10%高价值文档用LLM分块。
  4. 持续监控迭代​:嵌入模型更新后需重新评估分块效果(如text-embedding-3-small优化后支持更大分块)。

注:分块是RAG的“隐形架构师”,直接决定知识消化能力。建议结合LangChain文档和业务日志数据持续迭代分块矩阵,而非追求通用最优解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/86486.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/86486.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

能耗管理新革命:物联网实现能源高效利用

在全球能源危机与 “双碳” 目标的双重压力下&#xff0c;企业与社会对能耗管理的重视程度达到前所未有的高度。然而&#xff0c;传统能耗管理方式存在数据采集滞后、分析维度单一、节能措施粗放等问题&#xff0c;无法满足精细化管理需求。物联网技术凭借其强大的数据感知、传…

基于CMS的黄道吉日万年历源码(自适应)

本模板采用帝国cms7.5版UTF-8制作&#xff1b; 适用站点&#xff1a;时间查询、时差计算、万年历、黄道吉日查询、假期查询、节气表等&#xff1b; 源码优势&#xff1a;代码精简&#xff0c;利于SEO、UI大气精简&#xff0c;搜索引擎收录高&#xff1b; 全站伪静态无需刷新生成…

如何构建个人AIagent

构建个人AI Agent是一个结合技术实现和场景设计的系统工程&#xff0c;以下是分步骤的详细指南&#xff0c;涵盖从需求定义到部署落地的全流程&#xff1a; ​一、明确Agent定位&#xff08;关键第一步&#xff09;​​ ​角色定义矩阵​ 类型典型场景技术复杂度示例信息处理Ag…

lutris登录不进去

日志 Cannot create Vulkan instance.This problem is often caused by a faulty installation of the Vulkan driver or attempting to use a GPU thatdoes not support Vulkan.ERROR at /home/abuild/rpmbuild/BUILD/vulkan-tools-1.4.313-build/Vulkan-Tools-vulkan-sdk-1.…

缓存与加速技术实践-NoSQL之Redis配置与优化

目录 #1.1关系数据库与非关系型数据库 1.1.1关心型数据库 1.1.2非关系型数据库 1.1.3非关系型数据库产生背景 #2.1redis简介 2.1.1redis安装部署 2.1.2配置参数 #3.1redis命令工具 3.1.1redis-cli命令行工具 3.1.2redis-benchmark测试工具 #4.1redis数据库常用命令 4.1.1ke…

走近科学IT版:FreeBSD系统下ThinkPad键盘突然按不出b、n、/和空格键了!

走近科学IT版&#xff1a;FreeBSD系统下ThinkPad键盘突然按不出b和n键了&#xff01; 很慌&#xff0c;以为键盘坏了&#xff0c;在控制台无法按出b和n&#xff0c;但是在浏览器里&#xff0c;可以按出来。 重启机器&#xff0c;结果在浏览器里也按不出来了.... 按Ctrl空格&a…

聚铭网络入选嘶吼《中国网络安全细分领域产品名录》“云平台安全管理”与“态势感知”双领域TOP10

近日&#xff0c;在嘶吼安全产业研究院发布的《中国网络安全细分领域产品名录》中&#xff0c;聚铭网络凭借其核心产品——聚铭云端安全管家与聚铭安全态势感知与管控系统&#xff0c;分别入选“云平台安全管理”与“态势感知”两大关键细分领域TOP10榜单&#xff0c;充分展现了…

DEYOLO 全面复现,将双增强跨模态目标检测网络 DEYOLO 融合到 YOLOFuse 框架

模型架构模态精度 P召回率 RmAP50mAP50-95模型大小(MB)计算量(GFLOPs)yolov8n (baseline)RGB0.8880.8290.8910.5006.28.1yolo-fuse-中期特征融合RGBIR0.9510.8810.9470.6012.613.2yolo-fuse-早期特征融合RGBIR0.9500.8960.9550.6235.26.7yolo-fuse-决策级融合RGBIR0.9560.9050.…

python基于Django+mysql实现的图书管理系统【完整源码+数据库】

摘要 随着信息技术与教育现代化的深度融合&#xff0c;图书管理系统的智能化与自动化成为提升资源利用效率的关键需求。本文基于Python语言&#xff0c;采用Django框架与MySQL数据库设计并实现了一套功能完备的图书管理系统&#xff0c;旨在通过信息化手段优化图书借阅流程、强…

论软件设计方法及其应用

20250427-作 题目 软件设计&#xff08;Software Design&#xff0c;SD)根据软件需求规格说明书设计软件系统的整体结构、划分功能模块、确定每个模块的实现算法以及程序流程等&#xff0c;形成软件的具体设计方案。软件设计把许多事物和问题按不同的层次和角度进行抽象&…

QT 自定义ComboBox,实现下拉框文本颜色设置

最近在做项目中遇到需求&#xff0c;在下拉框中&#xff0c;文本需要设置不同的颜色&#xff0c;遂网上了解了一番后&#xff0c;得出以下代码&#xff0c;可以完美实现效果&#xff0c;现分享出来&#xff01; 1.实现效果 2.自定义类 colorcombobox.h #ifndef COLORCOMBOBOX…

【时间戳】

在编程竞赛和高效数据处理场景中&#xff0c;时间戳技巧是一种极其高效的标记方法&#xff0c;常用于避免频繁清空数组或 map&#xff0c;提高算法运行效率。本文将从定义、应用场景、模板代码、技巧细节等方面系统整理时间戳的使用方式。 一、时间戳技巧是什么&#xff1f; 时…

json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig)

有一次爬虫遇到了json的字符串响应对象 然后转为json对象 报这个错误 raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0) 意思是叫…

python训练day43 复习日

import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader, random_split import matplotlib.pyplot as plt import numpy as np# 设置中文字体支持&#xff0c;避免绘图时中文…

C++11 lambda

前言 在Cpp11以前&#xff0c;为了把函数当作对象调用&#xff0c;可以使用C中的函数指针类型&#xff0c;也可以使用Cpp98的仿函数。 但二者都不是很好用&#xff0c;函数指针 return_type (*name)(parameters)的长相就令人望而却步&#xff0c;仿函数将一个函数重载为一个类…

【国产化-K8s】混合架构的 K8s + KubeSphere 部署指南

本文由 KubeSphere 社区贡献者 天行1st 编写。本文为作者实践总结。本文记录了在信创环境中基于混合架构&#xff08;x86 与 ARM64&#xff09;部署 Kubernetes 和 KubeSphere 的实践过程&#xff0c;覆盖多种国产 CPU 和操作系统&#xff0c;具有一定的参考价值。 环境涉及软…

利用python实现NBA数据可视化

大家好&#xff0c;今天我们利用python爬取NBA球星每年的比赛数据并进行可视化展示。主要用到三个模块&#xff1a;xpath、matplotlib。其中xpth负责爬取网站上的信息。Matplotlib是Python开发人员常用的Python绘图库&#xff0c;可以用来绘制各种2D图形&#xff0c;具有绘图质…

基于 SpringBoot+JSP 的医疗预约与诊断系统设计与实现

摘要 本研究针对传统医疗预约与诊断流程中存在的效率低下、信息不透明、患者等待时间长等问题&#xff0c;设计并实现了一个基于 SpringBootJSP 的医疗预约与诊断系统。系统采用 B/S 架构&#xff0c;整合了用户管理、科室管理、医生排班、预约挂号、在线问诊、检查检验、诊断…

2025.6.27总结

最近工作又开始内耗了&#xff0c;一位同事的转岗直接让我破防了&#xff0c;明明他工作干得很不错&#xff0c;会得又多&#xff0c;性格又好&#xff0c;我还经常请教他业务上的问题。我和他的关系并不算太好&#xff0c;但他加入其他部门&#xff0c;竟然让我有些不舍&#…

详解HashMap底层原理

核心数据结构&#xff1a;数组 链表 / 红黑树 HashMap 的底层核心是一个 Node<K,V>[] table 数组&#xff08;通常称为 桶数组 或 哈希桶数组&#xff09;。这个数组的每个元素称为一个 桶。 Node<K,V> (链表节点)&#xff1a; 这是存储键值对的基本单位&#xf…