Interactive Quickstart Tutorial

September 20, 2026 · View on GitHub

Get Bernstein running and orchestrating agents in under 10 minutes.

What you'll build: A working multi-agent setup that reads a goal, spawns agents in isolated git worktrees, and merges verified results back to your branch automatically.

What you'll need:

  • Python 3.12 or later
  • Git (any recent version)
  • At least one CLI coding agent (Claude Code, Codex, or Gemini - see Step 2)
  • An API key for your chosen agent

Step 1: Install Bernstein

# Recommended - uv installs into an isolated tool environment
uv tool install bernstein

# Alternatives
pip install bernstein
pipx install bernstein

Verify the install:

bernstein --version

You should see something like:

bernstein, version 3.17.0

If you see "command not found": Make sure your tool bin directory is on $PATH. For uv: export PATH="$HOME/.local/bin:$PATH". For pip: check pip show -f bernstein.


Step 2: Check for CLI agents

Bernstein does not run models directly - it orchestrates CLI coding agents that you install separately. Check which ones are available on your system:

bernstein doctor

Example output:

Check           Category  Status  Detail                   Remediation
adapter:claude  adapter   ✗ FAIL  Binary `claude` not in PATH  Install via the adapter's vendor instructions or remove `claude` from bernstein.yaml
adapter:codex   adapter   ✗ FAIL  Binary `codex` not in PATH   Install via the adapter's vendor instructions or remove `codex` from bernstein.yaml
adapter:gemini  adapter   ✗ FAIL  Binary `gemini` not in PATH  Install via the adapter's vendor instructions or remove `gemini` from bernstein.yaml
adapter:qwen    adapter   ✗ FAIL  Binary `qwen` not in PATH    Install via the adapter's vendor instructions or remove `qwen` from bernstein.yaml
adapter:aider   adapter   ✗ FAIL  Binary `aider` not in PATH   Install via the adapter's vendor instructions or remove `aider` from bernstein.yaml

You need at least one adapter row to turn ✓ (doctor also checks auth, ports, and your .sdd workspace - those stay red until later steps). If none are installed:

# Claude Code (Anthropic)
npm install -g @anthropic-ai/claude-code

# Codex (OpenAI)
npm install -g @openai/codex

# Gemini CLI (Google)
npm install -g @google/gemini-cli

Step 3: Set your API key

Each CLI agent authenticates with its own provider. Bernstein passes the environment through to the agents - set the key for whichever agent you installed:

# Claude Code
export ANTHROPIC_API_KEY="sk-ant-..."

# Codex
export OPENAI_API_KEY="sk-..."

# Gemini
export GEMINI_API_KEY="..."

Add the export to your shell profile (~/.zshrc, ~/.bashrc) so it persists across sessions.


Step 4: Initialize a project

cd to any git repository (or create one) and initialize Bernstein's state directory:

cd your-project        # Must be a git repository
bernstein init

Expected output:

Initialising Bernstein workspace in /path/to/your-project
Created .sdd/config.yaml
Created bernstein.yaml
Created templates/ (default roles & prompts)
Created .gitignore (added .sdd/runtime/)

Done. Next steps:
  1. Edit bernstein.yaml: set a goal
  2. Run bernstein to start the orchestra

This creates:

  • .sdd/ - file-based state (backlog, logs, metrics, signals)
  • bernstein.yaml - project configuration

No git repository? Run git init && git commit --allow-empty -m "init" first. Bernstein requires git for worktree isolation.


Step 5: Run your first orchestration

Give Bernstein a goal:

bernstein -g "Add a hello() function to src/utils.py that returns 'Hello, world!'"

Bernstein will:

  1. Start the task server on port 8052
  2. Break the goal into tasks
  3. Spawn agents in isolated git worktrees
  4. Monitor agent progress via heartbeats
  5. Run quality gates (lint, type-check, tests) on the output
  6. Merge verified results back to your branch

Watch it work in real time:

# In another terminal - live TUI dashboard
bernstein live

# Or a quick status snapshot
bernstein status

bernstein status prints a banner, the task counts, and a Bernstein Agents table with one row per running session (session, role, CLI, model, worker, skills, worker PID, agent PID, runtime), followed by the spend so far.


Step 6: Understand the output

When a task completes, Bernstein merges the changes and shows a summary:

