AI大模型框架eino框架快速上手

graph图编排

无大模型的图编排

go 复制代码
package agent

import (
	"context"
	"fmt"

	"github.com/cloudwego/eino/compose"
)

func Graph_agent() {
	ctx := context.Background()
	//未添加模型的graph流程 注册图 同时定义输入输出的类型 这里都为string类型
	g := compose.NewGraph[string, string]()
	lambda0 := compose.InvokableLambda(func(ctx context.Context, input string) (output string, err error) {
		if input == "测试1" {
			return "输入1", nil
		} else if input == "测试2" {
			return "输入2", nil
		} else if input == "测试3" {
			return "输入3", nil
		}
		return "", nil
	})
	lambda1 := compose.InvokableLambda(func(ctx context.Context, input string) (output string, err error) {
		return "这里是节点1的输出", nil
	})
	lambda2 := compose.InvokableLambda(func(ctx context.Context, input string) (output string, err error) {
		return "这里是节点2的输出", nil
	})
	lambda3 := compose.InvokableLambda(func(ctx context.Context, input string) (output string, err error) {
		return "这里是节点3的输出", nil
	})
	// 加入节点
	err := g.AddLambdaNode("lambda0", lambda0)
	if err != nil {
		panic(err)
	}
	err = g.AddLambdaNode("lambda1", lambda1)
	if err != nil {
		panic(err)
	}
	err = g.AddLambdaNode("lambda2", lambda2)
	if err != nil {
		panic(err)
	}
	err = g.AddLambdaNode("lambda3", lambda3)
	if err != nil {
		panic(err)
	}
	// 分支连接 增加边 用来标记节点与节点怎样连接的
	err = g.AddEdge(compose.START, "lambda0")
	if err != nil {
		panic(err)
	}
	// 加入分支
	err = g.AddBranch("lambda0", compose.NewGraphBranch(func(ctx context.Context, in string) (endNode string, err error) {
		if in == "输入1" {
			return "lambda1", nil
		} else if in == "输入2" {
			return "lambda2", nil
		} else if in == "输入3" {
			return "lambda3", nil
		}
		// 否则,返回 compose.END,表示流程结束
		return compose.END, nil
	}, map[string]bool{"lambda1": true, "lambda2": true, "lambda3": true, compose.END: true}))
	if err != nil {
		panic(err)
	}
	//增加边 lambda1这个节点直接连接end节点
	err = g.AddEdge("lambda1", compose.END)
	if err != nil {
		panic(err)
	}
	err = g.AddEdge("lambda2", compose.END)
	if err != nil {
		panic(err)
	}
	err = g.AddEdge("lambda3", compose.END)
	if err != nil {
		panic(err)
	}
	// 编译
	r, err := g.Compile(ctx)
	if err != nil {
		panic(err)
	}
	// 执行
	answer, err := r.Invoke(ctx, "测试1")
	if err != nil {
		panic(err)
	}
	fmt.Println(answer)
}

来具体看下eino框架的各个api

  • compose.NewGraph 新建图

注意这个图只定义了各个节点之间的流向,没有定义大模型,这个是eion框架设计的重要思想

  • compose.InvokableLambda
    把一个普通的 Go 函数适配成"可调用的图节点"。它接收形如 func(ctx context.Context, input T) (output U, err error) 的函数,返回一个实现了可调用接口的节点对象,供 AddLambdaNode 加入到 Graph 中并在运行时由编排调用
  • g.AddLambdaNode
    增加图节点
  • g.AddEdge
    增加图节点的边
    即把当前的节点流向哪个节点
  • g.AddBranch
    增加图节点分支,即节点有多个分支输出的时候,可以使用AddBranch
  • g.Compile
    图编排编译,定义好的"静态图"生成一个可执行的运行器
  • r.Invoke
    eino框架图编排实际运行函数

测试当前输出

这里是由于节点0定义了流向下一个节点的规则:输入1指向节点1,输入2指向节点2,输入3指向节点3

这里测试给定的输入为 answer, err := r.Invoke(ctx, "测试1")

因此节点流向了1,因此输出如上

增加包含大模型节点的图编排

go 复制代码
package agent

import (
	"context"
	"fmt"

	"github.com/cloudwego/eino-ext/components/model/ollama"
	"github.com/cloudwego/eino/compose"
	"github.com/cloudwego/eino/schema"
)

