Eino:概览

简介

Eino(发音类似 “I know”,寓意为“我知道”) 是一个用 Golang 构建的终极 LLM 应用开发框架。它从 LangChain、LlamaIndex 等优秀开源框架中汲取灵感,同时结合前沿研究成果和真实业务场景,致力于构建一个更符合 Golang 编程风格的 LLM 应用开发框架,强调简单性、可扩展性、可靠性和高效性。

Eino 提供的能力包括:

  • 精心设计的 组件(component) 抽象及实现,可以方便地复用和组合,用于构建 LLM 应用;
  • 强大的 编排(composition) 框架,帮你完成类型检查、流式处理、并发管理、切面注入、参数配置等复杂任务;
  • 简洁清晰的 API,设计关注点就是简单易懂;
  • 不断增长的最佳实践集合,打包为 flows(流程)examples(示例)
  • 一整套实用工具,覆盖从可视化开发与调试,到在线追踪与评估的整个开发周期。

借助以上能力和工具,Eino 可以在 LLM 应用的各个阶段实现标准化、简化操作并提升效率:

Eino 概览 - 图1

👉 Eino GitHub 仓库


快速上手

直接使用一个组件:

  1. model, _ := openai.NewChatModel(ctx, config) // 创建一个可调用的 LLM 实例
  2. message, _ := model.Generate(ctx, []*Message{
  3. SystemMessage("you are a helpful assistant."),
  4. UserMessage("what does the future AI App look like?")})

当然可以这么用,Eino 提供了大量开箱即用的组件。不过更推荐你用编排(orchestration)方式,理由有三:

  • 编排能封装 LLM 应用中常见的模式;
  • 编排解决了流式响应处理这一大难题;
  • 编排自动处理类型安全、并发控制、切面注入和参数赋值。

Eino 提供了三套编排 API:

API 特点与用法
Chain 简单的链式有向图,只能向前执行
Graph 支持有环或无环的有向图,功能强大、灵活
Workflow 无环图,支持结构体字段级别的数据映射

让我们来构建一个简单的 Chain:一个 ChatTemplate 接一个 ChatModel。

Eino 概览 - 图2

  1. chain, err := NewChain[map[string]any, *Message]().
  2. AppendChatTemplate(prompt).
  3. AppendChatModel(model).
  4. Compile(ctx)
  5. if err != nil {
  6. return err
  7. }
  8. out, err := chain.Invoke(ctx, map[string]any{"query": "what's your name?"})

接下来我们构建一个 Graph:使用 ChatModel 生成工具调用,再用 ToolsNode 执行工具调用:

Eino 概览 - 图3

  1. graph := NewGraph[map[string]any, *schema.Message]()
  2. _ = graph.AddChatTemplateNode("node_template", chatTpl)
  3. _ = graph.AddChatModelNode("node_model", chatModel)
  4. _ = graph.AddToolsNode("node_tools", toolsNode)
  5. _ = graph.AddLambdaNode("node_converter", takeOne)
  6. _ = graph.AddEdge(START, "node_template")
  7. _ = graph.AddEdge("node_template", "node_model")
  8. _ = graph.AddBranch("node_model", branch)
  9. _ = graph.AddEdge("node_tools", "node_converter")
  10. _ = graph.AddEdge("node_converter", END)
  11. compiledGraph, err := graph.Compile(ctx)
  12. if err != nil {
  13. return err
  14. }
  15. out, err := compiledGraph.Invoke(ctx, map[string]any{"query": "Beijing's weather this weekend"})

接下来构建一个支持字段级数据映射的 Workflow:

Eino 概览 - 图4

  1. wf := NewWorkflow[[]*Message, *Message]()
  2. wf.AddChatModelNode("model", model).AddInput(START)
  3. wf.AddLambdaNode("l1", lambda1).AddInput(NewMapping("model").From("Content").To("Input"))
  4. wf.AddLambdaNode("l2", lambda2).AddInput(NewMapping("model").From("Role").To("Role"))
  5. wf.AddLambdaNode("l3", lambda3).AddInput(
  6. NewMapping("l1").From("Output").To("Query"),
  7. NewMapping("l2").From("Output").To("MetaData"),
  8. )
  9. wf.AddEnd([]*Mapping{NewMapping("node_l3")})
  10. runnable, _ := wf.Compile(ctx)
  11. runnable.Invoke(ctx, []*Message{UserMessage("kick start this workflow!")})

现在来创建一个 ReAct agent:一个 ChatModel 与 Tools 绑定。它接收消息后,判断是直接输出答案还是调用工具,工具执行结果会变成下一轮的上下文。

Eino 已在 flow 包中实现了完整的 ReAct agent,可查看代码:flow/agent/react

