Eino概述

Eino市场定位

Eino 基于明确的"组件"定义,提供强大的流程"编排",覆盖开发全流程,旨在帮助开发者以最快的速度实现最有深度的大模型应用。

产品特点

  • 内核稳定,API 简单易懂,有明确的上手路径,平滑的学习曲线。
  • 极致的扩展性,研发工作高度活跃,长期可持续。
  • 基于强类型语言 Golang,代码能看懂,易维护,高可靠。
  • 背靠字节跳动核心业务线的充分实践经验。
  • 提供开箱即用的配套工具。

项目地址:github.com/cloudwego/e...github.com/cloudwego/e...

快速认识Eino

Eino 是覆盖 devops 全流程的大模型应用开发框架,从最佳实践样例的 Eino Examples,到各环节的工具链,都是 Eino 的领域:

个人的认知当中,eino不仅仅是一个项目,而注重的是一个产品,这个产品整体上是以eino这个项目为主导,衍生出多个分支下的组件进行相辅相成

在目前初步认识eino的前提下,确定根据官方文档,主要是从这三个项目中进行展开,找到学习eino相关的突破口

eino的作用

那么 Eino 具体能做什么?首先,Eino 由一个个大模型领域的"组件"组成,比如最核心的是与大模型交互的 Chat Model:

