Agents
Controllers for AI interactions. Like Rails controllers, agents have actions, callbacks, views, and concerns—but they generate AI responses instead of rendering HTML.
Quick Example
class SupportAgent < ApplicationAgent
before_generation :load_user_context
def help
prompt message: "User needs help: #{params[:message]}"
end
private
def load_user_context
@user = User.find(params[:user_id]) if params[:user_id]
end
endUsage:
SupportAgent.with(user_id: 1, message: "Need help").help.generate_nowHow It Works
The request-response cycle mirrors Rails controllers:
- Action called -
Agent.with(params).action - Callbacks run -
before_generation,before_prompt - Context built -
prompt()orembed()configures messages - View rendered - ERB template (if exists) renders content
- Provider executes - AI service generates response
- Result returned - Response object with message and metadata
Building Agents
Basic Structure
Inherit from ActiveAgent::Base (or ApplicationAgent) and define actions:
class TranslationAgent < ApplicationAgent
generate_with :openai, model: "gpt-4o"
def translate
prompt message: "Translate '#{params[:text]}' to #{params[:target_lang]}"
end
endActions are public instance methods that call prompt() or embed().
Invocation
Call agents using with() to pass parameters:
# With parameters
generation = TranslationAgent.with(
text: "Hello world",
target_lang: "es"
).translate
# Execute synchronously
response = generation.generate_now
# response.message.content # => "Hola mundo"For prototyping, use direct methods:
response = ApplicationAgent.prompt(message: "Hello").generate_nowSee Generation for complete documentation on execution patterns and response objects.
Actions Interface
Agents define actions using prompt() or embed() to configure generation context:
class MyAgent < ApplicationAgent
def my_action
# Simple message
prompt "User message: #{params[:message]}"
end
def embed_text
# Simple input
embed "Text to embed: #{params[:input]}"
end
endSee Actions for complete documentation on messages, tools, structured output, and embeddings.
Advanced Features
Using Concerns
Extend agents with concerns to share functionality across multiple agents:
# app/agents/concerns/research_tools.rb
module ResearchTools
extend ActiveSupport::Concern
def search_papers
prompt message: "Search: #{params[:query]}"
end
def analyze_data
prompt message: "Analyze: #{params[:data]}"
end
end
# app/agents/research_agent.rb
class ResearchAgent < ApplicationAgent
include ResearchTools # Adds search_papers and analyze_data actions
generate_with :openai, model: "gpt-4o"
endConcerns let you:
- Share tool actions across multiple agents
- Organize complex agents into logical modules
- Reuse common patterns (authentication, logging, data access)
- Test functionality independently
Callbacks
Hook into the generation lifecycle:
class MyAgent < ApplicationAgent
before_generation :load_context
after_generation :log_response
def chat
prompt message: params[:message]
end
private
def load_context
@user = User.find(params[:user_id]) if params[:user_id]
end
def log_response
Rails.logger.info "Generated response"
end
endSee Callbacks for complete documentation.
Streaming
Stream responses in real-time:
class StreamingAgent < ApplicationAgent
on_stream :broadcast_chunk
def chat
prompt message: params[:message], stream: true
end
private
def broadcast_chunk(chunk)
# In real app: ActionCable.server.broadcast("chat", content: chunk.delta)
end
endSee Streaming for complete documentation.
Learn More
Core Features:
- Generation - Execution patterns and response objects
- Instructions - System prompts that guide behavior
- Callbacks - Lifecycle hooks and event handling
- Streaming - Real-time response updates
- Error Handling - Retries and graceful degradation
Related Topics:
- Tools - Use agent actions as AI-callable tools
- Structured Output - Extract typed data with schemas
- Embeddings - Vector generation for semantic search
- Testing - Test agents and concerns
- Instrumentation - Monitor with notifications