Skip to content

Latest commit

 

History

History
286 lines (210 loc) · 9.86 KB

README.md

File metadata and controls

286 lines (210 loc) · 9.86 KB

Jido (自動)

Jido is a foundational framework for building autonomous, distributed agent systems in Elixir.

The name "Jido" (自動) comes from the Japanese word meaning "automatic" or "automated", where 自 (ji) means "self" and 動 (dō) means "movement".

Hex Version Hex Docs Mix Test Coverage Status Apache 2 License

Quick Start

# First, define our Calculator agent with supported operations
iex> defmodule CalculatorAgent do
...>   use Jido.Agent,
...>     name: "calculator",
...>     actions: [Actions.Add, Actions.Subtract, Actions.Multiply, Actions.Divide]
...>   # Omitting the router that maps the "add" signal to the Add Action
...> end
{:module, CalculatorAgent, <<...>>, %{}}

# Start the agent process
iex> {:ok, pid} = CalculatorAgent.start_link()
{:ok, #PID<0.123.0>}

# Send a synchronous request to the agent
iex> {:ok, result} = CalculatorAgent.call(pid, Signal.new(%{type: "add", data: %{a: 1, b: 2}}))
{:ok, 3}

# Send an asynchronous request to the agent
iex> {:ok, request_id} = CalculatorAgent.cast(pid, Signal.new(%{type: "multiply", data: %{a: 2, b: 4}}))
{:ok, "req_abc123"}

# Receive the result of the asynchronous request
iex> flush()
{:jido_agent, "req_abc123", 8}
:ok

This example barely scratches the surface of what Jido can do. For more examples, see the Getting Started Guide and Jido Workbench to play with our growing catalog of real-life examples.

Overview

Jido provides a robust foundation for building autonomous agents that can plan, execute, and adapt their behavior in distributed Elixir applications. Think of it as a toolkit for creating smart, composable workflows that can evolve and respond to their environment.

Are You Sure You Need an Agent?

Agents are a hot topic right now, but they aren’t a silver bullet. In particular, Large Language Models (LLMs) are powerful yet slow and costly—if your application doesn’t require dynamic decision-making or complex planning, consider whether you really need an Agent at all.

  • LLMs aren’t required for all tasks — Avoid building them into your core logic unless necessary
  • Agents as Dynamic ETL — Agents dynamically direct data ingestion, transformation, and output based on:
    • LLMs (e.g., GPT)
    • Classical planning algorithms (A*, Behavior Trees, etc.)
  • Simplicity often wins — If you don’t need these dynamic behaviors, you probably don’t need an Agent. This library is likely overkill compared to straightforward code.

Our Definition of an Agent

An Agent is a system where LLMs or classical planning algorithms dynamically direct their own processes. Some great definitions from the community:

  • “Agents are Dynamic ETL processes directed by LLMs” — YouTube
  • “Agents are systems where LLMs dynamically direct their own processes” — Anthropic Research
  • “AI Agents are programs where LLM outputs control the workflow” — Hugging Face Blog

If your application doesn’t involve dynamic workflows or data pipelines that change based on AI or planning algorithms, you can likely do more with less.

💡 NOTE: This library intends to support both LLM planning and Classical AI planning (ie. Behavior Trees as a design principle via Actions. See jido_ai for example LLM actions.

This space is evolving rapidly. Last updated 2025-01-01

Key Features

  • 🧩 Composable Actions: Build complex behaviors from simple, reusable actions
  • 🤖 Autonomous Agents: Self-directing entities that plan and execute workflows
  • 📡 Real-time Sensors: Event-driven data gathering and monitoring
  • 🔄 Adaptive Learning: Agents can modify their capabilities at runtime
  • 📊 Built-in Telemetry: Comprehensive observability and debugging
  • Distributed by Design: Built for multi-node Elixir clusters
  • 🧪 Testing Tools: Rich helpers for unit and property-based testing

Installation

Add Jido to your dependencies:

def deps do
  [
    {:jido, "~> 1.0.0"}
  ]
end

Core Concepts

Actions

Actions are the fundamental building blocks in Jido. Each Action is a discrete, reusable unit of work with a clear interface:

defmodule MyApp.Actions.FormatUser do
  use Jido.Action,
    name: "format_user",
    description: "Formats user data by trimming whitespace and normalizing email",
    schema: [
      name: [type: :string, required: true],
      email: [type: :string, required: true]
    ]

  def run(params, _context) do
    {:ok, %{
      formatted_name: String.trim(params.name),
      email: String.downcase(params.email)
    }}
  end
end

Learn more about Actions →

Workflows

Workflows chain Actions together to accomplish complex tasks. Jido handles data flow and error handling between steps:

alias MyApp.Actions.{FormatUser, EnrichUserData, NotifyUser}

{:ok, result} = Jido.Workflow.Chain.chain(
  [FormatUser, EnrichUserData, NotifyUser],
  %{
    name: "John Doe ",
    email: "[email protected]"
  }
)

Learn more about Workflows →

Agents

Agents are stateful entities that can plan and execute Actions. They maintain their state through a schema and can adapt their behavior:

defmodule MyApp.CalculatorAgent do
  use Jido.Agent,
    name: "calculator",
    description: "An adaptive calculating agent",
    actions: [
      MyApp.Actions.Add,
      MyApp.Actions.Multiply,
      Jido.Actions.Directives.RegisterAction
    ],
    schema: [
      value: [type: :float, default: 0.0],
      operations: [type: {:list, :atom}, default: []]
    ]

  def on_after_run(agent, result) do
    # Track which operations we've used
    ops = [result.action | agent.state.operations] |> Enum.uniq()
    {:ok, %{agent | state: %{agent.state | operations: ops}}}
  end
end

Learn more about Agents →

Sensors

Sensors provide real-time monitoring and data gathering for your agents:

defmodule MyApp.Sensors.OperationCounter do
  use Jido.Sensor,
    name: "operation_counter",
    description: "Tracks operation usage metrics",
    schema: [
      emit_interval: [type: :pos_integer, default: 1000]
    ]

  def mount(opts) do
    {:ok, Map.merge(opts, %{counts: %{}})}
  end

  def handle_info({:operation, name}, state) do
    new_counts = Map.update(state.counts, name, 1, & &1 + 1)
    {:noreply, %{state | counts: new_counts}}
  end
end

Learn more about Sensors →

Running in Production

Start your agents under supervision:

# In your application.ex
children = [
  {Registry, keys: :unique, name: Jido.AgentRegistry},
  {Phoenix.PubSub, name: MyApp.PubSub},
  {Jido.Agent.Supervisor, pubsub: MyApp.PubSub},
  {Jido.Agent.Server,
    agent: MyApp.CalculatorAgent.new(),
    name: "calculator_1"
  }
]

Supervisor.start_link(children, strategy: :one_for_one)

Example Use Cases

  • Service Orchestration: Coordinate complex workflows across multiple services
  • Data Processing: Build adaptive ETL pipelines that evolve with your data
  • Business Automation: Model complex business processes with autonomous agents
  • System Monitoring: Create smart monitoring agents that adapt to system behavior
  • Transaction Management: Handle multi-step transactions with built-in compensation
  • Event Processing: Process and react to event streams in real-time

Documentation

Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository
  2. Run tests: mix test
  3. Run quality checks: mix quality
  4. Submit a PR

Please include tests for any new features or bug fixes.

See our Contributing Guide for detailed guidelines.

Testing

Jido is built with a test-driven mindset and provides comprehensive testing tools for building reliable agent systems. Our testing philosophy emphasizes:

  • Thorough test coverage for core functionality
  • Property-based testing for complex behaviors
  • Regression tests for every bug fix
  • Extensive testing helpers and utilities

Testing Utilities

Jido provides several testing helpers:

  • Jido.TestSupport - Common testing utilities
  • Property-based testing via StreamData
  • Mocking support through Mimic
  • PubSub testing helpers
  • Signal assertion helpers

Running Tests

# Run the test suite
mix test

# Run with coverage reporting
mix test --cover

# Run the full quality check suite
mix quality

While we strive for 100% test coverage, we prioritize meaningful tests that verify behavior over simple line coverage. Every new feature and bug fix includes corresponding tests to prevent regressions.

License

Apache License 2.0 - See LICENSE.md for details.

Support