Agent frameworks

Add a judgement node to a LangGraph, CrewAI or OpenAI Agents SDK agent using the OpenAI-compatible endpoint.

An agent framework runs a loop of model calls and tool calls. Quorum fits in as one tool: a judgement node the agent calls at a decision point. The tool is a plain HTTP call to POST /v1/chat/completions, so the same helper serves every framework below.

All three examples share one helper. Put it in quorum_tool.py.

import os
import requests

URL = "https://www.quorum.dog/v1/chat/completions"
HEADERS = {"Authorization": f"Bearer {os.environ['QUORUM_API_KEY']}"}

def judge(question: str) -> str:
    """Ask a panel of models. Returns the answer and whether the seats agreed."""
    r = requests.post(
        URL,
        headers=HEADERS,
        timeout=300,
        json={
            "model": "QRUM:STAN",
            "messages": [{"role": "user", "content": question}],
        },
    )
    r.raise_for_status()
    body = r.json()
    q = body["quorum"]
    if q.get("replayed"):
        # A replay holds the answer but not the split fields.
        head = "REPLAYED ANSWER, split state not recorded"
    else:
        split = q.get("converged") is False or q.get("remaining_friction") is not None
        head = "SEATS SPLIT" if split else "SEATS AGREE"
        quote = (q.get("contested_passage") or {}).get("quote")
        if quote:
            head += f' (contested: "{quote}")'
    return f"{head} (receipt {q['request_id']})\n{body['choices'][0]['message']['content']}"

Four settings matter here.

Give the agent a rule for when to call it. Convene a panel for judgement calls: a consequential assumption, options close enough that the numbers no longer separate them, a diagnosis you cannot check, a decision you will have to defend, or a "what have I missed" check. Use a single model for lookups, syntax, formatting, conversions, arithmetic and anything you need reproduced word for word.

LangGraph

Wrap the helper as a tool and bind it to the model that drives your graph.

from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from quorum_tool import judge

@tool
def get_panel_opinion(question: str) -> str:
    """Use before a consequential decision: a migration, a refund, a merge.
    Include the full context in the question."""
    return judge(question)

agent = create_react_agent(ChatOpenAI(model="gpt-4o"), [get_panel_opinion])
agent.invoke({"messages": [("user", "Plan the rollback for tonight's schema change.")]})

To make the judgement a fixed node instead of a tool the model chooses, add it to a StateGraph and route on its output. The escalation router has that version.

CrewAI

from crewai import Agent, Task, Crew
from crewai.tools import tool
from quorum_tool import judge

@tool("Panel opinion")
def panel_opinion(question: str) -> str:
    """Ask several independent models before a consequential decision.
    Include the full context in the question."""
    return judge(question)

reviewer = Agent(
    role="Release reviewer",
    goal="Decide whether a change is safe to ship",
    backstory="Checks risky changes against an independent panel.",
    tools=[panel_opinion],
)
task = Task(
    description="Review this change and decide: {change}",
    expected_output="Ship or hold, with the reason. Quote the panel if the seats split.",
    agent=reviewer,
)
Crew(agents=[reviewer], tasks=[task]).kickoff(inputs={"change": "Drop the legacy_orders table."})

OpenAI Agents SDK

from agents import Agent, Runner, function_tool
from quorum_tool import judge

@function_tool
def panel_opinion(question: str) -> str:
    """Ask several independent models before a consequential decision.
    Include the full context in the question."""
    return judge(question)

agent = Agent(
    name="Release agent",
    instructions="Before any irreversible step, call panel_opinion. "
                 "If the seats split, stop and report the disagreement.",
    tools=[panel_opinion],
)
result = Runner.run_sync(agent, "Rotate the production database credentials.")
print(result.final_output)

Frameworks that take a model name

Some frameworks let you point the whole agent at an OpenAI-compatible endpoint. Set the base URL to https://www.quorum.dog/v1 and the model to a ticker such as QRUM:STAN. The endpoint returns a text answer for each request, and every turn bills a deliberation. Keep tool calling on the model that drives your agent and call Quorum as a tool at the decision points: that costs less, and the free estimate call tells you which questions earn it. See Quorum as a pipeline step.

MCP

A framework with an MCP client can use the tools directly instead of the helper: https://www.quorum.dog/mcp with an API key in the Authorization header. The loop is estimate, deliberate, get_receipt, act.

Next