Eino: Document Transformer 使用说明
基本介绍
Document Transformer 是一个用于文档转换和处理的组件。它的主要作用是对输入的文档进行各种转换操作,如分割、过滤、合并等,从而得到满足特定需求的文档。这个组件可用于以下场景中:
- 将长文档分割成小段落以便于处理
- 根据特定规则过滤文档内容
- 对文档内容进行结构化转换
- 提取文档中的特定部分
组件定义
接口定义
type Transformer interface {
Transform(ctx context.Context, src []*schema.Document, opts ...TransformerOption) ([]*schema.Document, error)
}
Transform 方法
-
功能:对输入的文档进行转换处理
-
参数:
- ctx:上下文对象,用于传递请求级别的信息,同时也用于传递 Callback Manager
- src:待处理的文档列表
- opts:可选参数,用于配置转换行为
-
返回值:
[]*schema.Document
:转换后的文档列表- error:转换过程中的错误信息
Document 结构体
【TODO】 可把所有的公共结构体放到一个特定的地方
type Document struct {
// ID 是文档的唯一标识符
ID string
// Content 是文档的内容
Content string
// MetaData 用于存储文档的元数据信息
MetaData map[string]any
}
Document 结构体是文档的标准格式,包含以下重要字段:
-
ID:文档的唯一标识符,用于在系统中唯一标识一个文档
-
Content:文档的实际内容
-
MetaData:文档的元数据,可以存储如下信息:
- 文档的来源信息
- 文档的向量表示(用于向量检索)
- 文档的分数(用于排序)
- 文档的子索引(用于分层检索)
- 其他自定义元数据
公共 Option
Transformer 组件使用 TransformerOption 来定义可选参数,目前没有公共的 option。每个具体的实现可以定义自己的特定 Option,通过 WrapTransformerImplSpecificOptFn 函数包装成统一的 TransformerOption 类型。
使用方式
单独使用
// 初始化 transformer (以 markdown 为例)
transformer, err := markdown.NewHeaderSplitter(ctx, &markdown.HeaderSplitterConfig{
// 配置参数
})
if err != nil {
return err
}
// 转换文档
transformedDocs, err := transformer.Transform(ctx, docs)
if err != nil {
return err
}
在编排中使用
// 在 Chain 中使用
chain := compose.NewChain[[]*schema.Document, []*schema.Document]()
chain.AppendDocumentTransformer(transformer)
// 编译并运行
runnable, err := chain.Compile()
if err != nil {
return err
}
result, err := runnable.Invoke(ctx, input)
// 在 Graph 中使用
graph := compose.NewGraph[[]*schema.Document, []*schema.Document]()
graph.AddDocumentTransformerNode("transformer_node", transformer)
Option 和 Callback 使用
Callback 使用示例
// 创建 callback handler
handler := &document.TransformerCallbackHandler{
OnStart: func(ctx context.Context, info *callbacks.RunInfo, input *document.TransformerCallbackInput) context.Context {
fmt.Printf("开始转换文档,输入文档数量: %d\n", len(input.Input))
return ctx
},
OnEnd: func(ctx context.Context, info *callbacks.RunInfo, output *document.TransformerCallbackOutput) context.Context {
fmt.Printf("文档转换完成,输出文档数量: %d\n", len(output.Output))
return ctx
},
}
// 使用 callback handler
helper := template.NewHandlerHelper().
Transformer(handler).
Handler()
// 在运行时使用
runnable, err := chain.Compile()
if err != nil {
return err
}
result, err := runnable.Invoke(ctx, input, compose.WithCallbacks(helper))
已有实现
- Markdown Header Splitter: 基于 Markdown 标题进行文档分割 Splitter - markdown
- Text Splitter: 基于文本长度或分隔符进行文档分割 Splitter - semantic
- Document Filter: 基于规则过滤文档内容 Splitter - recursive
自行实现参考
实现自定义的 Transformer 组件时,需要注意以下几点:
- option 的处理
- callback 的处理
Option 机制
自定义 Transformer 需要实现自己的 Option 机制:
// 定义 Option 结构体
type MyTransformerOptions struct {
ChunkSize int
Overlap int
MinChunkLength int
}
// 定义 Option 函数
func WithChunkSize(size int) document.TransformerOption {
return document.WrapTransformerImplSpecificOptFn(func(o *MyTransformerOptions) {
o.ChunkSize = size
})
}
func WithOverlap(overlap int) document.TransformerOption {
return document.WrapTransformerImplSpecificOptFn(func(o *MyTransformerOptions) {
o.Overlap = overlap
})
}
Callback 处理
Transformer 实现需要在适当的时机触发回调:
// 这是由 transformer 定义的回调输入输出,自行组件在实现时需要满足结构的含义
type TransformerCallbackInput struct {
Input []*schema.Document
Extra map[string]any
}
type TransformerCallbackOutput struct {
Output []*schema.Document
Extra map[string]any
}
完整实现示例
type MyTransformer struct {
chunkSize int
overlap int
minChunkLength int
}
func NewMyTransformer(config *MyTransformerConfig) (*MyTransformer, error) {
return &MyTransformer{
chunkSize: config.DefaultChunkSize,
overlap: config.DefaultOverlap,
minChunkLength: config.DefaultMinChunkLength,
}, nil
}
func (t *MyTransformer) Transform(ctx context.Context, src []*schema.Document, opts ...document.TransformerOption) ([]*schema.Document, error) {
// 1. 处理 Option
options := &MyTransformerOptions{
ChunkSize: t.chunkSize,
Overlap: t.overlap,
MinChunkLength: t.minChunkLength,
}
options = document.GetTransformerImplSpecificOptions(options, opts...)
// 2. 获取 callback manager
cm := callbacks.ManagerFromContext(ctx)
// 3. 开始转换前的回调
ctx = cm.OnStart(ctx, info, &document.TransformerCallbackInput{
Input: src,
})
// 4. 执行转换逻辑
docs, err := t.doTransform(ctx, src, options)
// 5. 处理错误和完成回调
if err != nil {
ctx = cm.OnError(ctx, info, err)
return nil, err
}
ctx = cm.OnEnd(ctx, info, &document.TransformerCallbackOutput{
Output: docs,
})
return docs, nil
}
func (t *MyTransformer) doTransform(ctx context.Context, src []*schema.Document, opts *MyTransformerOptions) ([]*schema.Document, error) {
// 实现文档转换逻辑
return docs, nil
}
注意事项
- 转换后的文档需要注意对 metadata 的处理,注意保留原 metadata,以及新增自定义的 metadata
其他参考文档
最后修改
January 9, 2025
: feat: add eino cn docs (#1182) (ad75444)