DiegoVallejo

The Polaris Council: A Live Demo of Layered Agent Debate

aiMulti-Agent Systemstypescriptpolarisdemo

The Polaris Council: A Live Demo of Layered Agent Debate

An interactive policy-debate demo built on the POLARIS multi-agent framework: five biased agents, four layers, and a quality gate that decides when the answer is good enough.

The best way to understand a multi-agent topology is to watch it argue with itself.

I built Polaris Council as a concrete, interactive surface for the POLARIS pipeline. You type a hard policy question, and a council of five deliberately biased agents explores it, challenges it, drafts a recommendation, and a final quality gate decides whether to deliver the answer or send everyone back to work.

It is not a chatbot. It is a transparent reasoning assembly line.

Polaris Council UI showing the five pipeline stages and a generated recommendation
The Polaris Council UI: question input, live stage visualization, and structured recommendation output.

Why a Council?

Single-model reasoning has a hidden cost: every constraint loaded into the same prompt competes for the same attention budget. Ask one model to be creative, rigorous, concise, adversarial, and syntactically perfect all at once, and it will oscillate between those objectives in ways that are hard to predict and harder to debug.

POLARIS rejects that overload. It decomposes reasoning into narrow, topologically isolated agents, each optimized for exactly one cognitive role. The Polaris Council demo makes that decomposition visible.

The demo also answers a question that is hard to test with a single prompt: How do you preserve disagreement without collapsing it into a bland average? Most "multi-perspective" prompts ask one model to simulate several voices. The result is usually a polite consensus in costume. In Polaris Council, the agents are independent instances with conflicting goals and different temperatures. The disagreement is real because the optimization targets are different.

The Pipeline

The demo runs the full four-layer Polaris Creativa pipeline:

Stage Agent(s) Temperature Objective
Diverge Libertarian, Privacy Advocate, Utilitarian, Technologist, Regulator 0.80–0.90 Generate conflicting perspectives on the policy question.
Inquire Inquisitor 0.20 Filter the explorations for logical coherence and factual plausibility.
Synthesize Synthesizer 0.40 Weave surviving fragments into a structured, readable recommendation.
Orchestrate Orchestrator 0.10 Judge whether the draft satisfies the requirement; deliver or rerun.
Polaris Council four-stage pipeline diagram: Diverge, Inquire, Synthesize, Orchestrate
The four-stage Polaris Creativa pipeline. Information flows one way until the Orchestrator decides whether to loop back.

Each layer sees only the output of the previous layer. There is no cross-agent side-channel where the Inquisitor can peek at the prompt given to the Divergent agents. Isolation is what makes the system auditable: if the final draft is wrong, you can inspect the exact chain of messages that produced it.

The Five Personas

The council is intentionally not neutral. Each persona carries a different weighting of values, which forces the debate to surface trade-offs that a single model would normally smooth over.

Persona Bias Typical contribution
Libertarian Anti-regulation Individual autonomy, market dynamics, unintended consequences of state power.
Privacy Advocate Rights-first Surveillance risks, consent, data minimization, marginalized-community impact.
Utilitarian Outcome-focused Net welfare, cost-benefit, population-level effects, efficiency.
Technologist Capability-focused Feasibility, innovation speed, accuracy, engineering trade-offs.
Regulator Stability-focused Public safety, accountability, enforcement, precedents.

These roles are not stereotypes. They are constraints. The Libertarian does not have to disagree with the Privacy Advocate, but if they agree, they must do so from different premises. That difference is what the Inquisitor and Synthesizer have to reconcile.

Under the Hood: Strategy Pattern and Layer Messages

POLARIS agents are layer-blind. The same OpenAIStrategyAgent class can sit in any pipeline layer because its behavior is injected through PromptStrategy and OutputParserStrategy. The pipeline only moves typed LayerMessage<T> objects between layers.

const libertarian = new OpenAIStrategyAgent({
  name: 'Libertarian',
  role: task.roles['RISKY'],
  task,
  promptStrategy: new DivergentPromptStrategy(),
  outputParserStrategy: new DivergentOutputParser(),
  model: 'gpt-4o-mini',
  temperature: 0.9,
});

The DivergentPromptStrategy tells the agent to generate raw, unfiltered exploration. The InquisitorOutputParser enforces a JSON schema so the Inquisitor's verdict is machine-readable. The OrchestratorPromptStrategy injects cumulative token usage into the prompt, so the quality gate is also cost-aware.

