Skip to content

Quick Start

Get from zero to a running multi-agent API with visual debugging in under 60 seconds.


Prerequisites

Before you begin, make sure you have the following:

Requirement Version Check Command
Python 3.11+ python --version
pip or uv Latest pip --version / uv --version
LLM API key โ€” echo $OPENAI_API_KEY or local Ollama

Local LLMs with Ollama

You don't need an OpenAI API key to get started. Agentomatic works with Ollama out of the box:

# Install Ollama, then pull a model
ollama pull mistral:7b


1. Install Agentomatic

Install all features including Studio, Chat UI, database support, and optimization:

pip install agentomatic[all]
uv add agentomatic --extra all
poetry add agentomatic -E all

Install only the core platform and visual debugger:

pip install "agentomatic[studio,cli]"
Available Installation Extras

Agentomatic is modular โ€” install only what you need:

Extra What It Includes When You Need It
all Everything below Production / full development
langgraph LangGraph + LangChain Core LangGraph-based agents
langchain LangChain + LangChain Community LangChain LCEL agents
ollama LangChain-Ollama bindings Local LLM development with Ollama
openai LangChain-OpenAI bindings OpenAI API-based agents
azure LangChain-OpenAI (Azure) Azure OpenAI deployments
vertex LangChain-Google VertexAI Google Cloud Vertex AI
cli Rich terminal output, questionary prompts Better CLI experience
ui Chainlit chat interface Conversational testing at /chat
studio React-based visual debugger Graph debugging at /studio/ui/
db SQLAlchemy + aiosqlite SQLite thread persistence
db-postgres SQLAlchemy + asyncpg + psycopg PostgreSQL thread persistence
optimize DeepEval, HolySheet Automatic prompt tuning
metrics Prometheus client /metrics endpoint for monitoring
telemetry OpenTelemetry SDK Distributed tracing

Verify your installation

agentomatic doctor
This checks your Python version, installed packages, optional extras, and external service connections.


2. Scaffold Your First Agent

Generate a fully functional agent using the CLI:

agentomatic init my_chatbot --template basic

This creates a self-contained agent package under agents/:

agents/my_chatbot/
โ”œโ”€โ”€ __init__.py      # AgentManifest card
โ”œโ”€โ”€ agent.py         # REQUIRED: BaseGraphAgent subclass
โ”œโ”€โ”€ llm.py           # Stack-aware LLM helpers
โ”œโ”€โ”€ prompts.json     # Versioned system and user prompt templates
โ”œโ”€โ”€ langgraph.json   # LangGraph Studio local settings
โ”œโ”€โ”€ .env.example     # Environment variables blueprint
โ””โ”€โ”€ README.md        # Agent documentation

Available Templates

Template Description
basic / class Minimal class-based agent (recommended) โ€” quick start
chatbot Conversational class-based agent with memory
rag RAG class-based agent โ€” retrieve โ†’ generate pipeline
full All features: class agent with config, schemas, train/eval
coordinator Orchestrator that routes to specialists
pipeline Multi-step YAML workflow
deepagent Deep Agent with planning, tools, subagents
custom Framework-agnostic โ€” no LangGraph dependency
legacy_dict Legacy functional agent โ€” manifest + node_fn
plugin ML Model Plugin with REST endpoints
endpoint / connection / ingestion / extraction Ops / RAG building blocks

Select interactively by omitting the --template flag:

agentomatic init my_agent  # Shows interactive picker


3. Choose Your Framework

Agentomatic supports multiple agent frameworks. Here's a quickstart for each:

The default and most feature-rich option. Subclass BaseGraphAgent:

agents/my_chatbot/agent.py
from dataclasses import dataclass, field
from typing import Any
from agentomatic.agents import BaseGraphAgent

@dataclass
class ChatbotState:
    request: str = ""
    output: dict[str, Any] = field(default_factory=dict)

class ChatbotAgent(BaseGraphAgent[ChatbotState]):
    agent_name = "my_chatbot"
    agent_description = "A conversational chatbot."
    agent_framework = "graph_agent"

    def build_graph(self):
        g = self.new_graph()
        g.add_node("process", self.process)
        g.set_entry_point("process")
        g.set_finish_point("process")
        return g.compile()

    def process(self, state: ChatbotState) -> ChatbotState:
        state.output = {
            "response": f"Hello! You said: {state.request}",
            "agent_type": "agent-my_chatbot",
        }
        return state

    def input_to_state(self, input_data: dict[str, Any]) -> ChatbotState:
        return ChatbotState(request=input_data.get("current_query", ""))

    def state_to_output(self, state: ChatbotState) -> dict[str, Any]:
        return state.output

Use LangChain Expression Language (LCEL) chains. Expose your logic via node_fn:

agents/lcel_agent/__init__.py
from agentomatic import AgentManifest
from typing import Any

manifest = AgentManifest(
    name="lcel_agent",
    slug="lcel-agent",
    description="A LangChain LCEL-based summarizer agent.",
    intent_keywords=["summarize", "tldr", "summary"],
    version="1.0.0",
    framework="langchain",  # (1)!
)

async def node_fn(state: dict[str, Any]) -> dict[str, Any]:  # (2)!
    """Execute the LCEL chain directly."""
    from langchain_ollama import ChatOllama
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_core.output_parsers import StrOutputParser

    prompt = ChatPromptTemplate.from_messages([
        ("system", "You are a concise summarizer. Summarize the input in 2-3 sentences."),
        ("human", "{query}"),
    ])
    llm = ChatOllama(model="mistral:7b", temperature=0.3)
    chain = prompt | llm | StrOutputParser()  # (3)!

    query = state.get("current_query", "")
    result = await chain.ainvoke({"query": query})

    return {
        "response": result,
        "agent_type": "agent-lcel_agent",
        "steps_taken": ["lcel_chain"],
    }
  1. Framework hint for adapters โ€” Studio will show a linear chain view
  2. node_fn is the single-function alternative to graph_fn โ€” simpler but no graph visualization
  3. LCEL pipe syntax: prompt โ†’ LLM โ†’ output parser

Use the Deep Agent framework for hierarchical, goal-oriented agents:

agents/deep_planner/__init__.py
from agentomatic import AgentManifest
from .agent import build_deep_agent

manifest = AgentManifest(
    name="deep_planner",
    slug="deep-planner",
    description="A planning agent using Deep Agent framework.",
    intent_keywords=["plan", "organize", "schedule"],
    version="1.0.0",
    framework="langgraph",  # (1)!
)

def graph_fn():  # (2)!
    """Return the compiled Deep Agent as a LangGraph-compatible graph."""
    return build_deep_agent()
  1. Deep Agents compile to LangGraph graphs, so use framework="langgraph" for full Studio support
  2. The graph_fn returns the compiled graph โ€” Studio can inspect nodes, edges, and state
agents/deep_planner/agent.py
from deepagents import create_deep_agent

def build_deep_agent():
    """Build and return a Deep Agent workflow."""
    agent = create_deep_agent(
        name="planner",
        model="ollama/mistral:7b",
        goal="Break down user requests into actionable steps",
        tools=["web_search", "calculator"],
    )
    return agent.compile()  # (3)!
  1. .compile() returns a LangGraph CompiledStateGraph โ€” compatible with all Agentomatic features

Learn more about Deep Agent integration

See the Deep Agent Integration Guide for advanced configuration, custom tools, and multi-agent hierarchies.

No framework needed โ€” use plain Python with node_fn:

agents/simple_bot/__init__.py
from agentomatic import AgentManifest
from typing import Any

manifest = AgentManifest(
    name="simple_bot",
    slug="simple-bot",
    description="A zero-dependency echo agent in pure Python.",
    intent_keywords=["echo", "test", "ping"],
    version="1.0.0",
    framework="custom",  # (1)!
)

async def node_fn(state: dict[str, Any]) -> dict[str, Any]:  # (2)!
    """Pure Python agent โ€” no LLM, no framework."""
    query = state.get("current_query", "")
    return {
        "response": f"You said: {query}",
        "agent_type": "agent-simple_bot",
        "steps_taken": ["echo"],
        "suggestions": ["Say something else", "Try another agent"],
    }
  1. framework="custom" tells Agentomatic there's no graph to inspect โ€” Studio shows basic metadata only
  2. node_fn receives the full state dict and must return a dict with at least "response"

When to use node_fn vs graph_fn

Use node_fn when... Use graph_fn when...
Your agent is a single function Your agent has multiple steps/nodes
No graph visualization needed You want Studio graph debugging
Using LCEL chains or plain Python Using LangGraph StateGraph
Simpler is better Complex orchestration required

4. Run the Platform

Choose your preferred development mode:

Launch the platform with the visual debugging studio:

agentomatic run --studio --reload
Service URL
FastAPI Application http://localhost:8000
OpenAPI Swagger Docs http://localhost:8000/docs
Agentomatic Studio http://localhost:8000/studio/ui/

Studio is the primary debug tool

Studio provides graph visualization, SSE node streaming, time-travel debugging, state inspection, and live state editing. See the Studio Guide for details.

Launch with the Chainlit conversational interface:

agentomatic run --with-ui --reload
Service URL
FastAPI Application http://localhost:8000
OpenAPI Swagger Docs http://localhost:8000/docs
Chainlit Chat UI http://localhost:8000/chat

Run Studio and Chat UI together:

agentomatic run --studio --with-ui --reload

Create a main.py file for programmatic control:

