Chunking:RAG 系统中最容易被低估的核心技术

Summary

在 Retrieval-Augmented Generation(RAG)系统中,很多工程团队会把主要精力放在 Vector Database、Embedding Model、LLM 和 Retrieval Algorithm 上,却忽略了一个看似简单、实际上决定整个系统上限的问题:

如何把一份长文档切成适合检索的 Chunk?

Chunking 并不是简单地把文本按照固定字符数切成若干段。

一个好的 Chunk 应该同时满足:

  • 语义完整;
  • 检索粒度合理;
  • Embedding 后具有良好的语义表达能力;
  • 能够独立回答或者支持回答一个问题;
  • 不产生过多冗余;
  • 不破坏原始文档结构;
  • 能够携带足够的上下文;
  • 能够被准确地召回。

因此,从 RAG Pipeline 的角度来看:

Document
Parsing
Chunking
Embedding
Vector Database
Retrieval
Reranking
LLM

Chunking 位于 Document Processing 和 Retrieval 之间的关键边界

如果 Chunking 做错了,后面的 Embedding、Vector Database、Reranking 甚至 LLM 都很难完全弥补。

可以把它概括为:

Chunking 决定了 RAG 系统“以什么粒度理解知识”。


1. 为什么 Chunking 如此重要?

假设我们有一份 200 页的企业技术文档。

用户提出:

How do I configure Redis Cluster failover?

如果直接把整个文档作为一个向量:

Document → Embedding → Vector DB

那么这个向量实际上表达的是:

Redis
Cluster
Deployment
Security
Monitoring
Failover
Backup
Performance
...

它包含大量不同主题。

用户查询:

Redis Cluster failover configuration

但整个 Document 的 embedding 是一个非常粗粒度的语义表示。

这会导致:

Query
Embedding
Document Vector

只能回答:

这篇文档大概和 Redis Cluster 有关。

而不是:

这篇文档中具体哪一段描述了 failover configuration?

因此我们需要:

Document
├── Introduction
├── Architecture
├── Redis Cluster
│    ├── Node Configuration
│    ├── Failover
│    ├── Replication
│    └── Recovery
├── Security
└── Monitoring

进一步切成:

Chunk 1
Chunk 2
Chunk 3
...
Chunk N

于是 Retrieval 的目标从:

Find the relevant document

变成:

Find the relevant knowledge unit

这实际上是 RAG 最重要的一次粒度变化。


2. Chunking 的本质:知识粒度设计

从更抽象的角度来看,Chunking 本质上是在解决:

Knowledge Granularity Problem

假设一个文档:

D = {p1, p2, p3, ..., pn}

我们需要将它划分成:

C = {c1, c2, c3, ..., cm}

其中每个:

ci ⊂ D

理想情况下,每一个 Chunk 都应该尽可能满足:

Semantic Cohesion(ci) → high

同时:

Noise(ci) → low

以及:

Retrieval Utility(ci) → high

换句话说,一个 Chunk 不应该只是:

长度合适。

而应该是:

一个具有独立语义价值的知识单元。


3. Chunking 的三个核心矛盾

Chunking 最难的地方在于存在三个天然矛盾。

3.1 Chunk 太大

例如:

Chunk Size = 4000 tokens

优点:

  • 上下文完整;
  • 不容易丢失信息;
  • 适合复杂问题。

缺点:

  • Embedding 语义被稀释;
  • 无关内容增多;
  • Retrieval Precision 下降;
  • LLM Context 消耗增加。

例如一个 Chunk:

Redis Cluster Architecture
+
Redis Security
+
Redis Backup
+
Redis Monitoring
+
Redis Performance

用户只问:

How does Redis failover work?

这个 Chunk 包含大量无关信息。


3.2 Chunk 太小

例如:

Chunk Size = 100 tokens

可能产生:

Chunk 1:
Redis Cluster consists of...

Chunk 2:
Each master node...

Chunk 3:
A replica is promoted...

Chunk 4:
The promotion process...

虽然每个 Chunk 都很精确,但是语义可能不完整。

