Complete reference for configuring ROMA-DSPy agents, profiles, toolkits, and runtime settings.
- Overview
- Configuration System
- Profiles
- Agents Configuration
- Task-Aware Agent Mapping
- Toolkit Configuration
- LLM Configuration
- Runtime Settings
- Storage Configuration
- Observability (MLflow)
- Resilience Settings
- Logging Configuration
- Environment Variables
- Custom Prompts and Demos
- Configuration Examples
- Best Practices
ROMA-DSPy uses a layered configuration system combining:
- OmegaConf: Flexible YAML configuration with interpolation
- Pydantic: Type-safe validation and defaults
- Profiles: Pre-configured setups for different use cases
- Environment Variables: Runtime overrides
- Hierarchical Merging: Combine defaults, profiles, and overrides
- Type Validation: Catch configuration errors early
- Environment Interpolation:
${oc.env:API_KEY}for secrets - Profile System: Pre-configured agents for different domains
- Task-Aware Mapping: Different executors for different task types
Configuration is loaded and merged in this order:
- Pydantic Defaults - Base defaults from schema classes
- YAML Config - Explicit configuration file
- Profile - Profile overlay (if specified)
- CLI/Runtime Overrides - Command-line arguments
- Environment Variables -
ROMA__*variables - Validation - Final validation via Pydantic
Later layers override earlier ones.
# Use a profile
uv run python -m roma_dspy.cli solve "task" --profile crypto_agent
# Use custom config file
uv run python -m roma_dspy.cli solve "task" --config config/examples/basic/minimal.yaml
# With overrides
uv run python -m roma_dspy.cli solve "task" \
--profile general \
--override agents.executor.llm.temperature=0.5# Use profile
just solve "task" crypto_agent
# With all parameters
just solve "task" general 2 true json
# Parameters: <task> [profile] [max_depth] [verbose] [output]curl -X POST http://localhost:8000/api/v1/executions \
-H "Content-Type: application/json" \
-d '{
"goal": "Your task",
"config_profile": "general",
"max_depth": 2
}'from roma_dspy.config.manager import ConfigManager
# Load profile
config_mgr = ConfigManager()
config = config_mgr.load_config(profile="general")
# Load custom config
config = config_mgr.load_config(
config_path="config/custom.yaml",
overrides=["runtime.max_depth=2"]
)
# With environment prefix
config = config_mgr.load_config(
profile="crypto_agent",
env_prefix="ROMA_"
)Profiles are pre-configured agent setups for different use cases. Located in config/profiles/.
| Profile | Purpose | Use Cases | Models |
|---|---|---|---|
| general | General-purpose agent | Web research, code execution, file ops, calculations | Gemini Flash + Claude Sonnet 4.5 |
| crypto_agent | Cryptocurrency analysis | Price tracking, DeFi analysis, on-chain data | Task-aware (Gemini Flash / Claude Sonnet 4.5) |
# config/profiles/general.yaml
agents:
atomizer:
llm:
model: openrouter/google/gemini-2.5-flash
temperature: 0.0
max_tokens: 8000
signature_instructions: "prompt_optimization.seed_prompts.atomizer_seed:ATOMIZER_PROMPT"
demos: "prompt_optimization.seed_prompts.atomizer_seed:ATOMIZER_DEMOS"
executor:
llm:
model: openrouter/anthropic/claude-sonnet-4.5
temperature: 0.2
max_tokens: 32000
prediction_strategy: react
toolkits:
- class_name: E2BToolkit
enabled: true
- class_name: FileToolkit
enabled: true
runtime:
max_depth: 6
enable_logging: trueCreate config/profiles/my_profile.yaml:
agents:
executor:
llm:
model: openrouter/anthropic/claude-sonnet-4.5
temperature: 0.3
max_tokens: 16000
prediction_strategy: react
toolkits:
- class_name: MCPToolkit
enabled: true
toolkit_config:
server_name: my_server
server_type: http
url: https://my-mcp-server.com
runtime:
max_depth: 2 # Recommended: 1-2 for most tasks
timeout: 120
enable_logging: trueUse it:
just solve "task" my_profileROMA-DSPy has 5 core agent modules. Each can be configured independently.
| Agent | Role | Default Strategy | Toolkits |
|---|---|---|---|
| Atomizer | Classifies tasks as atomic or decomposable | chain_of_thought | None |
| Planner | Breaks complex tasks into subtasks | chain_of_thought | None |
| Executor | Executes atomic tasks | react | All toolkits |
| Aggregator | Synthesizes subtask results | chain_of_thought | None |
| Verifier | Validates outputs | chain_of_thought | None |
agents:
executor: # Agent type: atomizer, planner, executor, aggregator, verifier
# LLM configuration
llm:
model: openrouter/anthropic/claude-sonnet-4.5
temperature: 0.2
max_tokens: 32000
timeout: 30
num_retries: 3
cache: true
# Prediction strategy (chain_of_thought or react)
prediction_strategy: react
# Custom prompts (optional)
signature_instructions: "module.path:VARIABLE_NAME"
demos: "module.path:DEMOS_LIST"
# Agent-specific settings
agent_config:
max_executions: 10 # Max iterations for executor
# max_subtasks: 12 # Max subtasks for planner
# Strategy-specific settings
strategy_config:
# ReAct-specific settings
# Toolkits (executor only)
toolkits:
- class_name: E2BToolkit
enabled: true
toolkit_config:
timeout: 600Each agent has sensible defaults. Override only what you need:
# Minimal executor override
agents:
executor:
llm:
temperature: 0.3 # Override just temperature
# All other settings use defaultsatomizer:
agent_config:
confidence_threshold: 0.8 # Threshold for atomic classificationplanner:
agent_config:
max_subtasks: 12 # Maximum subtasks to generateexecutor:
agent_config:
max_executions: 10 # Maximum ReAct iterationsaggregator:
agent_config:
synthesis_strategy: hierarchical # How to aggregate resultsverifier:
agent_config:
verification_depth: moderate # Verification thoroughnessAdvanced Feature: Use different executor configurations for different task types.
ROMA-DSPy classifies tasks into 5 types:
| Task Type | Description | Example Tasks |
|---|---|---|
| RETRIEVE | Data fetching, web search | "price of bitcoin", "find documentation" |
| CODE_INTERPRET | Code execution, analysis | "run this script", "analyze CSV data" |
| THINK | Deep reasoning, analysis | "compare approaches", "analyze sentiment" |
| WRITE | Content creation | "write report", "create documentation" |
| IMAGE_GENERATION | Image creation | "generate diagram", "create visualization" |
# Default agents (used for atomizer, planner, aggregator, verifier)
agents:
executor:
llm:
model: openrouter/anthropic/claude-sonnet-4.5
prediction_strategy: react
toolkits:
- class_name: FileToolkit
enabled: true
# Task-specific executor configurations
agent_mapping:
executors:
# RETRIEVE: Fast model + web search
RETRIEVE:
llm:
model: openrouter/google/gemini-2.5-flash # Fast & cheap
temperature: 0.0
max_tokens: 16000
prediction_strategy: react
agent_config:
max_executions: 6
toolkits:
- class_name: MCPToolkit
enabled: true
toolkit_config:
server_name: exa
server_type: http
url: https://mcp.exa.ai/mcp
# CODE_INTERPRET: Powerful model + code execution
CODE_INTERPRET:
llm:
model: openrouter/anthropic/claude-sonnet-4.5 # Powerful
temperature: 0.1
max_tokens: 32000
agent_config:
max_executions: 15
toolkits:
- class_name: E2BToolkit
enabled: true
- class_name: FileToolkit
enabled: true- Cost Optimization: Use cheap models for simple tasks
- Quality Optimization: Use powerful models for complex tasks
- Right Tools: Each task type gets appropriate toolkits
- Performance: Faster execution with task-specific configs
The crypto_agent profile uses task-aware mapping:
- RETRIEVE: Gemini Flash (fast, cheap) + CoinGecko/Binance
- CODE_INTERPRET: Claude Sonnet 4.5 (powerful) + E2B + crypto data
- THINK: Claude Sonnet 4.5 + all toolkits
- WRITE: Claude Sonnet 4.5 (creative) + FileToolkit + research
Toolkits provide tools (functions) that agents can use. Configured per-agent.
ROMA-DSPy includes these built-in toolkits:
| Toolkit | Purpose | API Key Required | Config Options |
|---|---|---|---|
| FileToolkit | File I/O operations | ❌ No | enable_delete, max_file_size |
| CalculatorToolkit | Math operations | ❌ No | None |
| E2BToolkit | Code execution sandbox | ✅ Yes | timeout, auto_reinitialize |
| SerperToolkit | Web search | ✅ Yes | num_results, search_type |
| BinanceToolkit | Crypto market data | ❌ No | default_market, enable_analysis |
| CoinGeckoToolkit | Crypto prices | ❌ No | use_pro_api |
| DefiLlamaToolkit | DeFi protocol data | ❌ No | enable_pro_features |
| ArkhamToolkit | Blockchain analytics | ❌ No | enable_analysis |
The MCPToolkit is special - it can connect to any MCP (Model Context Protocol) server, giving you access to thousands of potential tools.
Two Types of MCP Servers:
-
HTTP MCP Servers (Remote)
- Public or private HTTP endpoints
- No installation required
- Examples: CoinGecko MCP, Exa MCP, or any custom HTTP MCP server
-
Stdio MCP Servers (Local)
- Run as local subprocesses
- Typically npm packages or custom scripts
- Examples: Filesystem, GitHub, SQLite, or any npm MCP server
Finding MCP Servers:
- Awesome MCP Servers: https://github.com/wong2/awesome-mcp-servers (hundreds of servers)
- MCP Documentation: https://modelcontextprotocol.io/
- Build your own: Any server implementing MCP protocol
agents:
executor:
toolkits:
# Simple toolkit with no config
- class_name: CalculatorToolkit
enabled: true
# Toolkit with basic config
- class_name: FileToolkit
enabled: true
toolkit_config:
enable_delete: false
max_file_size: 10485760 # 10MB- class_name: E2BToolkit
enabled: true
toolkit_config:
timeout: 600 # Execution timeout (seconds)
max_lifetime_hours: 23.5 # Sandbox lifetime
auto_reinitialize: true # Auto-restart on failureEnvironment Variables:
E2B_API_KEY=your_e2b_api_key
E2B_TEMPLATE_ID=roma-dspy-sandbox # Custom template
STORAGE_BASE_PATH=/opt/sentient # Shared storageConnect to any public HTTP MCP server:
- class_name: MCPToolkit
enabled: true
toolkit_config:
server_name: coingecko_mcp
server_type: http
url: "https://mcp.api.coingecko.com/sse"
use_storage: true # Store large results to Parquet
storage_threshold_kb: 10 # Store if > 10KBConnect to any authenticated HTTP MCP server:
- class_name: MCPToolkit
enabled: true
toolkit_config:
server_name: exa
server_type: http
url: https://mcp.exa.ai/mcp
headers:
Authorization: Bearer ${oc.env:EXA_API_KEY}
# Add any custom headers your MCP server needs
transport_type: streamable
use_storage: false
tool_timeout: 60Connect to any stdio MCP server (npm package or custom script):
- class_name: MCPToolkit
enabled: true
toolkit_config:
server_name: filesystem
server_type: stdio
command: npx # or python, node, etc.
args:
- "-y"
- "@modelcontextprotocol/server-filesystem"
- "/Users/yourname/Documents" # Server-specific arguments
env: # Optional environment variables for the server
CUSTOM_VAR: value
use_storage: falseCommon Stdio Examples:
# GitHub MCP Server
- class_name: MCPToolkit
toolkit_config:
server_name: github
server_type: stdio
command: npx
args:
- "-y"
- "@modelcontextprotocol/server-github"
env:
GITHUB_PERSONAL_ACCESS_TOKEN: ${oc.env:GITHUB_PERSONAL_ACCESS_TOKEN}
# SQLite MCP Server
- class_name: MCPToolkit
toolkit_config:
server_name: sqlite
server_type: stdio
command: npx
args:
- "-y"
- "@modelcontextprotocol/server-sqlite"
- "/path/to/database.db"
# Custom Python MCP Server
- class_name: MCPToolkit
toolkit_config:
server_name: my_custom_server
server_type: stdio
command: python
args:
- "/path/to/my_mcp_server.py"Prerequisites for Stdio Servers:
- npm packages:
npm install -g <package-name> - Custom scripts: Ensure executable and implements MCP protocol
- class_name: BinanceToolkit
enabled: true
include_tools: # Optional: limit to specific tools
- get_current_price
- get_ticker_stats
- get_klines
toolkit_config:
enable_analysis: true
default_market: spot # spot or futures- class_name: DefiLlamaToolkit
enabled: true
include_tools:
- get_protocols
- get_protocol_tvl
- get_chains
toolkit_config:
enable_analysis: true
enable_pro_features: trueLimit which tools from a toolkit are available:
- class_name: MCPToolkit
enabled: true
include_tools: # Only these tools
- get_simple_price
- get_coins_markets
- get_search
toolkit_config:
server_name: coingecko_mcp
server_type: http
url: "https://mcp.api.coingecko.com/sse"Configure language models for each agent.
agents:
executor:
llm:
model: openrouter/anthropic/claude-sonnet-4.5
temperature: 0.2
max_tokens: 32000
timeout: 30
num_retries: 3
cache: true| Parameter | Description | Range | Default |
|---|---|---|---|
| model | Model identifier | Provider-specific | gpt-4o-mini |
| temperature | Randomness (0=deterministic, 2=creative) | 0.0 - 2.0 | 0.7 |
| max_tokens | Maximum output tokens | 1 - 200000 | 2000 |
| timeout | Request timeout (seconds) | > 0 | 30 |
| num_retries | Retry attempts on failure | 0 - 10 | 3 |
| cache | Enable DSPy caching | true/false | true |
| adapter_type | DSPy adapter type | json or chat |
json |
| use_native_function_calling | Enable native tool calling | true/false | true |
ROMA-DSPy uses DSPy adapters to format inputs/outputs for LLMs. Two adapter types are available:
JSONAdapter (default, recommended):
- Uses structured JSON for inputs/outputs
- Better performance for Claude and Gemini models
- Cleaner prompt formatting
ChatAdapter:
- Uses chat message format
- Better performance for some OpenAI models
- More conversational style
Native Function Calling (enabled by default):
- Leverages LLM provider's native tool calling APIs (OpenAI, Anthropic, etc.)
- Automatic fallback to text-based parsing for unsupported models
- No reliability difference, cleaner provider integration
Both parameters have sensible defaults and are optional in configuration:
agents:
executor:
llm:
model: openrouter/anthropic/claude-sonnet-4.5
temperature: 0.2
max_tokens: 16000
# Defaults: adapter_type=json, use_native_function_calling=true
# Uncomment to override:
# adapter_type: chat
# use_native_function_calling: falseSingle API key for all models:
model: openrouter/anthropic/claude-sonnet-4.5
model: openrouter/google/gemini-2.5-flash
model: openrouter/openai/gpt-4oEnvironment: OPENROUTER_API_KEY=your_key
# Anthropic
model: claude-sonnet-4.5
# Requires: ANTHROPIC_API_KEY
# OpenAI
model: gpt-4o
# Requires: OPENAI_API_KEY
# Google
model: gemini-2.5-flash
# Requires: GOOGLE_API_KEY| Temperature | Use Case | Example |
|---|---|---|
| 0.0 | Deterministic, factual | Data retrieval, classification |
| 0.1-0.2 | Slight creativity | Code generation, analysis |
| 0.3-0.5 | Balanced | General tasks, reasoning |
| 0.6-1.0 | Creative | Content writing, brainstorming |
| 1.0+ | Very creative | Poetry, experimental |
Recommended max_tokens by agent:
| Agent | Recommended | Rationale |
|---|---|---|
| Atomizer | 1000-8000 | Simple classification |
| Planner | 4000-32000 | Complex task breakdowns |
| Executor | 16000-32000 | Detailed execution |
| Aggregator | 5000-32000 | Result synthesis |
| Verifier | 3000-16000 | Validation checks |
Pass provider-specific features via the extra_body parameter. This is particularly useful for OpenRouter's advanced features like web search, model routing, and provider preferences.
Security Note: Never include sensitive keys (api_key, secret, token) in extra_body. Use the api_key field instead.
Enable real-time web search for up-to-date information:
agents:
executor:
llm:
model: openrouter/google/gemini-2.5-flash
temperature: 0.0
extra_body:
plugins:
- id: web
engine: exa # Options: "exa", "native", or omit for auto
max_results: 3Alternative: Use the :online suffix for quick setup:
model: openrouter/anthropic/claude-sonnet-4.5:onlineFor OpenRouter's native search engine with customizable context:
extra_body:
plugins:
- id: web
engine: native
web_search_options:
search_context_size: high # Options: "low", "medium", "high"Automatic failover to alternative models:
extra_body:
models:
- anthropic/claude-sonnet-4.5
- openai/gpt-4o
- google/gemini-2.5-pro
route: fallback # Options: "fallback", "lowest-cost", "lowest-latency"Control which providers to use:
extra_body:
provider:
order:
- Anthropic
- OpenAI
data_collection: deny # Privacy control: "allow" or "deny"agents:
executor:
llm:
model: openrouter/anthropic/claude-sonnet-4.5
temperature: 0.2
max_tokens: 16000
extra_body:
# Enable web search with custom settings
plugins:
- id: web
engine: exa
max_results: 5
search_prompt: "Relevant information:"
# Fallback models for reliability
models:
- anthropic/claude-sonnet-4.5
- openai/gpt-4o
route: fallbackDocumentation: See OpenRouter Web Search Docs for all available options.
Cost Warning: Web search plugins may significantly increase API costs per request.
Control execution behavior, timeouts, and logging.
runtime:
max_depth: 6 # Recursion depth (recommended: 1-2)
max_concurrency: 5 # Parallel task limit
timeout: 120 # Global timeout (seconds)
verbose: true # Detailed output
enable_logging: true # Log to file
log_level: INFO # DEBUG, INFO, WARNING, ERROR
# Cache configuration
cache:
enabled: true
enable_disk_cache: true
enable_memory_cache: true
disk_cache_dir: .cache/dspy
disk_size_limit_bytes: 30000000000 # 30GB
memory_max_entries: 1000000| Parameter | Description | Range | Default | Recommended |
|---|---|---|---|---|
| max_depth | Maximum task decomposition depth | 1-20 | 5 | 1-2 |
| max_concurrency | Parallel subtasks | 1-50 | 5 | 5-10 |
| timeout | Global execution timeout (sec) | 1-300 | 30 | 120-300 |
| verbose | Print detailed output | bool | false | true (dev) |
| enable_logging | File logging | bool | false | true |
| log_level | Logging verbosity | DEBUG-CRITICAL | INFO | INFO |
IMPORTANT: Lower max_depth = faster, cheaper, more reliable execution.
| max_depth | Use Case | Trade-offs |
|---|---|---|
| 1 | Simple, atomic tasks | Fast, cheap, limited decomposition |
| 2 | Most production use cases | Recommended - good balance |
| 3-4 | Complex multi-step tasks | Slower, more expensive |
| 5+ | Highly complex hierarchical tasks | Very slow, expensive, may fail |
Best Practice: Start with max_depth=1, increase only if needed.
Configure persistent storage for execution data and tool results.
storage:
base_path: ${oc.env:STORAGE_BASE_PATH,/opt/sentient}
max_file_size: 104857600 # 100MB
# PostgreSQL (execution tracking)
postgres:
enabled: ${oc.env:POSTGRES_ENABLED,true}
connection_url: ${oc.env:DATABASE_URL,postgresql+asyncpg://localhost/roma_dspy}
pool_size: 10
max_overflow: 20# .env
STORAGE_BASE_PATH=/opt/sentient# .env
STORAGE_BASE_PATH=/opt/sentient
ROMA_S3_BUCKET=my-bucket
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your_key
AWS_SECRET_ACCESS_KEY=your_secret# .env
POSTGRES_ENABLED=true
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/roma_dspyOr via docker-compose (automatic):
just docker-up # Starts postgres automaticallyMCP and native toolkits can store large results to Parquet:
toolkits:
- class_name: MCPToolkit
toolkit_config:
use_storage: true
storage_threshold_kb: 10 # Store results > 10KBBenefits:
- Reduces context size
- Enables large dataset handling
- Automatic compression
- Queryable via DuckDB
Track execution metrics, traces, and model performance with MLflow.
observability:
mlflow:
enabled: ${oc.env:MLFLOW_ENABLED,false}
tracking_uri: ${oc.env:MLFLOW_TRACKING_URI,http://mlflow:5000}
experiment_name: ROMA-General-Agent
log_traces: true # Log full execution traces
log_compiles: true # Log DSPy compilations
log_evals: true # Log evaluations# .env
MLFLOW_ENABLED=true
MLFLOW_TRACKING_URI=http://mlflow:5000
MLFLOW_EXPERIMENT=ROMA-DSPy# Via Docker Compose (recommended)
just docker-up-full # Includes MLflow
# Access UI
open http://localhost:5000# Run task with MLflow enabled
MLFLOW_ENABLED=true just solve "analyze bitcoin price"
# View traces in MLflow UI
open http://localhost:5000- Execution metrics: Duration, depth, token usage
- LLM calls: Model, parameters, latency
- Tool usage: Tool calls, results, errors
- Traces: Full execution tree with spans
- Parameters: All config values
- Artifacts: Outputs, logs, checkpoints
Automatic error handling, retries, and recovery.
resilience:
# Retry configuration
retry:
enabled: true
max_attempts: 5
strategy: exponential_backoff
base_delay: 2.0 # Initial delay (seconds)
max_delay: 60.0 # Maximum delay
# Circuit breaker
circuit_breaker:
enabled: true
failure_threshold: 5 # Failures before opening
recovery_timeout: 120.0 # Seconds before retry
half_open_max_calls: 3 # Test calls when recovering
# Checkpointing
checkpoint:
enabled: true
storage_path: ${oc.env:ROMA_CHECKPOINT_PATH,.checkpoints}
max_checkpoints: 20
max_age_hours: 48.0
compress_checkpoints: true
verify_integrity: true| Strategy | Behavior | Use Case |
|---|---|---|
| exponential_backoff | Delay doubles each retry | Most cases (default) |
| fixed_delay | Same delay each retry | Predictable timing |
| random_backoff | Random jitter | Avoid thundering herd |
- Closed: Normal operation
- Open: Failing, reject new requests
- Half-Open: Testing recovery
Automatic recovery from failures:
from roma_dspy.core.engine.solve import solve
# Execution will checkpoint automatically
result = solve("complex task", max_depth=3)
# If interrupted, resume from checkpoint
result = solve("complex task", resume_from_checkpoint=True)Structured logging with loguru.
logging:
level: ${oc.env:LOG_LEVEL,INFO}
log_dir: ${oc.env:LOG_DIR,logs} # null = console only
console_format: detailed # minimal, default, detailed
file_format: json # default, detailed, json
colorize: true
serialize: true # JSON serialization
rotation: 500 MB # File rotation size
retention: 90 days # Keep logs for
compression: zip # Compress rotated logs
backtrace: true # Full tracebacks
diagnose: false # Variable values (disable in prod)
enqueue: true # Thread-safe| Level | Use Case |
|---|---|
| DEBUG | Development, detailed tracing |
| INFO | Production, important events |
| WARNING | Potential issues |
| ERROR | Errors, exceptions |
| CRITICAL | Fatal errors |
# .env
LOG_LEVEL=INFO
LOG_DIR=logs # or null for console only
LOG_CONSOLE_FORMAT=detailed
LOG_FILE_FORMAT=json- minimal: Level + message
- default: Time, level, module, message (colored)
- detailed: Full context with execution_id, line numbers
- default: Standard text format
- detailed: Includes process/thread info
- json: Machine-parseable structured logs
Environment variables override configuration values.
# OpenRouter (recommended - single key for all models)
OPENROUTER_API_KEY=your_key
# Or individual providers
OPENAI_API_KEY=your_key
ANTHROPIC_API_KEY=your_key
GOOGLE_API_KEY=your_key# Code Execution
E2B_API_KEY=your_key
E2B_TEMPLATE_ID=roma-dspy-sandbox
# Web Search
EXA_API_KEY=your_key
SERPER_API_KEY=your_key
# Crypto APIs (all optional, public endpoints work without keys)
COINGECKO_API_KEY=your_key # For Pro API
DEFILLAMA_API_KEY=your_key # For Pro features
ARKHAM_API_KEY=your_key
BINANCE_API_KEY=your_key
BINANCE_API_SECRET=your_secret
# GitHub MCP
GITHUB_PERSONAL_ACCESS_TOKEN=your_token
# Any MCP server may require its own environment variables# Storage
STORAGE_BASE_PATH=/opt/sentient
ROMA_S3_BUCKET=my-bucket
AWS_ACCESS_KEY_ID=your_key
AWS_SECRET_ACCESS_KEY=your_secret
# PostgreSQL
POSTGRES_ENABLED=true
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/roma_dspyMLFLOW_ENABLED=true
MLFLOW_TRACKING_URI=http://mlflow:5000
MLFLOW_EXPERIMENT=ROMA-DSPyUse ROMA__ prefix with double underscores:
# Override agents.executor.llm.temperature
ROMA__AGENTS__EXECUTOR__LLM__TEMPERATURE=0.5
# Override runtime.max_depth
ROMA__RUNTIME__MAX_DEPTH=2Format: ROMA__<path>__<to>__<setting>=value
In docker-compose, set in .env:
# .env
OPENROUTER_API_KEY=your_key
E2B_API_KEY=your_key
POSTGRES_ENABLED=true
MLFLOW_ENABLED=trueThen:
just docker-up # Automatically loads .envEnhance agent performance with optimized prompts and few-shot examples.
Custom instructions guide the agent's behavior.
1. Inline String
agents:
executor:
signature_instructions: "Execute the task step-by-step with clear reasoning."2. Jinja Template File
agents:
executor:
signature_instructions: "config/prompts/executor.jinja"3. Python Module Variable
agents:
executor:
signature_instructions: "prompt_optimization.seed_prompts.executor_seed:EXECUTOR_PROMPT"ROMA-DSPy includes optimized seed prompts in prompt_optimization/seed_prompts/:
| Module | Variable | Purpose |
|---|---|---|
atomizer_seed |
ATOMIZER_PROMPT |
Task classification |
planner_seed |
PLANNER_PROMPT |
Task decomposition |
executor_seed |
EXECUTOR_PROMPT |
General execution |
executor_retrieve_seed |
EXECUTOR_RETRIEVE_PROMPT |
Data retrieval |
executor_code_seed |
EXECUTOR_CODE_PROMPT |
Code execution |
executor_think_seed |
EXECUTOR_THINK_PROMPT |
Deep reasoning |
executor_write_seed |
EXECUTOR_WRITE_PROMPT |
Content creation |
aggregator_seed |
AGGREGATOR_PROMPT |
Result synthesis |
verifier_seed |
VERIFIER_PROMPT |
Output validation |
Provide examples to guide the agent.
agents:
executor:
demos: "prompt_optimization.seed_prompts.executor_seed:EXECUTOR_DEMOS"# my_prompts/executor_demos.py
import dspy
EXECUTOR_DEMOS = [
dspy.Example(
goal="Calculate 15% of 2500",
answer="375"
).with_inputs("goal"),
dspy.Example(
goal="What is the capital of France?",
answer="Paris"
).with_inputs("goal")
]Use in config:
agents:
executor:
demos: "my_prompts.executor_demos:EXECUTOR_DEMOS"Override the default DSPy signature:
agents:
executor:
signature: "goal -> answer: str, confidence: float"Note: Most users don't need this. Use signature_instructions instead.
ROMA-DSPy includes comprehensive configuration examples in config/examples/. These are real, working configurations that demonstrate different concepts and patterns.
| Example | Description | Use It |
|---|---|---|
| minimal.yaml | Simplest possible configuration | just solve "task" -c config/examples/basic/minimal.yaml |
| multi_toolkit.yaml | Multiple toolkits (E2B + File + Calculator) | just solve "task" -c config/examples/basic/multi_toolkit.yaml |
Demonstrates: Fundamentals, toolkit usage, basic configuration patterns
| Example | Description | Use It |
|---|---|---|
| http_public_server.yaml | Public HTTP MCP server (CoinGecko) - no setup | just solve "task" -c config/examples/mcp/http_public_server.yaml |
| stdio_local_server.yaml | Local stdio MCP server via npx | just solve "task" -c config/examples/mcp/stdio_local_server.yaml |
| multi_server.yaml | Multiple MCP servers (HTTP + stdio) | just solve "task" -c config/examples/mcp/multi_server.yaml |
| common_servers.yaml | Common MCP servers (GitHub, Filesystem, SQLite) | just solve "task" -c config/examples/mcp/common_servers.yaml |
Demonstrates: HTTP vs stdio MCP servers, multi-server orchestration, storage configuration
| Example | Description | Use It |
|---|---|---|
| crypto_agent.yaml | Real-world crypto analysis agent | just solve "task" -c config/examples/crypto/crypto_agent.yaml |
Demonstrates: Domain-specific agent, combining MCP + native toolkits, multi-source data aggregation
| Example | Description | Use It |
|---|---|---|
| task_aware_mapping.yaml | Task-specific executor configurations | just solve "task" -c config/examples/advanced/task_aware_mapping.yaml |
| custom_prompts.yaml | Custom prompts and demos | just solve "task" -c config/examples/advanced/custom_prompts.yaml |
Demonstrates: Task-aware agent mapping, cost/quality optimization per task type, loading custom signature instructions and demos
# Use a profile (recommended)
just solve "task" general
# Use an example configuration
just solve "task" -c config/examples/basic/minimal.yaml
# With CLI parameters
uv run python -m roma_dspy.cli solve "task" \
--config config/examples/basic/minimal.yaml \
--override runtime.max_depth=1Each example includes:
- Inline comments explaining each section
- Setup requirements (API keys, npm packages)
- Usage examples showing how to run
- Key learnings about what the example demonstrates
See config/examples/README.md for:
- Complete examples directory structure
- Detailed descriptions of each example
- Setup instructions
- Common issues and solutions
- Tips for success
# Start with minimal config
agents:
executor:
llm:
model: openrouter/anthropic/claude-sonnet-4.5
prediction_strategy: react
toolkits:
- class_name: FileToolkit
enabled: true
runtime:
max_depth: 1 # Start with 1, increase if neededAdd complexity only when needed.
Don't create configs from scratch. Start with a profile:
# Use existing profile
just solve "task" general
# Or copy and customize
cp config/profiles/general.yaml config/profiles/my_profile.yaml
# Edit my_profile.yaml
just solve "task" my_profileNever hardcode API keys in config files:
# ❌ Bad
headers:
Authorization: Bearer sk-1234567890
# ✅ Good
headers:
Authorization: Bearer ${oc.env:EXA_API_KEY}Most tasks need max_depth=1 or 2:
- Start with 1
- Increase to 2 if task needs decomposition
- Only use 3+ for complex hierarchical tasks
- Higher depth = slower + more expensive
Use cheap models for simple tasks:
agent_mapping:
executors:
RETRIEVE:
llm:
model: openrouter/google/gemini-2.5-flash # $0.075/1M tokens
CODE_INTERPRET:
llm:
model: openrouter/anthropic/claude-sonnet-4.5 # $3/1M tokensagents:
executor:
llm:
cache: true # Enable DSPy caching
runtime:
cache:
enabled: true
enable_disk_cache: trueSaves money and improves speed.
toolkits:
- class_name: MCPToolkit
toolkit_config:
use_storage: true
storage_threshold_kb: 10 # Store results > 10KBPrevents context overflow.
observability:
mlflow:
enabled: true
log_traces: trueTrack performance, costs, and errors.
resilience:
retry:
enabled: true
max_attempts: 5
circuit_breaker:
enabled: true
checkpoint:
enabled: trueAutomatic recovery from failures.
from roma_dspy.config.manager import ConfigManager
# Validate before using
try:
config = ConfigManager().load_config(profile="my_profile")
print("✅ Configuration valid")
except ValueError as e:
print(f"❌ Invalid configuration: {e}")- QUICKSTART.md - Get started quickly
- TOOLKITS.md - Complete toolkit reference
- MCP.md - MCP integration guide
- API.md - REST API reference
- DEPLOYMENT.md - Production deployment
- Examples:
config/examples/- Real-world examples
Questions? Check the examples in config/examples/ or create an issue on GitHub.