When a layer finishes, the pipeline builds a LayerMessage:

{
  sourceLayer: LayerType.DIVERGENT,
  targetLayer: LayerType.INQUISITOR,
  payload: { explorations: [...] },
  metadata: {
    tokenCount: 1840,
    sourceAgentIds: ["libertarian", "privacy-advocate", ...],
    pipelineIteration: 0,
  },
}

That metadata is what lets the UI render a live stage meter and what lets the Orchestrator compute ROI. The payload itself is pure data, not a prompt string. Prompt construction happens inside the receiving agent's injected strategy.

The Decay Loop in Practice

When the Orchestrator decides the draft is not good enough, it triggers the decay loop. The pipeline increments temperature, accumulates the list of identified deficiencies, and reinjects a correction prompt into the Divergent layer. The agents must now address the gaps without repeating the same reasoning.

This is controlled recursion, not a retry loop. The pipeline is bounded by a hard token budget and a maximum iteration count. If it cannot converge in time, it forces delivery with the best draft available rather than spinning forever.

The correction prompt is not generic. It carries the accumulated deficiencies from every prior iteration:

Refinement needed — adjust your approach based on the following feedback.
Iteration 2/3.
Deficiencies to address: [ignored enforcement costs; oversold accuracy claims].
Re-examine the problem from scratch.

On a test run with the question "Should cities ban facial recognition in public spaces?", the Orchestrator was satisfied on the second iteration with an error delta of 0.20 and a clean delivery verdict. Total tokens consumed: approximately 29,000.

What the Runs Look Like

I ran the council against a few canonical policy questions. The results were consistent across prompts:

Question Iterations Verdict Tokens Notes
Should cities ban facial recognition in public spaces? 2 clean delivery ~29,000 Draft balanced safety and civil-liberties trade-offs.
Should platforms be liable for user-generated content? 1 clean delivery ~14,000 Converged quickly on a regulatory framing.
Should society implement a four-day work week? 2 rerun → delivery ~22,000 First draft lacked labor-market specifics; rerun fixed it.

The most useful signal was not the final text. It was the errorDelta and the deficiencies array. Those tell you why the council thinks the answer is not ready yet. That is the information a single-model system usually buries inside its reasoning chain.

What It Reveals

Running the council on real questions surfaces three things that single-prompt systems hide:

  1. Perspective is not additive, it is structural. A libertarian and a privacy advocate can both oppose a policy for entirely different reasons. The pipeline captures both without averaging them away.
  2. Quality gates are cheaper than hallucination cleanup. The Orchestrator's rerun costs a few thousand tokens; a published recommendation based on an undetected error can cost a reputation.
  3. Transparency is a feature, not documentation. Because every stage is a typed LayerMessage, the entire reasoning chain can be logged, replayed, and diffed.

Limitations and Next Steps

The demo is intentionally thin. It does not solve memory across sessions, long-horizon context, or retrieval over a knowledge base. Those are the next layers:

  • Memory: The pipeline currently has no L2/L3 tiered memory. A long council session would have to be summarized and recalled explicitly.
  • Sentinel: POLARIS includes a SentinelAgent for bias and diversity analysis. The demo does not wire it in yet; doing so would surface groupthink warnings in the UI.
  • Multi-provider: The demo uses OpenAI, but POLARIS supports Anthropic and Google agents. A mixed-provider council would make provider-specific failure modes visible.

These are not missing features. They are extension points. The demo is meant to show the pipeline, not to be the final product.

Try It

Clone the repo, add an OpenAI API key, and run:

git clone https://github.com/DiegoVallejoDev/polaris-council.git
cd polaris-council
pnpm install
cp .env.example .env
# add OPENAI_API_KEY
pnpm run dev

The frontend will be at http://localhost:5173 and the API at http://localhost:3000.

The published npm package is polaris-framework, so you do not need to build Polaris from source. The demo is a standalone TypeScript project.

Conclusion

The Polaris Council demo is not the destination. It is a probe into what multi-agent reasoning feels like when the architecture, not the prompt, is doing the heavy lifting.

If the goal is to build AI systems that can be trusted on consequential questions, the first step is to stop asking one model to be the entire committee. Build the committee. Then give it a quality gate, a budget, and a way to explain itself.


Diego Vallejo, July 2026