Skip to content

Commit 6a9fa80

Browse files
docs(quickstart): improve chatwitheino documentation
- Update code links from eino to eino-examples repository - Add PROJECT_ROOT setup instructions for ch05-ch07 - Clarify Middleware execution order and Handlers field usage - Improve Callback documentation with HandlerHelper usage - Enhance Interrupt/Resume explanation with detailed pseudocode - Add documentation_review_report.md for review tracking~ Change-Id: I345bad56733d5159e5f0fbed8845ca6ac418bc6e
1 parent c3c4231 commit 6a9fa80

10 files changed

Lines changed: 1034 additions & 131 deletions

quickstart/chatwitheino/docs/ch01_chatmodel_agent_console.md

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,76 @@
22
title: "第一章:ChatModel 与 Message(Console)"
33
---
44

5+
## Eino 框架简介
6+
7+
**Eino 是什么?**
8+
9+
Eino 是一个 Go 语言实现的 AI 应用开发框架(Agent Development Kit),旨在帮助开发者快速构建可扩展、可维护的 AI 应用。
10+
11+
**Eino 解决什么问题?**
12+
13+
1. **模型抽象**:统一不同 LLM 提供商的接口(OpenAI、Ark、Claude 等),切换模型无需修改业务代码
14+
2. **能力组合**:通过 Component 接口实现可替换、可组合的能力单元(对话、工具、检索等)
15+
3. **编排框架**:提供 Agent、Graph、Chain 等编排抽象,支持复杂的多步骤 AI 工作流
16+
4. **运行时支持**:内置流式输出、中断与恢复、状态管理、Callback 可观测性等能力
17+
18+
**Eino 的主要仓库:**
19+
- **eino**(本仓库):核心库,定义接口、编排抽象和 ADK
20+
- **eino-ext**:扩展库,提供各类 Component 的具体实现(OpenAI、Ark、Milvus 等)
21+
- **eino-examples**:示例代码库,包含本 quickstart 系列
22+
23+
---
24+
25+
## ChatWithEino:与 Eino 文档对话的智能助手
26+
27+
**ChatWithEino 是什么?**
28+
29+
ChatWithEino 是一个基于 Eino 框架构建的智能助手,能够帮助开发者学习 Eino 框架并编写 Eino 代码。它通过访问 Eino 仓库的源码、注释和示例,为用户提供最准确、最及时的技术支持。
30+
31+
**核心能力:**
32+
- **对话交互**:理解用户关于 Eino 的问题,提供清晰的解答
33+
- **代码访问**:直接读取 Eino 源码、注释和示例,基于真实实现回答问题
34+
- **持久化会话**:支持多轮对话,记住上下文,可跨进程恢复会话
35+
- **工具调用**:能够执行文件读取、代码搜索等操作
36+
37+
**技术架构:**
38+
- **ChatModel**:与大语言模型通信(OpenAI、Ark、Claude 等)
39+
- **Tool**:文件系统访问、代码搜索等能力扩展
40+
- **Memory**:对话历史持久化存储
41+
- **Agent**:统一的执行框架,协调各组件协同工作
42+
43+
## Quickstart 文档系列:从零构建 ChatWithEino
44+
45+
本系列文档通过循序渐进的方式,带你从最基础的 ChatModel 调用开始,逐步构建一个功能完整的 ChatWithEino Agent。
46+
47+
**学习路径:**
48+
49+
| 章节 | 主题 | 核心内容 | 能力提升 |
50+
|------|------|----------|----------|
51+
| **第一章** | ChatModel 与 Message | 理解 Component 抽象,实现单次对话 | 基础对话能力 |
52+
| **第二章** | Agent 与 Runner | 引入执行抽象,实现多轮对话 | 会话管理能力 |
53+
| **第三章** | Memory 与 Session | 持久化对话历史,支持会话恢复 | 持久化能力 |
54+
| **第四章** | Tool 与文件系统 | 添加文件访问能力,读取源码 | 工具调用能力 |
55+
| **第五章** | Middleware | 中间件机制,统一处理横切关注点 | 扩展性增强 |
56+
| **第六章** | Callback | 回调机制,监控 Agent 执行过程 | 可观测性 |
57+
| **第七章** | Interrupt 与 Resume | 中断与恢复,支持长时间任务 | 可靠性增强 |
58+
| **第八章** | Graph 与 Tool | 使用 Graph 编排复杂工作流 | 复杂编排能力 |
59+
| **第九章** | A2UI | Agent 到 UI 的集成方案 | 生产级应用 |
60+
61+
**为什么这样设计?**
62+
63+
每一章都在前一章的基础上增加一个核心能力,让你:
64+
1. **理解每个组件的作用**:不是一次性展示所有功能,而是逐步引入
65+
2. **看到架构演进过程**:从简单到复杂,理解为什么需要每个抽象
66+
3. **掌握实际开发技能**:每章都有可运行的代码,可以动手实践
67+
68+
---
69+
570
本章目标:理解 Eino 的 Component 抽象,用最小代码调用一次 ChatModel(支持流式输出),并掌握 `schema.Message` 的基本用法。
671

