Skip to main content

LangChain Go TextSplitter 使用案例

这个项目演示了如何在 Go 语言中使用 LangChain 的 TextSplitter 组件来分割和处理文本文档。

项目结构

langchain_textsp/
├── go.mod # Go 模块配置
├── main.go # 基础 TextSplitter 使用示例
├── document_processor.go # 文档处理器实现和高级用法
├── configuration_demo.go # 配置选项详解和对比
└── README.md # 项目说明文档

功能特性

1. 基础文本分割器

  • 字符文本分割器 (Character Text Splitter): 使用单一分隔符分割文本
  • 递归字符文本分割器 (Recursive Character Text Splitter): 按优先级尝试多个分隔符
  • Token 文本分割器 (Token Text Splitter): 基于 Token 数量分割
  • Markdown 文本分割器 (Markdown Text Splitter): 专门处理 Markdown 格式文档

2. 配置选项

  • 块大小 (Chunk Size): 控制每个文本块的大小
  • 块重叠 (Chunk Overlap): 设置相邻块之间的重叠内容
  • 分隔符 (Separators): 定义文本分割的分隔符优先级
  • 长度函数 (Length Function): 自定义文本长度计算方式
  • 保持分隔符 (Keep Separator): 是否在分割后保留分隔符

3. 高级功能

  • 文档处理器: 封装了分割逻辑并添加元数据管理
  • 批量处理: 同时处理多个文档
  • 元数据支持: 为每个文档块添加自定义元数据
  • 代码文档处理: 专门优化的代码文档分割策略

快速开始

1. 安装依赖

go mod tidy

2. 运行基础示例

go run main.go

这将展示不同类型的 TextSplitter 的基本用法。

3. 运行文档处理示例

go run document_processor.go

这将演示如何处理实际的文档,包括技术文档和代码文档。

4. 运行配置选项演示

go run configuration_demo.go

这将详细展示各种配置选项的效果和对比。

使用场景

1. RAG (Retrieval-Augmented Generation) 系统

将长文档分割成适合向量化和检索的小块:

splitter := textsplitter.NewRecursiveCharacter(
textsplitter.WithChunkSize(1000),
textsplitter.WithChunkOverlap(200),
textsplitter.WithSeparators([]string{"\n\n", "\n", "。", " "}),
)

2. 文档问答系统

为问答系统准备上下文相关的文档片段:

splitter := textsplitter.NewRecursiveCharacter(
textsplitter.WithChunkSize(500),
textsplitter.WithChunkOverlap(50),
textsplitter.WithSeparators([]string{"\n\n"}),
)

3. 代码分析

分割代码文档以便进行语义分析:

splitter := textsplitter.NewRecursiveCharacter(
textsplitter.WithChunkSize(800),
textsplitter.WithChunkOverlap(100),
textsplitter.WithSeparators([]string{"\n\nfunc ", "\n\ntype ", "\n\n", "\n"}),
)

4. 多语言文档处理

处理中文文档时的特殊配置:

splitter := textsplitter.NewRecursiveCharacter(
textsplitter.WithChunkSize(300),
textsplitter.WithChunkOverlap(30),
textsplitter.WithSeparators([]string{"\n\n", "\n", "。", "!", "?", ";", ","}),
textsplitter.WithLenFunc(func(s string) int {
// 中文字符计算为2个单位
length := 0
for _, r := range s {
if r > 127 {
length += 2
} else {
length += 1
}
}
return length
}),
)

最佳实践

1. 选择合适的分割器

  • 递归字符分割器: 大多数场景的首选,提供最好的语义连贯性
  • Token 分割器: 与语言模型集成时,需要精确控制 Token 数量
  • Markdown 分割器: 处理 Markdown 文档时保持结构完整性

2. 配置建议

  • 块大小: 根据下游任务选择,一般 200-1000 字符
  • 重叠: 设置为块大小的 10-20%,保证上下文连续性
  • 分隔符: 优先使用语义分隔符(段落、句子),再使用语法分隔符

3. 性能优化

  • 大文档处理时使用流式处理
  • 批量处理多个文档时复用分割器实例
  • 根据文档类型选择合适的分隔符策略

常见问题

Q: 如何处理非常长的文档?

A: 可以先进行粗分割,再对每个大块进行细分割:

// 第一层:粗分割
coarseSplitter := textsplitter.NewRecursiveCharacter(
textsplitter.WithChunkSize(5000),
textsplitter.WithSeparators([]string{"\n\n"}),
)

// 第二层:细分割
fineSplitter := textsplitter.NewRecursiveCharacter(
textsplitter.WithChunkSize(1000),
textsplitter.WithChunkOverlap(100),
)

Q: 如何保持代码的完整性?

A: 使用专门的代码分隔符,并增加重叠:

splitter := textsplitter.NewRecursiveCharacter(
textsplitter.WithChunkSize(1500),
textsplitter.WithChunkOverlap(300),
textsplitter.WithSeparators([]string{
"\n\nclass ", "\n\nfunc ", "\n\ndef ", "\n\n", "\n", " "
}),
)

Q: 如何处理多语言混合文档?

A: 使用通用的分隔符并自定义长度函数:

splitter := textsplitter.NewRecursiveCharacter(
textsplitter.WithSeparators([]string{"\n\n", "\n", ". ", "。", "! ", "!", "? ", "?"}),
textsplitter.WithLenFunc(func(s string) int {
// 统一按字符计算
return len([]rune(s))
}),
)

扩展功能

项目中的 DocumentProcessor 类提供了更高级的功能:

  • 自动元数据管理
  • 批量文档处理
  • 文档块统计和分析
  • 错误处理和日志记录

依赖项

  • github.com/tmc/langchaingo: LangChain Go 实现
  • Go 1.23.4 或更高版本

贡献

欢迎提交 Issue 和 Pull Request 来改进这个项目。

许可证

MIT License