例如:

A replica is promoted...

如果不知道前面的:

Under master node failure...

那么这句话本身的语义是不完整的。

因此:

Small Chunk
→ High Precision
→ Low Context Completeness

3.3 Chunk 太多

如果 Chunk 很小:

1 Document
→ 1000 Chunks

那么 Retrieval Search Space 会迅速扩大。

这可能造成:

More Candidates
More Similar Chunks
More Redundancy
Lower Context Diversity

最终 LLM 收到的 Top-K 结果可能是:

Chunk 10
Chunk 11
Chunk 12
Chunk 13

它们实际上都来自同一个段落。

这就是典型的:

Retrieval Redundancy


4. Fixed-Size Chunking

最简单的 Chunking 方法是固定长度切分。

例如:

chunk_size = 500 tokens

算法:

def chunk(text, chunk_size):
    chunks = []

    for i in range(0, len(text), chunk_size):
        chunks.append(text[i:i + chunk_size])

    return chunks

实际上生产环境中通常还会增加 overlap。

例如:

chunk_size = 500
overlap = 100

那么:

Chunk 1:
0 ───────────── 500

Chunk 2:
400 ───────────── 900

Chunk 3:
800 ───────────── 1300

这样可以避免句子或语义在 Chunk 边界处被完全切断。


5. Overlap 为什么重要?

假设:

Chunk 1:
Redis Cluster uses a master-replica architecture.
When the master node fails, Sentinel detects...

如果恰好在这里切断:

Chunk 1:
Redis Cluster uses a master-replica architecture.
When the master node fails...

Chunk 2:
Sentinel detects the failure and promotes...

那么:

Chunk 2

缺失:

What failure?

通过 overlap:

Chunk 1:
...
When the master node fails,
Sentinel detects...

Chunk 2:
When the master node fails,
Sentinel detects the failure and promotes...

Chunk 2 的语义完整性明显提高。


6. Overlap 不是越大越好

很多初学者会认为:

overlap 越大,信息丢失越少。

实际上不是。

假设:

chunk_size = 500
overlap = 400

那么:

Chunk 1: 0 - 500
Chunk 2: 100 - 600
Chunk 3: 200 - 700
Chunk 4: 300 - 800

大量文本被重复 embedding。

最终:

Storage ↑
Embedding Cost ↑
Retrieval Redundancy ↑
Index Size ↑

而实际获得的 recall improvement 可能非常有限。

因此 Overlap 的目标不是:

最大化重叠。

而是:

降低 Chunk Boundary Information Loss。


7. Recursive Chunking

比 Fixed-Size 更好的方法是:

Recursive Chunking

核心思想是:

Document
Paragraph
Sentence
Phrase
Token

优先按照更高层次的语义边界切分。

例如:

1. Introduction

Paragraph 1
Paragraph 2

2. Architecture

Paragraph 3
Paragraph 4

3. Failover

Paragraph 5
Paragraph 6

系统可以优先尝试:

Section
→ Paragraph
→ Sentence
→ Token

只有当上一层粒度超过目标 Chunk Size 时,才继续向下一层切分。

这种策略比:

every 500 tokens

更符合自然语言结构。


8. Semantic Chunking

进一步的思路是:

不按照长度切,而按照语义变化切。

假设:

Sentence 1:
Redis Cluster contains multiple nodes.

Sentence 2:
Each master node can have replicas.

Sentence 3:
Replicas provide redundancy.

Sentence 4:
Prometheus can monitor Redis metrics.

Sentence 5:
Grafana provides visualization.

前 3 句话属于:

Redis Architecture

后 2 句话属于:

Monitoring

因此:

Chunk 1:
Redis Cluster contains multiple nodes.
Each master node can have replicas.
Replicas provide redundancy.

Chunk 2:
Prometheus can monitor Redis metrics.
Grafana provides visualization.

这里的核心不是:

Chunk Size

而是:

Semantic Similarity

9. Semantic Chunking 的基本算法

可以把每个 Sentence 转换成 embedding:

S1 → E1
S2 → E2
S3 → E3
S4 → E4
S5 → E5