Eino 背后自动处理了这些关键功能:

  • 类型检查:编译时保证输入输出类型匹配;
  • 流式处理:将多段消息拼接成流传递给 ChatModel 或 ToolsNode,并复制到回调处理器;
  • 状态管理:保证共享状态的读写安全;
  • 切面注入(Aspect Injection):在 ChatModel 执行前后自动注入回调;
  • 参数赋值:参数可全局设定、针对组件类型或指定节点设定。

比如可以加上回调函数:

  1. handler := NewHandlerBuilder().
  2. OnStartFn(func(ctx context.Context, info *RunInfo, input CallbackInput) context.Context {
  3. log.Infof("onStart, runInfo: %v, input: %v", info, input)
  4. return ctx
  5. }).
  6. OnEndFn(func(ctx context.Context, info *RunInfo, output CallbackOutput) context.Context {
  7. log.Infof("onEnd, runInfo: %v, out: %v", info, output)
  8. return ctx
  9. }).
  10. Build()
  11. compiledGraph.Invoke(ctx, input, WithCallbacks(handler))

或者给不同节点指定参数:

  1. // 所有节点
  2. compiledGraph.Invoke(ctx, input, WithCallbacks(handler))
  3. // 仅作用于 ChatModel 节点
  4. compiledGraph.Invoke(ctx, input, WithChatModelOption(WithTemperature(0.5)))
  5. // 指定某个节点 node_1
  6. compiledGraph.Invoke(ctx, input, WithCallbacks(handler).DesignateNode("node_1"))

主要特性

✅ 丰富的组件体系

  • 封装了常见能力为 组件抽象(component abstraction),每种抽象都有多个可直接使用的 组件实现(implementation)

    • 例如 ChatModel、Tool、PromptTemplate、Retriever、Document Loader、Lambda 等;
    • 每种组件类型都有明确的输入输出类型、参数类型、流式处理机制;
  • 抽象即编排的单位,组件实现可嵌套复杂业务逻辑;
  • 例如:React Agent、MultiQueryRetriever、Host MultiAgent 等;

    • 虽然内部复杂,但对外接口保持统一,如 MultiQueryRetriever 可以在任何接受 Retriever 的场景中使用。

⚙️ 强大的编排能力(Graph / Chain / Workflow)

  • 数据从 Retriever / Document Loaders / Prompt Template → ChatModel → Tools → 最终输出;
  • 组件实例是图节点,边表示数据流;
  • 支持复杂业务逻辑编排:

    • 类型检查、流处理、并发管理、切面注入、参数赋值;
    • 运行时分支、全局状态读写、字段级映射等。

🌊 完整的流式处理机制

  • ChatModel 在生成消息时是流式输出,因此流处理对于编排尤为关键;
  • Eino 自动处理如下场景:

    • 拼接流:下游只接受非流输入时会自动拼接;
    • 转为流:上游非流数据自动转为流;
    • 合并流:多个流合并成一个下游输入;
    • 复制流:将流分发给多个下游节点或回调;
    • 编排元素如 分支(branch)StateHandler 同样支持流处理;
  • 用户无需关心组件是否支持流,Eino 会自动转换;
  • 编译后的 Graph 支持四种流式调用模式:
调用模式 说明
Invoke 输入输出都是非流数据
Stream 输入非流,输出为 StreamReader[O]
Collect 输入为 StreamReader[I],输出为非流数据
Transform 输入为 StreamReader[I],输出为 StreamReader[O]

🔧 可扩展的切面机制(Callbacks)

  • 处理日志、链路追踪、监控等横切逻辑;
  • 支持五种回调:OnStart, OnEnd, OnError, OnStartWithStreamInput, OnEndWithStreamOutput
  • 自定义回调只需注册即可自动调用;
  • 甚至可以给原本不支持回调的组件注入切面。

Eino 框架结构

Eino 概览 - 图5

  • Eino:包含类型定义、流处理机制、组件抽象、编排逻辑、切面机制等;
  • EinoExt:组件实现、回调实现、工具库(如评估器、提示词优化器)等;
  • Eino Devops:可视化开发与调试工具;
  • EinoExamples:示例应用与最佳实践集合。

详细说明见:Eino 框架结构


使用文档

想学习和使用 Eino?我们提供了完整的用户手册,帮助你快速掌握概念和实践技能:

📘 Eino 使用手册 🚀 Eino 快速入门 📚 完整 API 文档


依赖要求

  • Go 1.18 及以上版本;
  • Eino 依赖 kin-openapi 提供的 OpenAPI JSONSchema 实现;
  • 为保持 Go 1.18 兼容性,已将其版本固定为 v0.118.0。

安全问题报告

如果你发现了潜在的安全问题,请通过 安全中心漏洞报告邮箱 向 ByteDance 安全团队反馈。

不要 通过 GitHub 公共 issue 报告安全漏洞。