main.py
from agentomatic import AgentPlatform

platform = AgentPlatform.from_folder(
    "agents/",
    title="My Agent Platform",
    enable_studio=True,   # (1)!
    enable_metrics=True,  # (2)!
)
app = platform.build()
  1. Enables Agentomatic Studio at /studio/ui/
  2. Enables Prometheus metrics at /metrics
uvicorn main:app --reload

5. Query Your Agent

Interact with the running agent using any HTTP client:

curl -X POST http://localhost:8000/api/v1/my_chatbot/invoke \
  -H "Content-Type: application/json" \
  -d '{"query": "Hello! What can you do?"}'
curl -N -X POST http://localhost:8000/api/v1/my_chatbot/invoke/stream \
  -H "Content-Type: application/json" \
  -d '{"query": "Tell me a story about a robot"}'

The -N flag disables output buffering so you see SSE events in real-time:

data: {"node": "greet", "output": {"agent_type": "agent-my_chatbot"}}
data: {"node": "respond", "output": {"response": "Once upon a time..."}}
data: [DONE]

# First message โ€” starts a conversation thread
curl -X POST http://localhost:8000/api/v1/my_chatbot/chat \
  -H "Content-Type: application/json" \
  -d '{
    "query": "My name is Alice",
    "thread_id": "thread_abc123",
    "user_id": "user-1"
  }'

# Follow-up โ€” Agentomatic remembers the thread history
curl -X POST http://localhost:8000/api/v1/my_chatbot/chat \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What is my name?",
    "thread_id": "thread_abc123",
    "user_id": "user-1"
  }'
test_invoke.py
import httpx

response = httpx.post(
    "http://localhost:8000/api/v1/my_chatbot/invoke",
    json={"query": "Hello! What can you do?"},
)
print(response.json())
test_stream.py
import httpx

with httpx.stream(
    "POST",
    "http://localhost:8000/api/v1/my_chatbot/invoke/stream",
    json={"query": "Tell me a story"},
) as response:
    for line in response.iter_lines():
        if line.startswith("data: "):
            print(line[6:])
# Opens a chat-like session in your terminal
agentomatic test my_chatbot
โšก agentomatic
๐Ÿงช Testing agent: my_chatbot
   API: http://localhost:8000/api/v1/my_chatbot/invoke
   Type 'quit' or 'exit' to stop

๐Ÿ—ฃ๏ธ  You: Hello!
๐Ÿค– my_chatbot: Hello! How can I assist you today?
   Steps: greet โ†’ respond
   โฑ 114ms

Expected JSON Response

{
  "response": "Hello! How can I assist you today?",
  "agent_type": "agent-my_chatbot",
  "thread_id": "thread_abc123",
  "suggestions": [],
  "citations": [],
  "steps_taken": ["greet", "respond"],
  "metadata": {},
  "duration_ms": 114.2
}

6. Auto-Generated Endpoints

Every registered agent gets a full suite of REST endpoints automatically:

Method Endpoint Description
POST /api/v1/{agent}/invoke Synchronous invocation
POST /api/v1/{agent}/invoke/stream SSE streaming invocation
POST /api/v1/{agent}/chat Multi-turn conversation with thread persistence
GET /api/v1/{agent}/health Agent health check
GET /api/v1/{agent}/config Agent configuration
GET /api/v1/{agent}/prompts Available prompt versions
GET /api/v1/{agent}/card A2A agent card
POST /api/v1/{agent}/a2a/tasks Submit A2A task
GET /api/v1/{agent}/a2a/tasks/{id} Get A2A task status
POST /api/v1/{agent}/threads Create thread
GET /api/v1/{agent}/threads List conversation threads
GET /api/v1/{agent}/threads/{id} Get thread history
PATCH /api/v1/{agent}/threads/{id} Update thread
DELETE /api/v1/{agent}/threads/{id} Delete thread
GET /api/v1/{agent}/threads/{id}/messages Get messages
DELETE /api/v1/{agent}/threads/{id}/messages Delete messages
GET /api/v1/{agent}/threads/{id}/summary Get thread summary
POST /api/v1/{agent}/feedback Submit user feedback
GET /api/v1/{agent}/feedback Retrieve feedback entries
GET /api/v1/{agent}/feedback/export Export feedback data
GET /api/v1/{agent}/threads/{id}/pending Get pending HITL actions
POST /api/v1/{agent}/threads/{id}/approve HITL approval
POST /api/v1/{agent}/threads/{id}/reject HITL rejection
POST /api/v1/{agent}/threads/{id}/fork Fork thread
GET /api/v1/{agent}/threads/{id}/lineage Get thread lineage
POST /api/v1/{agent}/optimize/invoke Optimization invocation

Full endpoint documentation

Visit http://localhost:8000/docs for the interactive Swagger UI with all endpoints, schemas, and try-it-out functionality.