772
## 代码位置
873

9-
- 入口代码:[cmd/ch01/main.go](https://github.com/cloudwego/eino/blob/main/examples/quickstart/chatwitheino/cmd/ch01/main.go)
74+
- 入口代码:[cmd/ch01/main.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/cmd/ch01/main.go)
1075

1176
## 为什么需要 Component 接口
1277

@@ -58,14 +123,21 @@ schema.ToolMessage("tool result", "call_id")
58123

59124
## 前置条件
60125

61-
- Go 版本:与本目录 `go.mod` 一致
126+
### 获取代码
127+
128+
```bash
129+
git clone https://github.com/cloudwego/eino-examples.git
130+
cd eino-examples/quickstart/chatwitheino
131+
```
132+
133+
- Go 版本:Go 1.21+(见 `go.mod`
62134
- 一个可调用的 ChatModel(默认使用 OpenAI;也支持 Ark)
63135

64136
### 方式 A:OpenAI(默认)
65137

66138
```bash
67139
export OPENAI_API_KEY="..."
68-
export OPENAI_MODEL="gpt-4.1-mini"
140+
export OPENAI_MODEL="gpt-4.1-mini" # OpenAI 2025 年新模型,也可用 gpt-4o、gpt-4o-mini 等
69141
# 可选:
70142
# OPENAI_BASE_URL(代理或兼容服务)
71143
# OPENAI_BY_AZURE=true(使用 Azure OpenAI)
@@ -103,7 +175,7 @@ go run ./cmd/ch01 -- "用一句话解释 Eino 的 Component 设计解决了什
103175
3. **调用 Stream**:所有 ChatModel 实现都必须支持 `Stream()`,返回 `StreamReader[*Message]`
104176
4. **打印结果**:迭代 `StreamReader` 逐帧打印 assistant 回复
105177

106-
关键代码片段(**注意:这是简化后的代码片段,不能直接运行,完整代码请参考** [cmd/ch01/main.go](https://github.com/cloudwego/eino/blob/main/examples/quickstart/chatwitheino/cmd/ch01/main.go)):
178+
关键代码片段(**注意:这是简化后的代码片段,不能直接运行,完整代码请参考** [cmd/ch01/main.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/cmd/ch01/main.go)):
107179

108180
```go
109181
// 构造输入

quickstart/chatwitheino/docs/ch02_chatmodel_agent_runner_console.md

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ title: "第二章:ChatModelAgent、Runner、AgentEvent(Console 多轮)"
66

77
## 代码位置
88

9-
- 入口代码:[cmd/ch02/main.go](https://github.com/cloudwego/eino/blob/main/examples/quickstart/chatwitheino/cmd/ch02/main.go)
9+
- 入口代码:[cmd/ch02/main.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/cmd/ch02/main.go)
1010

1111
## 前置条件
1212

@@ -176,7 +176,7 @@ events := runner.Query(ctx, "你好")
176176
type AgentEvent struct {
177177
AgentName string
178178
RunPath []RunStep
179-
179+
180180
Output *AgentOutput // 输出内容
181181
Action *AgentAction // 控制动作
182182
Err error // 执行错误
@@ -188,13 +188,24 @@ type AgentEvent struct {
188188
- `event.Output.MessageOutput`:message 或 message stream(流式)
189189
- `event.Action`:中断/转移/退出等控制动作(后续章节用到)
190190

191+
### AsyncIterator:事件流的消费方式
192+
193+
`Runner.Run()` 返回的是 `*AsyncIterator[*AgentEvent]`,这是一个非阻塞的流式迭代器。
194+
195+
**为什么用 AsyncIterator 而不是直接返回结果?**
196+
197+
因为 Agent 的执行是**流式**的:模型逐 token 生成回复,Tool 调用穿插其中。如果等全部完成再返回,用户需要等待更长时间。`AsyncIterator` 让你可以实时消费每一个事件。
198+
191199
**消费方式:**
192200

193201
```go
202+
// events 是 *AsyncIterator[*AgentEvent],由 runner.Run() 返回
203+
events := runner.Run(ctx, history)
204+
194205
for {
195-
event, ok := events.Next()
206+
event, ok := events.Next() // 获取下一个事件,阻塞直到有事件或结束
196207
if !ok {
197-
break
208+
break // 迭代器关闭,全部事件已消费
198209
}
199210
if event.Err != nil {
200211
// 处理错误
@@ -205,6 +216,8 @@ for {
205216
}
206217
```
207218

219+
**注意:**每次 `runner.Run()` 创建新的迭代器,消费一次后不可重复使用。
220+
208221
## 多轮对话的实现
209222

210223
本章实现的是简单的多轮对话:用户输入 → 模型回复 → 用户继续输入 → ...
@@ -218,7 +231,7 @@ for {
218231
3. 调用 `runner.Run(ctx, history)` 得到事件流,消费得到 assistant 文本
219232
4. 把本轮 assistant 文本追加回 history,进入下一轮
220233

221-
**关键代码片段(**注意:这是简化后的代码片段,不能直接运行,完整代码请参考** [cmd/ch02/main.go](https://github.com/cloudwego/eino/blob/main/examples/quickstart/chatwitheino/cmd/ch02/main.go)):
234+
**关键代码片段(**注意:这是简化后的代码片段,不能直接运行,完整代码请参考** [cmd/ch02/main.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/cmd/ch02/main.go)):
222235

223236
```go
224237
history := make([]*schema.Message, 0, 16)

quickstart/chatwitheino/docs/ch03_memory_session_jsonl.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ title: "第三章:Memory 与 Session(持久化对话)"
1515
1616
## 代码位置
1717

18-
- 入口代码:[cmd/ch03/main.go](https://github.com/cloudwego/eino/blob/main/examples/quickstart/chatwitheino/cmd/ch03/main.go)
19-
- Memory 实现:[mem/store.go](https://github.com/cloudwego/eino/blob/main/examples/quickstart/chatwitheino/mem/store.go)
18+
- 入口代码:[cmd/ch03/main.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/cmd/ch03/main.go)
19+
- Memory 实现:[mem/store.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/mem/store.go)
2020

2121
## 前置条件
2222

@@ -174,7 +174,7 @@ if err := session.Append(assistantMsg); err != nil {
174174
}
175175
```
176176

177-
**关键代码片段(**注意:这是简化后的代码片段,不能直接运行,完整代码请参考** [cmd/ch03/main.go](https://github.com/cloudwego/eino/blob/main/examples/quickstart/chatwitheino/cmd/ch03/main.go)):
177+
**关键代码片段(**注意:这是简化后的代码片段,不能直接运行,完整代码请参考** [cmd/ch03/main.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/cmd/ch03/main.go)):
178178

179179
```go
180180
// 创建或恢复 Session

quickstart/chatwitheino/docs/ch04_tool_backend_filesystem.md

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,25 @@ backend, err := localbk.NewBackend(ctx, &localbk.Config{})
113113

114114
本章使用 DeepAgent 预构建 Agent,它提供了 Backend 和 StreamingShell 的一级配置,可以方便地注册文件系统相关的工具。
115115

116+
### 从 ChatModelAgent 到 DeepAgent:何时需要切换?
117+
118+
前面章节一直使用 `ChatModelAgent`,它已经能处理多轮对话。但要访问文件系统,我们需要切换到 `DeepAgent`
119+
120+
**ChatModelAgent vs DeepAgent 对比:**
121+
122+
| 能力 | ChatModelAgent | DeepAgent |
123+
|------|----------------|-----------|
124+
| 多轮对话 |||
125+
| 添加自定义 Tool | ✅ 手动注册每个 Tool | ✅ 手动注册或自动注册 |
126+
| 文件系统访问(Backend) | ❌ 需手动创建并注册所有文件工具 | ✅ 一级配置,自动注册 |
127+
| 命令执行(StreamingShell) | ❌ 需手动创建 | ✅ 一级配置,自动注册 |
128+
| 内置任务管理 ||`write_todos` 工具 |
129+
| 支持子 Agent |||
130+
131+
**选择建议:**
132+
- 纯对话场景(无外部访问)→ 用 `ChatModelAgent`
133+
- 需要访问文件系统或执行命令 → 用 `DeepAgent`
134+
116135
### 为什么使用 DeepAgent?
117136

118137
相比直接使用 ChatModelAgent,DeepAgent 的优势:
@@ -159,72 +178,56 @@ agent, err := deep.New(ctx, &deep.Config{
159178

160179
## 代码位置
161180

162-
- 入口代码:[cmd/ch04/main.go](https://github.com/cloudwego/eino/blob/main/examples/quickstart/chatwitheino/cmd/ch04/main.go)
181+
- 入口代码[cmd/ch04/main.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/cmd/ch04/main.go)
163182

164183
## 前置条件
165184

166-
与第一章一致:需要配置一个可用的 ChatModel(OpenAI 或 Ark)
185+
与第一章一致:需要配置一个可用的 ChatModel(OpenAI 或 Ark)。
186+
187+
本章还需要设置 `PROJECT_ROOT`(可选,见下方运行说明)。
167188

168189
## 运行
169190

170191
`examples/quickstart/chatwitheino` 目录下执行:
171192

172193
```bash
173-
# 设置 Eino 核心库的根目录路径
174-
# 这是 Agent 能够访问的代码库范围,Agent 将检索和读取该目录下的代码和文档
194+
# 可选:设置 Eino 核心库的根目录路径
195+
# 未设置时,Agent 默认使用当前工作目录(即 chatwitheino 目录)作为根目录
196+
# 若要让 Agent 能检索完整的 Eino 代码库,建议指向 eino 核心库根目录
175197
export PROJECT_ROOT=/path/to/eino
176198

199+
# 验证路径是否正确(应该能看到 adk、components、compose 等目录)
200+
ls $PROJECT_ROOT
201+
177202
go run ./cmd/ch04
178203
```
179204

180-
**重要说明:**
205+
**`PROJECT_ROOT` 说明:**
181206

182-
`PROJECT_ROOT` 环境变量指定了 Eino 核心库在文件系统中的路径。因为本示例是 ChatWithDoc(与文档对话),Agent 需要知道 Eino 项目的代码在哪里,才能检索和读取代码及文档。
207+
- **不设置时**`PROJECT_ROOT` 默认为当前工作目录(`chatwitheino` 所在目录),Agent 只能访问本示例项目的文件。这对于快速试验已足够。
208+
- **设置后**:指向 Eino 核心库根目录,Agent 可以检索 Eino 框架的完整代码库(核心库、扩展库、示例库)。这是 ChatWithEino 的完整使用场景。
183209

184-
**三个仓库的相对路径关系:**
210+
**推荐的三仓库目录结构(如要完整体验):**
185211

186212
```
187-
PROJECT_ROOT/ # Eino 核心库根目录 (由 PROJECT_ROOT 指定)
188-
├── adk/ # Agent Development Kit
189-
├── components/ # 核心组件
190-
├── compose/ # 编排组件
191-
├── examples/ # 示例代码
192-
│ └── quickstart/ # 快速开始示例
193-
│ └── chatwitheino/ # 本示例所在位置
213+
eino/ # PROJECT_ROOT(Eino 核心库)
214+
├── adk/
215+
├── components/
216+
├── compose/
217+
├── ext/ # eino-ext(扩展组件,如 OpenAI、Ark 等实现)
218+
├── examples/ # eino-examples(本仓库,本示例所在位置)
219+
│ └── quickstart/
220+
│ └── chatwitheino/
194221
└── ...
195222
```
196223

197-
**依赖关系:**
198-
199-
- **eino**: 核心库,由 `PROJECT_ROOT` 指定路径
200-
- **eino-ext**: 扩展库,需要在 `PROJECT_ROOT/ext` 目录下(扩展组件实现,如 OpenAI、Ark 等)
201-
- **eino-examples**: 示例代码库,需要在 `PROJECT_ROOT/examples` 目录下
202-
203-
**重要**: 上述相对路径关系需要用户手动保证,不是自动配置的。可以使用 `dev_setup.sh` 脚本来快速设置:
224+
可以使用 `dev_setup.sh` 脚本自动设置上述目录结构:
204225

205226
```bash
206-
# 在 eino 根目录运行脚本,自动克隆扩展库和示例库到正确位置
227+
# 在 eino 根目录运行,自动克隆扩展库和示例库到正确位置
207228
bash scripts/dev_setup.sh
208229
```
209230

210-
脚本会创建以下目录结构:
211-
```
212-
eino/ # PROJECT_ROOT (核心库)
213-
├── ext/ # eino-ext (扩展组件)
214-
├── examples/ # eino-examples (示例代码)
215-
└── ... core framework
216-
```
217-
218-
**为什么需要设置 PROJECT_ROOT?**
219-
220-
`PROJECT_ROOT` 是 Eino 核心库的文件系统路径,通过这一个配置就能实现 Eino 框架全量的代码检索:
221-
222-
1. **核心库检索**: `PROJECT_ROOT` 指向 Eino 核心库,Agent 可以直接读取核心代码
223-
2. **扩展库检索**: 根据 `PROJECT_ROOT` 可以定位到 `eino-ext` 仓库(扩展组件实现)
224-
3. **示例库检索**: 根据 `PROJECT_ROOT` 可以定位到 `eino-examples` 仓库(示例代码)
225-
226-
**一个配置,全量检索** - 通过设置 `PROJECT_ROOT`,Agent 能够访问 Eino 框架的完整代码库,包括核心库、扩展库和示例库,为用户提供全面的技术支持。
227-
228231
输出示例:
229232

230233
```text

0 commit comments

Comments
 (0)