Eino中的组件-Loader & Parser

Eino 的 Loader 组件 是数据管道的起点,把各种来源(本地文件、URL、S3对象存储…)的原始内容,统一变成 []*schema.Document 列表,供下游 Transformer / Embedding / Indexer 继续处理。”

type Loader interface {
    Load(ctx context.Context, src Source, opts ...LoaderOption) ([]*schema.Document, error)
}

type Source struct {
    URI string // 本地路径 / http(s) URL / s3://bucket/key ...
}
  • 输入:URI (// 本地路径 / http(s) URL / s3://bucket/key ...)
  • 输出:标准 *schema.Document(含 Content + Metadata)
  • 自带回调钩子,可监听加载进度与错误

官方已实现三种 Loader

Loader 包路径 特点 典型配置字段
File Loader eino-ext/components/document/loader/file 本地文件 / 递归目录 / 黑白名单过滤 Path, Recursive, IncludePatterns, MaxFileSize
Web Loader eino-ext/components/document/loader/web 抓取网页,自动提取正文,可自定义 HTTP Client Client, RequestBuilder, Parser
S3 Loader eino-ext/components/document/loader/s3 从兼容 S3 的对象存储批量拉取 Bucket, Prefix, Region, AccessKey

Loader 用于load 本地文件, 并转换成DocumentTransformer能够直接处理的Document类型, Loader的实现主要基于Parser 实现, 用于从reader中读取文本数据, 并转换为Document
Parse parses the given reader and returns a list of documents.

type FileLoaderConfig struct {
    UseNameAsID bool
    Parser      parser.Parser
}

// FileLoader loads a local file and use its content directly as Document's content.
type FileLoader struct {
    FileLoaderConfig
}
// Parser is a document parser, can be used to parse a document from a reader.
type Parser interface {
    Parse(ctx context.Context, reader io.Reader, opts ...Option) ([]*schema.Document, error)
}

//  fmt.Println(docs[0].Content) // "hello world"
type TextParser struct{}

// Parse reads the text from a reader and returns a single document.
func (dp TextParser) Parse(ctx context.Context, reader io.Reader, opts ...Option) ([]*schema.Document, error) {
    data, err := io.ReadAll(reader)
    if err != nil {
        return nil, err
    }

    opt := GetCommonOptions(&Options{}, opts...)

    meta := make(map[string]any)
    meta[MetaKeySource] = opt.URI

    for k, v := range opt.ExtraMeta {
        meta[k] = v
    }

    doc := &schema.Document{
        Content:  string(data),
        MetaData: meta,
    }

    return []*schema.Document{doc}, nil
}


type ExtParser struct {
    parsers map[string]Parser
    fallbackParser Parser
}

// ExtParser 是一种根据文件扩展名来决定使用哪个具体的解析器。
// 你可以通过调用 RegisterParser 方法注册自己的解析器。
// Fallback parser to use when no other parser is found.
// Default is TextParser if not set.

// 在调用parse 时,是通过 filepath.Ext(uri) 的方式找到对应的 parser,因此使用时需要:
// ① 必须使用 parser.WithURI 在请求时传入 URI
// ② URI 必须能通过 filepath.Ext 来解析出符合预期的 ext

Eino 官方开源的代码仅有TextParser 和 MarkdownHeaderSplitter(按标题切片)解释器的实现, 其他如PDF,DOC, HTML等在eino-ext项目实现(pdf解析可以基于unipdf 、unidoc 实现, 这些库需要付费使用),可以基于其他免费的开源库自己实现, 并无缝接入Eino

协议 功能覆盖 现状
rsc.io/pdf BSD-3 只读文本、元数据、页面尺寸;0 依赖 维护一般,功能极简
pdfcpu Apache-2.0 读取、写入、合并、拆分、表单、水印、压缩 活跃维护,文本提取 pdfcpu extract -mode text 可直接用
go-fitz (MuPDF CGo) MIT 文本/图片抽取、渲染、OCR;功能最全 需 CGo,交叉编译稍麻烦
gopdf MIT 仅写 PDF(生成报告) 不适合解析

完整示例代码(基于默认的TextParser):

package main

import (
    "context"
    "github.com/cloudwego/eino/components/document/parser"
    "log"
    "os"
)

func main() {

    ctx := context.Background()
    conf := &parser.ExtParserConfig{}

    p, err := parser.NewExtParser(ctx, conf)
    if err != nil {
        panic(err)
    }

    f, err := os.Open("./app/eino/component_loader/testdata/test.md")
    if err != nil {
        panic(err)
    }
    defer f.Close()

    docs, err := p.Parse(ctx, f, parser.WithURI("./app/eino/component_loader/testdata/test.md"))
    if err != nil {
        panic(err)
    }
    for idx, doc := range docs {
        log.Printf("doc segment %v: %v", idx, doc.Content)
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容