mkdir my-agent && cd my-agent
go mod init my-agent
go get github.com/zzir/agents-go
export OPENAI_API_KEY=sk-...
An agent is a plain struct: instructions, a name, and optional configuration such as tools or a structured output type.
import "github.com/zzir/agents-go/agents"
historyTutor := &agents.Agent{
Name: "History Tutor",
HandoffDescription: "Specialist agent for historical questions",
Instructions: agents.StaticInstructions("You provide assistance with historical queries. Explain important events and context clearly."),
}
HandoffDescription gives the routing agent extra context for deciding where to hand off.
mathTutor := &agents.Agent{
Name: "Math Tutor",
HandoffDescription: "Specialist agent for math questions",
Instructions: agents.StaticInstructions("You help with math problems. Show your reasoning step by step."),
}
Handoffs lists the agents this agent may delegate to. The model sees each as a transfer_to_<name> tool.
triage := &agents.Agent{
Name: "Triage Agent",
Instructions: agents.StaticInstructions("You determine which agent to use based on the user's question."),
Handoffs: []agents.Handoff{agents.HandoffTo(historyTutor), agents.HandoffTo(mathTutor)},
}
import (
"context"
"fmt"
"log"
"github.com/zzir/agents-go/models/openai"
)
func main() {
provider := openai.NewProvider()
res, err := agents.Run(context.Background(), triage, "What is the French Revolution?", agents.RunOptions{
ModelProvider: provider,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(res.FinalOutputString()) // answered by the History Tutor
}
Guardrails run alongside the first model call and can stop a run before it wastes tokens.
triage.InputGuardrails = []agents.InputGuardrail{{
Name: "homework_only",
Run: func(ctx context.Context, rc *agents.RunContext, agent *agents.Agent, input []agents.TResponseInputItem) (agents.GuardrailFunctionOutput, error) {
// Inspect the input (or call a cheap classifier model here).
offTopic := false
return agents.GuardrailFunctionOutput{TripwireTriggered: offTopic}, nil
},
}}
When a tripwire fires, Run returns an *agents.InputGuardrailTripwireError.
NewFunctionTool reflects a typed Go function into a strict JSON-schema tool. Struct tags document the parameters.
type weatherArgs struct {
City string `json:"city" jsonschema:"the city to look up"`
}
weather := agents.NewFunctionTool("get_weather", "Look up the current weather for a city.",
func(ctx context.Context, tc *agents.ToolContext, args weatherArgs) (string, error) {
return "Sunny, 23°C in " + args.City, nil
})
mathTutor.Tools = []agents.Tool{weather}
See examples/handoffs and examples/tools for complete runnable programs, and: