Go-Agent Examples
This directory contains comprehensive examples demonstrating key features of the go-agent framework, focusing on CodeMode and agent-as-UTCP-tool patterns.
Examples Overview
File: cmd/example/codemode/main.go
Demonstrates the core CodeMode pattern where agents can orchestrate UTCP tools through generated Go code.
Key Concepts:
- Agents exposed as UTCP tools using
RegisterAsUTCPProvider()
- Direct UTCP tool calls via
client.CallTool()
- CodeMode-enabled agents that can generate and execute tool-calling code
- The flow: User Input (Natural Language) → LLM generates
codemode.CallTool() → UTCP executes tool
Run:
go run cmd/example/codemode/main.go
What it shows:
- Creating and registering an agent as a UTCP tool ("local.analyst")
- Calling the agent tool directly via the UTCP client
- Building an orchestrator agent with CodeMode enabled
- How CodeMode enables natural language → tool orchestration
2. Multi-Agent Workflow Orchestration
File: cmd/example/codemode_utcp_workflow/main.go
Shows how to orchestrate complex multi-step workflows involving multiple specialist agents.
Key Concepts:
- Multiple agents working together (Analyst, Writer, Reviewer)
- Each agent exposed as a UTCP tool
- CodeMode orchestrating multi-step workflows
- Chaining agent outputs through workflow steps
Run:
go run cmd/example/codemode_utcp_workflow/main.go
What it shows:
- Creating multiple specialist agents (analyst, writer, reviewer)
- Registering each as a UTCP tool
- Building an orchestrator that coordinates their work
- Natural language workflow description → coordinated agent execution
Example Workflow:
Step 1: Use analyst tool to analyze Q4 sales data
Step 2: Use writer tool to create a report based on the analysis
Step 3: Use reviewer tool to review the report
Step 4: Use writer tool again to finalize based on feedback
3. Agent-to-Agent Communication
File: cmd/example/agent_as_tool/main.go
Demonstrates hierarchical agent architectures where agents call other agents as tools.
Key Concepts:
- Exposing agents as UTCP tools for inter-agent communication
- Manager-specialist agent patterns
- Agent encapsulation and modularity
- Tool naming via "provider.toolname" format
Run:
go run cmd/example/agent_as_tool/main.go
What it shows:
- Creating a Researcher agent
- Exposing it as "agent.researcher" UTCP tool
- Creating a Manager agent that can call the Researcher
- Direct verification of tool calls
Architecture:
User Input → Manager Agent → agent.researcher (Researcher Agent) → Result
4. Agent State Persistence (Checkpoint/Restore)
File: cmd/example/checkpoint/main.go
Demonstrates how to save an agent's state to disk and restore it later, preserving conversation history and shared space memberships.
Key Concepts:
agent.Checkpoint(): Serializes state to []byte
agent.Restore(): Rehydrates state from []byte
- Persisting short-term memory and shared space context
- Resuming conversations across process restarts
Run:
go run cmd/example/checkpoint/main.go
What it shows:
- Creating an agent and having a conversation
- Checkpointing the agent to a JSON file
- Creating a fresh agent instance
- Restoring the state from the file
- Verifying the agent remembers the previous conversation
CodeMode Pattern Explained
CodeMode is a powerful feature that allows agents to orchestrate tools through generated Go code.
The Flow:
-
User provides natural language input
"Analyze Q4 sales and create a report"
-
LLM with CodeMode generates Go code
// Generated by the LLM
analysis, _ := codemode.CallTool("local.analyst", map[string]any{
"instruction": "Analyze Q4 sales data",
})
report, _ := codemode.CallTool("local.writer", map[string]any{
"instruction": fmt.Sprintf("Create report based on: %v", analysis),
})
-
CodeMode executes the generated code
- Calls are routed through the UTCP client
- Each tool (including agents) is invoked
- Results are returned and can be chained
-
Result delivered to user
Key Functions
RegisterAsUTCPProvider
Exposes an agent as a UTCP tool:
err := agent.RegisterAsUTCPProvider(ctx, client, "local.analyst", "Analyzes data")
- Name format:
"provider.toolname" (e.g., "local.analyst", "agent.researcher")
- Arguments: Always includes
instruction (user's request), optionally session_id
- Returns:
map[string]any with response and session_id fields
Directly call any registered UTCP tool:
result, err := client.CallTool(ctx, "local.analyst", map[string]any{
"instruction": "Analyze this data",
"session_id": "optional-session-id",
})
WithCodeModeUtcp
Enables CodeMode in an ADK agent:
kit, err := adk.New(ctx,
adk.WithDefaultSystemPrompt("You orchestrate workflows..."),
adk.WithModules(...),
adk.WithCodeModeUtcp(client, model), // Enable CodeMode
)
Common Patterns
// Create specialist agent
specialist, _ := agent.New(agent.Options{
Model: model,
Memory: memory,
SystemPrompt: "You are a specialist.",
})
// Expose as UTCP tool
specialist.RegisterAsUTCPProvider(ctx, client, "local.specialist", "Description")
// Call it
result, _ := client.CallTool(ctx, "local.specialist", map[string]any{
"instruction": "Do something",
})
Pattern 2: Multi-Step Workflow
// With a real LLM and CodeMode enabled:
userPrompt := `
Step 1: Analyze data using analyst
Step 2: Create report using writer
Step 3: Review using reviewer
`
// CodeMode orchestrator generates and executes:
// step1, _ := codemode.CallTool("local.analyst", ...)
// step2, _ := codemode.CallTool("local.writer", ...)
// step3, _ := codemode.CallTool("local.reviewer", ...)
Pattern 3: Hierarchical Agents
// Manager agent with sub-agents as tools
manager, _ := agent.New(agent.Options{
Model: managerModel,
Memory: managerMemory,
Tools: []agent.Tool{
researcher.AsTool("researcher", "Research specialist"),
coder.AsTool("coder", "Coding specialist"),
},
})
When registering agents as UTCP tools, follow the "provider.toolname" format:
- ✅
"local.analyst" - Good
- ✅
"agent.researcher" - Good
- ✅
"team.writer" - Good
- ❌
"analyst" - May cause issues without provider prefix
- ❌
"my-agent-123" - Avoid hyphens, use underscores or dots