计算相邻句子的 cosine similarity:

sim(E1, E2)
sim(E2, E3)
sim(E3, E4)
sim(E4, E5)

假设:

0.91
0.89
0.32
0.93

那么:

S1 ─ S2 ─ S3
          │ semantic boundary
S4 ─ S5

因此:

Chunk 1 = S1 + S2 + S3
Chunk 2 = S4 + S5

这种方法可以自动发现 Topic Boundary。


10. Structure-Aware Chunking

对于企业文档、技术文档、PDF、Markdown、HTML,单纯 Semantic Chunking 仍然不够。

因为文档本身包含大量结构信息:

Title
Heading
Subheading
Paragraph
List
Table
Code
Quote
Figure
Caption

这些结构实际上也是:

Metadata

例如:

## Redis Cluster

### Failover

When a master node fails...

如果只保存:

When a master node fails...

那么 embedding 之后:

Query:
How does Redis Cluster failover work?

可能无法很好地理解:

When a master node fails...

真正有价值的信息是:

Redis Cluster
→ Failover
→ When a master node fails...

因此可以构建:

Chunk Text =
Document Title
+
Section Title
+
Subsection Title
+
Content

例如:

Document: Redis Architecture Guide

Section: Redis Cluster

Subsection: Failover

Content:
When a master node fails, a replica can be promoted...

这比单独 embedding:

When a master node fails...

具有更好的语义定位能力。


11. Parent-Child Chunking

这是生产级 RAG 中非常重要的一种方法。

假设:

Parent Chunk

保存完整上下文:

Redis Cluster Failover
    ├── Child 1
    ├── Child 2
    ├── Child 3
    └── Child 4

检索时:

Query
Child Chunk Retrieval
Find relevant child
Load Parent Chunk
LLM

例如:

Child Chunk:

When a master fails, the replica with the highest
replication offset can be promoted.

这个 Child 非常适合 Retrieval。

但是 LLM 最终获得:

Parent Chunk:

Redis Cluster Failover

Redis uses replicas to provide high availability.

When a master fails, the replica with the highest
replication offset can be promoted.

The cluster then redirects traffic...

于是同时获得:

High Retrieval Precision
+
High Context Completeness

这实际上解决了:

Search Granularity 与 Generation Context 之间的矛盾。


12. Document Hierarchy Chunking

对于大型知识库,可以进一步构建层次结构:

Document
   ├── Section
   │      │
   │      ├── Subsection
   │      │       │
   │      │       ├── Chunk
   │      │       ├── Chunk
   │      │       └── Chunk
   │      │
   │      └── Subsection
   └── Section

这样 Retrieval 不再只是:

Vector → Chunk

而可以:

Query
Section Retrieval
Subsection Retrieval
Chunk Retrieval

这实际上已经开始接近:

Hierarchical Retrieval


13. Chunk Metadata

Chunk 不应该只有:

{
  "text": "..."
}

生产系统应该尽可能保留丰富 Metadata:

{
  "document_id": "redis-guide-001",
  "section": "Redis Cluster",
  "subsection": "Failover",
  "chunk_id": "chunk-042",
  "parent_id": "section-07",
  "page": 42,
  "source": "redis-cluster-guide.pdf",
  "language": "en",
  "version": "v3",
  "created_at": "2026-08-18"
}

这些 Metadata 可以参与:

Filtering
Ranking
Authorization
Debugging
Observability
Citation
Version Control

例如:

Query
+
document_type = architecture
+
version = v3
+
department = engineering

然后再进行 Vector Search。

这通常比单纯依赖 embedding 更可靠。


14. Chunking 与 Embedding 的关系

一个经常被忽略的问题:

Chunk Size 应该和 Embedding Model 配合设计。

假设 Embedding Model 的输入窗口非常大,并不意味着:

Larger Chunk = Better Embedding

Embedding 的目标是:

Text
Semantic Representation
Vector

如果一个 Chunk 同时包含:

Database
Security
Networking
Monitoring
Deployment