go 复制代码
model, _ := ark.NewChatModel(ctx, config) // 创建一个豆包大模型
message, _ := model.Generate(ctx, []*Message{
    SystemMessage("you are a helpful assistant."),
    UserMessage("what does the future AI App look like?")}

以 ReAct Agent 为例:一个 ChatModel(大模型),"绑定"了 Tool(工具),接收输入的 Message,由 ChatModel 自主判断是否调用 Tool 或输出最终结果。Tool 执行结果会再次成为给到 ChatModel 的 Message,并作为下一轮自主判断的上下文。

go 复制代码
// 构建一个 ReAct Agent,编译为一个输入为 []*Message,输出为 *Message 的 Runnable

// 创建包含 state 的 Graph,用户存储请求维度的 Message 上下文
graph = NewGraph[[]*Message, *Message](
   WithGenLocalState(func(ctx context.Context) *state {
      return &state{Messages: make([]*Message, 0, config.MaxStep+1)}
   }))

// 将一个轮次中的上下文和响应,存储到 Graph 的临时状态中
modelPreHandle = func(ctx context.Context, input []*Message, state *state) ([]*Message, error) {
    state.Messages = append(state.Messages, input...)
    return state.Messages, nil
}

_ = graph.AddChatModelNode(nodeKeyModel, chatModel, WithStatePreHandler(modelPreHandle))

_ = graph.AddEdge(START, nodeKeyModel)

_ = graph.AddToolsNode(nodeKeyTools, toolsNode)

// chatModel 的输出可能是多个 Message 的流
// 这个 StreamGraphBranch 根据流的首个包即可完成判断,降低延迟
modelPostBranch = NewStreamGraphBranch(
   func(_ context.Context, sr *schema.StreamReader[*Message]) (endNode string, err error) {
      defer sr.Close()

      if msg, err := sr.Recv(); err != nil {
         return "", err
      } else if len(msg.ToolCalls) == 0 {
         return END, nil
      }

      return nodeKeyTools, nil
   }, map[string]bool{nodeKeyTools: true, END: true})

_ =  graph.AddBranch(nodeKeyModel, modelPostBranch)

// toolsNode 执行结果反馈给 chatModel
_ = graph.AddEdge(nodeKeyTools, nodeKeyModel)

// 编译 Graph:类型检查、callback 注入、自动流式转换、生成执行器
agent, _ := graph.Compile(ctx, WithMaxRunSteps(config.MaxStep))

在上面这几十行代码的背后,Eino 自动做了一些事情:

  • 类型检查,在 compile 时确保相邻的节点的类型对齐。

  • 流式封装,编译出的 Runnable 既可以 Invoke 调用,也可以 Stream 调用,无论内部的 Tool 是否支持流。

  • 并发管理,对 state 这个公共状态的读写是并发安全的。

  • 横切面注入,如果某个组件(比如一个 tool)没有实现 callbacks 注入,则 Eino 自动注入。

  • Option 分配,编译出的 Runnable 可以灵活接收并把 option 分配给指定的节点。

Eino的独特优势

Eino尽力去做到,既需要封装领域内"不变"的通用核心要素 ,又需要基于最新进展敏捷的横向和纵向扩展

另一方面,目前较为主流的框架如 LangChain,LlamaIndex 等,都基于 Python,虽然能借助 Python 较为丰富的生态快速实现多样的功能,但是同时也继承了 Python 作为动态语言所带来的"弱类型检验"和"长期维护成本高"等问题。在大模型应用快速进入大规模线上运行阶段的当下,基于 Golang 这一强类型语言而实现的高可靠性高可维护性,逐渐具有更大的价值。

在Python垄断的主流框架之下,更希望使用Golang这样的强类型语言去对大模型进行开发

内核稳定

每类组件作为一个 interface,有完善、稳定的定义:具体的输入输出类型,明确的运行时 option,以及明确的流处理范式。(在对于开发规范和项目整体设计是要有明确的规定)

敏捷扩展

每类组件都可以横向扩展出不同的实现,比如 ChatModel 组件可以有 OpenAI、Gemini、Claude 等不同的实现等。这些具体的实现,在实现组件 interface 从而可作为组件参与编排的基础上,可以实现和持续扩展自身的特殊功能。

当实际业务场景中,出现需要进入编排但是不对应任何组件定义的功能时,Eino 支持将自定义 function 声明为 Lambda 类型。Lambda 有用户声明的输入输出以及 option 类型,可支持全部的流处理范式,具备完整的 Callback 能力,在编排视角等价于官方组件。

高可用易维护

基于 Golang 写 Eino 代码时,开发者可以充分利用 Golang 的强类型特性,为所有的组件、Lambda、编排产物等声明具体类型。这像是为代码绘制了一幅精确的地图,开发者可以沿着清晰的路径进行维护和扩展,即使在项目规模不断扩大、功能持续迭代的情况下,依然能够保有较高的可维护性。

同时,Eino 编排能力也充分利用了强类型系统的编译时校验能力,尽可能将类型匹配问题暴露的时机提前到 graph 的编译时,而不是 graph 的运行时。尽早并明确的暴露类型匹配问题,有助于开发者迅速定位和修复,减少因类型错误在运行时引发的难以排查的故障和性能问题。

另一方面,Eino 遵循模块化设计,核心库以及各组件实现是单独的 go module,每个 go module 做到依赖最小化。同时,API 设计以"精简"、"直观"和"同构性"为原则,辅以由浅入深的全面文档,尽可能让学习曲线更平滑。最重要的是,Eino 采用清晰的分层设计,每层职责明确、功能内聚,在提升维护性的同时能更好的保证稳定性。

工具生态完善

链路追踪、调试、可视化,是编排引擎的三个重要辅助工具。Eino 内置了 tracing callback,并与 APMPlus 和 Langfuse 平台做了集成。同时提供了 IDE 插件,可以在写代码的过程中随时可视化查看编排出的 graph,并进行调试运行,甚至可以通过 UI 拖拽的方式快速构建 graph 并导出为 Eino 代码。

对于Eino个人理解

对于笔者而言,也是由Go语言服务端开发,慢慢去熟悉大模型应用相关的领域;在开始学习Eino这样的大语言模型应用开发框架时也是十分吃力的,有些地方也是比较难去理解;但是笔者一个很好的朋友告诉我,难上手是正常的,多写几遍,就像你高考写解析几何一样,熟练度来自踩坑 踩的坑越多熟练度会越高; 笔者也十分坚定,携风而行,滴水石穿!

相关推荐
止语Lab8 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活8 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困8 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn8 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户298698530148 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
用户77283104908408 小时前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端
Conan在掘金8 小时前
鸿蒙报错速查:Function lacks ending return statement,返回路径漏 return 就炸,根因 + 真解法
后端
人间凡尔赛9 小时前
AI-Native 云原生架构:2026 年从容器编排到智能体编排的范式革命
后端·云原生·架构
IT_陈寒9 小时前
Vue的响应式让我加班到凌晨3点,原来问题出在这
前端·人工智能·后端
卷无止境9 小时前
提升 Python 代码健壮性的方法大盘点
后端·python