input := &adk.AgentInput{ Messages: []adk.Message{ schema.UserMessage("What's the capital of France?"), schema.AssistantMessage("The capital of France is Paris.", nil), schema.UserMessage("How far is it from London? "), }, }
funcnewChatModel() model.ToolCallingChatModel { cm, err := openai.NewChatModel(context.Background(), &openai.ChatModelConfig{ APIKey: os.Getenv("OPENAI_API_KEY"), Model: os.Getenv("OPENAI_MODEL"), }) if err != nil { log.Fatal(err) } return cm }
type GetWeatherInput struct { City string`json:"city"` }
funcNewWeatherAgent() adk.Agent { weatherTool, err := utils.InferTool( "get_weather", "Gets the current weather for a specific city.", // English description func(ctx context.Context, input *GetWeatherInput) (string, error) { return fmt.Sprintf(`the temperature in %s is 25°C`, input.City), nil }, ) if err != nil { log.Fatal(err) }
a, err := adk.NewChatModelAgent(context.Background(), &adk.ChatModelAgentConfig{ Name: "WeatherAgent", Description: "This agent can get the current weather for a given city.", Instruction: "Your sole purpose is to get the current weather for a given city by using the 'get_weather' tool. After calling the tool, report the result directly to the user.", Model: newChatModel(), ToolsConfig: adk.ToolsConfig{ ToolsNodeConfig: compose.ToolsNodeConfig{ Tools: []tool.BaseTool{weatherTool}, }, }, }) if err != nil { log.Fatal(err) } return a }
funcNewChatAgent() adk.Agent { a, err := adk.NewChatModelAgent(context.Background(), &adk.ChatModelAgentConfig{ Name: "ChatAgent", Description: "A general-purpose agent for handling conversational chat.", // English description Instruction: "You are a friendly conversational assistant. Your role is to handle general chit-chat and answer questions that are not related to any specific tool-based tasks.", Model: newChatModel(), }) if err != nil { log.Fatal(err) } return a }
funcNewRouterAgent() adk.Agent { a, err := adk.NewChatModelAgent(context.Background(), &adk.ChatModelAgentConfig{ Name: "RouterAgent", Description: "A manual router that transfers tasks to other expert agents.", Instruction: `You are an intelligent task router. Your responsibility is to analyze the user's request and delegate it to the most appropriate expert agent.If no Agent can handle the task, simply inform the user it cannot be processed.`, Model: newChatModel(), }) if err != nil { log.Fatal(err) } return a }
之后使用 Eino ADK 的 Transfer 能力搭建 Multi-Agent 并运行,ChatModelAgent 实现了 OnSubAgent 接口,在 adk.SetSubAgents 方法中会使用此接口向 ChatModelAgent 注册父/子 Agent,不需要用户处理 TransferAction 生成问题:
ctx := context.Background() a, err := adk.SetSubAgents(ctx, routerAgent, []adk.Agent{chatAgent, weatherAgent}) if err != nil { log.Fatal(err) }
runner := adk.NewRunner(ctx, adk.RunnerConfig{ Agent: a, })
// query weather println("\n\n>>>>>>>>>query weather<<<<<<<<<") iter := runner.Query(ctx, "What's the weather in Beijing?") for { event, ok := iter.Next() if !ok { break } if event.Err != nil { log.Fatal(event.Err) } if event.Action != nil { fmt.Printf("\nAgent[%s]: transfer to %+v\n\n======\n", event.AgentName, event.Action.TransferToAgent.DestAgentName) } else { fmt.Printf("\nAgent[%s]:\n%+v\n\n======\n", event.AgentName, event.Output.MessageOutput.Message) } }
// failed to route println("\n\n>>>>>>>>>failed to route<<<<<<<<<") iter = runner.Query(ctx, "Book me a flight from New York to London tomorrow.") for { event, ok := iter.Next() if !ok { break } if event.Err != nil { log.Fatal(event.Err) } if event.Action != nil { fmt.Printf("\nAgent[%s]: transfer to %+v\n\n======\n", event.AgentName, event.Action.TransferToAgent.DestAgentName) } else { fmt.Printf("\nAgent[%s]:\n%+v\n\n======\n", event.AgentName, event.Output.MessageOutput.Message) } } }