那么最终 Vector 很可能成为这些 Topic 的混合表示。

可以粗略理解为:

Embedding Vector
Topic A
+
Topic B
+
Topic C
+
Topic D

于是 Query:

Database indexing

可能无法很好地和这个 Chunk 对齐。

因此:

Embedding Context Window 是 Chunk Size 的上限,而不是 Chunk Size 的目标。


15. Chunking 与 Retrieval 的关系

Chunking 最终必须通过 Retrieval 来验证。

假设:

Top-K = 5

理想情况:

Query
 ├── Chunk A  ★★★
 ├── Chunk B  ★★★
 ├── Chunk C  ★★
 ├── Chunk D  ★
 └── Chunk E  ★

但如果 Chunk 太大:

Chunk A:
很多主题混合

Similarity 可能不够集中。

如果 Chunk 太小:

Chunk A
Chunk B
Chunk C
Chunk D

可能全部来自同一个语义片段。

于是:

Recall ↑
Precision ↓
Diversity ↓

因此 Chunking 实际上会直接影响:

Recall
Precision
MRR
NDCG
Context Relevance
Answer Faithfulness

16. Chunking 与 Reranking

很多团队发现:

Vector Search

效果不好,于是增加:

Reranker

例如:

Query
Vector Search
Top 50
Reranker
Top 5

Reranker 确实可以改善 Retrieval。

但是:

Reranking 不能完全解决错误 Chunking。

假设正确答案被错误地切成:

Chunk A:
When Redis master fails...

Chunk B:
The replica with highest replication offset...

Chunk C:
is promoted to master...

三个 Chunk 分别只有一句。

Reranker 即使发现:

A + B + C

相关,也需要把多个 Chunk 拼起来。

这会增加:

Context Length

同时增加:

Redundancy

所以:

Good Chunking
+
Good Retrieval
+
Good Reranking

才是完整方案。


17. Query-Aware Chunking

更加高级的思路是:

Chunking 不一定应该完全独立于 Query。

传统方式:

Document
Chunk
Embedding
Vector DB

Query-Aware Retrieval 则可以:

Document
Fine-grained Chunks
Index

Query
Understand Intent
Retrieve
Merge related chunks

例如用户问:

What happens when Redis master fails and how does the cluster recover?

这个问题实际上包含两个 sub-topics:

1. Failure Detection
2. Recovery / Promotion

系统可以将 Query 分解:

Q1:
How is master failure detected?

Q2:
How is a replica promoted?

然后:

Q1 → Chunk A
Q2 → Chunk B

最终:

A + B → LLM

这比单纯:

Embedding(Query) → Top-K

更加适合复杂问题。


18. Code Chunking

对于代码知识库,普通文本 Chunking 往往效果很差。

例如:

public class RedisService {

    public void save(String key, String value) {
        ...
    }

    public String get(String key) {
        ...
    }
}

如果简单按照 500 tokens 切:

Chunk 1:
public class RedisService {
    public void save(...)
Chunk 2:
public String get(...)
}

那么代码结构被破坏。

更合理的方法是:

Repository
   ├── Package
   ├── Class
   │    ├── Method
   │    ├── Method
   │    └── Method
   └── Test

例如:

Chunk:
Class = RedisService
Method = save

public void save(String key, String value) {
    ...
}

Metadata:

{
  "language": "java",
  "class": "RedisService",
  "method": "save",
  "package": "com.example.redis"
}

这比普通文本 Chunking 更适合:

Code Search
Code RAG
Repository QA
Bug Analysis

19. Table Chunking

表格是 RAG 中另一个非常容易出问题的场景。

例如:

RegionQ1 RevenueQ2 Revenue
US100120
EU8095
APAC6090

如果 PDF Parser 把它变成:

US 100 120
EU 80 95
APAC 60 90

那么:

What was APAC revenue in Q2?

可能仍然可以检索。

但如果问题是:

Compare APAC revenue growth between Q1 and Q2.

就需要保留:

Column Headers
+
Row
+
Table Title

因此更合理的 Chunk:

Table:
Regional Revenue

