项目全景与分层架构
今天不写代码。目标:搞清"Eino 是个什么框架、由哪几层组成、代码在哪",在脑子里建立一张地图。这张地图会贯穿后面 19 天——每天开头的"进度定位条"都会点亮你当前所在的格子。
它到底是什么
Eino(读音 /'aino/,谐音"爱诺")是字节跳动 CloudWeGo 团队开源的 Go 语言 LLM 应用开发框架。README 第 17 行原话:
翻译:它是 Go 版的 LLM 应用开发框架,借鉴了 LangChain、Google ADK,但遵循 Go 的工程习惯(强类型、接口、显式错误、高性能)。你可以把它当成"Go 版的 LangChain + LangGraph"。
🎯 一句话:它帮你把"调大模型 / 用工具 / 检索 / 拼提示词"这些积木,用"图和链"连起来跑,或直接搭成"能自己调工具干活的 Agent"——全程类型安全、原生支持流式。
动手前,先认识几个词
后面会反复出现这些词,今天先混个脸熟,不用记细节:
| 名词 | 大白话解释 | 哪天细讲 |
|---|---|---|
| LLM / ChatModel | 大语言模型(Claude/GPT 等)。Agent 的"大脑"。 | Day 04 |
| Component 组件 | 可复用的能力积木:调模型、用工具、检索、拼提示词。 | Day 04 |
| Message 消息 | 模型的输入输出统一结构(谁说的、说了什么)。 | Day 03 |
| Stream 流 | 模型"边想边吐字",一段段返回而不是等全部说完。 | Day 03/17 |
| Compose 编排 | 把组件用"链/图/工作流"连起来跑。框架的心脏。 | Day 06-10 |
| Graph 图 | 把组件当节点、用边连起来的流程图,支持分支和循环。 | Day 08 |
| Runnable 可运行体 | 编排产物的统一执行接口,有 4 种调用方式。 | Day 06 |
| ADK | Agent Development Kit,搭"会自己干活的 Agent"的套件。 | Day 11-15 |
| ReAct | 经典 Agent 模式:想→调工具→看结果→再想,循环。 | Day 12/15 |
| 中断/恢复 | Agent 跑一半暂停等人、再从断点续跑(eino 特色)。 | Day 14 |
四大支柱
README 明确列了 Eino 的四大支柱(README.md:19-23):
Components 组件
可复用积木:ChatModel / Tool / Retriever / ChatTemplate 等(本仓只放接口)。
Composition 编排
把组件连成 Chain / Graph / Workflow,能独立跑或暴露成 agent 工具。
ADK 智能体套件
搭带工具调用、多智能体协作、中断/恢复的 AI Agent。
Examples 范例
常见模式与真实用例的可跑代码(在独立仓 eino-examples)。
ChatModel 都是接口,真正能调 OpenAI 的实现要去 eino-ext 装。(Day 04/19 细讲)go get github.com/cloudwego/eino 装完就能直接调 OpenAI——其实不行。本仓只有接口和引擎,真正连上某家大模型还要再装 eino-ext 里对应的实现包(比如 eino-ext/components/model/openai)。四层架构总图(动起来看)
Eino 从下到上分 4 层。下图那颗发光小球是"一次请求从上层 API 落到底层数据类型"的过程。先建立直觉:越往下越基础(数据/接口),越往上越贴应用(编排/Agent);每层只依赖它下面的层。
schema(数据长什么样,Day 03)、再 components(能力接口,Day 04)、然后 compose(怎么连起来跑,Day 6-10,最重要)、最后 adk/flow(搭 Agent,Day 11-15)。这也是本教程的顺序。逐层拆解:每层管什么
L1 · schema/(数据契约)
定义"数据长什么样":Message(消息,一个结构体同时当输入/输出/模板)、StreamReader/Writer(流式抽象,全框架最精妙处,Day 03/17)、ToolInfo(工具描述)、Document(RAG 文档)。
L3 · components/(能力接口)
定义"有哪些能力接口":ChatModel(调大模型)、Tool(工具)、ChatTemplate(提示词模板)、Retriever/Embedder/Indexer(RAG 检索三件套)、Loader/Transformer(文档管线)。只有接口,实现在 eino-ext。
L2 · compose/(编排引擎 ⭐)
框架心脏:把组件连起来跑。Chain(一条线串)、Graph(节点+边+分支,支持循环并行)、Workflow(字段级映射)。核心是 Runnable 的 4 种流式范式,能自动互转(Day 06)。
L4 · adk/ + flow/(Agent 层)
搭"会自己干活的 Agent"。ChatModelAgent(模型+工具的 ReAct 循环)、DeepAgent(官方推荐)、多智能体、中断/恢复。flow/ 是现成模式(ReAct、Host 多智能体、RAG 流程)。ADK 建立在 compose 图引擎之上——Agent 其实就是一张 compose 图。
compose.NewGraph 搭出来的一张图(Day 12/15 会看到真实代码)。所以 compose(第 2 周)是理解一切的地基——学透了图引擎,Agent 就是水到渠成。招牌设计:Runnable 的 4 种流式范式
Eino 区别于其它框架最亮眼的设计——同一个组件,框架能在四种调用方式间自动转换。这四种叫"流式范式"(Day 06 精讲,这里先建立印象):
| 范式 | 输入→输出 | 什么时候用 |
|---|---|---|
Invoke | 非流 → 非流 | 普通调用:给一句,等一个完整答案 |
Stream | 非流 → 流 | 给一句,边生成边返回(打字机效果) |
Collect | 流 → 非流 | 输入是流,收齐了给一个完整答案 |
Transform | 流 → 流 | 流进流出:一段段处理一段段产出 |
Stream(它天生是流式的)。但你的图里下一个节点只要非流的完整值。Eino 会自动帮你把 Stream 的输出"拼接"成完整值(Collect),反过来也能把完整值"包装"成单元素流——这套自动转换的底层机制,是 schema 里注册的一堆"拼接函数"(Day 03/17 讲)。结果:组件作者只需实现对它有意义的那一两种范式,框架补齐其余四种。这就是"流式处理"作为 Eino 一等公民的体现。👨🏫 老师:因为很多组件天生做不到流式——比如"检索器"必须等全部结果排完序才知道谁排第一,你让它"边检索边吐"反而是错的。
👶 小白:那接到一个流式上游、非流式下游的组合怎么办?总不能报错吧?
👨🏫 老师:这正是 Eino 的招牌——框架自动转换:把流"收齐拼接"成完整值给下游,或把完整值"包装"成单元素流。组件作者只写自己擅长的那种,剩下框架补齐。
仓库目录地图
eino/
├── schema/ ★ L1 核心数据类型:Message / Stream / ToolInfo / Document
├── components/ ★ L3 组件接口层(只有接口,实现在 eino-ext)
│ ├── model/ ChatModel 大模型
│ ├── tool/ Tool 工具
│ ├── prompt/ ChatTemplate 提示词
│ ├── retriever/ embedding/ indexer/ RAG 检索三件套
│ └── document/ Loader/Transformer/Parser 文档管线
├── compose/ ★★ L2 编排引擎(框架心脏):Chain / Graph / Workflow / Runnable
├── adk/ ★★ L4 Agent 开发套件(122 文件,最大):ChatModelAgent / DeepAgent / 多智能体 / 中断恢复
├── flow/ L4 现成模式:ReAct agent、Host 多智能体、RAG 流程
├── callbacks/ 横切面/可观测:5 个切面回调(tracing 用)
├── internal/ 内部实现:流拼接、图执行核心、泛型工具、序列化
├── utils/ 辅助工具
└── README.md / README.zh_CN.md
compose/(心脏)、adk/react.go(Agent 循环范本)、schema/stream.go(流式精髓)、flow/agent/react/react.go("把组件搭成 Agent"的最佳示例)。本教程主要围绕它们。一个必知的设计:接口与实现分离
这是读 Eino 最容易困惑的点:本仓库 components/ 里几乎只有接口,没有具体实现。每个组件目录固定四件套:interface.go(接口)、option.go(选项)、callback_extra.go(回调结构)、doc.go。
OpenAI / Claude / Gemini / Ollama / Elasticsearch 这些真正能干活的实现,全在独立仓库 eino-ext。
components/model/,你只会看到四件套:interface.go(定义 ChatModel 接口)、option.go、callback_extra.go、doc.go——全是"约定",没有一行真调 OpenAI 的代码。真正的 openai.NewChatModel(...) 在另一个仓 eino-ext 里。所以:import github.com/cloudwego/eino/components/model 拿到的是接口,import .../eino-ext/components/model/openai 才是实现。openai.NewChatModel 之类,记住那是 eino-ext 里的,不在本仓。三条学习主线
纵向:从一次调用到一个 Agent
schema(数据)→ components(组件)→ compose(编排)→ adk(Agent)。这是全教程的主轴。
横向:吃透"流式"这条暗线
StreamReader(Day 03)→ 4 种范式自动转换(Day 06)→ 流在图里怎么流(Day 17)。这是 Eino 最独特的地方。
范本:ReAct Agent 精读
Day 15 逐行读 flow/agent/react/react.go——它是"如何用图引擎搭一个 Agent 循环"的最佳教材,把前面所有概念串起来。
NOT RECOMMENDED——官方推荐用 Agent-as-Tool / DeepAgent(把子 Agent 当工具调,父 Agent 保持控制),而不是"把控制权整个交出去"的 transfer。Day 13 会讲这个取舍。今日小结 + 动手
🧠 今天你应该能回答
- Eino 是什么?(字节 CloudWeGo 的 Go LLM 应用框架,Go 版 LangChain+LangGraph)
- 四大支柱?(Components / Composition / ADK / Examples)
- 四层架构?(schema → components → compose → adk/flow,只能上依赖下)
- 招牌设计?(Runnable 的 4 种流式范式,能自动互转)
- 接口与实现为什么分离?(核心零第三方依赖,实现在 eino-ext)
- 心脏是哪个包?(compose/,ADK 其实建立在它之上)
✋ 动手 5 分钟(可选)
# 1. 看项目定位
head -30 README.md # 或 README.zh_CN.md
# 2. 感受四层结构
ls schema/ components/ compose/ adk/ flow/
# 3. 数一数各层代码量(adk 最大,compose 是心脏)
for d in schema components compose adk flow; do echo "$(find $d -name '*.go'|wc -l) $d"; done
# 4. 瞄一眼核心数据类型和编排入口(明后天细读)
head -30 schema/message.go
grep -n "func NewGraph\|func NewChain" compose/*.go | head