Skip to main content
Multiple reference models consult first — their perspectives fold into context — then a single aggregator model acts with full tool access and produces the final answer.
from praisonaiagents import Agent

agent = Agent(
    name="Research Assistant",
    instructions="Answer with high accuracy.",
    llm={
        "provider": "panel",
        "references": ["gpt-4o", "claude-opus-4-8"],
        "aggregator": "claude-sonnet-5",
    },
)
agent.start("Which SSD is faster, X or Y, and why?")
The user asks a tough question; reference models consult first, then the aggregator answers with tools.

Quick Start

1

Inline descriptor

Pass a dict with provider: "panel" to Agent(llm=...):
from praisonaiagents import Agent

agent = Agent(
    name="Research Assistant",
    instructions="Answer with high accuracy.",
    llm={
        "provider": "panel",
        "references": ["gpt-4o", "claude-opus-4-8"],
        "aggregator": "claude-sonnet-5",
    },
)

agent.start("Compare the performance of NVMe vs SATA SSDs.")
2

Named preset

Register once, reuse by name anywhere:
from praisonaiagents import Agent
from praisonaiagents.llm.panel import register_panel_preset

register_panel_preset("deep", {
    "references": ["gpt-4o", "claude-opus-4-8"],
    "aggregator": "claude-sonnet-5",
})

agent = Agent(
    name="Research Assistant",
    instructions="Answer with high accuracy.",
    llm="panel:deep",
)

agent.start("Compare the performance of NVMe vs SATA SSDs.")

How It Works

PhaseWhat happens
ReferenceEach reference model receives the conversation (tool-free, stripped of system prompt and tool messages) and replies with its perspective
InjectReference guidance is appended to the tail of the latest user turn — not the system prompt — so Anthropic prompt caching on the stable prefix is preserved
AggregateThe aggregator model acts as the real agent: it has full tool access, hooks, session, and memory

Selecting a Model


Configuration Options

OptionTypeDefaultDescription
providerstrMust be "panel"
referenceslist[str]Advisory model names (run first, tool-free)
aggregatorstrThe acting model (gets full agent loop)
enabledboolTrueSet to False to disable the panel without changing the descriptor
reference_temperaturefloat0.0Temperature for reference calls (stable advice)
base_urlstrNoneCustom endpoint forwarded to both aggregator and references
api_keystrNoneAPI key forwarded to both aggregator and references
api_versionstrNoneAPI version forwarded to both aggregator and references
Extra options inside the dict descriptor (base_url, api_key, temperature, api_version, auth) survive both the inline and named-preset paths and reach the aggregator. Explicit Agent(base_url=..., api_key=...) arguments take precedence.

Common Patterns

High-accuracy Q&A

from praisonaiagents import Agent

agent = Agent(
    name="Fact Checker",
    instructions="Be precise and cite sources.",
    llm={
        "provider": "panel",
        "references": ["gpt-4o", "gemini-1.5-pro"],
        "aggregator": "claude-sonnet-5",
    },
)
agent.start("What is the capital of Australia?")

Creative writing with multiple voices

from praisonaiagents import Agent

agent = Agent(
    name="Creative Writer",
    instructions="Blend multiple stylistic voices into one coherent piece.",
    llm={
        "provider": "panel",
        "references": ["gpt-4o", "claude-haiku-3-5"],
        "aggregator": "claude-opus-4-8",
    },
)
agent.start("Write a short story about a robot that discovers music.")

Local + cloud hybrid

from praisonaiagents import Agent

agent = Agent(
    name="Hybrid Assistant",
    instructions="Answer using local context and cloud intelligence.",
    llm={
        "provider": "panel",
        "references": ["ollama/mistral"],
        "aggregator": "gpt-4o",
        "base_url": "http://localhost:11434",
    },
)
agent.start("Summarize the attached document.")

Disable panel temporarily

agent = Agent(
    name="Assistant",
    instructions="Answer helpfully.",
    llm={
        "provider": "panel",
        "references": ["gpt-4o"],
        "aggregator": "claude-sonnet-5",
        "enabled": False,
    },
)

Best Practices

Reference models run tool-free by design. Only the aggregator has tool access. This is intentional: references provide perspective, not actions. Don’t expect tool results from reference calls.
The default reference_temperature=0.0 gives you stable, deterministic advisory perspectives. Raise it only when you want diverse creative suggestions from references.
References and the aggregator cannot themselves be panel descriptors — the SDK raises ValueError on detection. This prevents infinite recursion and makes the call graph explicit.
Reference guidance is injected at the tail of the latest user turn, never in the system prompt. This keeps the stable cached prefix intact so Anthropic prompt caching stays effective.
If a reference model call fails, the SDK logs a warning and replaces the result with "(unavailable: reference call failed)". The aggregator still runs with the available perspectives.

LLM Configuration

Configure LLM providers and endpoints

Failover

Automatic fallback when a model fails

Model Router

Route requests to different models by criteria

Tools

Give agents executable capabilities