
eino实现Agent
eino 是字节官方出来的Agent框架,类似spring-ai
初体验-对话
对接deepseek
go
package main
import (
"context"
"fmt"
"github.com/cloudwego/eino-ext/components/model/deepseek"
"github.com/cloudwego/eino/schema"
)
func main() {
// 创建模型
cm, err := deepseek.NewChatModel(context.Background(), &deepseek.ChatModelConfig{
Model: "deepseek-chat",
APIKey: "sk-xxxxxxxxxxxxxxxxx",
})
if err != nil {
fmt.Printf("创建模型失败: %v\n", err)
return
}
// 直接调用Generate 是一次性返回全部
resp, err := cm.Generate(context.Background(), []*schema.Message{
schema.SystemMessage("你是一个有用的助手"),
schema.UserMessage("Go 语言适合做 AI 开发吗?"),
})
if err != nil {
fmt.Printf("调用模型失败: %v\n", err)
return
}
fmt.Println(resp.Content)
}对接本地Ollama
go
package main
import (
"context"
"fmt"
"github.com/cloudwego/eino-ext/components/model/ollama"
"github.com/cloudwego/eino/schema"
)
func main() {
// 创建模型
cm, err := ollama.NewChatModel(context.Background(), &ollama.ChatModelConfig{
BaseURL: "http://localhost:11434", // Ollama 默认地址
Model: "qwen2.5:3b", // 你本地已下载的模型名称
})
if err != nil {
fmt.Printf("创建模型失败: %v\n", err)
return
}
// 直接调用
resp, err := cm.Generate(context.Background(), []*schema.Message{
schema.SystemMessage("你是一个有用的助手"),
schema.UserMessage("你是谁?"),
})
if err != nil {
fmt.Printf("调用模型失败: %v\n", err)
return
}
fmt.Println(resp.Content)
}连续对话
go
package main
import (
"bufio"
"context"
"fmt"
"log"
"os"
"strings"
"github.com/cloudwego/eino-ext/components/model/ollama"
"github.com/cloudwego/eino/schema"
)
func main() {
ctx := context.Background()
// 创建模型
cm, err := ollama.NewChatModel(context.Background(), &ollama.ChatModelConfig{
BaseURL: "http://localhost:11434", // Ollama 默认地址
Model: "qwen2.5:3b", // 你本地已下载的模型名称
})
if err != nil {
fmt.Printf("创建模型失败: %v\n", err)
return
}
// 对话历史
messages := []*schema.Message{
schema.SystemMessage("你是一个友好的 AI 助手"),
}
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("开始对话(输入 'exit' 退出):")
for {
fmt.Print("\n你: ")
if !scanner.Scan() {
break
}
userInput := strings.TrimSpace(scanner.Text())
if userInput == "exit" {
fmt.Println("再见!")
break
}
if userInput == "" {
continue
}
// 添加用户消息
messages = append(messages, schema.UserMessage(userInput))
// 生成 AI 响应
response, err := cm.Generate(ctx, messages)
if err != nil {
log.Printf("生成失败: %v", err)
continue
}
// 添加 AI 响应到历史
messages = append(messages, response)
fmt.Printf("\\nAI: %s\\n", response.Content)
}
}流式对话
go
package main
import (
"context"
"errors"
"fmt"
"io"
"log"
"strings"
"github.com/cloudwego/eino-ext/components/model/ollama"
"github.com/cloudwego/eino/schema"
)
func main() {
ctx := context.Background()
// 创建模型
chatModel, err := ollama.NewChatModel(context.Background(), &ollama.ChatModelConfig{
BaseURL: "http://localhost:11434", // Ollama 默认地址
Model: "qwen2.5:3b", // 你本地已下载的模型名称
})
if err != nil {
fmt.Printf("创建模型失败: %v\n", err)
return
}
messages := []*schema.Message{
schema.UserMessage("请列举 5 个 Go 语言的特点"),
}
stream, err := chatModel.Stream(ctx, messages)
if err != nil {
log.Fatalf("流式生成失败: %v", err)
}
defer stream.Close()
var fullContent strings.Builder
fmt.Print("AI 回复: ")
for {
chunk, err := stream.Recv()
if err != nil {
if errors.Is(err, io.EOF) {
break
}
log.Fatalf("接收失败: %v", err)
}
// 实时打印
fmt.Print(chunk.Content)
// 同时收集完整内容
fullContent.WriteString(chunk.Content)
}
fmt.Println("\\n\\n======== 完整响应 ========")
fmt.Println(fullContent.String())
}Token 使用统计
go
package main
import (
"context"
"fmt"
"github.com/cloudwego/eino-ext/components/model/ollama"
"github.com/cloudwego/eino/schema"
)
func main() {
// 创建模型
chatModel, err := ollama.NewChatModel(context.Background(), &ollama.ChatModelConfig{
BaseURL: "http://localhost:11434", // Ollama 默认地址
Model: "qwen2.5:3b", // 你本地已下载的模型名称
})
if err != nil {
fmt.Printf("创建模型失败: %v\n", err)
return
}
// 直接调用
resp, err := chatModel.Generate(context.Background(), []*schema.Message{
schema.SystemMessage("你是一个有用的助手"),
schema.UserMessage("你是谁?"),
})
if err != nil {
fmt.Printf("调用模型失败: %v\n", err)
return
}
fmt.Println(resp.Content)
printTokenUsage(resp)
}
// 打印 Token 使用情况
func printTokenUsage(response *schema.Message) {
if response.ResponseMeta != nil && response.ResponseMeta.Usage != nil {
fmt.Printf("\nToken 使用统计:\n")
fmt.Printf(" 输入 Token: %d\n", response.ResponseMeta.Usage.PromptTokens)
fmt.Printf(" 输出 Token: %d\n", response.ResponseMeta.Usage.CompletionTokens)
fmt.Printf(" 总计 Token: %d\n", response.ResponseMeta.Usage.TotalTokens)
if response.ResponseMeta.Usage.PromptTokenDetails.CachedTokens > 0 {
fmt.Printf(" 缓存 Token: %d\n", response.ResponseMeta.Usage.PromptTokenDetails.CachedTokens)
}
}
}流式统计
go
package main
import (
"context"
"fmt"
"github.com/cloudwego/eino-ext/components/model/ollama"
"github.com/cloudwego/eino/schema"
)
func main() {
ctx := context.Background()
chatModel, err := ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
BaseURL: "http://localhost:11434",
Model: "qwen2.5:3b",
})
if err != nil {
fmt.Printf("创建模型失败: %v\n", err)
return
}
// 准备消息
messages := []*schema.Message{
schema.SystemMessage("你是一个有用的助手"),
schema.UserMessage("讲一个100字左右的小故事"),
}
// 流式调用
streamResult, err := chatModel.Stream(ctx, messages)
if err != nil {
fmt.Printf("流式调用失败: %v\n", err)
return
}
// 收集所有响应
var fullContent string
var finalUsage *schema.TokenUsage
for {
msg, err := streamResult.Recv()
if err != nil {
// 注意:EOF 表示流结束
if err.Error() == "EOF" {
break
}
fmt.Printf("接收流数据出错: %v\n", err)
return
}
// 累积内容
fullContent += msg.Content
// 检查是否有 Usage 信息(通常在最后一个包中)
if msg.ResponseMeta != nil && msg.ResponseMeta.Usage != nil {
finalUsage = msg.ResponseMeta.Usage
}
}
// 输出结果
fmt.Println(fullContent)
// 打印 Token 统计
if finalUsage != nil {
fmt.Printf("\nToken 使用统计:\n")
fmt.Printf(" 输入 Token: %d\n", finalUsage.PromptTokens)
fmt.Printf(" 输出 Token: %d\n", finalUsage.CompletionTokens)
fmt.Printf(" 总计 Token: %d\n", finalUsage.TotalTokens)
if finalUsage.PromptTokenDetails.CachedTokens > 0 {
fmt.Printf(" 缓存 Token: %d\n", finalUsage.PromptTokenDetails.CachedTokens)
}
} else {
fmt.Println("\n未获取到 Token 使用信息")
}
}ChatTemplate模版
简单对话
go
package main
import (
"context"
"fmt"
"github.com/cloudwego/eino-ext/components/model/ollama"
"github.com/cloudwego/eino/components/prompt"
"github.com/cloudwego/eino/schema"
)
func main() {
ctx := context.Background()
// 1. 创建 ChatTemplate
template := prompt.FromMessages(schema.FString,
&schema.Message{
Role: schema.System,
Content: "你是一个{role}助手,擅长{skill}领域",
},
&schema.Message{
Role: schema.User,
Content: "请解释一下:{question}",
},
)
// 2. 准备模板变量
variables := map[string]any{
"role": "专业的 AI",
"skill": "Go 语言编程",
"question": "什么是 ChatTemplate?",
}
// 3. 格式化模板生成消息列表
messages, err := template.Format(context.Background(), variables)
if err != nil {
fmt.Printf("格式化模板失败: %v\n", err)
return
}
//4.查看生成的消息
fmt.Println("生成的消息:")
for i, msg := range messages {
fmt.Printf("%d. [%s] : %s \n", i+1, msg.Role, msg.Content)
}
// 4. 创建 ChatModel
chatModel, err := ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
BaseURL: "http://localhost:11434",
Model: "qwen2.5:3b",
})
if err != nil {
fmt.Printf("创建模型失败: %v\n", err)
return
}
// 5. 使用格式化的消息调用模型
resp, err := chatModel.Generate(ctx, messages)
if err != nil {
fmt.Printf("调用模型失败: %v\n", err)
return
}
fmt.Println(resp.Content)
}历史对话
go
package main
import (
"context"
"fmt"
"github.com/cloudwego/eino-ext/components/model/ollama"
"github.com/cloudwego/eino/components/prompt"
"github.com/cloudwego/eino/schema"
)
func main() {
ctx := context.Background()
// ✅ 正确方式:使用 prompt.FromMessages 创建 ChatTemplate
template := prompt.FromMessages(
schema.FString, // 模板格式:FString 支持 {variable} 占位符
// 系统消息模板
schema.SystemMessage("你是一个{personality}助手,用{language}语言回答"),
// 消息占位符:插入历史消息(true 表示可选)
schema.MessagesPlaceholder("history", true),
// 用户消息模板
schema.UserMessage("{question}"),
)
// 初始化模型
chatModel, err := ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
BaseURL: "http://localhost:11434",
Model: "qwen2.5:3b",
})
if err != nil {
fmt.Printf("创建模型失败: %v\n", err)
return
}
// 准备输入变量
input := map[string]any{
"personality": "友好且专业",
"language": "简洁",
"history": []*schema.Message{
schema.UserMessage("你好"),
schema.AssistantMessage("你好!有什么可以帮你的?", nil),
},
"question": "eino 框架的 ChatTemplate 有什么用?",
}
// 格式化消息
messages, err := template.Format(ctx, input)
if err != nil {
fmt.Printf("格式化失败: %v\n", err)
return
}
//查看生成的消息
fmt.Println("生成的消息:")
for i, msg := range messages {
fmt.Printf("%d. [%s] : %s \n", i+1, msg.Role, msg.Content)
}
// 调用模型
resp, err := chatModel.Generate(ctx, messages)
if err != nil {
fmt.Printf("调用失败: %v\n", err)
return
}
fmt.Println("AI 回复:", resp.Content)
}
