Configuration
agentfast.yaml, environment variables, and budgets.
One file: agentfast.yaml, in your project root. Every value supports ${VAR} and
${VAR:-default} interpolation, so the same file works across environments without a templating
step.
A complete file
agent: support # support | research | code
sdk: langgraph # langgraph | vanilla | crewai
# | claude_agent_sdk | openai_agents_sdk
model: ${AGENTFAST_MODEL:-claude-sonnet-4-5}
database_url: ${AGENTFAST_DATABASE_URL:-postgresql+asyncpg://agentfast:agentfast@localhost:5432/agentfast}
redis_url: ${AGENTFAST_REDIS_URL:-}
kb_dir: kb
scratchpad_dir: .agentfast/scratchpad
vector_backend: pgvector # pgvector | chroma
api_host: 0.0.0.0
api_port: 8321
api_auth_token: ${AGENTFAST_API_TOKEN:-}
cors_origins: ["http://localhost:3400", "http://localhost:3401"]
budget:
max_iterations: 50
max_tokens: 150000
max_duration_ms: 300000
memory_enabled: true
complexity_classifier: heuristic # off | heuristic | llm
guardrails:
pii_enabled: true
pii_kinds: [email, card, ssn, phone, ip, secret]
safety_enabled: true
injection_action: flag # flag | block | allow
rate_limits:
global: "100/minute"
default_per_tool: "20/minute"
tool_overrides:
refund_request:
risk: high
hitl_mode: suspend # suspend | defer
observability:
otel_endpoint: ${OTEL_ENDPOINT:-}
langsmith:
api_key: ${LANGSMITH_API_KEY:-}
pricing:
claude-sonnet-4-5:
input_per_1m: 3.00
output_per_1m: 15.00
cache_read_per_1m: 0.30
evals:
cases: evals/cases.yaml
thresholds:
containment: 0.8
tool_use: 0.9
grounding: 0.7
mcp_servers: []
mcp_provider:
expose_agent: true
expose_tools: true
auto_approve: false
The keys that matter most
| Key | Default | Why you'd change it |
|---|---|---|
| sdk | langgraph | Switch orchestration. Nothing else changes |
| model | claude-sonnet-4-5 | Any LangChain id — openai:gpt-4o, anthropic:claude-haiku-4-5. scripted-support runs keyless |
| tool_overrides | {} | The most important key here — decides what needs a human |
| api_auth_token | unset | Set it before exposing the API anywhere |
| budget | 50 / 150k / 5min | Sized for a support ticket. Research runs want more |
| complexity_classifier | heuristic | llm for a smarter pre-flight; off for fixed budgets |
| redis_url | unset | Required before scaling past one instance |
Environment variables
| Variable | Overrides |
|---|---|
| ANTHROPIC_API_KEY | Provider credential |
| AGENTFAST_MODEL | model |
| AGENTFAST_DATABASE_URL | database_url |
| AGENTFAST_REDIS_URL | redis_url |
| AGENTFAST_API_TOKEN | api_auth_token |
These work through interpolation in the YAML, so the file stays the single source of truth rather than the env quietly winning.
Budgets are a safety mechanism
Checked at the top of every iteration. Exceeding one ends the run as error with a readable reason
rather than looping until someone notices the bill:
budget:
max_iterations: 50 # hard cap on model calls
max_tokens: 150000 # input + output across the run
max_duration_ms: 300000 # wall clock
A run that survives restarts and also has no budget is a run that can survive restarts forever. Set budgets deliberately — they're the layer that stops a stuck agent becoming an invoice.
Scaling checklist
Before more than one instance:
- Set
redis_url— otherwise rate limits are per-process and effectively N× your intended limit. - Set
api_auth_token. - Narrow
cors_originsto your real front-end origins. - Know that live streaming re-attach is per-worker until the bus is
Redis-backed. Polling
GET /api/runs/{id}works across workers today.