7. Configuration

Environment Variables

Set these in your .env file or export them in your shell:

Variable Default Description
AGENTOMATIC_AGENTS_DIR agents Directory to scan for agent packages
AGENTOMATIC_HOST 0.0.0.0 Server bind address
AGENTOMATIC_PORT 8000 Server bind port
AGENTOMATIC_LOG_LEVEL INFO Logging level (DEBUG, INFO, WARNING, ERROR)
AGENTOMATIC_DB_URL sqlite:///data/threads.db Database URL for thread persistence
OPENAI_API_KEY โ€” Required for OpenAI-based agents
OLLAMA_BASE_URL http://localhost:11434 Ollama API base URL

Per-Agent Configuration

Each agent can define its own config.py with a Pydantic model:

agents/my_chatbot/config.py
from pydantic import BaseModel, Field

class AgentConfig(BaseModel):
    prompt_version: str = Field("v1", description="Active prompt template version")
    temperature: float = Field(0.7, ge=0.0, le=2.0)
    max_tokens: int = Field(2048)
    llm_model: str = Field("gpt-4o-mini")

Runtime Access

Configuration is accessible via the API at GET /api/v1/my_chatbot/config and can be modified at runtime via POST /api/v1/my_chatbot/config.


Understanding the State Dictionary

When Agentomatic receives a REST request and invokes your agent, it maps the request body fields into a state dictionary. Understanding this mapping is crucial:

REST Request Field State Dict Key Description
query current_query The user's input text
user_id user_id User identifier (default: "default-user")
thread_id thread_id Conversation thread (for multi-turn chat)
context context and flattened top-level keys Arbitrary context dict; keys are also merged into the transform payload for class agents
metadata metadata Request metadata dict
prompt_version prompt_version Active prompt version (default: "v1")

Class-based agents vs functional agents

  • Class-based agents: You control mapping via input_to_state() โ€” use input_data.get("current_query") or any key you prefer. Fields sent under context are flattened into that dict (top-level keys win on collision), so input_data.get("snapshot") works for {"query": "...", "context": {"snapshot": {...}}}.
  • Functional agents (node_fn): The state dict is passed directly with keys above โ€” use state.get("current_query") / state.get("context").

Invoke URL shape

Agents mount at /api/v1/{agent_name}/invoke โ€” there is no /agents/ segment. Example: POST /api/v1/my_chatbot/invoke (not /api/v1/agents/my_chatbot/invoke).


Troubleshooting

My agent isn't being discovered
  1. Check the folder: Your agent must be in the agents/ directory (or wherever --agents-dir points)
  2. Check for errors: Look at the console output for โŒ Failed to discover messages
  3. Class agents: Need agent.py with a BaseGraphAgent subclass
  4. Functional agents: Need __init__.py with a manifest variable
ModuleNotFoundError when starting

This usually means a dependency is missing. Common fixes:

pip install agentomatic[langgraph]  # For LangGraph-based agents
pip install agentomatic[ollama]     # For Ollama LLM provider
pip install agentomatic[all]        # Install everything

Agent returns empty response
  • Class agents: Make sure state_to_output() returns a dict with a "response" key
  • Functional agents: Make sure node_fn returns a dict with a "response" key
  • Check that your node methods actually return the updated state (return state)
Port already in use
# Kill the existing process
lsof -ti :8000 | xargs kill -9
# Or use a different port
agentomatic run --port 8001
CORS errors from frontend

Pass your frontend origin to the platform configuration:

platform = AgentPlatform.from_folder(
    "agents/",
    cors_origins=["http://localhost:3000"],
)


What's Next?

Now that your first agent is running, explore these resources:

Recommended Learning Path

First Agent โ†’ Class-Based Agents โ†’ Cookbook โ†’ Configuration โ†’ Studio

Topic Description
Your First Agent Step-by-step tutorial building an agent from scratch with annotated code
Class-Based Agents Complete guide to BaseGraphAgent, graph wiring, ML lifecycle
Cookbook & Recipes 10 copy-paste patterns: RAG, routing, HITL, schemas, ML plugins
Agent Structure Folder conventions, manifest fields, and auto-discovery
Agentomatic Studio Visual debugging with graph view, state inspection, and time-travel
Deep Agent Integration Register and debug Deep Agent workflows with full Studio support
Chat Interface Chainlit-based conversational testing
Prompt Management Template versioning, hot-reload, and A/B testing
Prompt Optimization Auto-tune prompts with DSPy-inspired optimization
Storage Backends Configure PostgreSQL, SQLite, or custom adapters
Middleware Auth, rate limiting, metrics, and custom middleware
Configuration Platform settings, CORS, environment variables
CLI Reference Every command and flag documented
API Reference All 26 endpoints with request/response schemas