bernstein recap

Example output:

  Metric          Value
  Total tasks     3
  Completed       3
  Failed          0
  Success rate    100.0%

bernstein recap then prints a git diff summary, quality scores, and a per-model cost breakdown below that table. The exact numbers depend on what the run produced.

Inspect a specific task's changes:

bernstein diff <task-id>     # Git diff produced by the agent
bernstein trace <task-id>    # Decision trace (which rules fired, what was approved)
bernstein logs tail -a <task-id>  # Full agent output

Step 7: Run a plan file

For deterministic, repeatable execution, describe your work in a YAML plan file instead of a natural language goal. Create plans/hello.yaml:

name: "Hello Bernstein"
description: "A simple two-stage plan"

stages:
  - name: implementation
    steps:
      - goal: "Create src/greeting.py with a greet(name: str) -> str function that returns 'Hello, {name}!'"
        role: backend
        priority: 1
        files: ["src/greeting.py"]
        complexity: low

  - name: tests
    depends_on: [implementation]    # Waits for implementation stage to finish
    steps:
      - goal: "Write pytest tests for the greet() function in tests/test_greeting.py"
        role: qa
        priority: 2
        files: ["tests/test_greeting.py"]
        complexity: low

Run it:

bernstein run plans/hello.yaml

The tests stage waits for implementation to finish. Bernstein manages the dependency automatically - you do not need to sequence the commands yourself.


Step 8: Check cost and token usage

bernstein cost

Example output:

Model   Tasks  Tokens In  Tokens Out  Cost USD  Cost/Task  Avg Duration
claude  2      3,443      1,102       \$0.0180   \$0.0090    63.0s
TOTAL   2      3,443      1,102       \$0.0180

Set a per-run budget limit in bernstein.yaml:

# Spending cap for the run. Accepts "\$5", 5, or 5.0.
budget: "\$5"

For a hard stop that refuses further agent spawns past the cap, configure a cost envelope with hard_budget_usd (see CONFIG.md).


Step 9: Open the web dashboard

While Bernstein is running, open the dashboard in your browser:

http://127.0.0.1:8052/dashboard

The dashboard shows:

  • Active agents and their current tasks
  • Task queue (open, in progress, completed, failed)
  • Token usage and cost estimate
  • Recent activity timeline
  • Agent logs (live streaming)

Step 10: Stop Bernstein

bernstein stop

This gracefully drains in-progress tasks (30-second timeout by default), then shuts down the task server and all agents.

bernstein stop --force   # Hard kill without draining

What next?

You have a working Bernstein setup. Here are common next steps:

  • Add more adapters: Run bernstein integrations list to see what else is installable
  • Configure model routing: Set role_model_policy in bernstein.yaml to use cheaper models for simple tasks
  • Write a plan file: For real project work, a plan file gives you more control than an inline goal
  • Set up guardrails: Add .bernstein/rules.yaml to control what agents are allowed to do

Useful references:


Troubleshooting

"No agents available"

bernstein doctor    # See which agent CLIs are installed and authenticated

Install at least one:

npm install -g @anthropic-ai/claude-code    # Claude Code
npm install -g @openai/codex               # Codex

"Port 8052 already in use"

Another Bernstein instance is running, or another process has the port:

lsof -i :8052                    # Find what's using the port
BERNSTEIN_PORT=8053 bernstein run # Use a different port

"Task failed: permission denied"

The agent tried to modify a file outside its role's allowed paths. Check which file caused the violation:

bernstein trace <task-id>   # Shows which permission rule fired

To allow it, add the path to the role's allowed paths in bernstein.yaml:

roles:
  backend:
    allowed_paths:
      - "src/**"
      - "config/**"   # Add this

"Agent stalled / no heartbeat"

Bernstein detects stalled agents automatically and retries the task. To check status manually:

bernstein status --mode expert   # Show agent detail, including heartbeats
bernstein agents showcase        # List available agents grouped by role

"bernstein init fails - not a git repository"

git init
git commit --allow-empty -m "init"
bernstein init

API key errors from the agent

Bernstein passes your shell environment to agents unchanged. Verify the key is set:

echo $ANTHROPIC_API_KEY    # Should show your key (not empty)

If it's empty, set it and restart:

export ANTHROPIC_API_KEY="sk-ant-..."
bernstein run