Building an AI Agent in Go with Inferable
In this tutorial, we'll build a simple AI agent that manages inventory operations using Go and Inferable. Our agent will be able to check stock levels, process orders, and restock items - all through natural language commands.
Prerequisites
Before we begin, make sure you have:
- Go 1.20 or later installed
- Basic familiarity with Go
- Inferable CLI installed (
npm install -g @inferablehq/inferable
)
Authenticate with Inferable
inf auth login
Setting Up the Project
First, let's create a new Go project and install the Inferable SDK:
inf bootstrap go
This will run you through the steps of creating a new Go project and installing the Inferable SDK.
The project will contain some boilerplate code to get you started. Let's remove that because we'll be starting from scratch.
rm -rf main.go
Creating Our Inventory System
Let's start by defining our basic inventory types and a simple in-memory store:
package main
import (
"fmt"
"sync"
"github.com/inferablehq/inferable-go"
)
// Item represents a product in our inventory
type Item struct {
ID string `json:"id"`
Name string `json:"name"`
Price float64 `json:"price"`
Quantity int `json:"quantity"`
}
// Store is our simple in-memory inventory
type Store struct {
items map[string]Item
mu sync.RWMutex
}
// NewStore creates a new inventory store
func NewStore() *Store {
return &Store{
items: make(map[string]Item),
}
}
// Initialize with some sample data
func (s *Store) Initialize() {
s.items = map[string]Item{
"LIGHT-1": {ID: "LIGHT-1", Name: "Lightsaber", Price: 199.99, Quantity: 5},
"DROID-1": {ID: "DROID-1", Name: "Astromech Droid", Price: 2499.99, Quantity: 2},
"FORCE-1": {ID: "FORCE-1", Name: "Force Crystal", Price: 99.99, Quantity: 10},
}
}
Implementing Inventory Functions
Now, let's create the functions that our AI agent will use:
// CheckStockInput represents the input for checking stock
type CheckStockInput struct {
ItemID string `json:"itemId" jsonschema:"required"`
}
// OrderInput represents the input for placing an order
type OrderInput struct {
ItemID string `json:"itemId" jsonschema:"required"`
Quantity int `json:"quantity" jsonschema:"minimum=1"`
}
// CheckStock returns the current stock level of an item
func (s *Store) CheckStock(input CheckStockInput) (*Item, error) {
s.mu.RLock()
defer s.mu.RUnlock()
item, exists := s.items[input.ItemID]
if !exists {
return nil, fmt.Errorf("item not found: %s", input.ItemID)
}
return &item, nil
}
// ProcessOrder handles a new order
func (s *Store) ProcessOrder(input OrderInput) (*Item, error) {
s.mu.Lock()
defer s.mu.Unlock()
item, exists := s.items[input.ItemID]
if !exists {
return nil, fmt.Errorf("item not found: %s", input.ItemID)
}
if item.Quantity < input.Quantity {
return nil, fmt.Errorf("insufficient stock: requested %d, available %d",
input.Quantity, item.Quantity)
}
item.Quantity -= input.Quantity
s.items[input.ItemID] = item
return &item, nil
}
Creating the Inferable Agent
Now comes the exciting part - connecting our inventory system to Inferable:
func main() {
// Initialize our store
store := NewStore()
store.Initialize()
// Create Inferable client
client, err := inferable.New(inferable.InferableOptions{
APISecret: os.Getenv("INFERABLE_API_SECRET"),
})
if err != nil {
log.Fatal(err)
}
// Register our inventory service
service := client.Default
// Register the CheckStock function
err = service.RegisterFunc(inferable.Function{
Name: "checkStock",
Description: "Check the current stock level of an item",
Func: func(input CheckStockInput) (*Item, error) {
return store.CheckStock(input)
},
})
if err != nil {
log.Fatal(err)
}
// Register the ProcessOrder function
err = service.RegisterFunc(inferable.Function{
Name: "processOrder",
Description: "Process an order for an item",
Func: func(input OrderInput) (*Item, error) {
return store.ProcessOrder(input)
},
})
if err != nil {
log.Fatal(err)
}
// Start the service
err = service.Start()
if err != nil {
log.Fatal(err)
}
// Keep the application running
select {}
}
Using our multi-agent system
To run the agent, use the inf app
command from within the project directory.
inf app
With our agent running, we can now interact with it through natural language using the Inferable platform. Here are some example interactions:
-
Checking stock:
"What's the current stock level of lightsabers?"
-
Processing an order:
"I'd like to order 2 lightsabers please"
The agent will understand these natural language requests and automatically:
- Parse the intent
- Map to the appropriate function
- Extract the required parameters
- Execute the function
- Return the results in a user-friendly format
How It Works
Behind the scenes, Inferable:
- Uses LLMs to understand the natural language input
- Maps the intent to our registered functions
- Validates the input against our JSON schemas
- Executes the functions in our Go service
- Formats the response for the user
The agent can handle complex queries and even multi-step operations. For example, it can check stock before processing an order, all from a single natural language request.
Security and Control
One of the best parts about this implementation is that all the actual inventory operations run in your own machine. Inferable never has direct access to your data - it only orchestrates the function calls based on the natural language input.
Next Steps
You can extend this basic agent in several ways:
- Add more complex inventory operations
- Implement persistent storage
- Add approval workflows for large orders
- Integrate with real inventory systems
- Add data masking for sensitive information
Conclusion
We've built a simple but powerful AI agent that can manage inventory operations through natural language. The Inferable Go SDK made it easy to connect our existing Go code to an AI interface, while maintaining full control over our business logic and data.