Columns:
Region | Q1 Revenue | Q2 Revenue

Row:
APAC | 60 | 90

甚至可以进一步转换成结构化文本:

Regional Revenue.
APAC revenue was 60 in Q1 and 90 in Q2.

对于复杂表格,结构化处理通常优于简单文本切分。


20. Chunking Pipeline

一个成熟的企业 RAG Pipeline 可以设计为:

                Document
              Document Parser
             Structure Analysis
          ┌────────┴────────┐
          │                 │
          ▼                 ▼
       Markdown           PDF
          │                 │
          └────────┬────────┘
             Semantic Units
           Structure-Aware
              Chunking
          Parent / Child Chunks
             Metadata Enrich
               Embedding
             Vector Database

这个 Pipeline 比:

split every N characters

成熟得多。


21. 如何选择 Chunk Size?

没有一个适用于所有场景的:

Best Chunk Size

这是一个非常重要的工程认知。

Chunk Size 应该由以下因素共同决定:

Document Type
+
Embedding Model
+
Query Type
+
Retrieval Strategy
+
LLM Context Window
+
Answer Complexity

一个可以用于实验的起始范围:

场景Chunk Size
FAQ100–300 tokens
Technical Documentation300–800 tokens
General Articles300–700 tokens
Legal Documents500–1000 tokens
Academic Papers500–1200 tokens
CodeFunction/Class based
TablesStructure based

这些不是固定标准,而应该作为:

Experimental Starting Point


22. Chunk Size 应该通过实验决定

不要问:

Chunk Size 应该设置成 500 还是 1000?

更专业的问题应该是:

在我的 Query Distribution 下,哪个 Chunk Size 能获得最好的 Retrieval Quality?

例如建立实验:

Chunk Size:
200
400
600
800
1000

分别测试:

Recall@5
Recall@10
MRR
NDCG
Answer Accuracy
Faithfulness
Latency
Cost

最终得到:

Chunk Size
Retrieval Quality
Answer Quality

例如实验结果:

200 → Recall 82%
400 → Recall 89%
600 → Recall 93%
800 → Recall 92%
1000 → Recall 88%

那么:

600

可能是更合理的选择。


23. Chunking Evaluation

Chunking 不能只通过:

看起来切得挺好。

来判断。

应该建立 Evaluation Dataset:

Question
Ground Truth Chunk
Expected Answer

例如:

{
  "question": "How does Redis failover work?",
  "relevant_chunks": [
    "redis-failover-042"
  ]
}

然后测试:

Query
Retriever
Top-K
Compare Ground Truth

计算:

Recall@K

Recall@K =
Relevant Chunks Retrieved
-------------------------
Total Relevant Chunks

Precision@K

Precision@K =
Relevant Chunks Retrieved
-------------------------
K

MRR

如果正确 Chunk 排名越靠前:

MRR ↑

这意味着:

Chunking 不再是一个“经验参数”,而成为可以通过数据优化的系统参数。


24. Chunking 的一个更深层理解

如果从 Information Retrieval 的角度来看:

Document

是一个非常大的 Information Unit。

Chunking 做的实际上是:

Document
Information Units
Retrieval Units

因此 Chunk 并不是:

Document 的一小段。

而是:

Searchable Knowledge Unit

这是理解 Chunking 最关键的一点。


25. Chunking 的最终目标

优秀的 Chunking Strategy 应该让:

Query
Relevant Knowledge
Relevant Chunk
Relevant Context
Correct Answer

形成一条稳定的信息链。

而糟糕的 Chunking 往往形成:

Query
Wrong Chunk
Reranker
More Chunks
LLM
Hallucination

所以很多所谓:

“RAG 效果不好”

实际上并不是:

LLM 不够强

也不是:

Vector Database 不够好

而可能是:

Chunking Strategy 不合理

26. 推荐的企业级 Chunking Architecture

