Community Project: This is an unofficial community-maintained Go SDK for building AI agents with OpenAI's API. Inspired by the official Python and JavaScript SDKs, but not affiliated with or endorsed by OpenAI.
A production-ready, type-safe Go framework for building intelligent multi-agent workflows with comprehensive security guardrails, persistent sessions, and enterprise-grade observability.
- PII Detection & Protection: Automatically detect and mask sensitive data (SSNs, credit cards, emails, phone numbers)
- 9+ Built-in Guardrails: Rate limiting, profanity filtering, prompt injection detection, URL validation, secret scanning
- Content Moderation: OpenAI Moderation API integration with 13 safety categories
- Tool Approvals: Human-in-the-loop safety for dangerous operations
- Zero Dependencies: Core SDK has no external dependencies (beyond OpenAI Go SDK)
- Type Safety: Full compile-time type checking with Go generics
- Session Management: Persistent conversations with multiple backends (memory, file, SQLite, PostgreSQL, Redis)
- Observability: OpenTelemetry tracing for monitoring agent behavior
- Error Handling: Comprehensive error types with retry strategies
- Idiomatic Go: Clean, maintainable code following Go best practices
- Rich Examples: 25+ working examples covering all features
- Comprehensive Docs: Full documentation site with guides and API reference
- Multi-Agent Workflows: Seamless agent handoffs and composition
- Streaming Support: Real-time token-by-token and event-based streaming
go get github.com/MitulShah1/openai-agents-go@latestRequirements: Go 1.24 or higher
package main
import (
"context"
"fmt"
"log"
"os"
agents "github.com/MitulShah1/openai-agents-go"
"github.com/openai/openai-go"
"github.com/openai/openai-go/option"
)
func main() {
// Initialize OpenAI client
client := openai.NewClient(option.WithAPIKey(os.Getenv("OPENAI_API_KEY")))
runner := agents.NewRunner(&client)
// Create an agent
agent := agents.NewAgent("Assistant")
agent.Instructions = "You are a helpful assistant"
// Run the agent
messages := []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Write a haiku about Go programming"),
}
result, err := runner.Run(context.Background(), agent, messages, nil, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.FinalOutput)
}The SDK provides comprehensive security and safety guardrails to protect your applications from malicious inputs, data leaks, and policy violations.
Automatically detect and mask 10+ types of sensitive data:
package main
import (
"github.com/MitulShah1/openai-agents-go/guardrail/security"
)
func main() {
// Create PII guardrail
piiGuardrail := security.NewPII(
security.WithTripwire(true), // Block instead of mask
security.WithDetectors( // Customize detectors
security.PIITypeSSN,
security.PIITypeCreditCard,
security.PIITypeEmail,
security.PIITypePhone,
),
)
// Run agent with PII protection
result, err := runner.Run(
ctx,
agent,
messages,
nil,
agents.WithGuardrails([]agents.Guardrail{piiGuardrail}),
)
}Supported PII Types:
- Social Security Numbers (SSN)
- Credit Card Numbers
- Email Addresses
- Phone Numbers
- IP Addresses
- API Keys & Secrets
- Dates of Birth
- Passport Numbers
- Driver's License Numbers
- Medical Record Numbers
Block harmful content using OpenAI's Moderation API:
import "github.com/MitulShah1/openai-agents-go/guardrail/moderation"
moderationGuardrail := moderation.NewModeration(
client,
moderation.WithThresholds(0.7), // Custom threshold
)Detects 13 Categories:
- Hate speech
- Harassment
- Self-harm
- Sexual content
- Violence
- And more...
Protect against abuse and control costs:
import "github.com/MitulShah1/openai-agents-go/guardrail/ratelimit"
rateLimiter := ratelimit.NewRateLimiter(
100, // 100 requests
time.Minute, // per minute
ratelimit.WithBurst(10), // Allow bursts
)import (
"github.com/MitulShah1/openai-agents-go/guardrail/content"
"github.com/MitulShah1/openai-agents-go/guardrail/security"
)
// Block profanity
profanityFilter := content.NewProfanityFilter()
// Detect prompt injection attacks
injectionDetector := security.NewPromptInjection()
// Validate URLs
urlFilter := security.NewURLFilter(
security.WithAllowedDomains([]string{"example.com"}),
)
// Custom regex validation
customFilter := content.NewRegexFilter(
`\b[A-Z]{3}\d{3}\b`, // Match pattern
true, // Block on match
)Chain multiple guardrails with sequential or parallel execution:
import "github.com/MitulShah1/openai-agents-go/guardrail"
// Sequential: Stop at first violation
sequential := guardrail.NewSequence(
piiGuardrail,
moderationGuardrail,
profanityFilter,
)
// Parallel: Check all simultaneously
parallel := guardrail.NewParallel(
rateLimiter,
urlFilter,
injectionDetector,
)
// Combine
combined := guardrail.NewSequence(parallel, sequential)โ Full Guardrails Documentation
Maintain conversation context across multiple interactions with flexible storage backends.
import "github.com/MitulShah1/openai-agents-go/session"
sess := session.NewMemorySession()
result, _ := runner.Run(
ctx,
agent,
messages,
nil,
agents.WithSession(sess, "user-123"),
)sess := session.NewFileSession("./sessions")// SQLite (built-in)
sess, _ := session.NewSQLiteSession("./sessions.db")
// PostgreSQL (requires build tag: -tags postgres)
sess, _ := session.NewPostgresSession(
"postgres://user:pass@localhost/db",
)
// Redis (requires build tag: -tags redis)
sess, _ := session.NewRedisSession("localhost:6379", 0)- Message History: Automatic conversation tracking
- Context Variables: Pass state between agent runs
- Encryption: Secure sensitive data at rest
- Compaction: Automatic history pruning
- Cloud Backend: OpenAI Conversations API integration
โ Full Sessions Documentation
Agents can call Go functions as tools to perform actions, fetch data, or interact with external systems.
import "github.com/MitulShah1/openai-agents-go/tools"
weatherTool := tools.New(
"get_weather",
"Get current weather for a city",
map[string]any{
"type": "object",
"properties": map[string]any{
"city": map[string]any{
"type": "string",
"description": "City name",
},
},
"required": []string{"city"},
},
func(args map[string]any, ctx tools.ContextVariables) (any, error) {
city := args["city"].(string)
// Call weather API
return fmt.Sprintf("Weather in %s: Sunny, 72ยฐF", city), nil
},
)
agent.Tools = []tools.Tool{weatherTool}Require approval before executing dangerous operations:
deleteFileTool := tools.New(
"delete_file",
"Delete a file from the system",
schema,
deleteFileFunc,
)
// Static approval requirement
deleteFileTool.NeedsApproval = true
// Or dynamic approval logic
deleteFileTool.ApprovalFunc = func(args map[string]any) (bool, error) {
filename := args["filename"].(string)
return strings.HasPrefix(filename, "/tmp/"), nil // Only approve /tmp files
}
// Handle approvals inline
result, err := runner.Run(
ctx,
agent,
messages,
nil,
agents.WithApprovalHandler(func(req tools.ApprovalRequest) (bool, error) {
fmt.Printf("Approve %s with args %v? (y/n): ", req.Name, req.Args)
var response string
fmt.Scanln(&response)
return response == "y", nil
}),
)
// Or pause/resume workflow
if errors.As(err, &agents.ToolApprovalRequiredError{}) {
approvalErr := err.(agents.ToolApprovalRequiredError)
// Review requests
for i, req := range approvalErr.Requests {
approved := getUserApproval(req)
approvalErr.Requests[i].Approved = approved
}
// Resume execution
result, err = runner.Resume(ctx, approvalErr.State, approvalErr.Requests)
}Return images, files, and rich content:
func generateChart(args map[string]any, ctx tools.ContextVariables) (any, error) {
// Generate chart image
imageData := createChartImage(args)
return tools.MultimodalResponse{
Text: "Here's your chart:",
Images: []tools.ImageContent{
{Data: imageData, MimeType: "image/png"},
},
}, nil
}Execute multiple tools concurrently for better performance:
config := &agents.RunConfig{
MaxToolConcurrency: 5, // Run up to 5 tools in parallel
}Create specialized agents and orchestrate handoffs for complex workflows.
import "github.com/MitulShah1/openai-agents-go/handoff"
// Specialized agents
weatherAgent := agents.NewAgent("Weather Specialist")
weatherAgent.Instructions = "You are an expert at weather information"
weatherAgent.Tools = []tools.Tool{weatherTool}
newsAgent := agents.NewAgent("News Specialist")
newsAgent.Instructions = "You provide the latest news"
newsAgent.Tools = []tools.Tool{newsTool}
// Main coordinator agent
mainAgent := agents.NewAgent("Main Assistant")
mainAgent.Instructions = `You coordinate with specialists.
Transfer weather questions to the weather specialist.
Transfer news questions to the news specialist.`
mainAgent.Tools = []tools.Tool{
handoff.New(weatherAgent).ToTool(),
handoff.New(newsAgent).ToTool(),
}
// Handoffs happen automatically during execution
result, _ := runner.Run(ctx, mainAgent, messages, nil, nil)- Input Filtering: Control what data passes to target agent
- History Nesting: Isolate or merge conversation context
- Dynamic Enablement: Conditional handoff availability
- Bidirectional Transfers: Agents can hand back control
โ Full Handoffs Documentation
Get schema-validated JSON responses for reliable parsing and type safety.
import "github.com/MitulShah1/openai-agents-go/jsonschema"
// Define schema
schema := jsonschema.Object().
WithProperty("answer", jsonschema.Integer()).
WithProperty("reasoning", jsonschema.String()).
WithRequired("answer", "reasoning")
// Create agent with structured output
agent := agents.NewAgent("Math Tutor")
agent.ResponseFormat = jsonschema.JSONSchema("math_response", schema)
messages := []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("What is 15 + 27?"),
}
result, _ := runner.Run(ctx, agent, messages, nil, nil)
// Parse response
type MathResponse struct {
Answer int `json:"answer"`
Reasoning string `json:"reasoning"`
}
var response MathResponse
json.Unmarshal([]byte(result.FinalOutput), &response)// Nested objects
personSchema := jsonschema.Object().
WithProperty("name", jsonschema.String()).
WithProperty("age", jsonschema.Integer()).
WithProperty("address", jsonschema.Object().
WithProperty("street", jsonschema.String()).
WithProperty("city", jsonschema.String()).
WithRequired("street", "city"),
).
WithRequired("name", "age")
// Arrays
listSchema := jsonschema.Object().
WithProperty("items", jsonschema.Array(jsonschema.String())).
WithRequired("items")
// Enums
statusSchema := jsonschema.String().
WithEnum([]string{"pending", "approved", "rejected"})โ Full Structured Outputs Documentation
Stream responses token-by-token or event-by-event for real-time applications.
stream := runner.Stream(ctx, agent, messages, nil, nil)
for event := range stream.Events() {
switch e := event.(type) {
case *stream.TextDeltaEvent:
fmt.Print(e.Delta)
case *stream.TextDoneEvent:
fmt.Println("\nComplete:", e.Text)
case *stream.FinalEvent:
fmt.Println("Final output:", e.Result.FinalOutput)
}
}streamResult := runner.StreamWithResult(ctx, agent, messages, nil, nil)
// Process events
for event := range streamResult.StreamEvents() {
switch e := event.(type) {
case *stream.AgentMessageEvent:
fmt.Println("Agent:", e.Message)
case *stream.ToolCallEvent:
fmt.Println("Calling tool:", e.Name)
case *stream.ToolResultEvent:
fmt.Println("Tool result:", e.Result)
case *stream.ApprovalRequiredEvent:
fmt.Println("Approval needed:", e.Requests)
}
}
// Get final result
result := streamResult.Result()โ Full Streaming Documentation
Monitor agent behavior with OpenTelemetry integration.
import (
"github.com/MitulShah1/openai-agents-go/tracing"
"go.opentelemetry.io/otel"
)
// Enable tracing
tracer := otel.Tracer("my-app")
runner := agents.NewRunner(&client)
// Run with tracing context
ctx := tracing.StartAgentSpan(ctx, tracer, "main-agent")
defer tracing.EndSpan(ctx)
result, _ := runner.Run(ctx, agent, messages, nil, nil)Traced Operations:
- Agent runs (start, end, turns)
- Tool calls (arguments, results, duration)
- Session operations (load, save)
- Guardrail checks (input, output, violations)
โ Full Tracing Documentation
The repository includes 25+ comprehensive examples covering all features:
- 01_basic - Hello world agent
- 02_tools - Tool integration
- 03_handoffs - Agent handoffs
- 05_lifecycle_hooks - Execution hooks
- 06_config_usage - Run configuration
- 09_guardrails_demo - Comprehensive guardrails
- 14_guardrail_composition - Chaining guardrails
- 23_tool_approvals - Human-in-the-loop approvals
- 10_sessions_demo - Session management
- 15_session_backends - Database backends
- 12_conversations_session - Cloud sessions
- 07_structured_output - Structured JSON
- 19_streaming_basic - Streaming responses
- 22_parallel_tools - Parallel execution
- 16_tracing - OpenTelemetry tracing
- 24_prompts_demo - Prompts API
- 25_multi_provider - Multiple LLM providers
- 17_production_chatbot - Complete chatbot
- 18_type_safe_tools - Type-safe tools
Run any example:
export OPENAI_API_KEY="your-key-here"
cd examples/09_guardrails_demo
go run main.go- ๐ Documentation Site - Complete guides
- ๐ Quickstart Guide
- ๐ Examples Directory
- ๐ค Agents
- ๐ง Tools
- ๐ค Handoffs
- ๐ Structured Outputs
- ๐ก๏ธ Guardrails
- ๐พ Sessions
- ๐ก Streaming
- ๐ Tracing
- ๐ฏ Models & Providers
- ๐ Prompts API
- ๐ Running Agents
- ๐ API Documentation - GoDoc
- ๐ CHANGELOG - Release history
| Feature | Python SDK | JavaScript SDK | Go SDK (This) |
|---|---|---|---|
| Agents | โ | โ | โ |
| Tools | โ | โ | โ |
| Handoffs | โ | โ | โ |
| Structured Outputs | โ | โ | โ |
| Streaming | โ | โ | โ |
| Guardrails | โ | โ | โ 9+ types |
| PII Detection | โ | โ | โ 10+ detectors |
| Tracing | โ | โ | โ OpenTelemetry |
| Tool Approvals | โ | โ | โ |
| Prompts API | โ | โ | โ |
| Model Abstraction | โ | โ | โ |
| MCP Support | โ | โ | โ |
| Computer Use | โ | โ | โ |
| Voice Agents | โ | โ | ๐ฎ Planned |
| Type Safety | โ Compile-time | ||
| Zero Dependencies | โ | โ | โ Core only |
| Performance | ~ | ~ | โ Native Go |
- Go 1.24+
- golangci-lint
- goimports
# Run all tests
go test -v ./...
# With coverage
go test -v -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
# Run linter
golangci-lint run ./...
# Or use Makefile
make check
make test
make lint# Install MkDocs
pip install mkdocs-material
# Serve locally
mkdocs serve
# Build site
mkdocs buildContributions are welcome! This is a community project.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Ensure all tests pass (
make check) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please ensure:
- All tests pass
- Code is formatted (
gofmt,goimports) - Documentation is updated
- Examples demonstrate new features
This project is inspired by:
Built with:
MIT License - see LICENSE file for details.
- ๐ Report Issues
- ๐ฌ Discussions
- โญ Star the repo if you find it useful!
- ๐ Full Documentation
Made with โค๏ธ by the Go community
Documentation โข Examples โข API Reference โข GitHub
