main.go

Overview

This file demonstrates a practical approach to creating a composite AI agent system capable of handling multiple tool types within a single agent context. Due to limitations in the underlying genai API, which restricts the use of diverse tool types (e.g., Google Search and custom functions) directly in one agent, this file implements a workaround by wrapping agents specialized for different toolsets into sub-agents. These sub-agents are then managed collectively by a root agent, allowing diversified capabilities such as web search and poem generation to coexist seamlessly.

The main functionality includes:

This approach supports modular AI agent design, enabling flexible multi-tool integration despite API constraints.

Detailed Explanation

Package Import and Setup

The file imports essential packages for context management, logging, and environment variable access, alongside multiple specialized packages from Google's AI Development Kit (adk), including:

Main Function

func main()

Step 1: Model Initialization

model, err := gemini.NewModel(ctx, "gemini-2.5-flash", &genai.ClientConfig{
    APIKey: os.Getenv("GOOGLE_API_KEY"),
})

Step 2: Search Agent Creation

searchAgent, err := llmagent.New(llmagent.Config{
    Name:        "search_agent",
    Model:       model,
    Description: "Does google search.",
    Instruction: "You're a specialist in Google Search.",
    Tools: []tool.Tool{
        geminitool.GoogleSearch{},
    },
})

Step 3: Poem Generator Tool and Agent

type Input struct {
    LineCount int `json:"lineCount"`
}
type Output struct {
    Poem string `json:"poem"`
}
handler := func(ctx tool.Context, input Input) (Output, error) {
    return Output{
        Poem: strings.Repeat("A line of a poem,", input.LineCount) + "\n",
    }, nil
}
poemTool, err := functiontool.New(functiontool.Config{
    Name:        "poem",
    Description: "Returns poem",
}, handler)
poemAgent, err := llmagent.New(llmagent.Config{
    Name:        "poem_agent",
    Model:       model,
    Description: "returns poem",
    Instruction: "You return poems.",
    Tools: []tool.Tool{
        poemTool,
    },
})

Step 4: Root Agent Composition

a, err := llmagent.New(llmagent.Config{
    Name:        "root_agent",
    Model:       model,
    Description: "You can do a google search and generate poems.",
    Instruction: "Answer questions about weather based on google search unless asked for a poem," +
        " for a poem generate it with a tool.",
    Tools: []tool.Tool{
        agenttool.New(searchAgent, nil), agenttool.New(poemAgent, nil),
    },
})

Step 5: Agent Launcher Setup and Execution

config := &launcher.Config{
    AgentLoader: agent.NewSingleLoader(a),
}

l := full.NewLauncher()
if err = l.Execute(ctx, config, os.Args[1:]); err != nil {
    log.Fatalf("Run failed: %v\n\n%s", err, l.CommandLineSyntax())
}

Classes, Functions, and Methods

llmagent.New(config llmagent.Config) (*llmagent.Agent, error)

gemini.NewModel(ctx context.Context, modelName string, config *genai.ClientConfig) (*gemini.Model, error)

functiontool.New(config functiontool.Config, handler interface{}) (tool.Tool, error)

agenttool.New(agent agent.Agent, options interface{}) tool.Tool

launcher.Config

full.NewLauncher()

Implementation Details and Algorithms

Interaction with Other System Components

Usage Example

To run the root agent, execute the compiled binary with optional CLI arguments. The agent will:

Visual Diagram

flowchart TD
Main -->|Creates| GeminiModel[Gemini Model]
GeminiModel -->|Used by| SearchAgent[Search Agent]
GeminiModel -->|Used by| PoemAgent[Poem Agent]
SearchAgent -->|Uses| GoogleSearchTool[Google Search Tool]
PoemAgent -->|Uses| PoemTool[Poem Function Tool]
RootAgent[Root Agent]
SearchAgent -->|Wrapped as Tool| RootAgent
PoemAgent -->|Wrapped as Tool| RootAgent
Main -->|Creates| RootAgent
RootAgent -->|Managed by| Launcher[Launcher]
Launcher -->|Executes| RootAgent

This flowchart represents the primary structure and relationships:


This documentation references concepts from LLM Integration and Agents, Function Tools, and Agent Tools related to agent construction, tool wrapping, and multi-agent composition. It also leverages the launcher framework detailed in REST API and Web Launchers for runtime execution.