11種Spring?AI文檔切割策略全解析
項(xiàng)目源碼:github.com/XiFYuW/spring-ai-course/tree/main/phase-15
一、前言
1.1 為什么文檔切割如此重要
在 RAG(檢索增強(qiáng)生成)系統(tǒng)中,文檔切割(Document Splitting)是最關(guān)鍵的前置步驟之一:
- 影響檢索精度:切割得當(dāng),檢索更準(zhǔn)確
- 影響上下文完整性:保持語(yǔ)義連貫性
- 影響 Token 利用率:避免浪費(fèi) LLM 的上下文窗口
- 影響響應(yīng)質(zhì)量:好的切割 = 更好的回答
1.2 本文將收獲什么
讀完本文,你將掌握:
- 11 種切割策略的核心原理和適用場(chǎng)景
- 5 種新高級(jí)策略的詳細(xì)使用方法
- 如何根據(jù)文檔類(lèi)型選擇最佳策略
- 實(shí)戰(zhàn)中的性能優(yōu)化技巧
二、環(huán)境準(zhǔn)備
2.1 項(xiàng)目依賴(lài)
<dependencies>
<!-- Spring AI OpenAI -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<!-- Spring AI Elasticsearch Vector Store -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-elasticsearch</artifactId>
</dependency>
<!-- WebFlux -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>2.2 配置文件
# application.yml
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
embedding:
options:
model: text-embedding-3-small
vectorstore:
elasticsearch:
index-name: document-store
dimensions: 1536三、基礎(chǔ)策略回顧
在深入新策略之前,先快速回顧 6 種基礎(chǔ)策略:
| 策略 | 特點(diǎn) | 適用場(chǎng)景 |
|---|---|---|
| RECURSIVE | 遞歸字符切割,保持語(yǔ)義完整性 | 通用文本 |
| MARKDOWN | 識(shí)別標(biāo)題層級(jí),保留文檔結(jié)構(gòu) | Markdown 文檔 |
| TOKEN | 估算 Token 數(shù)量,適配 LLM 限制 | 需要精確控制 Token |
| SEMANTIC | 基于 Embedding 相似度切割 | 高質(zhì)量語(yǔ)義切割 |
| SMART_PARAGRAPH | 段落+字符混合切割 | 長(zhǎng)段落文檔 |
| CHARACTER | 固定字符切割,簡(jiǎn)單快速 | 快速處理 |
四、新策略詳解
4.1 Agentic 切割 - 智能主題邊界
4.1.1 核心思想
Agentic 切割借鑒了 LLM Agent 的理念,使用啟發(fā)式規(guī)則在主題邊界處進(jìn)行切割,確保每個(gè)塊都圍繞一個(gè)完整的主題。
4.1.2 實(shí)現(xiàn)原理
/**
* Agentic 切割核心邏輯
*
* 1. 首先使用遞歸切割獲得初步塊
* 2. 識(shí)別主題轉(zhuǎn)換標(biāo)記詞
* 3. 在主題邊界處優(yōu)化切割點(diǎn)
*/
public List<Document> splitAgentic(String text, String filename, SplitOptions options) {
// 第一步:遞歸切割獲得初步塊
List<TextChunk> initialChunks = recursiveSplitInternal(
normalizeText(text),
0,
chunkSize * 2, // 更大的初始?jí)K
chunkOverlap,
0
);
// 第二步:使用啟發(fā)式規(guī)則優(yōu)化切割點(diǎn)
for (TextChunk chunk : initialChunks) {
// 識(shí)別主題轉(zhuǎn)換標(biāo)記詞
String optimizedContent = optimizeChunkBoundary(content, chunkSize);
// ...
}
}
4.1.3 主題標(biāo)記詞識(shí)別
// 主題轉(zhuǎn)換標(biāo)記詞(中英文)
String[] topicMarkers = {
// 標(biāo)點(diǎn)符號(hào)
"\n\n", "\n", ". ", "? ", "! ", "。", "?", "!",
// 中文序列詞
"首先", "其次", "然后", "接下來(lái)", "最后",
"第一", "第二", "第三", "另一方面", "此外", "總之"
};
4.1.4 使用示例
# 上傳長(zhǎng)文檔,使用 Agentic 切割 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=AGENTIC&chunkSize=1500" \ -F "file=@long-article.txt"
返回的元數(shù)據(jù):
{
"split_method": "agentic",
"original_separator": "\n\n",
"optimization_applied": true,
"chunk_group": 0
}
4.1.5 適用場(chǎng)景
- 長(zhǎng)篇文章:確保每個(gè)塊圍繞一個(gè)主題
- 技術(shù)文檔:保持概念完整性
- 論文/報(bào)告:避免在論證中間切割
4.2 代碼感知切割 - 程序員的福音
4.2.1 核心思想
代碼感知切割專(zhuān)門(mén)針對(duì)源代碼文件,能夠識(shí)別:
- 函數(shù)/方法邊界
- 類(lèi)/接口/枚舉定義
- Import/依賴(lài)語(yǔ)句
- 代碼注釋
4.2.2 支持的語(yǔ)言
| 語(yǔ)言 | 擴(kuò)展名 | 識(shí)別能力 |
|---|---|---|
| Java | .java | 類(lèi)、接口、枚舉、方法、注解 |
| Python | .py | 類(lèi)、函數(shù)、裝飾器 |
| JavaScript/TypeScript | .js, .ts | 函數(shù)、類(lèi)、箭頭函數(shù) |
| Go | .go | 函數(shù)、結(jié)構(gòu)體、接口 |
| Rust | .rs | 函數(shù)、結(jié)構(gòu)體、枚舉、trait |
| C/C++ | .c, .cpp, .cc | 函數(shù)、類(lèi)、結(jié)構(gòu)體 |
| C# | .cs | 類(lèi)、接口、方法、屬性 |
| PHP | .php | 類(lèi)、函數(shù)、命名空間 |
| Ruby | .rb | 類(lèi)、方法、模塊 |
| Swift | .swift | 類(lèi)、函數(shù)、結(jié)構(gòu)體 |
| Kotlin | .kt | 類(lèi)、函數(shù)、接口 |
| Scala | .scala | 類(lèi)、特質(zhì)、函數(shù) |
4.2.3 實(shí)現(xiàn)原理
/**
* 代碼感知切割
*
* 1. 檢測(cè)編程語(yǔ)言
* 2. 解析代碼塊(類(lèi)、方法等)
* 3. 提取 import 語(yǔ)句
* 4. 按代碼結(jié)構(gòu)切割
*/
public List<Document> splitCodeAware(String text, String filename, SplitOptions options) {
// 檢測(cè)語(yǔ)言
String language = detectLanguage(filename);
// 解析代碼塊
List<CodeBlock> codeBlocks = parseCodeBlocks(text, language);
// 提取 imports
List<String> imports = extractImports(text, language);
// 構(gòu)建文檔
for (CodeBlock block : codeBlocks) {
Map<String, Object> metadata = buildCodeMetadata(
filename, chunkIndex, block, imports, language
);
// ...
}
}
4.2.4 代碼塊解析示例
// Java 代碼塊解析正則
Pattern pattern = Pattern.compile(
"(?:(public|private|protected|static|final|abstract|class|interface|enum|record|void|@\\w+)\\s+)?" +
"(?:<[^>]+>\\s*)?" +
"(\\w+)\\s*\\([^)]*\\)\\s*(?:throws\\s+\\w+(?:\\s*,\\s*\\w+)*)?\\s*\\{[^}]*\\}" +
"|(?:public|private|protected)?\\s*(?:static\\s+)?(?:final\\s+)?(?:abstract\\s+)?" +
"(?:class|interface|enum|record)\\s+(\\w+)",
Pattern.DOTALL
);
4.2.5 使用示例
# 上傳 Java 文件 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=CODE_AWARE" \ -F "file=@UserService.java" # 上傳 Python 文件 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=CODE_AWARE" \ -F "file=@main.py"
返回的元數(shù)據(jù):
{
"split_method": "code_aware",
"language": "java",
"block_type": "method",
"block_name": "getUserById",
"start_line": 45,
"imports_count": 12,
"has_imports": true
}4.2.6 適用場(chǎng)景
- 代碼庫(kù) RAG:構(gòu)建代碼知識(shí)庫(kù)
- 代碼審查:按方法檢索相關(guān)代碼
- 技術(shù)文檔:配合代碼示例的文檔
4.3 層次結(jié)構(gòu)切割 - 文檔樹(shù)構(gòu)建
4.3.1 核心思想
層次結(jié)構(gòu)切割將文檔構(gòu)建成樹(shù)狀結(jié)構(gòu):
文檔 (Root)
├── 章節(jié) 1 (Chapter)
│ ├── 小節(jié) 1.1 (Section)
│ │ ├── 段落 1 (Paragraph)
│ │ └── 段落 2 (Paragraph)
│ └── 小節(jié) 1.2 (Section)
│ └── 段落 3 (Paragraph)
└── 章節(jié) 2 (Chapter)
└── 小節(jié) 2.1 (Section)
└── 段落 4 (Paragraph)
4.3.2 實(shí)現(xiàn)原理
/**
* 層次結(jié)構(gòu)切割
*
* 構(gòu)建文檔樹(shù):文檔 → 章節(jié) → 小節(jié) → 段落
*/
public List<Document> splitHierarchical(String text, String filename, SplitOptions options) {
// 構(gòu)建層次樹(shù)
DocumentNode root = buildHierarchicalTree(text, filename);
// 展平樹(shù)為文檔列表
List<Document> documents = new ArrayList<>();
flattenTree(root, documents, filename, 0, maxChunkSize);
return documents;
}
/**
* 構(gòu)建層次樹(shù)
*/
private DocumentNode buildHierarchicalTree(String text, String filename) {
DocumentNode root = new DocumentNode("root", "document", text, 0, 0);
// 第一層:按章節(jié)分割
String[] chapters = text.split(
"(?=(?:^|\\n)\\s*(?:第[一二三四五六七八九十\\d]+[章節(jié)篇]|Chapter\\s+\\d+|\\d+\\.\\s+[^\\n]+))"
);
// 第二層:按小節(jié)分割
// 第三層:按段落分割
// ...
}
4.3.3 章節(jié)識(shí)別模式
| 模式 | 示例 |
|---|---|
| 中文章節(jié) | 第一章, 第二節(jié), 第三篇 |
| 英文章節(jié) | Chapter 1, Chapter 2 |
| 數(shù)字章節(jié) | 1. 引言, 2. 背景 |
4.3.4 使用示例
# 上傳結(jié)構(gòu)化長(zhǎng)文檔 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=HIERARCHICAL&chunkSize=2000" \ -F "file=@book.txt"
返回的元數(shù)據(jù):
{
"split_method": "hierarchical",
"node_id": "section_0_1",
"node_type": "section",
"hierarchy_level": 2,
"node_index": 1,
"has_children": true,
"children_count": 3
}4.3.5 適用場(chǎng)景
- 書(shū)籍/教材:保持章節(jié)結(jié)構(gòu)
- 技術(shù)手冊(cè):按章節(jié)檢索
- 法律文檔:保持條款層次
- 論文:保持章節(jié)邏輯
4.4 滑動(dòng)窗口切割 - RAG 神器
4.4.1 核心思想
滑動(dòng)窗口切割使用高重疊率(默認(rèn) 50%)的窗口滑動(dòng)切割文本,確保:
- 無(wú)信息遺漏:每個(gè)位置都被多個(gè)窗口覆蓋
- 上下文連續(xù)性:相鄰塊有大量重疊
- 檢索召回率提升:適合 RAG 場(chǎng)景
4.4.2 實(shí)現(xiàn)原理
/**
* 滑動(dòng)窗口切割
*
* 特點(diǎn):
* - 高重疊率(默認(rèn) 50%)
* - 確保沒(méi)有信息遺漏
* - 適合檢索增強(qiáng)生成 (RAG)
*/
public List<Document> splitSlidingWindow(String text, String filename, SplitOptions options) {
int windowSize = options.getChunkSize() != null ? options.getChunkSize() : DEFAULT_CHUNK_SIZE;
int overlapRatio = options.getChunkOverlap() != null ? options.getChunkOverlap() : 50;
// 計(jì)算步長(zhǎng)
int stride = Math.max(1, windowSize * (100 - overlapRatio) / 100);
while (startIndex < normalizedText.length()) {
int endIndex = Math.min(startIndex + windowSize, normalizedText.length());
// 嘗試在句子邊界結(jié)束
if (endIndex < normalizedText.length()) {
endIndex = findBestSplitPoint(normalizedText, endIndex);
}
// 滑動(dòng)窗口
startIndex += stride;
}
}
4.4.3 重疊率計(jì)算
| 窗口大小 | 重疊率 | 步長(zhǎng) | 效果 |
|---|---|---|---|
| 1000 | 50% | 500 | 中等重疊 |
| 1000 | 70% | 300 | 高重疊,高召回 |
| 1000 | 30% | 700 | 低重疊,高效率 |
4.4.4 使用示例
# 高重疊率(70%)- 適合高精度檢索 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=SLIDING_WINDOW&chunkSize=1000&chunkOverlap=70" \ -F "file=@document.txt" # 中等重疊率(50%)- 平衡方案 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=SLIDING_WINDOW&chunkSize=1000&chunkOverlap=50" \ -F "file=@document.txt"
返回的元數(shù)據(jù):
{
"split_method": "sliding_window",
"window_start": 0,
"window_end": 1000,
"window_size": 1000,
"stride": 500,
"overlap_ratio": 50,
"overlap_with_previous": 0
}4.4.5 適用場(chǎng)景
- RAG 系統(tǒng):提升檢索召回率
- 問(wèn)答系統(tǒng):確保答案不被切割
- 長(zhǎng)文檔檢索:避免邊界信息丟失
- 關(guān)鍵信息提取:多重覆蓋確保完整
4.5 結(jié)構(gòu)化數(shù)據(jù)切割 - 數(shù)據(jù)文件專(zhuān)用
4.5.1 核心思想
結(jié)構(gòu)化數(shù)據(jù)切割專(zhuān)門(mén)針對(duì) CSV、JSON、XML、YAML 等結(jié)構(gòu)化格式,保持記錄完整性。
4.5.2 自動(dòng)格式檢測(cè)
/**
* 檢測(cè)結(jié)構(gòu)化數(shù)據(jù)格式
*/
private String detectStructuredFormat(String filename, String content) {
String lower = filename.toLowerCase();
if (lower.endsWith(".csv")) return "csv";
if (lower.endsWith(".json")) return "json";
if (lower.endsWith(".xml")) return "xml";
if (lower.endsWith(".yaml") || lower.endsWith(".yml")) return "yaml";
// 根據(jù)內(nèi)容檢測(cè)
String trimmed = content.trim();
if (trimmed.startsWith("[") || trimmed.startsWith("{")) return "json";
if (trimmed.startsWith("<?xml") || trimmed.startsWith("<")) return "xml";
// ...
}
4.5.3 CSV 切割
/**
* CSV 切割 - 保留表頭
*/
private List<Document> splitCsv(String text, String filename, SplitOptions options) {
int maxRows = options.getChunkSize() != null ? options.getChunkSize() / 50 : 100;
// 提取表頭
String header = lines[0];
List<String> headers = parseCsvLine(header);
// 每個(gè)塊都包含表頭
for (String line : dataLines) {
if (rowCount >= maxRows) {
// 保存當(dāng)前塊
// 新塊以表頭開(kāi)始
currentChunk.append(header).append("\n");
}
currentChunk.append(line).append("\n");
}
}
4.5.4 JSON 切割
/**
* JSON 切割 - 按對(duì)象/條目分割
*/
private List<Document> splitJson(String text, String filename, SplitOptions options) {
// JSON 數(shù)組:提取每個(gè)對(duì)象
if (trimmed.startsWith("[")) {
List<String> objects = extractJsonObjects(trimmed);
processJsonObjects(objects, filename, documents, maxSize);
}
// JSON 對(duì)象:按頂層鍵分割
else if (trimmed.startsWith("{")) {
List<String> entries = extractJsonEntries(trimmed);
processJsonObjects(entries, filename, documents, maxSize);
}
}
4.5.5 XML 切割
/**
* XML 切割 - 按元素分割
*/
private List<Document> splitXml(String text, String filename, SplitOptions options) {
// 提取 XML 聲明
String declaration = "";
int declEnd = text.indexOf("?>");
if (declEnd > 0) {
declaration = text.substring(0, declEnd + 2) + "\n";
}
// 提取主要元素
List<String> elements = extractXmlElements(text);
// 每個(gè)塊包含聲明
for (String elem : elements) {
currentChunk.append(declaration);
currentChunk.append(elem);
}
}
4.5.6 使用示例
# CSV 文件 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=STRUCTURED_DATA" \ -F "file=@users.csv" # JSON 文件 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=STRUCTURED_DATA" \ -F "file=@data.json" # XML 文件 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=STRUCTURED_DATA" \ -F "file=@config.xml" # YAML 文件 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=STRUCTURED_DATA" \ -F "file=@config.yaml"
返回的元數(shù)據(jù)(CSV):
{
"split_method": "structured_data",
"format": "csv",
"start_index": 1,
"end_index": 100,
"record_count": 100,
"headers": ["id", "name", "email"],
"header_count": 3
}返回的元數(shù)據(jù)(JSON):
{
"split_method": "structured_data",
"format": "json",
"start_index": 0,
"end_index": 49,
"record_count": 50
}4.5.7 適用場(chǎng)景
- 數(shù)據(jù)文件處理:CSV、JSON、XML、YAML
- 配置文件檢索:按配置項(xiàng)檢索
- 日志分析:結(jié)構(gòu)化日志處理
- API 文檔:OpenAPI/Swagger 規(guī)范
五、策略選擇指南
5.1 按文檔類(lèi)型選擇
文檔類(lèi)型
├── 普通文本
│ ├── 短文本 → CHARACTER
│ ├── 長(zhǎng)文章 → RECURSIVE / AGENTIC
│ └── 需要高召回 → SLIDING_WINDOW
├── Markdown
│ ├── 技術(shù)文檔 → MARKDOWN
│ └── 博客文章 → MARKDOWN / AGENTIC
├── 代碼文件
│ ├── Java/Python/JS → CODE_AWARE
│ └── 通用代碼 → RECURSIVE
├── 結(jié)構(gòu)化數(shù)據(jù)
│ ├── CSV → STRUCTURED_DATA
│ ├── JSON → STRUCTURED_DATA
│ ├── XML → STRUCTURED_DATA
│ └── YAML → STRUCTURED_DATA
├── 書(shū)籍/論文
│ ├── 教材 → HIERARCHICAL
│ ├── 論文 → HIERARCHICAL
│ └── 手冊(cè) → HIERARCHICAL
└── 特殊需求
├── 精確 Token 控制 → TOKEN
├── 語(yǔ)義連貫性 → SEMANTIC
└── 段落完整性 → SMART_PARAGRAPH
5.2 按使用場(chǎng)景選擇
| 場(chǎng)景 | 推薦策略 | 原因 |
|---|---|---|
| 快速原型 | CHARACTER | 簡(jiǎn)單快速 |
| 生產(chǎn)環(huán)境 | RECURSIVE | 平衡效果與性能 |
| 高質(zhì)量 RAG | SLIDING_WINDOW | 高召回率 |
| 代碼知識(shí)庫(kù) | CODE_AWARE | 保持代碼結(jié)構(gòu) |
| 企業(yè)文檔 | HIERARCHICAL | 保持文檔層次 |
| 數(shù)據(jù)檢索 | STRUCTURED_DATA | 記錄完整性 |
| 語(yǔ)義搜索 | SEMANTIC | 基于語(yǔ)義切割 |
5.3 參數(shù)調(diào)優(yōu)建議
| 策略 | chunkSize | chunkOverlap | 說(shuō)明 |
|---|---|---|---|
| RECURSIVE | 1000-1500 | 200 | 標(biāo)準(zhǔn)配置 |
| AGENTIC | 1500-2000 | 200 | 更大的塊保持主題 |
| CODE_AWARE | 2000-3000 | 0 | 按代碼塊自然分割 |
| HIERARCHICAL | 2000-5000 | 0 | 按層次自然分割 |
| SLIDING_WINDOW | 1000 | 50-70 | 高重疊率 |
| STRUCTURED_DATA | - | - | 按記錄數(shù)控制 |
六、API 使用示例
6.1 完整 API 列表
# 基礎(chǔ)策略 POST /api/vector-store/upload?splitStrategy=RECURSIVE POST /api/vector-store/upload?splitStrategy=MARKDOWN POST /api/vector-store/upload?splitStrategy=TOKEN POST /api/vector-store/upload?splitStrategy=SEMANTIC POST /api/vector-store/upload?splitStrategy=SMART_PARAGRAPH POST /api/vector-store/upload?splitStrategy=CHARACTER # 新策略 POST /api/vector-store/upload?splitStrategy=AGENTIC POST /api/vector-store/upload?splitStrategy=CODE_AWARE POST /api/vector-store/upload?splitStrategy=HIERARCHICAL POST /api/vector-store/upload?splitStrategy=SLIDING_WINDOW POST /api/vector-store/upload?splitStrategy=STRUCTURED_DATA
6.2 完整請(qǐng)求示例
# 1. Agentic 切割 - 長(zhǎng)文章 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=AGENTIC&chunkSize=1500&chunkOverlap=200" \ -H "Content-Type: multipart/form-data" \ -F "file=@article.txt" # 2. 代碼感知切割 - Java 文件 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=CODE_AWARE" \ -F "file=@UserService.java" # 3. 層次結(jié)構(gòu)切割 - 書(shū)籍 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=HIERARCHICAL&chunkSize=3000" \ -F "file=@book.txt" # 4. 滑動(dòng)窗口切割 - RAG 場(chǎng)景 curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=SLIDING_WINDOW&chunkSize=1000&chunkOverlap=70" \ -F "file=@knowledge-base.txt" # 5. 結(jié)構(gòu)化數(shù)據(jù)切割 - CSV curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=STRUCTURED_DATA" \ -F "file=@products.csv" # 6. 結(jié)構(gòu)化數(shù)據(jù)切割 - JSON curl -X POST "http://localhost:8080/api/vector-store/upload?splitStrategy=STRUCTURED_DATA" \ -F "file=@api-docs.json"
6.3 響應(yīng)示例
{
"success": true,
"message": "File uploaded and processed successfully",
"data": {
"filename": "article.txt",
"chunkCount": 12,
"totalCharacters": 15420,
"splitMethod": "AGENTIC",
"message": "Processed with AGENTIC strategy"
}
}七、性能優(yōu)化建議
7.1 大文件處理
// 對(duì)于大文件,建議:
// 1. 使用流式處理
// 2. 增加 chunkSize 減少塊數(shù)
// 3. 使用異步處理
// 推薦配置
SplitOptions options = new SplitOptions()
.withChunkSize(2000) // 更大的塊
.withChunkOverlap(100); // 較小的重疊
7.2 批量處理
// 批量上傳多個(gè)文件
for (File file : files) {
// 根據(jù)文件類(lèi)型選擇策略
SplitStrategy strategy = selectStrategy(file);
documentSplitterService.split(
readFile(file),
file.getName(),
strategy,
options
);
}
7.3 緩存優(yōu)化
// 對(duì)于重復(fù)處理的文檔,可以緩存切割結(jié)果
@Cacheable(value = "documentChunks", key = "#filename + '_' + #strategy")
public List<Document> split(String text, String filename, SplitStrategy strategy) {
// ...
}
八、總結(jié)
8.1 11 種策略一覽
| 策略 | 類(lèi)型 | 核心優(yōu)勢(shì) |
|---|---|---|
| RECURSIVE | 基礎(chǔ) | 語(yǔ)義完整性 |
| MARKDOWN | 基礎(chǔ) | 結(jié)構(gòu)保留 |
| TOKEN | 基礎(chǔ) | Token 精確控制 |
| SEMANTIC | 基礎(chǔ) | 語(yǔ)義相似度 |
| SMART_PARAGRAPH | 基礎(chǔ) | 段落完整性 |
| CHARACTER | 基礎(chǔ) | 簡(jiǎn)單快速 |
| AGENTIC | 新增 | 智能主題邊界 |
| CODE_AWARE | 新增 | 代碼結(jié)構(gòu)識(shí)別 |
| HIERARCHICAL | 新增 | 文檔樹(shù)構(gòu)建 |
| SLIDING_WINDOW | 新增 | 高召回率 |
| STRUCTURED_DATA | 新增 | 數(shù)據(jù)完整性 |
8.2 核心要點(diǎn)
- 沒(méi)有最好的策略,只有最適合的策略
- 根據(jù)文檔類(lèi)型選擇:代碼用 CODE_AWARE,數(shù)據(jù)用 STRUCTURED_DATA
- 根據(jù)場(chǎng)景選擇:RAG 用 SLIDING_WINDOW,書(shū)籍用 HIERARCHICAL
- 參數(shù)調(diào)優(yōu)很重要:chunkSize 和 chunkOverlap 需要根據(jù)實(shí)際需求調(diào)整
8.3 后續(xù)學(xué)習(xí)
- 深入理解 Embedding 原理
- 學(xué)習(xí)向量數(shù)據(jù)庫(kù)優(yōu)化
- 探索多模態(tài)文檔處理
- 研究 Agentic RAG 架構(gòu)
以上就是11種Spring AI文檔切割策略全解析的詳細(xì)內(nèi)容,更多關(guān)于Spring AI文檔切割的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot使用Caffeine實(shí)現(xiàn)緩存的示例代碼
本文主要介紹了SpringBoot使用Caffeine實(shí)現(xiàn)緩存的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
Java內(nèi)存劃分:運(yùn)行時(shí)數(shù)據(jù)區(qū)域
聽(tīng)說(shuō)Java運(yùn)行時(shí)環(huán)境的內(nèi)存劃分是挺進(jìn)BAT的必經(jīng)之路,這篇文章主要給大家介紹了關(guān)于Java運(yùn)行時(shí)數(shù)據(jù)區(qū)域(內(nèi)存劃分)的相關(guān)資料,需要的朋友可以參考下2021-07-07
Java 8 中 Map 騷操作之 merge() 的使用方法
本文簡(jiǎn)單介紹了一下Map.merge()的方法,除此之外,Java 8 中的HashMap實(shí)現(xiàn)方法使用了TreeNode和 紅黑樹(shù),原理很相似,今天通過(guò)本文給大家介紹Java 8 中 Map 騷操作之 merge() 的用法 ,需要的朋友參考下吧2021-07-07
Java整合mybatis實(shí)現(xiàn)過(guò)濾數(shù)據(jù)
這篇文章主要介紹了Java整合mybatis實(shí)現(xiàn)過(guò)濾數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01
Java 線程安全與 volatile與單例模式問(wèn)題及解決方案
文章主要講解線程安全問(wèn)題的五個(gè)成因(調(diào)度隨機(jī)、變量修改、非原子操作、內(nèi)存可見(jiàn)性、指令重排序)及解決方案,強(qiáng)調(diào)使用volatile關(guān)鍵字可同時(shí)解決內(nèi)存可見(jiàn)性和指令重排問(wèn)題,并結(jié)合單例模式中的餓漢與懶漢實(shí)現(xiàn)方式分析線程安全的處理,感興趣的朋友一起看看吧2025-06-06
SpringBoot中的WebSocketSession原理詳解
這篇文章主要介紹了SpringBoot中的WebSocketSession原理詳解,傳統(tǒng)的?HTTP?協(xié)議是無(wú)法支持實(shí)時(shí)通信的,因?yàn)樗且环N無(wú)狀態(tài)協(xié)議,每次請(qǐng)求都是獨(dú)立的,無(wú)法保持連接。為了解決這個(gè)問(wèn)題,WebSocket?協(xié)議被引入,需要的朋友可以參考下2023-07-07

