Skip to content

Tools and Actions

Active Agent supports tool/function calling, allowing agents to interact with external services and perform actions.

Tool Support

Agents can define and use tools to extend their capabilities:

ruby
class SupportAgent < ApplicationAgent
  layout "agent"
  generate_with :openai, model: "gpt-4o-mini", instructions: "You're a support agent. Your job is to help users with their questions."

  def get_cat_image
    prompt(content_type: "image_url", context_id: params[:context_id]) do |format|
      format.text { render plain: CatImageService.fetch_image_url }
    end
  end
end

Tool Usage Example

Here's how an agent uses tools to fulfill user requests:

ruby
message = "Show me a cat"
prompt = SupportAgent.with(message: message).prompt_context

Tool Call Response

When a tool is called, the response includes the tool's output in the conversation:

ruby
response = prompt.generate_now
Response Example

activeagent/test/agents/support_agent_test.rb:20

ruby
# Response object
#<ActiveAgent::GenerationProvider::Response:0x3930
  @message=#<ActiveAgent::ActionPrompt::Message:0x3944
    @action_id=nil,
    @action_name=nil,
    @action_requested=false,
    @charset="UTF-8",
    @content="Here is a cute cat for you!\n\n![Cat](data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAB8A...",
    @role=:assistant>
  @prompt=#<ActiveAgent::ActionPrompt::Prompt:0x3958 ...>
  @content_type="text/plain"
  @raw_response={...}>

# Message content
response.message.content # => "Here is a cute cat for you!\n\n![Cat](data:image/jpeg;base64,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)"

Tool Response Structure

When tools are used, the response includes:

  • System Message: Initial instructions for the agent
  • User Message: The original user request
  • Assistant Message: The agent's decision to use a tool
  • Tool Message: The result from the tool execution

The final response contains 4 messages showing the complete tool interaction flow.

Implementing Tools

Tools are defined as methods in your agent class. The tool's JSON schema is defined in the corresponding view template:

Tool Implementation

ruby
class SupportAgent < ApplicationAgent
  layout "agent"
  generate_with :openai, model: "gpt-4o-mini", instructions: "You're a support agent. Your job is to help users with their questions."

  def get_cat_image
    prompt(content_type: "image_url", context_id: params[:context_id]) do |format|
      format.text { render plain: CatImageService.fetch_image_url }
    end
  end
end

Tool Schema Definition

erb
<%= {
  type: :function,
  function: {
    name: 'get_cat_image',
    description: "This action takes no params and gets a random cat image and returns it as a base64 string.",
    parameters: {
      type: :object,
      properties: {}
    }
  }
}.to_json.html_safe %>