Skip to content
Playground

Choosing a Stack

Last updated 9 days ago · 1db78aa

↑ Updated 9 days ago

"docs(guides): dual-syntax tabbed code examples across all guide pages" · 1db78aa · 2026-10-02

  • ## Start with a profile
  • ## Default Recommendation
  • ### Cost-first profile
  • ### Quality-first profile

Use this guide to choose a default stack quickly, then tune for cost and reliability.

The fastest way to compose capabilities is a HarnessProfile preset — it sets the default-on capability bundle in one line, and you override individual pieces afterward (later calls win). The declarative equivalent is the profile config key. (HarnessProfile ships in v0.12+; on earlier versions use the explicit .with*() chain below.)

import { createAgent } from "reactive-agents";
const agent = await createAgent({
name: "production-agent",
provider: "anthropic",
profile: "balanced", // memory + RI + verifier + strategy switching
tools: { builtins: true },
});
PresetUse when
HarnessProfile.lean()Latency/cost-sensitive paths or ablations — model only, all default capabilities off.
HarnessProfile.balanced()Most production apps — the full stack (memory + reactive intelligence + verifier + strategy switching). Memory is off in a bare builder as of v0.12; balanced() enables it explicitly.
HarnessProfile.intelligent()You want cross-session compounding learning — balanced + skill persistence.

Override after the preset: .withProfile(HarnessProfile.lean()).withMemory() re-enables just memory (declaratively, profile: "lean" alongside a memory: {} key does the same — explicit keys always win over the preset).

For most production apps, the equivalent explicit chain:

const agent = await createAgent({
name: "production-agent",
provider: "anthropic",
model: "claude-sonnet-4-6",
reasoning: { defaultStrategy: "adaptive" },
tools: { builtins: true },
memory: {},
guardrails: {},
costTracking: {},
observability: { verbosity: "normal" },
});
DecisionStart hereMove when
ProviderAnthropicYou need local/offline (ollama) or existing proxy infra (litellm)
Model tierMid/high capabilityLatency or budget pressure dominates quality
Memory tierTier 1You need semantic similarity retrieval (Tier 2 vectors)
Reasoning strategyAdaptiveWorkload is consistent and you want deterministic behavior
ToolsBuilt-ins onlyYou need external systems via MCP/custom tools
WorkloadStrategy
API automation / deterministic tool workreactive
Long multi-step tasks with explicit plansplan-execute-reflect
Exploration and branching ideastree-of-thought
Self-critique and iterative improvementreflexion
Mixed unknown workloadsadaptive

The .withContextProfile() override is builder-only — it has no declarative config key, so the cost-first tuning knob stays in code:

const agent = await ReactiveAgents.create()
.withName("cost-first-agent")
.withProvider("ollama")
.withModel("qwen3:4b")
.withContextProfile({ tier: "local", toolResultMaxChars: 800 })
.withReasoning({ defaultStrategy: "reactive" })
.withMaxIterations(6)
.build();

Everything else in a quality-first stack is declarative too:

const agent = await createAgent({
name: "quality-first-agent",
provider: "anthropic",
model: "claude-sonnet-4-6",
reasoning: { defaultStrategy: "adaptive" },
memory: { tier: "enhanced" },
verification: {},
execution: { maxIterations: 20 },
});
  • Guardrails + identity + audit
  • Tier 1 memory
  • Adaptive strategy
  • Normal observability
  • Gateway + policies + kill switch
  • Strong budgets and alerts
  • Event subscriptions for suppression/exhaustion events
  • Tools + verification + memory tier 2
  • Plan-execute or reflexion
  • Higher max iterations
  • Turning on all layers before proving need
  • Using tier: "enhanced" memory without an embedding provider configured
  • Long max iterations without budget controls
  • MCP subprocess usage without guaranteed disposal