Skip to content

AutonomousAgentAlgos (AAA)

An async, event-driven Python library of agent algorithms you can run in production, over data of any shape, with any LLM gateway.

AAA is for the part of an agent system that is not the model: the loops, plans, routing, retries, budgets, approvals, persistence and recovery that decide whether an agent is a demo or something you can put on call. It gives you ready-made algorithms (tool loops, ReAct, plan-and-execute, routers, supervisors, generate-test-repair, workflows, state machines, RAG, voting) and the runtime that makes them durable, bounded and observable.

"""Quickstart: a tool-using agent in ~25 lines. Runs offline with a scripted model."""

import asyncio

from aaa.algos import ToolLoop
from aaa.llm import FakeLLMClient, LLMHandler
from aaa.llm.fake import text, tool_call
from aaa.runtime import Budget, Engine
from aaa.tools import ToolHandler, ToolRegistry, tool


@tool
def multiply(a: int, b: int) -> int:
    """Multiply two integers."""
    return a * b


def scripted_model(request):  # stands in for a real LLM (see "LLM gateways" to swap it)
    last = request.messages[-1]
    if last.role == "user":  # first turn: the model asks for the tool
        return tool_call("multiply", a=17, b=23)
    return text(f"17 x 23 = {last.content}")  # second turn: it answers using the tool result


async def main() -> None:
    registry = ToolRegistry([multiply])
    async with Engine() as engine:
        LLMHandler(FakeLLMClient(scripted_model)).attach(engine)  # who answers LLM requests
        ToolHandler(registry).attach(engine)  # who runs tool calls
        outcome = await engine.run(
            ToolLoop(registry),
            {"task": "What is 17 times 23?"},
            budget=Budget(max_steps=20, deadline_s=30),
        )
    print(outcome.kind.value, "-", outcome.value["text"])


asyncio.run(main())
success - 17 x 23 = 391

That example runs offline

A scripted model stands in for the LLM so every example in these docs is executable and tested. The LLM gateways guide shows how to point the same code at a real model.

Why AAA

  • The log is the truth

    Every run is an append-only stream of immutable events. State, plans, conversations and spend are folds of that log, so runs can be replayed, audited, resumed after a crash, and moved between processes. :octicons-arrow-right-24: Events and the log

  • Your data, not ours

    Algorithms see an Item envelope; you keep your own types (Pydantic, dataclasses, dicts, DataFrame rows, documents). A small codec teaches AAA to render, store and fingerprint them. :octicons-arrow-right-24: Data model

  • Bounded by construction

    Budgets (steps, tokens, cost), deadlines, cancellation, approval gates and tool timeouts are enforced by the engine, outside the model's control. Failures are facts on the log, not exceptions. :octicons-arrow-right-24: Runs and the engine

  • Any LLM gateway

    One OpenAI-compatible client with presets for LiteLLM, Portkey, Cloudflare, Vercel, Bifrost, Kong and MLflow, an in-process LiteLLM adapter, and a plug-in point for anything custom. :octicons-arrow-right-24: LLM gateways

  • Durable and distributed

    SQLite for one machine; Postgres or Redis plus a partitioned bus for many. Kill a worker mid-tool-call and another finishes the job. :octicons-arrow-right-24: Running a cluster

  • Safe side effects

    Exclusive execution leases, numbered attempts as fencing tokens, at-most-once / at-least-once delivery, and idempotency keys for tools that send email or move money. :octicons-arrow-right-24: Tool execution guard

The algorithms

Algorithm Use it when
ToolLoop The model should call your functions until it can answer. The default choice.
ReAct The model/gateway has no native tool calling (text Thought/Action protocol).
PlanAndExecute A task decomposes into steps with dependencies that can run in parallel.
Router Pick exactly one specialist: rules first, an LLM only for what rules do not decide.
Supervisor An LLM coordinates several workers, possibly in parallel.
GenerateTestRepair You can verify output deterministically (schema, tests, rules).
GeneratorCritic You can only verify with another model.
WorkflowGraph The control flow is known; no LLM should decide it.
FSM Long-lived, event-driven processes with explicit states (approvals, onboarding).
SelfConsistency Answers are exactly comparable; majority vote beats one sample.
RAGAgent Answers must be grounded in your documents, with citations.

Choosing an algorithm walks through the decision, and Writing your own shows the 40-line recipe for a new one.

Status

Alpha software: read the limits

AAA is version 0.x. The test suite is substantial (unit, store/bus contract tests across four backends, real multi-process tests that SIGKILL workers) but you should know what has and has not been proven:

  • Verified live against a real model server (a local Ollama running gemma4), including tool calls, streaming, structured output, plan-and-execute and repair loops.
  • Not yet verified live against any hosted gateway (Portkey, Cloudflare, Vercel, Bifrost, Kong, MLflow, LiteLLM proxy). Their URLs and headers follow vendor documentation and are covered by mocked-transport tests. A smoke-test script is provided.
  • Not load tested. Correctness under failure is tested; throughput numbers are only given for the single-process log-growth benchmark.

The full list is on Status and limitations.

Where to go next

  1. Install it and run the quickstart.
  2. Read the mental model (ten minutes; everything else follows from it).
  3. Pick an algorithm, or go straight to persistence and clusters if you are deploying.
  4. Keep the event catalog and configuration reference open while you build.

AAA is MIT licensed. Source: github.com/innerkorehq/AutonomousAgentAlgos.