Day 01 / 共 20 天 · 第 1 周 建立心智

项目全景与分层架构

今天不写代码。目标:搞清"Eino 是个什么框架、由哪几层组成、代码在哪",在脑子里建立一张地图。这张地图会贯穿后面 19 天——每天开头的"进度定位条"都会点亮你当前所在的格子。

📍 你在整门课的位置 · 第 1 周 建立心智(共 4 周 · 20 天)
D1 全景架构 D2 环境搭建 D3 schema 数据 D4 组件接口 D5 一次调用旅程
L01

它到底是什么

🤔 痛点:不用框架,自己拿 Go 调大模型会怎样? 你得手写 HTTP 请求拼 OpenAI 的 JSON、自己解析流式返回的一段段 chunk、自己维护"对话历史"、模型说"我要调工具"时你还得手动解析参数→执行→把结果塞回去再问一遍……换个模型(Claude/Gemini)又要重写一遍。全是重复的胶水代码。
💡 本质:把 LLM 应用的"胶水"沉淀成可复用积木 + 编排引擎 Eino 干的事,就是把"调模型 / 用工具 / 检索 / 拼提示词"抽象成统一接口的组件,再给你一套图/链编排引擎把积木连起来跑。类比:它之于 Go LLM 开发,就像 Spring 之于 Java Web——你只管拼业务,脏活框架包了。

