
eino整合Tools
单次对话
go
package main
import (
"context"
"fmt"
"log"
"github.com/cloudwego/eino-ext/components/model/ollama"
"github.com/cloudwego/eino/adk"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/components/tool/utils"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/schema"
)
type WeatherParams struct {
City string `json:"city" jsonschema:"required" jsonschema_description:"城市名称,例如:北京、上海、广州"`
}
type WeatherResult struct {
City string `json:"city"`
Temperature float64 `json:"temperature"`
Condition string `json:"condition"`
WindSpeed float64 `json:"wind_speed"`
}
func getWeather(ctx context.Context, params WeatherParams) (WeatherResult, error) {
fmt.Printf("正在调用天气查询工具,查询城市:%s\n", params.City)
weatherData := map[string]WeatherResult{
"北京": {
City: "北京",
Temperature: 25.5,
Condition: "晴",
WindSpeed: 3.2,
},
"上海": {
City: "上海",
Temperature: 28.3,
Condition: "多云",
WindSpeed: 2.8,
},
"广州": {
City: "广州",
Temperature: 32.1,
Condition: "雷阵雨",
WindSpeed: 4.5,
},
}
result, ok := weatherData[params.City]
if !ok {
result = WeatherResult{
City: params.City,
Temperature: 20.0,
Condition: "未知城市,默认天气",
WindSpeed: 1.0,
}
}
return result, nil
}
func main() {
ctx := context.Background()
baseModel, err := ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
BaseURL: "http://localhost:11434",
Model: "qwen2.5:7b",
Options: &ollama.Options{
Temperature: 0.7,
},
})
if err != nil {
log.Fatalf("初始化模型失败:%v", err)
}
weatherTool, err := utils.InferTool[WeatherParams, WeatherResult](
"get_weather",
"获取指定城市的天气信息,例如:北京、上海、广州",
getWeather,
)
if err != nil {
log.Fatalf("创建工具失败:%v", err)
}
agent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Model: baseModel,
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{weatherTool},
},
},
})
if err != nil {
log.Fatalf("创建 Agent 失败:%v", err)
}
runner := adk.NewRunner(ctx, adk.RunnerConfig{Agent: agent})
query := "北京今天天气怎么样?"
fmt.Printf("用户提问:%s\n\n", query)
iter := runner.Query(ctx, query)
fmt.Println("Agent 响应:")
for {
event, ok := iter.Next()
if !ok {
break
}
if event.Err != nil {
fmt.Printf("\n错误:%v\n", event.Err)
continue
}
if event.Output != nil && event.Output.MessageOutput != nil {
msgOutput := event.Output.MessageOutput
msg := msgOutput.Message
// 展示工具调用请求(由模型生成)
if msgOutput.Role == schema.Assistant && len(msg.ToolCalls) > 0 {
fmt.Println("\n📞 [模型请求调用工具]")
for _, tc := range msg.ToolCalls {
fmt.Printf(" 函数: %s\n", tc.Function.Name)
fmt.Printf(" 参数: %s\n", tc.Function.Arguments)
}
continue
}
// 展示工具返回结果
if msgOutput.Role == schema.Tool {
fmt.Printf("\n🔧 [工具返回] 工具: %s\n", msg.ToolName)
fmt.Printf(" 内容: %s\n", msg.Content)
continue
}
if msgOutput.Role == schema.Assistant {
if msgOutput.IsStreaming {
msg, err := msgOutput.GetMessage()
if err == nil {
fmt.Print(msg.Content)
}
} else {
fmt.Print(msgOutput.Message.Content)
}
}
}
}
fmt.Println()
}连续对话
连续对话,要注意携带历史信息。
go
package main
import (
"bufio"
"context"
"fmt"
"log"
"os"
"strings"
"github.com/cloudwego/eino-ext/components/model/ollama"
"github.com/cloudwego/eino/adk"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/components/tool/utils"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/schema"
)
// ---------- 工具定义(保持不变) ----------
type WeatherParams struct {
City string `json:"city" jsonschema:"required" jsonschema_description:"城市名称,例如:北京、上海、广州"`
}
type WeatherResult struct {
City string `json:"city"`
Temperature float64 `json:"temperature"`
Condition string `json:"condition"`
WindSpeed float64 `json:"wind_speed"`
}
func getWeather(ctx context.Context, params WeatherParams) (WeatherResult, error) {
fmt.Printf("🌤️ [工具执行] 正在查询城市:%s\n", params.City)
weatherData := map[string]WeatherResult{
"北京": {City: "北京", Temperature: 25.5, Condition: "晴", WindSpeed: 3.2},
"上海": {City: "上海", Temperature: 28.3, Condition: "多云", WindSpeed: 2.8},
"广州": {City: "广州", Temperature: 32.1, Condition: "雷阵雨", WindSpeed: 4.5},
}
if result, ok := weatherData[params.City]; ok {
return result, nil
}
return WeatherResult{
City: params.City,
Temperature: 20.0,
Condition: "未知城市,默认天气",
WindSpeed: 1.0,
}, nil
}
func main() {
ctx := context.Background()
// ---------- 初始化模型 ----------
baseModel, err := ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
BaseURL: "http://localhost:11434",
Model: "qwen2.5:7b",
Options: &ollama.Options{Temperature: 0.7},
})
if err != nil {
log.Fatalf("初始化模型失败:%v", err)
}
// ---------- 创建工具 ----------
weatherTool, err := utils.InferTool[WeatherParams, WeatherResult](
"get_weather",
"获取指定城市的天气信息,例如:北京、上海、广州",
getWeather,
)
if err != nil {
log.Fatalf("创建工具失败:%v", err)
}
// ---------- 构建 Agent ----------
agent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Model: baseModel,
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{weatherTool},
},
},
})
if err != nil {
log.Fatalf("创建 Agent 失败:%v", err)
}
// ---------- 创建 Runner ----------
runner := adk.NewRunner(ctx, adk.RunnerConfig{Agent: agent})
// ---------- 手动维护对话历史 ----------
var history []*schema.Message
fmt.Println("🤖 连续对话模式启动!输入 'exit' 或 'quit' 退出程序。")
scanner := bufio.NewScanner(os.Stdin)
for {
fmt.Print("\n👤 你:")
if !scanner.Scan() {
break
}
userInput := strings.TrimSpace(scanner.Text())
if userInput == "" {
continue
}
if userInput == "exit" || userInput == "quit" {
fmt.Println("👋 再见!")
break
}
// 1. 添加用户消息到历史
userMsg := schema.UserMessage(userInput)
history = append(history, userMsg)
// 2. 调用 Runner.Run() 传入完整历史
iter := runner.Run(ctx, history)
fmt.Print("🤖 Agent:")
var assistantContent string
var tempMessages []*schema.Message // 用于暂存本次生成的消息
for {
event, ok := iter.Next()
if !ok {
break
}
if event.Err != nil {
fmt.Printf("\n❌ 错误:%v\n", event.Err)
continue
}
if event.Output != nil && event.Output.MessageOutput != nil {
msgOutput := event.Output.MessageOutput
msg := msgOutput.Message
// 暂存所有消息,稍后追加到 history
tempMessages = append(tempMessages, msg)
// 展示工具调用请求(由模型生成)
if msgOutput.Role == schema.Assistant && len(msg.ToolCalls) > 0 {
fmt.Println("\n📞 [模型请求调用工具]")
for _, tc := range msg.ToolCalls {
fmt.Printf(" 函数: %s\n", tc.Function.Name)
fmt.Printf(" 参数: %s\n", tc.Function.Arguments)
}
continue
}
// 展示工具返回结果
if msgOutput.Role == schema.Tool {
fmt.Printf("\n🔧 [工具返回] 工具: %s\n", msg.ToolName)
fmt.Printf(" 内容: %s\n", msg.Content)
continue
}
// 展示最终文本回答
if msgOutput.Role == schema.Assistant {
if msgOutput.IsStreaming {
streamMsg, _ := msgOutput.GetMessage()
fmt.Print(streamMsg.Content)
assistantContent += streamMsg.Content
} else {
fmt.Print(msg.Content)
assistantContent = msg.Content
}
}
}
}
// 3. 将本次生成的所有消息追加到 history(包括 assistant 消息、tool 消息等)
history = append(history, tempMessages...)
fmt.Println() // 换行美观
}
}
