Skip to content

Commit b324caa

Browse files
authored
doc: eino doc update (#1214)
1 parent eea25ec commit b324caa

File tree

108 files changed

+1253
-1062
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+1253
-1062
lines changed

content/zh/docs/eino/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
Description: Eino 是基于 Golang 的 AI 应用开发框架
3-
date: "2025-01-15"
3+
date: "2025-01-20"
44
lastmod: ""
55
linktitle: Eino
66
menu:

content/zh/docs/eino/core_modules/chain_and_graph_orchestration/call_option_capabilities.md

Lines changed: 105 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
Description: ""
3-
date: "2025-01-15"
3+
date: "2025-01-20"
44
lastmod: ""
55
tags: []
66
title: 'Eino: CallOption 能力与规范'
@@ -10,7 +10,7 @@ weight: 0
1010
**CallOption**: 对 Graph 编译产物进行调用时,直接传递数据给特定的一组节点(Component、Implementation、Node)的渠道
1111
- 和 节点 Config 的区别: 节点 Config 是实例粒度的配置,也就是从实例创建到实例消除,Config 中的值一旦确定就不需要改变了
1212
- CallOption:是请求粒度的配置,不同的请求,其中的值是不一样的。更像是节点入参,但是这个入参是直接由 Graph 的入口直接传入,而不是上游节点传入。
13-
- 举例:LarkDocLoader 中,需要提供请求粒度的 RefreshToken,这个 RefreshToken 每个用户每次使用后,都需要更换
13+
- 举例:给一个 ChatModel 节点传入 Temperature 配置;给一个 Lambda 节点传入自定义 option。
1414

1515
## 组件 CallOption 形态
1616

@@ -31,12 +31,12 @@ eino/components/model
3131
3232
// 抽象实现所在代码位置
3333
eino-ext/components/model
34-
├── maas
35-
│   ├── call_option.go
36-
│   └── Implementation.go
37-
├── openai
34+
├── claude
35+
│   ├── option.go // Component 的一种实现的 CallOption 入参
36+
│   └── chatmodel.go
37+
├── ollama
3838
│   ├── call_option.go // Component 的一种实现的 CallOption 入参
39-
│   ├── Implementation.go
39+
│   ├── chatmodel.go
4040
```
4141

4242
### Model 抽象
@@ -60,11 +60,18 @@ type ChatModel interface {
6060
}
6161

6262
// 此结构体是【组件抽象CallOption】的统一定义。 组件的实现可根据自己的需要取用【组件抽象CallOption】的信息
63+
// Options is the common options for the model.
6364
type Options struct {
64-
Temperature float32
65-
MaxTokens int
66-
Model string
67-
TopP float32
65+
// Temperature is the temperature for the model, which controls the randomness of the model.
66+
Temperature *float32
67+
// MaxTokens is the max number of tokens, if reached the max tokens, the model will stop generating, and mostly return an finish reason of "length".
68+
MaxTokens *int
69+
// Model is the model name.
70+
Model *string
71+
// TopP is the top p for the model, which controls the diversity of the model.
72+
TopP *float32
73+
// Stop is the stop words for the model, which controls the stopping condition of the model.
74+
Stop []string
6875
}
6976

7077
// Option is the call option for ChatModel component.
@@ -78,34 +85,47 @@ type Option struct {
7885
implSpecificOptFn any
7986
}
8087

88+
// WithTemperature is the option to set the temperature for the model.
8189
func WithTemperature(temperature float32) Option {
8290
return Option{
8391
apply: func(opts *Options) {
84-
opts.Temperature = temperature
92+
opts.Temperature = &temperature
8593
},
8694
}
8795
}
8896

97+
// WithMaxTokens is the option to set the max tokens for the model.
8998
func WithMaxTokens(maxTokens int) Option {
9099
return Option{
91100
apply: func(opts *Options) {
92-
opts.MaxTokens = maxTokens
101+
opts.MaxTokens = &maxTokens
93102
},
94103
}
95104
}
96105

106+
// WithModel is the option to set the model name.
97107
func WithModel(name string) Option {
98108
return Option{
99109
apply: func(opts *Options) {
100-
opts.Model = name
110+
opts.Model = &name
101111
},
102112
}
103113
}
104114

115+
// WithTopP is the option to set the top p for the model.
105116
func WithTopP(topP float32) Option {
106117
return Option{
107118
apply: func(opts *Options) {
108-
opts.TopP = topP
119+
opts.TopP = &topP
120+
},
121+
}
122+
}
123+
124+
// WithStop is the option to set the stop words for the model.
125+
func WithStop(stop []string) Option {
126+
return Option{
127+
apply: func(opts *Options) {
128+
opts.Stop = stop
109129
},
110130
}
111131
}
@@ -156,149 +176,116 @@ func GetImplSpecificOptions[T any](base *T, opts ...Option) *T {
156176
}
157177
```
158178

159-
### OpenAI 实现
179+
### Claude 实现
160180

161-
> 组件的实现均类似 OpenAI 的实现
162-
>
163-
> 注:此处为样例,eino-ext/components/model 中暂时没有此场景
181+
[https://github.com/cloudwego/eino-ext/blob/main/components/model/claude/option.go](https://github.com/cloudwego/eino-ext/blob/main/components/model/claude/option.go)
164182

165183
```go
166-
package openai
184+
package claude
167185

168186
import (
169187
"github.com/cloudwego/eino/components/model"
170188
)
171189

172-
// openAIOptions 实现粒度的 CallOption 配置
173-
type requestOptions struct {
174-
APIKey string
175-
Stop []string
176-
PresencePenalty float32
190+
type options struct {
191+
TopK *int32
177192
}
178193

179-
// openai 下的 WithXX() 方法,只能对 openai 这一种实现生效
180-
func WithAPIKey(apiKey string) model.Option {
181-
return model.WrapImplSpecificOptFn[requestOptions](func(o *requestOptions) {
182-
o.APIKey = apiKey
183-
})
184-
}
185-
186-
func WithStop(stop []string) model.Option {
187-
return model.WrapImplSpecificOptFn[requestOptions](func(o *requestOptions) {
188-
o.Stop = stop
189-
})
190-
}
191-
192-
func WithPresencePenalty(presencePenalty float32) model.Option {
193-
return model.WrapImplSpecificOptFn[requestOptions](func(o *requestOptions) {
194-
o.PresencePenalty = presencePenalty
194+
func WithTopK(k int32) model.Option {
195+
return model.WrapImplSpecificOptFn(func(o *options) {
196+
o.TopK = &k
195197
})
196198
}
197199
```
198200

199-
model/openai/Implementation.go
201+
[https://github.com/cloudwego/eino-ext/blob/main/components/model/claude/claude.go](https://github.com/cloudwego/eino-ext/blob/main/components/model/claude/claude.go)
200202

201203
```go
202-
type ChatModel struct {}
204+
func (c *claude) genMessageNewParams(input []*schema.Message, opts ...model.Option) (anthropic.MessageNewParams, error) {
205+
if len(input) == 0 {
206+
return anthropic.MessageNewParams{}, fmt.Errorf("input is empty")
207+
}
203208

204-
func (cm *ChatModel) Generate(ctx context.Context, in []*schema.Message, opts ...model.Option) (
205-
206-
cmOpts := model.GetCommonOptions(&model.Options{
207-
Model: "gpt-3.5-turbo",
208-
MaxTokens: 1024,
209-
Temperature: 0.7,
210-
}, opts...)
211-
212-
implOpts := model.GetImplSpecificOptions[requestOptions](&requestOptions{
213-
Stop: nil,
214-
PresencePenalty: 1,
209+
commonOptions := model.GetCommonOptions(&model.Options{
210+
Model: &c.model,
211+
Temperature: c.temperature,
212+
MaxTokens: &c.maxTokens,
213+
TopP: c.topP,
214+
Stop: c.stopSequences,
215215
}, opts...)
216+
claudeOptions := model.GetImplSpecificOptions(&options{TopK: c.topK}, opts...)
216217

217-
// 在这里开发 OpenAI 的 Model 逻辑
218-
_ = cmOpts
219-
_ = implOpts
218+
// omit mulple lines...
219+
return nil, nil
220220
}
221+
```
222+
223+
## 编排中的 CallOption
221224

222-
func (cm *ChatModel) Stream(ctx context.Context, in []*schema.Message,
223-
opts ...model.Option) (outStream *schema.StreamReader[*schema.Message], err error) {
224-
// 同 Generate 接口
225+
[https://github.com/cloudwego/eino/blob/main/compose/runnable.go](https://github.com/cloudwego/eino/blob/main/compose/runnable.go)
226+
227+
Graph 编译产物是 Runnable
228+
229+
```go
230+
type Runnable[I, O any] interface {
231+
Invoke(ctx context.Context, input I, opts ...Option) (output O, err error)
232+
Stream(ctx context.Context, input I, opts ...Option) (output *schema.StreamReader[O], err error)
233+
Collect(ctx context.Context, input *schema.StreamReader[I], opts ...Option) (output O, err error)
234+
Transform(ctx context.Context, input *schema.StreamReader[I], opts ...Option) (output *schema.StreamReader[O], err error)
225235
}
226236
```
227237

228-
### Graph 编译产物
238+
Runnable 各方法均接收 compose.Option 列表。
229239

230-
> Graph 的编译产物是 Runnable[I, O]
240+
[https://github.com/cloudwego/eino/blob/main/compose/graph_call_options.go](https://github.com/cloudwego/eino/blob/main/compose/graph_call_options.go)
231241

232-
option.go
242+
包括 graph run 整体的配置,各类组件的配置,特定 Lambda 的配置等。
233243

234244
```go
245+
// Option is a functional option type for calling a graph.
235246
type Option struct {
236-
options []any
237-
nodeHandler []callbacks.Handler
238-
keys []string
247+
options []any
248+
handler []callbacks.Handler
239249

240-
graphHandler []callbacks.Handler
241-
graphOption []GraphRunOption
242-
}
250+
paths []*NodePath
243251

244-
// 可指定 NodeKey 定点生效 CallOption
245-
func (o Option) DesignateNode(key ...string) Option {
246-
o.keys = append(o.keys, key...)
247-
return o
252+
maxRunSteps int
248253
}
249254

250-
func WithChatModelOption(opts ...model.Option) Option {
251-
o := make([]any, 0, len(opts))
252-
for i := range opts {
253-
o = append(o, opts[i])
254-
}
255-
return Option{
256-
options: o,
257-
keys: make([]string, 0),
255+
// DesignateNode set the key of the node which will the option be applied to.
256+
// notice: only effective at the top graph.
257+
// e.g.
258+
//
259+
// embeddingOption := compose.WithEmbeddingOption(embedding.WithModel("text-embedding-3-small"))
260+
// runnable.Invoke(ctx, "input", embeddingOption.DesignateNode("my_embedding_node"))
261+
func (o Option) DesignateNode(key ...string) Option {
262+
nKeys := make([]*NodePath, len(key))
263+
for i, k := range key {
264+
nKeys[i] = NewNodePath(k)
258265
}
266+
return o.DesignateNodeWithPath(nKeys...)
259267
}
260-
```
261-
262-
runnable.go
263268

264-
```go
265-
type Runnable[I, O any] interface {
266-
Invoke(ctx context.Context, input I, opts ...Option) (output O, err error)
267-
Stream(ctx context.Context, input I, opts ...Option) (output *schema.StreamReader[O], err error)
268-
Collect(ctx context.Context, input *schema.StreamReader[I], opts ...Option) (output O, err error)
269-
Transform(ctx context.Context, input *schema.StreamReader[I], opts ...Option) (output *schema.StreamReader[O], err error)
269+
// DesignateNodeWithPath sets the path of the node(s) to which the option will be applied to.
270+
// You can make the option take effect in the subgraph by specifying the key of the subgraph.
271+
// e.g.
272+
// DesignateNodeWithPath({"sub graph node key", "node key within sub graph"})
273+
func (o Option) DesignateNodeWithPath(path ...*NodePath) Option {
274+
o.paths = append(o.paths, path...)
275+
return o
270276
}
271-
```
272-
273-
Graph 调用
274277

275-
```go
276-
g := NewGraph[map[string]any, *schema.Message]()
277-
278-
_nodeOfModel := &openai.ChatModel{}_
279-
280-
err = g.AddChatModelNode("openAIModel", _nodeOfModel_)
281-
282-
r, err := g.Compile()
283-
284-
// 默认情况下,WithXXX() 的 Option 方法是按照 Component 的类型进行分发的
285-
// 同一个 WithXXX() 会对同一种 Component 的不同实例同时生效
286-
// 必要情况下可通过指定 NodeKey,仅针对一个 Node 生效 WithXXX() 方法
287-
out, err = r.Invoke(ctx, in, WithChatModelOption(
288-
openai.WithAKSK("ak", "sk"),
289-
openai.WithURL("url"),
290-
),
291-
// 这组 CallOption 仅针对 openAIModel 这个节点生效
292-
WithChatModelOption(
293-
model.WithModel("gpt-3.5-turto"),
294-
openai.WithAPIKey("xxxx"),
295-
).DesignateNode("openAIModel"),
296-
)
278+
// WithEmbeddingOption is a functional option type for embedding component.
279+
// e.g.
280+
//
281+
// embeddingOption := compose.WithEmbeddingOption(embedding.WithModel("text-embedding-3-small"))
282+
// runnable.Invoke(ctx, "input", embeddingOption)
283+
func WithEmbeddingOption(opts ...embedding.Option) Option {
284+
return withComponentOption(opts...)
285+
}
297286
```
298287

299-
## 编排中的 CallOption
300-
301-
CallOption 可以按需分配给 Graph 中不同的节点。
288+
compose.Option 可以按需分配给 Graph 中不同的节点。
302289

303290
![](/img/eino/graph_runnable_after_compile.png)
304291

content/zh/docs/eino/core_modules/chain_and_graph_orchestration/callback_manual.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
---
22
Description: ""
3-
date: "2025-01-15"
3+
date: "2025-01-20"
44
lastmod: ""
55
tags: []
66
title: 'Eino: Callback 用户手册'
77
weight: 0
88
---
99

10-
> 💡
11-
> TL;DR
12-
>
13-
> 长文,用意是“明确的、无歧义的、充分的”说明 Eino Callback 设计、实现和使用方式的各方面,可用作解决某个具体问题的工具参考,也可以作为入门后想要更进一步了解细节的一个途径。
14-
>
15-
> 快速入门请移步 :[Eino: 公共切面 - Callbacks](/zh/docs/eino/core_modules/chain_and_graph_orchestration/callbacks_common_aspects)
16-
1710
## 解决的问题
1811

1912
Component(包括 Lambda)、Graph 编排共同解决“把业务逻辑定义出来”的问题。而 logging, tracing, metrics, 上屏展示等横切面性质的功能,需要有机制把功能注入到 Component(包括 Lambda)、Graph 中。
@@ -121,8 +114,6 @@ type CallbackInput struct {
121114
Messages []*schema.Message
122115
// Tools is the tools to be used in the model.
123116
Tools []*schema.ToolInfo
124-
// ToolChoice is the tool choice, which controls the tool to be used in the model.
125-
ToolChoice any // string / *schema.ToolInfo
126117
// Config is the config for the model.
127118
Config *Config
128119
// Extra is the extra information for the callback.
@@ -194,6 +185,8 @@ Graph 会为内部所有的 Node 自动注入 RunInfo。机制是每个 Node 的
194185

195186
## 触发方式
196187

188+
![](/img/eino/graph_node_callback_run_place.png)
189+
197190
### 组件实现内部触发(Component Callback)
198191

199192
在组件实现的代码中,调用 callbacks 包中的 `OnStart(), OnEnd(), OnError(), OnStartWithStreamInput(), OnEndWithStreamInput()`。以 Ark 的 ChatModel 实现为例,在 Generate 方法中:
@@ -444,3 +437,15 @@ Handler 内不建议修改 input / output。原因是:
444437
不同 Handler 之间,没有执行顺序的保证,因此不建议通过上面的机制在不同 Handler 间传递信息。本质上是无法保证某一个 Handler 返回的 context,一定会进入下一个 Handler 的函数执行中。
445438

446439
如果需要在不同 Handler 之间传递信息,建议的方式是在最外层的 context(如 graph 执行时传入的 context)中,设置一个全局的、请求维度的变量作为公共信息的存取空间,在各个 Handler 中按需读取和更新这个公共变量。在有 stream 的情况下,可能需要格外注意和保证这个公共变量的并发安全。
440+
441+
### 流切记要 Close
442+
443+
以存在 ChatModel 这种具有真流输出的节点为例,当存在 Callback 切面时,ChatModel 的输出流:
444+
- 既要被下游节点作为输入来消费,又要被 Callback 切面来消费
445+
- 一个流中的一个帧(Chunk),只能被一个消费方消费到,即流不是广播模型
446+
447+
所以此时需要将流进行复制,其复制关系如下:
448+
449+
![](/img/eino/graph_stream_chunk_copy.png)
450+
451+
- 如果其中一个 Callback n 没有 Close 对应的流,可能导致原始 Stream 无法 Close 和释放资源。

0 commit comments

Comments
 (0)