func NewGraphWithModel() {
	ctx := context.Background()
	//新建图
	g := compose.NewGraph[map[string]string, *schema.Message]()
	lambda := compose.InvokableLambda(func(ctx context.Context, input map[string]string) (output map[string]string, err error) {
		if input["role"] == "gongke" {
			return map[string]string{"role": "gongke", "content": input["content"]}, nil
		}
		if input["role"] == "wenke" {
			return map[string]string{"role": "wenke", "content": input["content"]}, nil
		}
		return map[string]string{"role": "user", "content": input["content"]}, nil
	})
	GongkeLambda := compose.InvokableLambda(func(ctx context.Context, input map[string]string) (output []*schema.Message, err error) {
		return []*schema.Message{
			{
				Role:    schema.System,
				Content: "你是一个专业的工科专业人士,回答问题很严肃认真,不会说废话",
			},
			{
				Role:    schema.User,
				Content: input["content"],
			},
		}, nil
	})
	WenkeLambda := compose.InvokableLambda(func(ctx context.Context, input map[string]string) (output []*schema.Message, err error) {
		return []*schema.Message{
			{
				Role:    schema.System,
				Content: "你是一位专业的文科人士,回答问题很温柔,拥有大量的文科知识",
			},
			{
				Role:    schema.User,
				Content: input["content"],
			},
		}, nil
	})

	model, err := ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
		BaseURL: "http://localhost:11434", // Ollama 服务地址
		Model:   "qwen3:0.6b",             // 模型名称
	})
	if err != nil {
		panic(err)
	}
	//注册节点
	err = g.AddLambdaNode("lambda", lambda)
	if err != nil {
		panic(err)
	}
	err = g.AddLambdaNode("gongke", GongkeLambda)
	if err != nil {
		panic(err)
	}
	err = g.AddLambdaNode("wenke", WenkeLambda)
	if err != nil {
		panic(err)
	}
	err = g.AddChatModelNode("model", model)
	if err != nil {
		panic(err)
	}

	//链接节点 start->lambda
	err = g.AddEdge(compose.START, "lambda")
	if err != nil {
		panic(err)
	}
	//加入分支分之直接把两个lambda节点和branch链接了 lambda-> gongke   lambda->wenke
	g.AddBranch("lambda", compose.NewGraphBranch(func(ctx context.Context, in map[string]string) (endNode string, err error) {
		if in["role"] == "gongke" {
			return "gongke", nil
		}
		if in["role"] == "wenke" {
			return "wenke", nil
		}
		return "wenke", nil
	}, map[string]bool{"wenke": true, "gongke": true}))
	//把两个lambda节点和model节点进行连接 gongke->model
	err = g.AddEdge("gongke", "model")
	if err != nil {
		panic(err)
	}
	// wenke->model
	err = g.AddEdge("wenke", "model")
	if err != nil {
		panic(err)
	}
	//结束节点 model->END
	err = g.AddEdge("model", compose.END)
	if err != nil {
		panic(err)
	}
	//编译
	r, err := g.Compile(ctx)
	if err != nil {
		panic(err)
	}
	input := map[string]string{
		"role":    "wenke",
		"content": "介绍下你自己",
	}
	//执行
	answer, err := r.Invoke(ctx, input)
	if err != nil {
		panic(err)
	}
	fmt.Println(answer.Content)
}

输出

这里的函数逻辑和无大模型节点差不多,知识多了一段逻辑

g.AddChatModelNode

增加大模型节点

注意下注册大模型客户端

这里采用的本地化ollama部署 大模型使用的qwen3

go 复制代码
model, err := ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
		BaseURL: "http://localhost:11434", // Ollama 服务地址
		Model:   "qwen3:0.6b",             // 模型名称
	})

这里通过区分role角色使得lambda节点流向不同的分支,在分支中拿到不同的提示词,从而输出给到下个大模型节点,从而输出不同的信息,如上输出给出的role=wenke

接下来把role修改下role=gongke

输出

可以看到用户的输出思考会根据用户给定的系统提示词作出思考输出

参考
b站eino开发框架教程

相关推荐
哥布林学者2 分钟前
吴恩达深度学习课程五:自然语言处理 第一周:循环神经网络 (五)门控循环单元 GRU
深度学习·ai
酩酊仙人1 小时前
fastmcp构建mcp server和client
python·ai·mcp
格林威2 小时前
传送带上运动模糊图像复原:提升动态成像清晰度的 6 个核心方案,附 OpenCV+Halcon 实战代码!
人工智能·opencv·机器学习·计算机视觉·ai·halcon·工业相机
源代码•宸5 小时前
Leetcode—39. 组合总和【中等】
经验分享·算法·leetcode·golang·sort·slices
MonkeyKing_sunyuhua5 小时前
大模型常见的专用名词
大模型
大模型真好玩6 小时前
大模型训练全流程实战指南(一)——为什么要学习大模型训练?
人工智能·pytorch·python·大模型·deep learning
悟乙己6 小时前
使用TimeGPT进行时间序列预测案例解析
机器学习·大模型·llm·时间序列·预测
数据饕餮6 小时前
提示词工程实训营09- 4.2 风格模仿与调整——从“千篇一律“到“风格百变“的AI魔法
大模型·提示词工程
桃子叔叔6 小时前
基于SWIFT框架的预训练微调和推理实战指南之完整实战项目
大模型·swift
盒子69106 小时前
【golang】替换 ioutil.ReadAll 为 io.ReadAll 性能会下降吗
开发语言·后端·golang