<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alex Chernysh</title>
    <description>The latest articles on DEV Community by Alex Chernysh (@alex_chernysh).</description>
    <link>https://dev.to/alex_chernysh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3867467%2F289c1248-2b35-42b9-a79d-2ee8ce4b0a93.jpeg</url>
      <title>DEV Community: Alex Chernysh</title>
      <link>https://dev.to/alex_chernysh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alex_chernysh"/>
    <language>en</language>
    <item>
      <title>Why I Stopped Using LLMs to Schedule LLMs</title>
      <dc:creator>Alex Chernysh</dc:creator>
      <pubDate>Wed, 08 Apr 2026 12:56:54 +0000</pubDate>
      <link>https://dev.to/alex_chernysh/why-i-stopped-using-llms-to-schedule-llms-4176</link>
      <guid>https://dev.to/alex_chernysh/why-i-stopped-using-llms-to-schedule-llms-4176</guid>
      <description>&lt;p&gt;Last year I had 10 open tickets, a week-long deadline, and three AI coding agents installed on my machine. Claude Code, Codex, Gemini CLI. Each one individually capable of knocking out a task in minutes. Together? Absolute chaos.&lt;/p&gt;

&lt;p&gt;Agent A edits &lt;code&gt;auth.py&lt;/code&gt;. Agent B edits &lt;code&gt;auth.py&lt;/code&gt;. Agent A's changes get silently overwritten. Meanwhile, Agent C decides to "refactor" the test suite and breaks everything. Nobody runs the linter. Nobody checks types. I spend more time mediating conflicts than I would have just writing the code myself.&lt;/p&gt;

&lt;p&gt;So I built an orchestrator. And the single most important design decision I made was: &lt;strong&gt;the orchestrator is not an LLM&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The insight that changed everything
&lt;/h2&gt;

&lt;p&gt;My first attempt used an LLM to coordinate the other LLMs. A "manager" agent would read the backlog, decide what to assign where, check in on progress, re-plan when things failed.&lt;/p&gt;

&lt;p&gt;It was slow. It was expensive. It hallucinated priorities. It forgot what it had already assigned. It spent 40% of total tokens on coordination overhead — not on actual coding.&lt;/p&gt;

&lt;p&gt;Then I had a realization that felt almost too obvious: &lt;strong&gt;scheduling is a solved problem&lt;/strong&gt;. Operating systems have been scheduling concurrent processes since the 1960s. We don't use neural networks for &lt;code&gt;cron&lt;/code&gt;. Why was I using one for task assignment?&lt;/p&gt;

&lt;p&gt;I ripped out the LLM scheduler and replaced it with deterministic Python. The result is &lt;a href="https://github.com/chernistry/bernstein" rel="noopener noreferrer"&gt;Bernstein&lt;/a&gt; — an open-source multi-agent orchestrator that coordinates any CLI coding agent with zero LLM tokens on scheduling decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture: how it actually works
&lt;/h2&gt;

&lt;p&gt;The pipeline is four stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Decompose&lt;/strong&gt; — An LLM (this is the &lt;em&gt;only&lt;/em&gt; place one is used) takes your goal and breaks it into a task graph with roles, owned files, dependencies, and completion signals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spawn&lt;/strong&gt; — Each task gets a fresh CLI agent in an isolated git worktree. Agents work in parallel. Main branch stays untouched.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify&lt;/strong&gt; — A janitor process checks concrete signals: tests pass, files exist, linter clean, types correct. No vibes. No "looks good to me."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merge&lt;/strong&gt; — Verified work lands on main. Failed tasks get retried, routed to a different model, or decomposed further.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Goal → LLM Planner → Task Graph → Orchestrator → Agents (parallel)
                                       ↓
                                   Janitor (verify)
                                       ↓
                                   Git merge → main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The orchestrator is a Python event loop that polls a local task server, matches open tasks to available agents, and manages their lifecycle. It's deterministic, auditable, and reproducible. If you run it twice with the same inputs, you get the same scheduling decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The worktree trick
&lt;/h2&gt;

&lt;p&gt;This is the part that made everything click. Instead of letting agents stomp on the same working tree, each agent gets its own &lt;a href="https://git-scm.com/docs/git-worktree" rel="noopener noreferrer"&gt;git worktree&lt;/a&gt; on a disposable branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Bernstein does this internally for each spawned agent:&lt;/span&gt;
git worktree add .sdd/worktrees/session-abc123 &lt;span class="nt"&gt;-b&lt;/span&gt; agent/session-abc123

&lt;span class="c"&gt;# Agent works in complete isolation...&lt;/span&gt;
&lt;span class="c"&gt;# On success, janitor verifies, then:&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; .sdd/worktrees/session-abc123
git checkout main
git merge agent/session-abc123 &lt;span class="nt"&gt;--no-ff&lt;/span&gt;

