Skip to content

Commit

Permalink
feat: update eino docs (#1207)
Browse files Browse the repository at this point in the history
  • Loading branch information
kuhahalong authored Jan 15, 2025
1 parent 19adbcf commit 7096744
Show file tree
Hide file tree
Showing 40 changed files with 756 additions and 338 deletions.
57 changes: 2 additions & 55 deletions content/zh/docs/eino/_index.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,15 @@
---
Description: Eino 是基于 Golang 的 AI 应用开发框架
date: "2025-01-07"
date: "2025-01-15"
lastmod: ""
linktitle: Eino
menu:
main:
parent: 文档
weight: 6
tags: []
title: Eino 用户手册
title: Eino
weight: 6
---

> Eino 发音:美 / 'aino /,近似音: i know,有希望应用程序达到 "i know" 的愿景

# Eino 是什么

> 💡
> Go AI 集成组件的研发框架。
Eino 旨在提供 Golang 语言的 AI 应用开发框架。 Eino 参考了开源社区中诸多优秀的 AI 应用开发框架,例如 LangChain、LangGraph、LlamaIndex 等,提供了更符合 Golang 编程习惯的 AI 应用开发框架。

Eino 提供了丰富的辅助 AI 应用开发的**原子组件****集成组件****组件编排****切面扩展**等能力,可以帮助开发者更加简单便捷地开发出架构清晰、易维护、高可用的 AI 应用。

以 React Agent 为例:

- 提供了 ChatModel、ToolNode、PromptTemplate 等常用组件,并且业务可定制、可扩展。
- 可基于现有组件进行灵活编排,产生集成组件,在业务服务中使用。

![](/img/eino/react_agent_graph.png)

# Eino 组件

> Eino 的其中一个目标是:搜集和完善 AI 应用场景下的组件体系,让业务可轻松找到一些通用的 AI 组件,方便业务的迭代。
Eino 会围绕 AI 应用的场景,提供具有比较好的抽象的组件,并围绕该抽象提供一些常用的实现。

- Eino 组件的抽象定义在:[eino/components](https://github.com/cloudwego/eino/tree/main/components)
- Eino 组件的实现在:[eino-ext/components](https://github.com/cloudwego/eino-ext/tree/main/components)

# Eino 应用场景

得益于 Eino 轻量化和内场亲和属性,用户只需短短数行代码就能给你的存量微服务引入强力的大模型能力,让传统微服务进化出 AI 基因。

可能大家听到【Graph 编排】这个词时,第一反应就是将整个应用接口的实现逻辑进行分段、分层的逻辑拆分,并将其转换成可编排的 Node。 这个过程中遇到的最大问题就是**长距离的上下文传递(跨 Node 节点的变量传递)**问题,无论是使用 Graph/Chain 的 State,还是使用 Options 透传,整个编排过程都极其复杂,远没有直接进行函数调用简单。

基于当前的 Graph 编排能力,适合编排的场景具有如下几个特点:

- 整体是围绕模型的语义处理相关能力。这里的语义不限模态
- 编排产物中有极少数节点是 Session 相关的。整体来看,绝大部分节点没有类似用户/设备等不可枚举地业务实体粒度的处理逻辑

- 无论是通过 Graph/Chain 的 State、还是通过 CallOptions,对于读写或透传用户/设备粒度的信息的方式,均不简便
- 需要公共的切面能力,基于此建设观测、限流、评测等横向治理能力

编排的意义是什么: 把长距离的编排元素上下文以固定的范式进行聚合控制和呈现。

**整体来说,“Graph 编排”适用的场景是: 业务定制的 AI 集成组件。 ****即把 AI 相关的原子能力,进行灵活编排****,提供简单易用的场景化的 AI 组件。 并且该 AI 组件中,具有统一且完整的横向治理能力。**

- 推荐的使用方式

![](/img/eino/recommend_way_of_handler.png)

- 挑战较大的方式 -- 【业务全流程的节点编排】
- Biz Handler 一般重业务逻辑,轻数据流,比较适合函数栈调用的方式进行开发
- 如果采用图编排的方式进行逻辑划分与组合,会增大业务逻辑开发的难度

![](/img/eino/big_challenge_graph.png)
13 changes: 8 additions & 5 deletions content/zh/docs/eino/core_modules/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ weight: 3
Eino 中的核心模块有如下几个部分:

- **Components 组件**[Eino: Components 组件](/zh/docs/eino/core_modules/components)
Eino 抽象出来的大模型应用中常用的组件,例如 `ChatModel``Embedding``Retriever` 等,这是实现一个大模型应用搭建的积木,是应用能力的基础,也是复杂逻辑编排时的原子对象。

Eino 抽象出来的大模型应用中常用的组件,例如 `ChatModel``Embedding``Retriever` 等,这是实现一个大模型应用搭建的积木,是应用能力的基础,也是复杂逻辑编排时的原子对象。

- **Chain/Graph 编排**[Eino: Chain/Graph 编排功能](/zh/docs/eino/core_modules/chain_and_graph_orchestration/chain_graph_introduction)
多个组件混合使用来实现业务逻辑的串联,Eino 提供 Chain/Graph 的编排方式,把业务逻辑串联的复杂度封装在了 Eino 内部,提供易于理解的业务逻辑编排接口,提供统一的横切面治理能力。

多个组件混合使用来实现业务逻辑的串联,Eino 提供 Chain/Graph 的编排方式,把业务逻辑串联的复杂度封装在了 Eino 内部,提供易于理解的业务逻辑编排接口,提供统一的横切面治理能力。

- **Flow 集成工具 (agents)**: [Eino: Flow 集成组件](/zh/docs/eino/core_modules/flow_integration_components)
Eino 把最常用的大模型应用模式封装成简单、易用的工具,让通用场景的大模型应用开发极致简化,目前提供了 `React Agent``Host Multi Agent`
- **EinoDev 开发辅助工具**[EinoDev: 应用开发工具链](/zh/docs/eino/core_modules/application_development_toolchain)
Eino 致力于让全码开发大模型应用变得非常简单,EinoDev 则为 Eino 编排提供了 `可视化``交互式` 的开发调试方案,所见即所得,让开发者的精力从 `调试地狱` 中释放出来,专注于场景逻辑。

Eino 把最常用的大模型应用模式封装成简单、易用的工具,让通用场景的大模型应用开发极致简化,目前提供了 `React Agent``Host Multi Agent`

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
Description: ""
date: "2025-01-06"
date: "2025-01-15"
lastmod: ""
tags: []
title: 'Eino: Chain & Graph 编排功能'
weight: 2
---

在大模型应用中,`Components` 组件 是提供 『原子能力』的最小单元,比如:
在大模型应用中,`Components` 组件是提供 『原子能力』的最小单元,比如:

- `ChatModel` 提供了大模型的对话能力
- `Embedding` 提供了基于语义的文本向量化能力
Expand Down Expand Up @@ -39,20 +39,15 @@ Eino 对「编排」有着这样的洞察:
具体来说,实现了如下特性:

- 一切以 “组件” 为核心,规范了业务功能的封装方式,让**职责划分变得清晰**,让**复用**变成自然而然

- 详细信息参考:[Eino: Components 组件](/zh/docs/eino/core_modules/components)
- 业务逻辑复杂度封装到组件内部,编排层拥有更全局的视角,让**逻辑层次变得非常清晰**
- 提供了切面能力,callback 机制支持了基于节点的**统一治理能力**

- 详细信息参考:[Eino: 公共切面 - Callbacks](/zh/docs/eino/core_modules/chain_and_graph_orchestration/callbacks_common_aspects)
- 提供了 call option 的机制,**扩展性**是快速迭代中的系统最基本的诉求

- 详细信息参考:[Eino: CallOption 能力与规范](/zh/docs/eino/core_modules/chain_and_graph_orchestration/call_option_capabilities)
- 提供了 “类型对齐” 的开发方式的强化,降低开发者心智负担,把 golang 的**类型安全**特性发挥出来

- 详细信息参考:[Eino: 编排的设计理念](/zh/docs/eino/core_modules/chain_and_graph_orchestration/orchestration_design_principles)
- 提供了 “**流的自动转换**” 能力,让 “流” 在「编排系统的复杂性来源榜」中除名

- 详细信息参考:[Eino 流式编程要点](/zh/docs/eino/core_modules/chain_and_graph_orchestration/stream_programming_essentials)

Graph 本身是强大且语义完备的,可以用这项底层几乎绘制出所有的 “数据流动网络”,比如 “分支”、“并行”、“循环”。
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
---
Description: ""
date: "2025-01-07"
date: "2025-01-15"
lastmod: ""
tags: []
title: 'Eino: CallOption 能力与规范'
weight: 0
---

**CallOption**: 对 Graph 编译产物进行调用时,直接传递数据给特定的一组节点(Component、Implementation、Node)的渠道
- 和 节点 Config 的区别: 节点 Config 是实例粒度的配置,也就是从实例创建到实例消除,Config 中的值一旦确定就不需要改变了
- CallOption:是请求粒度的配置,不同的请求,其中的值是不一样的。更像是节点入参,但是这个入参是直接由 Graph 的入口直接传入,而不是上游节点传入。
- 举例:LarkDocLoader 中,需要提供请求粒度的 RefreshToken,这个 RefreshToken 每个用户每次使用后,都需要更换

## 组件 CallOption 形态

Expand All @@ -24,15 +27,15 @@ weight: 0
// 抽象所在代码位置
eino/components/model
├── interface.go
├── **option.go** // Component 抽象粒度的 CallOption 入参
├── option.go // Component 抽象粒度的 CallOption 入参
// 抽象实现所在代码位置
eino-ext/components/model
├── maas
│   ├── **call_option.go**
│   ├── call_option.go
│   └── Implementation.go
├── openai
│   ├── **call_option.go** // Component 的一种实现的 CallOption 入参
│   ├── call_option.go // Component 的一种实现的 CallOption 入参
│   ├── Implementation.go
```

Expand Down Expand Up @@ -156,6 +159,7 @@ func GetImplSpecificOptions[T any](base *T, opts ...Option) *T {
### OpenAI 实现

> 组件的实现均类似 OpenAI 的实现
>
> 注:此处为样例,eino-ext/components/model 中暂时没有此场景
```go
Expand Down Expand Up @@ -281,26 +285,33 @@ r, err := g.Compile()
// 同一个 WithXXX() 会对同一种 Component 的不同实例同时生效
// 必要情况下可通过指定 NodeKey,仅针对一个 Node 生效 WithXXX() 方法
out, err = r.Invoke(ctx, in, WithChatModelOption(
**openai.**WithAKSK("ak", "sk"),
**openai**.WithURL("url"),
openai.WithAKSK("ak", "sk"),
openai.WithURL("url"),
),
// 这组 CallOption 仅针对 openAIModel 这个节点生效
WithChatModelOption(
**model.**WithModel("gpt-3.5-turto"),
model.WithModel("gpt-3.5-turto"),
openai.WithAPIKey("xxxx"),
).DesignateNode("openAIModel"),
)
```

## CallOption 产品形态
## 编排中的 CallOption

每个节点的 CallOption 最终都会映射到 Graph 编排产物的 CallOption 入参上。 因此说 CallOption 是对 Graph 编译产物进行调用时,直接传递数据给特定的一组节点(Component、Implementation、Node)的渠道
CallOption 可以按需分配给 Graph 中不同的节点。

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

需要明确几个点:
```go
// 所有节点都生效的 call option
compiledGraph.Invoke(ctx, input, WithCallbacks(handler))

// 只对特定类型节点生效的 call option
compiledGraph.Invoke(ctx, input, WithChatModelOption(WithTemperature(0.5))

- 每个节点的 CallOption 是否需要再 Graph 的 UI 上直观体现
- Graph 部署后,产生的服务接口,需要有能指定 CallOption 的入参。
// 只对特定节点生效的 call option
compiledGraph.Invoke(ctx, input, WithCallbacks(handler).DesignateNode("node_1"))

- 这个 CallOption 是否需要由 Graph 编排者再次加工后暴露,还是直接裸暴露其中每个节点的 CallOption
// 只对特定内部嵌套图或其中节点生效的 Call option
compiledGraph.Invoke(ctx, input, WithCallbacks(handler).DesignateNodeWithPath(NewNodePath("1", "2"))
```
Loading

0 comments on commit 7096744

Please sign in to comment.