如果设计一个生产级 RAG 系统,我更推荐:

                    Documents
                 Document Parser
              Structure Extraction
        ┌───────────────┴───────────────┐
        │                               │
        ▼                               ▼
   Text Structure                  Tables / Code
        │                               │
        ▼                               ▼
 Semantic / Recursive             Specialized Parser
      Chunking                          │
        │                               │
        └───────────────┬───────────────┘
                Parent / Child
                     Chunks
                  Metadata Layer
                    Embedding
                 Vector Database
                    Retrieval
                    Reranking
                   Context Builder
                       LLM

这里最重要的思想是:

不同类型的数据,不应该使用同一种 Chunking Strategy。


27. Chunking Strategy Decision Matrix

可以建立如下决策模型:

                    Document
            ┌──────────┼──────────┐
            │          │          │
           FAQ       Article     Code
            │          │          │
         Small      Semantic    Function
         Chunk      Chunking     Chunking
            │          │          │
            └──────────┼──────────┘
                 Enterprise RAG

进一步:

文档类型推荐策略
FAQQuestion-Answer Chunk
MarkdownHeading-Aware Chunk
HTMLDOM-Aware Chunk
PDFLayout + Semantic Chunk
Technical DocsHierarchical Chunk
CodeAST / Function Chunk
TablesTable-Aware Chunk
LegalSection / Clause Chunk
EmailThread / Message Chunk
LogsTime-window / Event Chunk

这说明:

Chunking 应该是 Data-Type Aware 的。


28. 从 Chunking 走向 Context Engineering

Chunking 最终会自然演化成:

Context Engineering

因为真正的问题不是:

How to split documents?

而是:

How to construct the optimal context
for an LLM?

这会进一步涉及:

Chunking
+
Retrieval
+
Reranking
+
Context Compression
+
Context Filtering
+
Metadata Filtering
+
Query Expansion
+
Parent Context
+
Conversation Context

最终形成:

User Query
Query Understanding
Retrieval
Reranking
Context Compression
Context Assembly
LLM

因此:

Chunking 是 Context Engineering 的基础设施。


29. 最值得记住的几个结论

如果只记住这篇文章的几个核心观点,可以总结为:

第一

Chunking 不是文本切割问题,而是知识粒度设计问题。

第二

Chunk Size 没有 universally optimal value,必须通过 Retrieval Evaluation 确定。

第三

Chunk 应该优先保持 Semantic Cohesion,而不是机械追求固定长度。

第四

Overlap 的目标是减少 Boundary Information Loss,而不是越大越好。

第五

Structure-aware Chunking 通常优于纯 Fixed-size Chunking。

第六

Parent-Child Chunking 可以同时解决 Retrieval Precision 和 Context Completeness。

第七

Code、Table、PDF、Legal Document 等不同数据类型应该使用不同 Chunking Strategy。

第八

Chunking 的质量最终应该通过 Recall、Precision、MRR、NDCG 和 End-to-End Answer Quality 来验证。


30. Conclusion

在 RAG 系统中:

Embedding 决定如何表示知识
Vector Database 决定如何存储知识
Retriever 决定如何寻找知识
Reranker 决定哪些知识更重要
LLM 决定如何利用知识

而:

Chunking

决定的是:

系统究竟把什么东西定义为“知识”。

这是为什么 Chunking 看似简单,却是 RAG 系统中最值得深入研究的基础技术之一。

一个成熟的 RAG 系统不应该简单地使用:

text[:500]

然后认为问题已经解决。

真正生产级的 Chunking 应该逐渐演化为:

Structure-Aware
+
Semantic-Aware
+
Metadata-Aware
+
Query-Aware
+
Domain-Aware
+
Evaluation-Driven

最终目标不是生成更多 Chunk,而是生成:

更容易被检索、更容易被理解、更容易被正确利用的 Knowledge Units。

从这个角度来看,Chunking 并不是 RAG Pipeline 中一个简单的 preprocessing step。

它实际上是:

Document
Knowledge Representation
Retrieval Unit
Context Construction
LLM Reasoning

之间的关键桥梁。

而这也是为什么:

RAG 的效果上限,很大程度上取决于你如何切分知识。

Vincent zhai
Vincent zhai
Full-Stack Engineer