&lt;span class="c"&gt;# Cleanup:&lt;/span&gt;
git worktree remove .sdd/worktrees/session-abc123
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; agent/session-abc123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each agent thinks it owns the entire repo. No merge conflicts during work. No file locks. No coordination protocol between agents. When the janitor passes the work, it merges cleanly because tasks have declared file ownership — the orchestrator won't assign overlapping files to concurrent agents.&lt;/p&gt;

&lt;p&gt;The worktrees live under &lt;code&gt;.sdd/worktrees/&lt;/code&gt; (Bernstein's state directory). Expensive directories like &lt;code&gt;node_modules&lt;/code&gt; or &lt;code&gt;.venv&lt;/code&gt; get symlinked from the main tree so you don't pay the setup cost per agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model routing: contextual bandits, not vibes
&lt;/h2&gt;

&lt;p&gt;Not every task needs Opus. Renaming a variable doesn't require a $15/million-token model. But deciding &lt;em&gt;which&lt;/em&gt; model to use per task is genuinely hard to do with static rules.&lt;/p&gt;

&lt;p&gt;Bernstein uses a &lt;a href="https://en.wikipedia.org/wiki/Contextual_bandit" rel="noopener noreferrer"&gt;LinUCB contextual bandit&lt;/a&gt; that learns from outcomes. The feature vector for each task includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complexity tier (low / medium / high)&lt;/li&gt;
&lt;li&gt;Scope (number of files)&lt;/li&gt;
&lt;li&gt;Role (backend, frontend, security, etc.)&lt;/li&gt;
&lt;li&gt;Estimated token budget&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reward signal is &lt;code&gt;quality_score * (1 - normalized_cost)&lt;/code&gt; — it optimizes for the cheapest model that passes the janitor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# From bernstein/core/bandit_router.py (simplified)
&lt;/span&gt;&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TaskContext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;complexity_tier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;   &lt;span class="c1"&gt;# 0=LOW, 1=MEDIUM, 2=HIGH
&lt;/span&gt;    &lt;span class="n"&gt;scope_tier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;        &lt;span class="c1"&gt;# 0=SMALL, 1=MEDIUM, 2=LARGE
&lt;/span&gt;    &lt;span class="n"&gt;priority_norm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;   &lt;span class="c1"&gt;# 0=critical, 1=nice-to-have
&lt;/span&gt;    &lt;span class="n"&gt;file_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;estimated_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;

&lt;span class="c1"&gt;# LinUCB selects from available arms: ["haiku", "sonnet", "opus"]
# High-stakes roles (manager, architect, security) never start at haiku
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During cold start (under 50 completions), it falls back to static cascade routing: haiku for simple stuff, sonnet for medium, opus for hard. After warm-up, the bandit takes over. Policy persists across runs in &lt;code&gt;.sdd/routing/policy.json&lt;/code&gt; so learning accumulates over time.&lt;/p&gt;

&lt;p&gt;In practice, this cuts costs by roughly 23% compared to using the same model for everything, because most tasks are boilerplate that cheap models handle fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it compares to CrewAI, AutoGen, and LangGraph
&lt;/h2&gt;

&lt;p&gt;I keep getting asked this, so here's the honest breakdown:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Bernstein&lt;/th&gt;
&lt;th&gt;CrewAI&lt;/th&gt;
&lt;th&gt;AutoGen&lt;/th&gt;
&lt;th&gt;LangGraph&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scheduling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Deterministic code&lt;/td&gt;
&lt;td&gt;LLM-driven&lt;/td&gt;
&lt;td&gt;LLM-driven&lt;/td&gt;
&lt;td&gt;Graph + LLM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Works with&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Any CLI agent (18+)&lt;/td&gt;
&lt;td&gt;Python SDK classes&lt;/td&gt;
&lt;td&gt;Python agents&lt;/td&gt;
&lt;td&gt;LangChain nodes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Git isolation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Worktrees per agent&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Verification&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Janitor + quality gates&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Conditional edges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent lifetime&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Short (spawn, work, exit)&lt;/td&gt;
&lt;td&gt;Long-running&lt;/td&gt;
&lt;td&gt;Long-running&lt;/td&gt;
&lt;td&gt;Long-running&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;State model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;File-based (.sdd/)&lt;/td&gt;
&lt;td&gt;In-memory&lt;/td&gt;
&lt;td&gt;In-memory&lt;/td&gt;
&lt;td&gt;Checkpointer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The core difference is philosophical. CrewAI, AutoGen, and LangGraph are frameworks — you write agents in their SDK, using their abstractions. Bernstein is infrastructure — it orchestrates CLI agents you already have installed. You don't write Bernstein agents. You point Bernstein at Claude Code or Codex or Gemini CLI (or all three in the same run) and it handles the rest.&lt;/p&gt;

&lt;p&gt;The other frameworks also use LLMs for coordination, which means scheduling decisions are non-deterministic, expensive, and hard to debug. When Bernstein assigns task #47 to Sonnet, you can trace exactly why: the bandit policy selected it based on the task's feature vector, and you can read the policy file to verify. No prompt archaeology required.&lt;/p&gt;

&lt;p&gt;The trade-off is real, though. Bernstein doesn't have agent-to-agent chat, built-in RAG, or a cloud-hosted option. It's a CLI tool for people who want their agents to write code and get out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real results
&lt;/h2&gt;

&lt;p&gt;Here's the part where I tell you Bernstein built itself.&lt;/p&gt;

&lt;p&gt;During a 47-hour development marathon, I had 12 agents running on a single MacBook. The system consumed its own backlog: 737 tickets closed, 826 commits generated, averaging 15.7 tasks per hour. Bernstein's codebase — all 522,000+ lines of it — was largely written by agents that Bernstein orchestrated.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;--evolve&lt;/code&gt; flag takes this further. It analyzes its own metrics (which models failed, which tasks took too long, which prompts produced bad output) and proposes improvements to routing rules and prompt templates. Then agents implement those improvements. It's not AGI. It's a feedback loop.&lt;/p&gt;

&lt;p&gt;Benchmarks against single-agent baseline: &lt;strong&gt;1.78x faster&lt;/strong&gt; on a 12-task test suite, &lt;strong&gt;23% lower cost&lt;/strong&gt; from model routing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What still sucks
&lt;/h2&gt;

&lt;p&gt;I'm not going to pretend this is solved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agents still hallucinate file paths.&lt;/strong&gt; They'll confidently import from modules that don't exist. The janitor catches this, but it means wasted cycles and retries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context windows fill up.&lt;/strong&gt; On large codebases, agents run out of context and start forgetting earlier instructions. Short-lived agents help (fresh context per task), but it's still a fundamental constraint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost adds up.&lt;/strong&gt; 12 parallel agents burning Opus tokens is not cheap. The bandit router helps, budgets help, but if you're not paying attention you can blow through $50 in an afternoon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-trivial setup.&lt;/strong&gt; You need at least one CLI agent installed and authenticated. You need API keys. The &lt;code&gt;bernstein doctor&lt;/code&gt; command catches most config issues, but it's not zero-friction yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Merge conflicts still happen.&lt;/strong&gt; Despite file ownership declarations, agents occasionally touch files they weren't supposed to. The janitor catches regressions, but conflict resolution still needs work.&lt;/p&gt;

&lt;p&gt;This is v1.4, not v10. Lots of rough edges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;bernstein
&lt;span class="nb"&gt;cd &lt;/span&gt;your-project
bernstein init                    &lt;span class="c"&gt;# creates .sdd/ workspace + config&lt;/span&gt;
bernstein &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s2"&gt;"Add rate limiting"&lt;/span&gt;  &lt;span class="c"&gt;# agents spawn, work, verify, merge&lt;/span&gt;
bernstein live                    &lt;span class="c"&gt;# watch progress in the TUI&lt;/span&gt;
bernstein cost                    &lt;span class="c"&gt;# see what you spent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For multi-stage projects, write a YAML plan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# plan.yaml&lt;/span&gt;
&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backend&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;goal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Add&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;rate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;limiting&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;middleware"&lt;/span&gt;
        &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backend&lt;/span&gt;
        &lt;span class="na"&gt;complexity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;medium&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;goal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;integration&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tests&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;rate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;limiter"&lt;/span&gt;
        &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;qa&lt;/span&gt;
        &lt;span class="na"&gt;complexity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;low&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docs&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;goal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Document&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;rate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;limiting&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;API&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;OpenAPI&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;spec"&lt;/span&gt;
        &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docs&lt;/span&gt;
        &lt;span class="na"&gt;complexity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;low&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bernstein run plan.yaml              &lt;span class="c"&gt;# deterministic execution, no LLM planning&lt;/span&gt;
bernstein run &lt;span class="nt"&gt;--dry-run&lt;/span&gt; plan.yaml    &lt;span class="c"&gt;# preview tasks and estimated cost&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works with whatever CLI agents you have installed. Bernstein auto-discovers them. Mix Claude Code for architecture decisions, Gemini CLI for boilerplate, Aider with a local Ollama model for offline work — all in the same run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/chernistry/bernstein" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; — Apache 2.0, PRs welcome.&lt;/p&gt;

&lt;p&gt;If you've been babysitting one agent at a time and wondering why your backlog isn't shrinking, maybe the answer isn't a better agent. Maybe it's a conductor.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;"To achieve great things, two things are needed: a plan and not quite enough time." — Leonard Bernstein&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>python</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
