跳转至

ChunkingService 概览 / ChunkingService Overview

ChunkingService 和相关策略类负责把长文本切成适合 embedding 与检索的文本块。它们位于 Parser 之后、Embedding 之前,是 RAG 摄取质量与召回效果的关键调节点。

本文聚焦模块职责、策略选择、兼容入口和调优方向;具体类、工厂函数和方法签名以 核心服务 API 参考 中的自动渲染结果为准。

何时阅读本页 / When to Read This Page

适合在以下场景阅读本页:

  • 需要理解为什么同一份文档会被切成多个 chunk
  • 需要在 fixed_sizesentenceparagraphrecursive 等策略之间做选择
  • 需要判断新代码应直接使用策略类,还是暂时复用兼容性的 ChunkingService
  • 需要调优块大小、重叠率和语义边界保留方式

关键文件 / Key Files

路径 作用
ai_service/services/chunking.py 分块策略、策略工厂和兼容服务入口的源码所在
Parser 子系统 分块上游,负责产出待切分的纯文本
EmbeddingService 概览 分块下游,负责对 chunk 生成向量
IngestionService 概览 摄取主流程如何选择并应用分块策略
核心服务 API 参考 ChunkingServiceget_chunking_service 等对象的源码级说明

核心类与函数 / Core Classes and Functions

  • BaseChunkingStrategy 所有分块策略的抽象基类,定义统一的 chunk_text() 契约。
  • get_chunking_strategy 按策略名称和参数返回具体策略实例,是新代码优先使用的入口。
  • validate_chunking_strategy_configuration 对策略名称、参数名和运行时可用性做预检,供 API 在持久化前复用。
  • list_chunking_strategy_capabilities 产出当前环境下各策略的 capability 元数据,供 /chunking-strategies API 和管理台选择器使用。
  • ChunkingService 兼容层,内部包装固定大小策略,保留给历史调用路径使用。
  • get_chunking_service 兼容服务的单例工厂。

规则:新代码优先使用策略工厂与具体策略类;ChunkingService 主要用于向后兼容。

数据流 / Data Flow

flowchart LR
    A[Parsed text] --> B[Resolve chunking strategy]
    B --> C{Strategy type}
    C -->|fixed_size| D[Uniform chunks with overlap]
    C -->|sentence or paragraph| E[Respect sentence or paragraph boundaries]
    C -->|recursive| F[Fallback across separator levels]
    C -->|semantic family| G[Use semantic boundary heuristics]
    D --> H[ChunkResult list]
    E --> H
    F --> H
    G --> H
    H --> I[EmbeddingService]

策略选择 / Strategy Selection

系统当前支持的主策略可以这样理解:

策略 标识 适用场景
固定大小 fixed_size 通用、稳定、低复杂度的默认场景
句子级 sentence 需要保持句子完整性的文章类文本
段落级 paragraph 结构化文档、说明书、较长段落文本
递归层级 recursive 希望兼顾结构边界和通用鲁棒性
语义分割 semantic 需要实验性语义边界能力的场景
句子窗口 sentence_window 需要句子中心 + 周边上下文的检索场景
语义切分器 semantic_splitter 使用 LlamaIndex 语义边界能力的场景

推荐规则

  • 不确定时优先从 recursivefixed_size 开始
  • 文本叙事性强时优先 sentence
  • 结构化文档较强时优先 paragraph
  • 只有在明确接受额外依赖与实验成本时再启用语义类策略

策略参数详解 / Strategy Parameters

Fixed Size(固定大小)

参数 类型 默认值 说明
chunk_size int 512 每个 chunk 的目标字符数,控制 chunk 的最大长度
chunk_overlap int 50 相邻 chunk 之间的重叠字符数,用于减少语义断裂

调优建议: - 增加 chunk_size 可以包含更多上下文,但会降低检索精确度 - 增加 chunk_overlap 可以减少语义断裂,但会增加向量数量和索引成本 - chunk_overlap 必须小于 chunk_size,否则会抛出 ValueError


Sentence(句子级)

参数 类型 默认值 说明
target_size int 512 每个 chunk 的目标字符数,作为分组句子的参考上限
max_sentences_per_chunk int 10 每个 chunk 允许包含的最大句子数,防止 chunk 过长

调优建议: - 适用于需要保持句子完整性的文章类文本 - target_size 是软限制,实际 chunk 大小可能略小于该值 - max_sentences_per_chunk 是硬限制,达到后会强制分割


Paragraph(段落级)

参数 类型 默认值 说明
target_size int 1024 每个 chunk 的目标字符数,作为分组段落的参考上限
max_paragraphs_per_chunk int 5 每个 chunk 允许包含的最大段落数,防止 chunk 过长

调优建议: - 适用于结构化文档、说明书、较长段落文本 - 段落边界通过 \n\n 识别 - target_size 默认较大,适合段落较长的文档


Recursive(递归层级)

参数 类型 默认值 说明
chunk_size int 512 每个 chunk 的目标字符数
chunk_overlap int 50 相邻 chunk 之间的重叠字符数
separators list[str] ["\n\n", "\n", ". ", " ", ""] 分隔符优先级列表,按顺序尝试分割