Eino(读音 /'aino/,谐音"爱诺")是字节跳动 CloudWeGo 团队开源的 Go 语言 LLM 应用开发框架。README 第 17 行原话:

"Eino is an LLM application development framework in Golang. It draws from LangChain, Google ADK, and other open-source frameworks, and is designed to follow Golang conventions."

翻译:它是 Go 版的 LLM 应用开发框架,借鉴了 LangChain、Google ADK,但遵循 Go 的工程习惯(强类型、接口、显式错误、高性能)。你可以把它当成"Go 版的 LangChain + LangGraph"。

🎯 一句话:它帮你把"调大模型 / 用工具 / 检索 / 拼提示词"这些积木,用"图和链"连起来跑,或直接搭成"能自己调工具干活的 Agent"——全程类型安全、原生支持流式。

为什么要一个"Go 版"的? Python 的 LangChain 生态最大,但很多公司的后端服务是 Go 写的(字节内部尤其多)。用 Go 写 LLM 应用能直接融进现有 Go 服务、享受 Go 的高并发和强类型。Eino 就是给这些团队用的——所以它特别强调"类型安全"和"流式处理"(Go 服务对性能敏感)。
L02

动手前,先认识几个词

后面会反复出现这些词,今天先混个脸熟,不用记细节:

名词大白话解释哪天细讲
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
ADKAgent Development Kit,搭"会自己干活的 Agent"的套件。Day 11-15
ReAct经典 Agent 模式:想→调工具→看结果→再想,循环。Day 12/15
中断/恢复Agent 跑一半暂停等人、再从断点续跑(eino 特色)。Day 14
L03

四大支柱

README 明确列了 Eino 的四大支柱(README.md:19-23):

🧩

Components 组件

可复用积木:ChatModel / Tool / Retriever / ChatTemplate 等(本仓只放接口)。

🔗

Composition 编排

把组件连成 Chain / Graph / Workflow,能独立跑或暴露成 agent 工具。

🤖

ADK 智能体套件

搭带工具调用、多智能体协作、中断/恢复的 AI Agent。

📚

Examples 范例

常见模式与真实用例的可跑代码(在独立仓 eino-examples)。

三个仓库要分清(重要)eino(本仓)= 类型/流机制/组件接口/编排引擎/Agent 套件;eino-ext = 官方组件实现(OpenAI/Claude/Gemini/Ollama/Elasticsearch…)+ 回调 handler + DevOps 可视化调试;eino-examples = 示例代码。所以本仓里你看到的 ChatModel 都是接口,真正能调 OpenAI 的实现要去 eino-ext 装。(Day 04/19 细讲)
⚠️ 小白常见误解:以为 go get github.com/cloudwego/eino 装完就能直接调 OpenAI——其实不行。本仓只有接口和引擎,真正连上某家大模型还要再装 eino-ext 里对应的实现包(比如 eino-ext/components/model/openai)。
L04

四层架构总图(动起来看)

💡 生活类比:一家餐厅的四层分工(这套类比今天会一直用) schema 就像"统一的食材规格"(土豆切多大、肉腌几分钟,全店统一,谁拿到都认识);components 就像"岗位标准"(炒锅岗、切配岗各自该会什么——先定标准,不管具体雇谁);compose 就像"菜谱流程"(把各岗位按步骤串起来出一道菜);adk 就像"会自己看单配菜的大厨"(不用你指挥每一步,他自己决定先做哪步、要不要回锅)。

Eino 从下到上分 4 层。下图那颗发光小球是"一次请求从上层 API 落到底层数据类型"的过程。先建立直觉:越往下越基础(数据/接口),越往上越贴应用(编排/Agent);每层只依赖它下面的层

L4 · Agent 层  ·  adk/ + flow/
ChatModelAgent开箱即用
DeepAgent官方推荐
多智能体Agent-as-Tool
中断/恢复human-in-loop
L2 · 编排引擎  ·  compose/(核心)
Chain链式
Graph
Workflow字段映射
Runnable4 流式范式
L3 · 组件接口  ·  components/
ChatModel
Tool
Retriever
ChatTemplate
L1 · 核心数据类型  ·  schema/
Message
StreamReader
ToolInfo
Document
读源建议:就按这个从下往上的顺序读——先 schema(数据长什么样,Day 03)、再 components(能力接口,Day 04)、然后 compose(怎么连起来跑,Day 6-10,最重要)、最后 adk/flow(搭 Agent,Day 11-15)。这也是本教程的顺序。
L05

逐层拆解:每层管什么

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 图。

一个关键认知:ADK 不是独立于 compose 的新引擎。一个 Agent 的"想→调工具→循环"其实是用 compose.NewGraph 搭出来的一张图(Day 12/15 会看到真实代码)。所以 compose(第 2 周)是理解一切的地基——学透了图引擎,Agent 就是水到渠成。
L06

招牌设计:Runnable 的 4 种流式范式

💡 生活类比:还是那家餐厅——上菜的两种方式 流式输出就像厨师"好一道上一道"(烤串好一串上一串,你不用干等),非流式就像"全做完一起上"(一整桌菜齐了才开饭)。四种范式其实就是"点单方式 × 上菜方式"的 2×2 组合:你一次报完菜名还是想到一道报一道(输入非流/流)× 后厨一次上齐还是好一道上一道(输出非流/流)。

Eino 区别于其它框架最亮眼的设计——同一个组件,框架能在四种调用方式间自动转换。这四种叫"流式范式"(Day 06 精讲,这里先建立印象):

范式输入→输出什么时候用
Invoke非流 → 非流普通调用:给一句,等一个完整答案
Stream非流 → 流给一句,边生成边返回(打字机效果)
Collect流 → 非流输入是流,收齐了给一个完整答案
Transform流 → 流流进流出:一段段处理一段段产出
为什么这个设计牛? 一个组件(比如某个大模型)可能只实现了 Stream(它天生是流式的)。但你的图里下一个节点只要非流的完整值。Eino 会自动帮你把 Stream 的输出"拼接"成完整值(Collect),反过来也能把完整值"包装"成单元素流——这套自动转换的底层机制,是 schema 里注册的一堆"拼接函数"(Day 03/17 讲)。结果:组件作者只需实现对它有意义的那一两种范式,框架补齐其余四种。这就是"流式处理"作为 Eino 一等公民的体现。
🤔 对话时间:小白最容易在这里卡住 👶 小白:为什么不干脆规定所有组件都实现流式,统一多好?
👨‍🏫 老师:因为很多组件天生做不到流式——比如"检索器"必须等全部结果排完序才知道谁排第一,你让它"边检索边吐"反而是错的。
👶 小白:那接到一个流式上游、非流式下游的组合怎么办?总不能报错吧?
👨‍🏫 老师:这正是 Eino 的招牌——框架自动转换:把流"收齐拼接"成完整值给下游,或把完整值"包装"成单元素流。组件作者只写自己擅长的那种,剩下框架补齐。
L07

仓库目录地图

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"的最佳示例)。本教程主要围绕它们。
L08

一个必知的设计:接口与实现分离

这是读 Eino 最容易困惑的点:本仓库 components/ 里几乎只有接口,没有具体实现。每个组件目录固定四件套:interface.go(接口)、option.go(选项)、callback_extra.go(回调结构)、doc.go

OpenAI / Claude / Gemini / Ollama / Elasticsearch 这些真正能干活的实现,全在独立仓库 eino-ext

📝 举个例子:一个组件目录里到底有什么 去数 components/model/,你只会看到四件套:interface.go(定义 ChatModel 接口)、option.gocallback_extra.godoc.go——全是"约定",没有一行真调 OpenAI 的代码。真正的 openai.NewChatModel(...) 在另一个仓 eino-ext 里。所以:import github.com/cloudwego/eino/components/model 拿到的是接口,import .../eino-ext/components/model/openai 才是实现。
eino 本仓(零第三方依赖) interface ChatModel interface Tool / Retriever eino-ext(各家 SDK 实现) openai.NewChatModel claude / gemini / ollama… implements(实现接口)
接口在 eino、实现在 eino-ext:本仓只定义"长什么样",谁来干活由 eino-ext 填空。
为什么这么分? 如果把所有厂商 SDK 都塞进核心框架,那核心框架就得依赖一堆第三方库(OpenAI SDK、各种数据库驱动…),又重又容易冲突。核心框架只定义"接口长什么样"(零第三方依赖),你用哪家就去 eino-ext 装哪家的实现。这是 Go 生态推崇的"面向接口编程 + 依赖倒置"——和 gov-agents 教程的 Protocol、claude-code 教程的 CoreTool 是同一种思想。写教程/读代码时凡看到 openai.NewChatModel 之类,记住那是 eino-ext 里的,不在本仓。
L09

三条学习主线

1

纵向:从一次调用到一个 Agent

schema(数据)→ components(组件)→ compose(编排)→ adk(Agent)。这是全教程的主轴。

2

横向:吃透"流式"这条暗线

StreamReader(Day 03)→ 4 种范式自动转换(Day 06)→ 流在图里怎么流(Day 17)。这是 Eino 最独特的地方。

3

范本:ReAct Agent 精读

Day 15 逐行读 flow/agent/react/react.go——它是"如何用图引擎搭一个 Agent 循环"的最佳教材,把前面所有概念串起来。

一个官方定调值得记住:ADK 源码里大量 transfer/handoff 多智能体方式都标了 NOT RECOMMENDED——官方推荐用 Agent-as-Tool / DeepAgent(把子 Agent 当工具调,父 Agent 保持控制),而不是"把控制权整个交出去"的 transfer。Day 13 会讲这个取舍。
L10

今日小结 + 动手

🧠 今天你应该能回答

  • Eino 是什么?(字节 CloudWeGo 的 Go LLM 应用框架,Go 版 LangChain+LangGraph)
  • 四大支柱?(Components / Composition / ADK / Examples)
  • 四层架构?(schema → components → compose → adk/flow,只能上依赖下)
  • 招牌设计?(Runnable 的 4 种流式范式,能自动互转)
  • 接口与实现为什么分离?(核心零第三方依赖,实现在 eino-ext)
  • 心脏是哪个包?(compose/,ADK 其实建立在它之上)
🎵 记忆口诀:四层架构一句话数据打底(schema)、组件立柱(components)、编排串线(compose)、Agent 封顶(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
明天预告 · Day 02:地图有了,我们把环境搭起来——装 Go、拉依赖,跑通官方的 ChatModelAgent 示例,用最小代码感受"给个模型 + 工具 = 一个能自己干活的 Agent"。
← 返回 20 天总目录 下一天 · 环境搭建 & 第一个 Agent →