0x00 前言
本文梳理下笔者实践过eino的若干示例
- self-correcting-agent:自我反思与结果判定
0x01 Eino开发:review
Eino 的核心思想是图(Graph),可以将一个复杂的 AI 任务拆解成一个个独立的节点(Node),然后用边(Edge)将它们连接起来,定义数据的流向和处理逻辑。最终,这张Graph会被编译(Compile)成一个可执行的对象(Runnable)
- Graph:构建工作流的画布
- Node: 图中的操作单元
- ChatModelNode: 专门用于和 LLM 进行交互的节点。它的输入是标准的消息格式(
[]*schema.Message),输出是模型的回复(*schema.Message) - LambdaNode:一个通用的瑞士军刀,可以封装任意自定义的 Go 函数。通常用于:
- 数据转换,即将一种数据类型转换为另一种,例如将简单的字符串输入包装成 ChatModelNode 需要的
[]*schema.Message格式 - Prompt 格式化:根据输入动态生成复杂的提示词
- 输出解析:从模型的原始输出中提取和清理需要的信息,例如从一段文本中解析出 code 或 general 这样的分类标签
- 数据转换,即将一种数据类型转换为另一种,例如将简单的字符串输入包装成 ChatModelNode 需要的
- ChatModelNode: 专门用于和 LLM 进行交互的节点。它的输入是标准的消息格式(
- BranchNode: 实现工作流的条件分支。它内部包含一个函数,该函数根据输入动态地返回下一个应该执行的节点的名称。这使得图可以根据不同的情况执行不同的路径,是实现智能路由的关键
- Edge:定义数据在节点之间的流向
- Runnable: 由图编译而成的可执行实例
如何选择节点?
- 当需要与 LLM 对话时,使用 ChatModelNode
- 当需要进行数据格式化、自定义逻辑处理、或者在调用模型前后进行预处理/后处理时,使用 LambdaNode,它是连接不同节点的胶水
- 当需要根据某个条件动态地决定下一步走向时(如根据问题类型选择不同的专家模型),使用 BranchNode
0x01 基础编排示例:Chain
定义节点 –> 连接节点 –> 编译 –> 执行
func main(ctx context.Context) {
// 1. 配置并创建模型实例
qwenConfig := &openai.ChatModelConfig{
BaseURL: "http://localhost:11434/v1", // Ollama 端点
APIKey: "ollama", // 任意字符串
Model: "qwen2.5:0.5b",
}
qwenModel, _ := openai.NewChatModel(ctx, qwenConfig)
// 2. 创建图 (Graph)
sg := compose.NewGraph[string, *schema.Message]()
// 3. 添加节点 (Node)
// 节点1: LambdaNode,将 string 类型的输入(input)转换成模型需要的 []*schema.Message
formatInput := compose.InvokableLambda(func(ctx context.Context, input string/*用户提问的问题*/) ([]*schema.Message, error) {
return []*schema.Message, nil
})
_ = sg.AddLambdaNode("format_input", formatInput)
// 节点2: ChatModelNode,代表大模型
_ = sg.AddChatModelNode("qwen_model", qwenModel)
// 4. 添加边 (Edge),定义数据流
_ = sg.AddEdge(compose.START, "format_input") // 数据从起点流入 format_input
_ = sg.AddEdge("format_input", "qwen_model") // format_input 的输出是 qwen_model 的输入
_ = sg.AddEdge("qwen_model", compose.END) // qwen_model 的输出是整个链的最终输出
// 5. 编译 (Compile) 成 Runnable
simpleChain, _ := sg.Compile(ctx)
// 6. 执行 (Invoke)
result, _ := simpleChain.Invoke(ctx, "Go语言的主要特点是什么?")
fmt.Println(result.Content)
}
0x02 self-correcting-agent
本agent的实现流程如下:
flowchart TB
A[用户问题] --> B[调度链 Invoke]
B --> C{决策}
C -->|code| D[代码专家链 Invoke]
C -->|general| E[通用专家链 Invoke]
D --> F[质检链 Invoke]
E --> F
F --> G{质检结果}
G -->|good| H[✅ 接受结果]
G -->|bad| I{重试次数 < 3?}
I -->|是| D
I -->|是| E
I -->|否| J[接受最后一次结果]
- 调度链(Dispatcher Chain):主要职责是接收用户问题,并输出问题的分类
- 主路由图(Main Router Graph):它包含两个并行的专家模型节点(代码专家链和通用专家链)。它使用一个特殊的 BranchNode 来调用调度链,并根据其结果,动态地决定数据应该流向哪个专家节点
参考
FEATURED TAGS
Latex
gRPC
负载均衡
OpenSSH
Authentication
Consul
Etcd
Kubernetes
性能优化
Python
分布式锁
WebConsole
后台开发
Golang
OpenSource
Nginx
Vault
网络安全
Perl
分布式理论
Raft
正则表达式
Redis
分布式
限流
go-redis
微服务
反向代理
ReverseProxy
Cache
缓存
连接池
OpenTracing
GOMAXPROCS
GoMicro
微服务框架
日志
zap
Pool
Kratos
Hystrix
熔断
并发
Pipeline
证书
Prometheus
Metrics
PromQL
Breaker
定时器
Timer
Timeout
Kafka
Xorm
MySQL
Fasthttp
bytebufferpool
任务队列
队列
异步队列
GOIM
Pprof
errgroup
consistent-hash
Zinx
网络框架
设计模式
HTTP
Gateway
Queue
Docker
网关
Statefulset
NFS
Machinery
Teleport
Zero Trust
Oxy
存储
Confd
热更新
OAuth
SAML
OpenID
Openssl
AES
微服务网关
IM
KMS
安全
数据结构
hashtable
Sort
Asynq
基数树
Radix
Crontab
热重启
系统编程
sarama
Go-Zero
RDP
VNC
协程池
UDP
hashmap
网络编程
自适应技术
环形队列
Ring Buffer
Circular Buffer
InnoDB
timewheel
GroupCache
Jaeger
GOSSIP
CAP
Bash
websocket
事务
GC
TLS
singleflight
闭包
Helm
network
iptables
MITM
HTTPS
Tap
Tun
路由
wireguard
gvisor
Git
NAT
协议栈
Envoy
FRP
DPI
gopacket
Cgroup
Namespace
DNS
eBPF
GoZero
Gost
Clash
Tracee
gopsutil
Linux
HIDS
ELKEID
XDP
TC
Systemd
netlink
Kernel
BCC
rootkit
bpftrace
AI