调优建议: - 适用于希望兼顾结构边界和通用鲁棒性的场景 - separators 按优先级从高到低尝试:先尝试段落分割,再尝试句子分割,最后按字符分割 - 自定义 separators 可以适应特殊文档格式 - chunk_overlap 必须小于 chunk_size


Semantic(语义分割)

参数 类型 默认值 说明
similarity_threshold float 0.7 相似度阈值(0-1),低于此值时进行分割
min_chunk_size int 200 最小 chunk 大小(字符数),防止产生过短的 chunk
max_chunk_size int 1000 最大 chunk 大小(字符数),防止产生过长的 chunk

调优建议: - 适用于需要实验性语义边界能力的场景 - 当前实现为简化版本,实际使用句子级分割作为 fallback - 完整语义分割需要与 EmbeddingService 集成 - similarity_threshold 越高,分割越频繁,chunk 越小


Sentence Window(句子窗口)

参数 类型 默认值 说明
window_size int 3 上下文窗口大小,每个句子前后包含的句子数

调优建议: - 适用于需要句子中心 + 周边上下文的检索场景 - 需要 llama-index-core 依赖 - 每个句子都会成为一个独立的 chunk,但检索时会包含窗口内的上下文 - 适合高精度的 QA 工作负载


Semantic Splitter(语义切分器)

参数 类型 默认值 说明
buffer_size int 1 缓冲区大小,用于平滑语义边界
breakpoint_percentile_threshold int 95 断点百分位阈值(0-100),控制分割的激进程度

调优建议: - 适用于使用 LlamaIndex 语义边界能力的场景 - 需要 llama-index-core 依赖 - 使用 EmbeddingService 的嵌入模型,不再依赖 OpenAI - breakpoint_percentile_threshold 越高,分割越保守,chunk 越大 - buffer_size 越大,边界越平滑,但可能降低分割精度


运行约定 / Runtime Behavior

兼容层与新入口

  • get_chunking_strategy() 是面向新代码的首选入口
  • ChunkingService 保留为兼容层,内部默认包装固定大小策略
  • IngestionService 中,可根据任务或知识源配置动态选择具体策略

块大小与重叠

  • 块越小,检索定位通常越精确,但上下文碎片化风险越高
  • 重叠可以减少语义断裂,但会增加向量数量和索引成本
  • 实际最优值依赖文档类型、查询粒度和模型上下文预算

依赖差异

  • 基础策略不需要额外依赖
  • sentence_windowsemantic_splitter 依赖 llama-index-core
  • semantic_splitter 不再走 LlamaIndex 的默认 OpenAI embedding 路径,而是显式注入一个基于 EmbeddingService 的 LlamaIndex adapter
  • 这意味着 semantic_splitter 的可用性不仅取决于 llama-index-core,也取决于仓库当前 embedding 配置是否有效
  • sentence_windowsemantic_splitter 只会向 LlamaIndex 转发其原生支持的参数
  • API 与 Admin UI 现在会在保存知识源默认值、保存 Agent 默认值、以及启动 ingestion 之前做预检;除显式兼容的历史字段外,其它未知参数会直接收到 422
  • 对直接 Python 调用而言,semantic_splitter.target_size 仍保留历史兼容行为:构造时会忽略该字段并记录告警;但这条兼容路径不会再通过 API 暴露给运营配置

常见集成模式 / Common Integration Patterns

通过策略工厂创建策略

from ai_service.services.rag.chunking import get_chunking_strategy

chunking_strategy = get_chunking_strategy(
    strategy_type="sentence",
    params={"target_size": 512, "max_sentences_per_chunk": 10},
)

在保存或执行前做能力预检

from ai_service.services.rag.chunking import validate_chunking_strategy_configuration

validation_result = validate_chunking_strategy_configuration(
    strategy_type="semantic_splitter",
    params={"buffer_size": 1, "breakpoint_percentile_threshold": 95},
)

if not validation_result.is_valid:
    raise ValueError(validation_result.error_message)

暴露策略 capability 给控制台

from ai_service.services.rag.chunking import list_chunking_strategy_capabilities

capability_list = list_chunking_strategy_capabilities()

直接使用兼容服务

from ai_service.services.rag.chunking import get_chunking_service

chunking_service = get_chunking_service()
chunk_results = chunking_service.chunk_text(
    text="long text",
    document_id="doc-123",
    document_name="example.txt",
    source_id="source-456",
)

在摄取链路中显式注入

from ai_service.services.rag.chunking import ChunkingService
from ai_service.services.rag.ingestion import IngestionService

custom_chunking_service = ChunkingService(chunk_size=500, chunk_overlap=100)
ingestion_service = IngestionService(chunking_service=custom_chunking_service)

不应在本页重复维护的内容 / What This Page Should Not Duplicate

以下内容应留在 API 参考或配置页,而不是继续堆在模块页中:

  • 每个策略类的完整构造参数表
  • ChunkResult 的完整字段清单
  • chunk_text()estimate_chunk_count() 的详细签名
  • 与源码 docstring 完全重复的策略实现细节