基本介绍
Document Loader 是一个用于加载文档的组件。它的主要作用是从不同来源(如网络 URL、本地文件等)加载文档内容,并将其转换为标准的文档格式。这个组件在处理需要从各种来源获取文档内容的场景中发挥重要作用,比如:
- 从网络 URL 加载网页内容
- 读取本地 PDF、Word 等格式的文档
组件定义
2.1 接口定义
代码位置:eino/components/document/interface.go
go
type Loader interface {
Load(ctx context.Context, src Source, opts ...LoaderOption) ([]*schema.Document, error)
}
2.2 Load 方法
-
功能:从指定的数据源加载文档
-
参数:
ctx:上下文对象,用于传递请求级别的信息,同时也用于传递 Callback Managersrc:文档来源,包含文档的 URI 信息opts:加载选项,用于配置加载行为
-
返回值:
[]*schema.Document:加载的文档列表error:加载过程中的错误信息
2.3 Source 结构体
go
type Source struct {
URI string
}
Source 结构体定义了文档的来源信息:
URI:文档的统一资源标识符,可以是网络 URL 或本地文件路径
2.4 Document 结构体
go
type Document struct {
// ID 是文档的唯一标识符
ID string
// Content 是文档的内容
Content string
// MetaData 用于存储文档的元数据信息
MetaData map[string]any
}
Document 结构体是文档的标准格式,包含以下重要字段:
-
ID:文档的唯一标识符,用于在系统中唯一标识一个文档 -
Content:文档的实际内容 -
MetaData:文档的元数据,可以存储如下信息:- 文档的来源信息
- 文档的向量表示(用于向量检索)
- 文档的分数(用于排序)
- 文档的子索引(用于分层检索)
- 其他自定义元数据
2.5 公共选项
Loader组件使用LoaderOption来定义加载选项。Loader目前没有公共的Option,每个具体的实现可以定义自己的特定选项,通过WrapLoaderImplSpecificOptFn函数包装成统一的LoaderOption类型。
应用
3.1 本地文件加载 (Loader - local file)
代码位置:eino-ext/components/document/loader/f ile/file_loader.go
配置参数说明:
UseNameAsID:是否将文件名用作文档 IDParser:文档解析器,如果不指定则使用默认的扩展名解析器(ExtParser,当前仅实现了TextParser)
go
package main
import (
"context"
"github.com/cloudwego/eino-ext/components/document/loader/file"
"github.com/cloudwego/eino/components/document"
"github.com/cloudwego/eino/components/document/parser"
"log"
)
func main() {
ctx := context.Background()
// 本地文件
loader, _ := file.NewFileLoader(ctx, &file.FileLoaderConfig{
UseNameAsID: true,
Parser: &parser.TextParser{}, // 可选:指定自定义解析器
})
filePath := "./file_data/Go 1.24震撼发布!这些新特性你必须知道!.md"
docs, err := loader.Load(ctx, document.Source{
URI: filePath,
})
if err != nil {
panic(err)
}
log.Printf("doc content: %v", docs[0].Content)
for _, doc := range docs {
println(doc.Content) // go1.25 的新特性,不需要 fmt.Println
println(doc.ID)
// 访问元数据
println(doc.MetaData[file.MetaKeyFileName])
println(doc.MetaData[file.MetaKeyExtension])
println(doc.MetaData[file.MetaKeySource])
}
}
3.2 网络文件加载 (Loader - web url)
代码位置:eino-ext/components/document/loader/url/url.go
配置参数说明:
Parser:文档解析器,默认使用 HTML 解析器,会提取网页正文内容Client:HTTP 客户端,可以自定义超时、代理等配置RequestBuilder:请求构建器,用于自定义请求方法、请求头等
go
package main
import (
"context"
"github.com/cloudwego/eino-ext/components/document/loader/url"
"github.com/cloudwego/eino/components/document"
"github.com/cloudwego/eino/components/document/parser"
"log"
"net/http"
)
func main() {
ctx := context.Background()
// 网络文件加载
loader, _ := url.NewLoader(ctx, &url.LoaderConfig{
Parser: &parser.TextParser{},
Client: &http.Client{},
RequestBuilder: func(ctx context.Context, source document.Source, opts ...document.LoaderOption) (*http.Request, error) {
return nil, nil
},
})
docs, err := loader.Load(ctx, document.Source{
URI: "https://www.alipan.com/s/kKxyyXhjckz", // 真实的 pdf 文档的地址
})
if err != nil {
panic(err)
}
log.Printf("doc content: %v", docs[0].Content)
// 使用文档内容
for _, doc := range docs {
println(doc.Content)
}
}
3.3 解析 PDF 为纯文本 (Parser - pdf)
代码位置:eino-ext/components/document/parser/pdf.pdf.go
配置参数说明:
ToPages:是否将 PDF 按页面分割成多个文档,默认为 false
解析选项:
- 支持通过
parser.WithURI设置文档 URI - 支持通过
parser.WithExtraMeta添加额外元数据
go
package main
import (
"context"
"log"
"os"
"github.com/cloudwego/eino-ext/components/document/parser/pdf"
)
func main() {
ctx := context.Background()
parser, _ := pdf.NewPDFParser(ctx, &pdf.Config{
ToPages: false, // 是否按页面分割文档
})
file, err := os.Open("./file_data/2021-09《我们为什么控制不了自己》.pdf")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// 解析文档
docs, err := parser.Parse(ctx, file)
if err != nil {
log.Fatal(err)
}
// 打印解析结果
for _, doc := range docs {
println(doc.Content)
}
}
3.4 解析 HTML 为纯文本
代码位置:eino-ext/components/document/parser/html/html.go
配置参数说明:
-
Selector:可选参数,指定要提取的内容区域,使用goquery选择器语法- 例如:body 表示提取 标签内容
#content表示提取 id 为 "content" 的元素内容
解析器会自动提取以下 metadata:
html.MetaKeyTitle("_title"):网页标题html.MetaKeyDesc("_description"):网页描述html.MetaKeyLang("_language"):网页语言html.MetaKeyCharset("_charset"):字符编码html.MetaKeySource("_source"):文档来源 URI
go
package main
import (
"context"
"fmt"
"strings"
"github.com/cloudwego/eino-ext/components/document/parser/html"
)
func main() {
ctx := context.Background()
// 初始化解析器
p, err := html.NewParser(ctx, &html.Config{
Selector: "#content", // 选择器,指定只提取 id 为 content 的元素内容,默认为 body
}) // 使用默认配置
if err != nil {
panic(err)
}
// HTML 内容
document := `
<html lang="zh">
<head>
<title>示例页面</title>
<meta name="description" content="这是一个示例页面">
<meta charset="UTF-8">
</head>
<body>
<div id="content">
<h1>欢迎</h1>
<p>这是正文内容。</p>
</div>
</body>
</html>
`
// 解析文档
docs, err := p.Parse(ctx, strings.NewReader(document))
if err != nil {
panic(err)
}
// 使用解析结果
doc := docs[0]
fmt.Println("内容:", doc.Content)
fmt.Println("标题:", doc.MetaData[html.MetaKeyTitle])
fmt.Println("描述:", doc.MetaData[html.MetaKeyDesc])
fmt.Println("语言:", doc.MetaData[html.MetaKeyLang])
}
总结
Eino 框架是字节跳动内部半年多的使用和迭代,基于 Go 的大模型应用综合开发框架
介绍了 Eino: Components 组件中的 Document Loader 组件的用法
- 本地文件加载
- 远程文件加载
- 解析 pdf
- 解析 html
通过内部封装好的组件,可以更快、更高效的基实现大模型所具备的其中一个核心能力:
- 基于语义的文本处理能力
这项能力可以让开发者专注与业务逻辑的实现,避免重复造轮子,以快速构建高质量的大模型应用。