前言
开发基于大模型的软件应用,就像指挥一支足球队:组件是能力各异的队员,编排是灵活多变的战术,数据是流转的足球。Eino 是字节跳动开源的大模型应用开发框架,拥有稳定的内核,灵活的扩展性,完善的工具生态,可靠且易维护,背靠豆包、抖音等应用的丰富实践经验。初次使用 Eino,就像接手一支实力雄厚的足球队,即使教练是初出茅庐的潜力新人,也可以踢出高质量、有内容的比赛。
下面就让我们一起踏上新手上路之旅!
认识队员
Eino 应用的基本构成元素是功能各异的组件,就像足球队由不同位置角色的队员组成:
组件名 |
组件功能 |
ChatModel |
与大模型交互,输入 Message 上下文,得到模型的输出 Message |
Tool |
与世界交互,根据模型的输出,执行对应的动作 |
Retriever |
获取相关的上下文,让模型的输出基于高质量的事实 |
ChatTemplate |
接收外界输入,转化成预设格式的 prompt 交给模型 |
Document Loader |
加载指定的文本 |
Document Transformer |
按照特定规则转化指定的文本 |
Indexer |
存储文件并建立索引,供后续 Retriever 使用 |
Embedding |
Retriever 和 Indexer 的共同依赖,文本转向量,捕获文本语义 |
Lambda |
用户定制 function |
这些组件抽象代表了固定的输入输出类型、Option 类型和方法签名:
type ChatModel interface {
Generate(ctx context.Context, input []*schema.Message, opts ...Option) (*schema.Message, error)
Stream(ctx context.Context, input []*schema.Message, opts ...Option) (
*schema.StreamReader[*schema.Message], error)
BindTools(tools []*schema.ToolInfo) error
}
真正的运行,需要的是具体的组件实现:
组件名 |
官方组件实现 |
ChatModel |
OpenAI, Claude, Gemini, Ark, Ollama... |
Tool |
Google Search, Duck Duck Go... |
Retriever |
Elastic Search, Volc VikingDB... |
ChatTemplate |
DefaultChatTemplate... |
Document Loader |
WebURL, Amazon S3, File... |
Document Transformer |
HTMLSplitter, ScoreReranker... |
Indexer |
Elastic Search, Volc VikingDB... |
Embedding |
OpenAI, Ark... |
Lambda |
JSONMessageParser... |
Eino 的开发过程中,首先要做的是决定“我需要使用哪个组件抽象”,再决定“我需要使用哪个具体组件实现”。就像足球队先决定“我要上 1 个前锋”,再挑选“谁来担任这个前锋”。
组件可以像使用任何的 Go interface 一样单独使用。但要想发挥 Eino 这支球队真正的威力,需要多个组件协同编排,成为一个相互联结的整体。
制定战术
在 Eino 编排场景中,每个组件成为了“节点”(Node),节点之间 1 对 1 的流转关系成为了“边”(Edge),N 选 1 的流转关系成为了“分支”(Branch)。基于 Eino 开发的应用,经过对各种组件的灵活编排,就像一支足球队可以采用各种阵型,能够支持无限丰富的业务场景。
足球队的战术千变万化,但却有迹可循,有的注重控球,有的简单直接。对 Eino 而言,针对不同的业务形态,也有更合适的编排方式:
编排方式 |
特点和场景 |
Chain |
链式有向图,始终向前,简单。适合数据单向流动,没有复杂分支的场景。 |
Graph |
有向图,有最大的灵活性;或有向无环图,不支持分支,但有清晰的祖先关系。 |
Chain,如简单的 ChatTemplate + ChatModel 的 Chain:
chain, _ := NewChain[map[string]any, *Message]().
AppendChatTemplate(prompt).
AppendChatModel(model).
Compile(ctx)
chain.Invoke(ctx, map[string]any{"query": "what's your name?"})
</