Scaffolding Templates¶
Agent Scaffolding and Project Generation
Agentomatic ships with 16 templates for rapid agent and component creation. They generate the appropriate runnable package or workflow artefact for the selected use case.
๐ Quick Start¶
For agent templates, both commands create agents/my_agent/. Integration and
pipeline templates use their own auto-discovered directories; see Component
and integration templates.
๐ Template Comparison¶
| Template | Framework | Graph | Config | Tools | Custom API | Best For |
|---|---|---|---|---|---|---|
basic |
Built-in | โ | โ | โ | โ | Quick prototyping and learning |
class |
Built-in | โ | โ | โ | โ | Alias for basic |
full |
Built-in | โ | โ | โ | โ | Production agents with all overrides |
coordinator |
Built-in | โ | โ | โ | โ | Delegating work to specialist agents |
pipeline |
YAML | โ | โ | โ | โ | Multi-step workflows across components |
rag |
Built-in | โ | โ | โ | โ | Knowledge bases, Q&A over documents |
chatbot |
Built-in | โ | โ | โ | โ | Conversational agents with memory |
deepagent |
LangGraph | โยน | โ | โ | โ | Autonomous planning with sub-agents |
custom |
Custom | โ | โ | โ | โ | Framework-agnostic, minimal deps |
legacy_dict |
LangGraph | โ | โ | โ | โ | Legacy functional agent (3 files) |
langchain |
LangChain | โ | โ | โ | โ | LangChain-native prompt and message workflows |
plugin |
Plugin | โ | โ | โ | โ | ML model plugins with REST endpoints |
endpoint |
HTTP | โ | โ | โ | โ | Wrapping an external model or service |
connection |
Connection | โ | โ | โ | โ | Per-agent database and HTTP connections |
ingestion |
Ingestion | โ | โ | โ | โ | Packaging document ingestion as a task |
extraction |
Built-in | โ | โ | โ | โ | Parallel markdown extraction workflows |
ยน Deep agent uses agent.py with create_deep_agent() instead of build_graph()
Core class-agent templates use AgentGraph
The basic, full, rag, chatbot, coordinator, and extraction
templates generate BaseGraphAgent subclasses backed by agentomatic's
built-in AgentGraph runtime โ no LangGraph dependency required.
๐ Generated Files by Template¶
basic โ Minimal Agent¶
The simplest starting point โ a class-owned BaseGraphAgent (also
available as --template class).
agents/my_agent/
โโโ __init__.py # AgentManifest card
โโโ agent.py # BaseGraphAgent subclass
โโโ llm.py # Stack-aware LLM helpers
โโโ prompts.json # v1/v2 prompt templates
โโโ langgraph.json # LangGraph Studio config
โโโ .env.example # Environment variable template
โโโ README.md # Agent documentation
Class-agent layout
basic / class emit agent.py + llm.py โ not the legacy
graph.py / nodes.py layout (use --template legacy_dict for that).
full โ All Override Files¶
Includes every possible override file. Ideal for production agents that need full control.
agents/my_agent/
โโโ __init__.py # AgentManifest card
โโโ agent.py # BaseGraphAgent subclass (+ get_graph export)
โโโ llm.py # Stack-aware LLM helpers
โโโ config.py # Pydantic config (MyAgentConfig)
โโโ schemas.py # Custom request/response models
โโโ tools.py # Tool definitions
โโโ api.py # Optional custom FastAPI router
โโโ dataset.jsonl # Sample train/eval data
โโโ train.py / eval.py / optimize.py / predict.py
โโโ search_space.yaml # PromptFitter search space
โโโ Makefile
โโโ prompts.json
โโโ langgraph.json # Points at ./agent.py:get_graph
โโโ .env.example
โโโ README.md
Generated config.py
"""Configuration for My Agent agent."""
from pydantic import BaseModel, Field
class MyAgentConfig(BaseModel):
"""Agent-specific configuration."""
prompt_version: str = Field("v1", description="Active prompt version")
temperature: float = Field(0.1, ge=0.0, le=2.0)
max_tokens: int = Field(2048, ge=1)
enable_memory: bool = Field(True, description="Enable conversation memory")
Generated schemas.py
"""Custom schemas for my_agent."""
from pydantic import BaseModel, Field
class MyAgentRequest(BaseModel):
"""Custom request model."""
query: str = Field(..., description="User query")
context: dict = Field(default_factory=dict)
class MyAgentResponse(BaseModel):
"""Custom response model."""
answer: str
confidence: float = Field(0.0, ge=0.0, le=1.0)
sources: list[str] = Field(default_factory=list)
Generated api.py
"""Custom API router for my_agent.
If this file exports a `router`, it REPLACES the auto-generated endpoints.
Remove this file to use auto-generated endpoints instead.
"""
from fastapi import APIRouter
router = APIRouter()
@router.get("/status")
async def status() -> dict:
"""Custom status endpoint."""
return {"agent": "my_agent", "custom_router": True}
Custom Router Override
When api.py is present and exports a router, the generated per-agent
API is replaced by that router. Remove api.py to restore the default
REST API.
rag โ Retrieval-Augmented Generation¶
A two-stage pipeline (retrieve โ generate) pre-configured for knowledge-base Q&A.
agents/knowledge_bot/
โโโ __init__.py # AgentManifest with RAG keywords
โโโ agent.py # BaseGraphAgent: retrieve โ generate
โโโ llm.py # Stack-aware LLM helpers
โโโ config.py # Pydantic config
โโโ tools.py # Search tool stubs
โโโ prompts.json
โโโ langgraph.json # ./agent.py:get_graph
โโโ .env.example
โโโ README.md
Class-agent RAG
The rag template is a BaseGraphAgent with retrieve + generate
nodes โ not the legacy graph.py / nodes.py layout.
chatbot โ Conversational Agent¶
Optimized for multi-turn conversations with memory support.
agents/assistant/
โโโ __init__.py # AgentManifest with chat keywords
โโโ agent.py # BaseGraphAgent conversational agent
โโโ llm.py # Stack-aware LLM helpers
โโโ config.py # Pydantic config
โโโ prompts.json
โโโ langgraph.json # ./agent.py:get_graph
โโโ .env.example
โโโ README.md
Class-agent chatbot
The chatbot template is a BaseGraphAgent subclass with prompt-backed
conversation, not the legacy graph.py / nodes.py layout.
deepagent โ Deep Agent with Planning¶
Uses the deepagents package for autonomous planning, tool usage, and sub-agent delegation.
agents/researcher/
โโโ __init__.py # Manifest + graph_fn + node_fn
โโโ agent.py # Deep agent definition with tools
โโโ llm.py # Stack-aware LLM helpers
โโโ config.py # Pydantic config
โโโ prompts.json # v1/v2 prompt templates
โโโ .env.example # Environment variable template
โโโ README.md # Agent documentation
Generated agent.py
"""Deep Agent definition for researcher.
Uses LangChain's `deepagents` harness for planning, tools,
subagent delegation, and context management.
"""
from functools import lru_cache
def internet_search(query: str, max_results: int = 5) -> str:
"""Search the internet for information."""
# TODO: Replace with real search (Tavily, SerpAPI, etc.)
return f"Search results for: {query} ({max_results} results)"
@lru_cache(maxsize=1)
def create_agent():
"""Create and compile the deep agent."""
from deepagents import create_deep_agent
return create_deep_agent(
model="openai:gpt-4o",
system_prompt=(
"You are Researcher, "
"an expert AI assistant. Be thorough and accurate."
),
tools=[internet_search],
)
Dependency
The deepagent template requires the deepagents package: pip install deepagents
custom โ Framework-Agnostic¶
The most minimal template. Pure Python with no LangGraph dependency โ ideal for simple API wrappers or custom frameworks.
agents/simple/
โโโ __init__.py # Manifest + node_fn (framework="custom")
โโโ prompts.json # v1/v2 prompt templates
โโโ .env.example # Environment variable template
โโโ README.md # Agent documentation
Generated custom __init__.py
"""Agent: simple (framework-agnostic)."""
from __future__ import annotations
from typing import Any
from agentomatic import AgentManifest
manifest = AgentManifest(
name="simple",
slug="agent-simple",
description="Simple agent",
intent_keywords=["simple"],
framework="custom",
)
async def node_fn(state: dict[str, Any]) -> dict[str, Any]:
"""Process the request directly โ no graph framework needed."""
query = state.get("current_query", "")
return {
"response": f"Hello from simple! You asked: {query}",
"agent_type": "agent-simple",
}
legacy_dict โ Legacy Functional Agent¶
The classic agentomatic pattern using __init__.py with manifest + node_fn. Ideal for quick utilities or migrating existing LangGraph code.
agents/helper/
โโโ __init__.py # Manifest + graph-invoking node_fn
โโโ graph.py # Compiled LangGraph definition
โโโ nodes.py # Async graph node functions
โโโ prompts.json # Prompt templates
โโโ langgraph.json # LangGraph Studio configuration
โโโ .env.example # Environment config
โโโ README.md # Agent documentation
Generated __init__.py
"""Agent: helper (legacy functional pattern)."""
from __future__ import annotations
from typing import Any
from agentomatic import AgentManifest
manifest = AgentManifest(
name="helper",
slug="agent-helper",
description="Helper agent",
intent_keywords=["helper", "assist"],
framework="langgraph",
)
async def node_fn(state: dict[str, Any]) -> dict[str, Any]:
from .graph import get_graph
return await get_graph().ainvoke(state)
When to use legacy_dict
Use this template when you need the established module-level LangGraph
layout (manifest, graph.py, and nodes.py) rather than a
class-based agent. It is useful for migrating existing LangGraph code.
plugin โ ML Model Plugin¶
Wrap a classical ML model (scikit-learn, XGBoost, etc.) as a REST endpoint using BaseMLPlugin.
plugins/my_classifier/
โโโ __init__.py # Plugin package marker
โโโ plugin.py # BaseMLPlugin subclass
โโโ dataset.jsonl # Sample train/eval data
โโโ train.py / eval.py / optimize.py / predict.py
โโโ Makefile # Training and evaluation shortcuts
โโโ README.md # Plugin documentation
Generated plugin.py
"""ML Plugin: my_classifier."""
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, Field
from agentomatic.plugins import BaseMLPlugin
class PredictInput(BaseModel):
features: list[float] = Field(..., description="Input feature vector")
class PredictOutput(BaseModel):
prediction: float = Field(..., description="Model prediction")
confidence: float = Field(0.0, description="Prediction confidence")
class MyClassifierPlugin(BaseMLPlugin[PredictInput, PredictOutput]):
plugin_name = "my_classifier"
plugin_description = "Classification model plugin"
plugin_version = "1.0.0"
def load_model(self) -> Any:
"""Load and return the trained model."""
# Example: return joblib.load("model.pkl")
return None
def predict(self, model: Any, input_data: PredictInput) -> PredictOutput:
"""Run prediction on the loaded model."""
return PredictOutput(
prediction=0.0,
confidence=0.95,
)
ML Plugin Features
Plugins get automatic REST endpoints (/predict, /health, /model-card) and can be deployed alongside agents in the same platform. See ML Plugins for the full guide.
Component and integration templates¶
These templates scaffold platform components rather than a conventional agent.
When no --dir is supplied, plugin, endpoint, ingestion, and pipeline
are written to their auto-discovered top-level directories; connection stays
under agents/ because it belongs to one agent.
| Template | Default location | Main file | Purpose |
|---|---|---|---|
endpoint |
endpoints/<name>/ |
endpoint.py |
Call and aggregate external model services |
connection |
agents/<name>/ |
connections.py |
Define authenticated database and HTTP connections |
ingestion |
ingestion/<name>/ |
ingestor.py |
Package an ingestion workflow as a task job |
pipeline |
pipelines/<name>/ |
pipeline.yaml |
Compose agents and components into a workflow |
extraction |
agents/<name>/ |
agent.py |
Extract scoped markdown and provide a companion pipeline |
langchain โ LangChain-native agent¶
Use this when the agent should own LangChain prompt and message primitives while remaining discoverable through Agentomatic's standard REST and Studio paths.
The generated package includes agent.py, llm.py, prompts.json, and
langgraph.json. See LangChain / LangGraph Adapter for
the runtime bridge and message conversion helpers.
This is the basic template pattern
The tree below is the complete output of agentomatic init analyzer
--template basic. Other class-agent templates add files specific to their
capabilities.
agents/analyzer/
โโโ __init__.py # AgentManifest card
โโโ agent.py # BaseGraphAgent subclass with build_graph()
โโโ llm.py # Stack-aware LLM helpers
โโโ prompts.json # Prompt templates
โโโ langgraph.json # LangGraph Studio configuration
โโโ .env.example # Environment config
โโโ README.md # Agent documentation
Example agent.py customization
This illustrates extending the generated class agent; the exact scaffold
is intentionally smaller and contains only the process node.
"""Class-based agent: analyzer."""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any
from agentomatic.agents import BaseGraphAgent
@dataclass
class AnalyzerState:
"""Agent state โ per-run transient data."""
request: str = ""
context: list[str] = field(default_factory=list)
output: dict[str, Any] = field(default_factory=dict)
class AnalyzerAgent(BaseGraphAgent[AnalyzerState]):
"""ML-like class agent for analyzer.
Usage::
agent = AnalyzerAgent(llm=my_llm)
result = agent.transform({"request": "Hello"})
"""
agent_name = "analyzer"
agent_description = "Analyzer agent"
def __init__(self, *, llm: Any = None) -> None:
super().__init__()
self.llm = llm
self.system_prompt = "You are a helpful assistant."
# --- Graph Definition ---
def build_graph(self):
"""Wire the execution graph."""
g = self.new_graph()
g.add_node("process", self.process)
g.add_node("generate", self.generate)
g.set_entry_point("process")
g.add_edge("process", "generate")
g.set_finish_point("generate")
return g.compile()
# --- Node Methods ---
def process(self, state: AnalyzerState) -> AnalyzerState:
"""Process the input request."""
state.context = [f"Processed: {state.request}"]
return state
def generate(
self, state: AnalyzerState,
) -> AnalyzerState:
"""Generate the final output."""
state.output = {
"response": f"Result for: {state.request}",
"agent_type": "analyzer",
}
return state
# --- State Conversion ---
def input_to_state(
self, input_data: dict[str, Any],
) -> AnalyzerState:
return AnalyzerState(
request=input_data.get("request", ""),
)
def state_to_output(
self, state: AnalyzerState,
) -> dict[str, Any]:
return state.output
No LangGraph Required
Class agents use the built-in AgentGraph runtime. Wire your graph in build_graph() using new_graph() โ no need for langgraph or StateGraph.
๐ค Which Template Should I Use?¶
flowchart TD
A["What are you building?"] --> B["Simple API wrapper<br/>or utility?"]
A --> C["Multi-step pipeline?"]
A --> D["Conversational<br/>chatbot?"]
A --> E["Knowledge base<br/>Q&A?"]
A --> F["Autonomous<br/>researcher?"]
A --> G2["Wrap an ML model?"]
A --> H2["Legacy LangGraph<br/>code?"]
B -->|Yes| G["custom"]
C -->|Simple pipeline| H["basic"]
C -->|Need all overrides| I["full"]
D -->|Yes| J["chatbot"]
E -->|Yes| K["rag"]
F -->|Yes| L["deepagent"]
G2 -->|Yes| N["plugin"]
H2 -->|Yes| O["legacy_dict"]
style G fill:#f3e5f5
style H fill:#e8f5e9
style I fill:#e3f2fd
style J fill:#fff3e0
style K fill:#fce4ec
style L fill:#e0f2f1
style N fill:#fbe9e7
style O fill:#f1f8e9
| If you need... | Use template |
|---|---|
| Quick prototype, minimum files | basic |
| Full control over API, schemas, tools | full |
| Document retrieval + answer generation | rag |
| Multi-turn conversation with memory | chatbot |
| Autonomous planning with tools | deepagent |
| No framework dependency, pure Python | custom |
| Legacy functional agent (dict-based) | legacy_dict |
| Wrap a classical ML model | plugin |
๐ Common Files¶
Most agent templates include these common files (component and pipeline templates intentionally have a smaller, purpose-specific layout):
| File | Purpose |
|---|---|
prompts.json |
Two prompt versions (v1 concise, v2 detailed) with system and user templates |
langgraph.json |
LangGraph Studio config (./agent.py:get_graph for class agents, ./graph.py:get_graph for legacy) |
.env.example |
Template for agent-specific env vars (LLM settings, feature flags) |
README.md |
Auto-generated documentation with quick start commands and file reference |
Common prompts.json Content¶
{
"v1": {
"system": "You are a helpful AI assistant. Be concise and accurate.",
"user_template": "{query}"
},
"v2": {
"system": "You are an advanced AI assistant. Provide detailed, well-structured responses with examples when helpful.",
"user_template": "Please help with the following: {query}"
}
}
Common .env.example Content¶
# my_agent agent configuration
# Copy to .env and fill in values
# LLM Settings
MY_AGENT_LLM_PROVIDER=ollama
MY_AGENT_LLM_MODEL=mistral:7b
MY_AGENT_TEMPERATURE=0.1
MY_AGENT_MAX_TOKENS=2048
# Feature Flags
MY_AGENT_ENABLE_MEMORY=true
MY_AGENT_ENABLE_STREAMING=true
๐งช After Scaffolding¶
Once your agent is generated, start the platform and test:
# Start the platform
agentomatic run
# Test your agent
curl -X POST http://localhost:8000/api/v1/my_agent/invoke \
-H "Content-Type: application/json" \
-d '{"query": "Hello, world!"}'
# Check health
curl http://localhost:8000/api/v1/my_agent/health
# View in Swagger docs
open http://localhost:8000/docs