文本切分与分块(中文译文)
原始 DeepWiki 页面:https://deepwiki.com/open-webui/open-webui/7.3-text-splitting-and-chunking
翻译时间:2026-06-09T16:09:12.482Z
翻译模型:deepseek-chat
原文字符数:8788
项目:Open WebUI (open-webui)
---
文本分割与分块
相关源文件
以下文件为本 Wiki 页面的生成提供了上下文:
backend/open_webui/models/memories.pybackend/open_webui/retrieval/loaders/datalab_marker.pybackend/open_webui/retrieval/loaders/main.pybackend/open_webui/retrieval/loaders/mineru.pybackend/open_webui/retrieval/loaders/paddleocr_vl.pybackend/open_webui/retrieval/utils.pybackend/open_webui/routers/memories.pybackend/open_webui/routers/retrieval.pysrc/lib/apis/retrieval/index.tssrc/lib/components/admin/Settings/Documents.sveltesrc/lib/components/admin/Settings/WebSearch.svelte
本文档介绍 Open WebUI 的 RAG(检索增强生成)流水线中使用的文本分割与分块系统。文本分割是将大型文档拆分为更小、语义上有意义的块的过程,这些块可以被高效地嵌入和检索。
关于分块之前的文档内容提取,请参阅 7.2 内容提取引擎。关于分块之后的嵌入生成,请参阅 7.4 嵌入生成。
目的与范围
文本分割是 RAG 系统的关键组件,它将提取的文档内容转换为适合向量嵌入的块。本文涵盖以下内容:
- LangChain 提供的可用文本分割器实现。
- 通过
PersistentConfig系统配置的块大小和重叠参数。 - 与文档摄取流水线及用户记忆等专用系统的集成。
系统概览
分块系统位于内容提取和嵌入生成之间。文档的文本内容被提取后,会被分割成既符合嵌入模型令牌限制又能保留语义上下文的块。
RAG 数据流
下图展示了文本从原始提取到后端结构化块的流转过程。
graph LR
Extract["加载器流水线<br/>(build_loader_from_config)"]
Split["文本分割<br/>(RecursiveCharacter,<br/>Token, MarkdownHeader)"]
Embed["嵌入生成<br/>(get_embedding_function)"]
Store["向量存储<br/>(VECTOR_DB_CLIENT)"]
Extract --> Split
Split --> Embed
Embed --> Store
Config["PersistentConfig<br/>CHUNK_SIZE<br/>CHUNK_OVERLAP"]
Config -.->|配置| Split
来源:backend/open_webui/retrieval/utils.py:86-124、backend/open_webui/routers/retrieval.py:32-36、backend/open_webui/routers/retrieval.py:139-160
配置参数
分块系统由后端配置系统管理,允许将设置持久化到数据库中,并通过管理界面在运行时更新。
| 参数 | 默认值 | 用途 |
|---|---|---|
CHUNK_SIZE | 1500 | 每个块的最大字符数/令牌数。 |
CHUNK_OVERLAP | 100 | 相邻块之间的重叠单元数,用于保持上下文连贯性。 |
TIKTOKEN_ENCODING_NAME | "cl100k_base" | TokenTextSplitter 使用的编码方式。 |
配置管理架构
下图将用户设置的"自然语言空间"与后端配置系统的"代码实体空间"连接起来。
graph TB
subgraph "代码实体空间:存储"
ConfigTable["Memory (SQLAlchemy 表)"]
PersistentConfigClass["PersistentConfig (泛型类)"]
ENV["open_webui/env.py"]
end
subgraph "代码实体空间:检索 API"
RetrievalRouter["routers/retrieval.py (APIRouter)"]
GetRAGConfigEndpoint["GET /retrieval/config"]
UpdateRAGConfigEndpoint["POST /retrieval/config/update"]
RetrievalRouter --> GetRAGConfigEndpoint
RetrievalRouter --> UpdateRAGConfigEndpoint
end
subgraph "自然语言空间:管理界面"
DocumentsTab["Settings/Documents.svelte"]
SubmitHandler["submitHandler (Svelte 函数)"]
DocumentsTab -->|触发| SubmitHandler
end
UpdateRAGConfigEndpoint -->|updateRAGConfig| PersistentConfigClass
SubmitHandler -->|updateRAGConfig| UpdateRAGConfigEndpoint
来源:src/lib/components/admin/Settings/Documents.svelte:229-240、src/lib/apis/retrieval/index.ts:63-91、backend/open_webui/routers/retrieval.py:14-25
文本分割器类型
Open WebUI 使用 langchain_text_splitters 为不同文档类型提供多种分割策略。
递归字符文本分割器
默认实现。它尝试按字符列表(通常为 ["\n\n", "\n", " ", ""])递归分割文本,直到块足够小。这种方式尽可能保留段落和句子结构。 来源:backend/open_webui/routers/retrieval.py:32-33
令牌文本分割器
使用 tiktoken 基于令牌数量分割文本。这对于确保块能够适配 GPT-4 或本地 Llama 模型等特定 Transformer 模型的上下文窗口非常准确。 来源:backend/open_webui/routers/retrieval.py:29-29、backend/open_webui/routers/retrieval.py:34-34
Markdown 标题文本分割器
根据 Markdown 标题(#、## 等)分割文档。这非常适合结构化技术文档,因为它能在块元数据中保留层级结构,使检索器能够理解文本所属的章节。 来源:backend/open_webui/routers/retrieval.py:35-36
文档流水线中的分块
文本分割是文档摄取流水线中的一个步骤。一旦 Loader 提取出文本,系统会在生成嵌入之前应用配置好的分割器。
graph TD
UploadFile["UploadFile (FastAPI)"] --> Loader_load["Loader.load()"]
Loader_load --> RawDocs["List[Document]"]
RawDocs --> SplitLogic["langchain_text_splitters"]
SplitLogic --> ChunkedDocs["List[Document]"]
ChunkedDocs --> EF["get_ef() / get_embedding_function()"]
EF --> VDB["VECTOR_DB_CLIENT.upsert()"]
subgraph "代码实体:分割器"
SplitLogic -.-> RecursiveCharacterTextSplitter["RecursiveCharacterTextSplitter"]
SplitLogic -.-> TokenTextSplitter["TokenTextSplitter"]
SplitLogic -.-> MarkdownHeaderTextSplitter["MarkdownHeaderTextSplitter"]
end
来源:backend/open_webui/routers/retrieval.py:32-36、backend/open_webui/retrieval/loaders/main.py:231-241、backend/open_webui/routers/retrieval.py:139-160
实现细节
元数据保留
在分割过程中,系统确保原始文档的元数据(如 source、page 和 file_name)被传递到每个单独的块中。这对于引用和混合搜索排序至关重要。 来源:backend/open_webui/retrieval/utils.py:158-160、backend/open_webui/retrieval/loaders/paddleocr_vl.py:86-93
记忆分块
"记忆"系统中存在一种特殊形式的分块。当用户通过 memories 路由添加记忆时,内容被视为一个离散单元。它使用 EMBEDDING_FUNCTION 进行嵌入,并存储在用户特定的集合中。与大型文档不同,记忆通常足够短,可以作为一个单独的块处理。
# backend/open_webui/routers/memories.py:84-98
memory = await Memories.insert_new_memory(user.id, form_data.content)
vector = await request.app.state.EMBEDDING_FUNCTION(memory.content, user=user)
await ASYNC_VECTOR_DB_CLIENT.upsert(
collection_name=f'user-memory-{user.id}',
items=[
{
'id': memory.id,
'text': memory.content,
'vector': vector,
'metadata': {'created_at': memory.created_at},
}
],
)
来源:backend/open_webui/routers/memories.py:84-98、backend/open_webui/models/memories.py:44-69
检索与重排序集成
文本分割并存储后,检索通过向量相似度和 BM25 的组合进行。如果配置了重排序模型(如 ColBERT 或 CrossEncoder),则会使用该模型重新评估检索到的块的相关性。 来源:backend/open_webui/retrieval/utils.py:15-20、backend/open_webui/routers/retrieval.py:173-206