Agent Symposia¶
An Agent Symposium is URSA's peer-review collaboration pattern. Instead of asking one coordinator to divide the work, a symposium gives the same problem to multiple participants. Each participant works independently, reviews the submitted writeups, revises its own answer, and then an organizer synthesizes the final report.
The pattern is inspired by a research symposium or review panel: different participants may bring different tools, assumptions, models, and reasoning styles. The goal is not just to get more text. The goal is to make disagreement visible, let participants catch one another's mistakes, and give the final organizer a richer evidence base for synthesis.
Why independence matters¶
A single model can be confidently wrong. It may make an arithmetic mistake, overlook a constraint, hallucinate an unsupported claim, or choose a brittle implementation. A symposium gives you several chances to catch those failures:
- members work independently before seeing each other's answers,
- reviewers critique strengths, weaknesses, missing checks, evidence quality, and reproducibility,
- members revise only their own work after seeing review feedback,
- the organizer compares consensus and disagreement before producing the final answer.
A particularly valuable use of symposia is assigning different LLMs to different members. For example, one participant might use a strong coding model, another a local open model, and another a model from a different provider. Different models make different errors. When their outputs are forced through review and synthesis, one model can catch mistakes another model missed.
This does not make the result automatically correct. It does make the workflow more resilient than asking one model to solve, critique, and bless its own answer in a single pass.
When a symposium is the right shape¶
Use an Agent Symposium when you want:
- independent approaches to the same complex problem,
- critique before final synthesis,
- comparison between tools, models, or methods,
- a nested team to compete or collaborate with an independent solver,
- a final answer that reports consensus, disagreement, uncertainty, and evidence quality.
Use an Agent Team instead when one PI should assign specialist subtasks and produce one integrated answer without independent peer-review rounds.
What happens during a symposium run¶
A symposium run has four phases:
- Independent work. Each member receives the original task and writes a self-contained solution.
- Peer review. Each member receives all submitted writeups, including its own, and writes critical reviews. Review prompts explicitly instruct members not to edit or overwrite reviewed work.
- Revision. Each member revises only its own work using the reviews and what it learned from comparing submissions.
- Synthesis. The organizer receives final writeups and peer reviews, then produces the final symposium report.
Initial work, reviews, and revisions are run asynchronously across members when
using the environment's async implementation. Synchronous callers can still use
invoke(...); async callers should use await ainvoke(...).
Minimal symposium YAML¶
name: example_symposium
group: default
description: >
A symposium where several participants solve, review, revise, and synthesize
a complex technical problem.
revision_rounds: 1
organizer:
name: organizer
role: Final synthesizer and judge of evidence quality
agent: ChatAgent
config:
use_web: false
members:
- name: implementation_path
role: Builds and tests a concrete solution
agent: ExecutionAgent
config:
use_web: false
- name: review_path
role: Looks for hidden assumptions, missing checks, and weak evidence
agent: ChatAgent
config:
use_web: false
The repository also includes an example at
examples/environments/agent_symposium.yaml. That example demonstrates a nested
AgentTeamEnvironment as one symposium member and an independent ExecutionAgent
as another member.
Run a symposium from Python¶
from langchain.chat_models import init_chat_model
from ursa.environments import AgentSymposiumEnvironment
llm = init_chat_model(model="openai:gpt-4o-mini")
symposium = AgentSymposiumEnvironment.from_yaml(
"examples/environments/agent_symposium.yaml",
llm=llm,
)
result = symposium.invoke(
"Compare two solution strategies for this problem and recommend one."
)
print(result["final"])
The returned mapping includes more than the final answer:
task: the normalized task,initial_writeups: each member's first independent answer,review_rounds: the review output from each round,reviews: the latest review round,final_writeups: each member's revised answer,organizer_result: the organizer's raw result,final: best-effort text extracted from the organizer result.
That structure is useful when you want to audit how the final synthesis was made.
Use different LLMs for different members¶
Member-specific model: blocks let symposium members use different model
providers or endpoints. This is one of the main reasons to use a symposium: model
diversity can expose blind spots.
name: multi_model_symposium
group: default
revision_rounds: 1
organizer:
name: organizer
role: Synthesizes consensus, disagreement, and evidence quality
agent: ChatAgent
model:
model: openai:gpt-4o-mini
api_key_env: OPENAI_API_KEY
members:
- name: coding_model
role: Prioritizes implementation, tests, and reproducibility
agent: ExecutionAgent
model:
model: openai:gpt-4o-mini
api_key_env: OPENAI_API_KEY
- name: local_critic
role: Reviews assumptions from an independent local-model perspective
agent: ChatAgent
model:
model: ollama:llama3.1
base_url: http://localhost:11434
- name: alternate_provider
role: Looks for conceptual mistakes and alternative explanations
agent: ChatAgent
model:
model: anthropic:claude-3-5-sonnet-latest
api_key_env: ANTHROPIC_API_KEY
The environment-level llm is still required when you construct the symposium.
Any member without a model: block inherits that default model.
Nested teams as symposium members¶
A symposium member can itself be an AgentTeamEnvironment. This is useful when
you want one participant to be a coordinated team and another participant to be an
independent solver.
members:
- name: team_path
role: Nested team pursuing a coordinated solution
agent: AgentTeamEnvironment
config:
config:
name: nested_solution_team
description: A nested team used as one symposium participant.
pi:
name: pi
role: Nested-team PI
agent: ExecutionAgent
members:
- name: implementer
role: Implements and tests a solution
agent: ExecutionAgent
- name: critic
role: Reviews the nested team's reasoning
agent: ChatAgent
- name: independent_path
role: Independent solver for comparison
agent: ExecutionAgent
The nested config: config: shape is intentional in this implementation: the
outer member's config contains constructor keyword arguments for
AgentTeamEnvironment, and that constructor receives its own team config.
Revision rounds¶
revision_rounds controls how many review-and-revision cycles occur. The
implementation runs at least one round, even if the configured value is less than
one.
Start with one round. Additional rounds can improve difficult work, but they also increase cost and runtime because each round invokes every member for review and revision.
Saving a symposium configuration¶
from ursa.environments import AgentSymposiumConfig, save_symposium_config
config = AgentSymposiumConfig(name="design_review", group="default")
path = save_symposium_config(config)
print(path)
When no path is supplied, URSA writes to:
~/.cache/ursa/<group>/environments/agent_symposia/<name>/symposium.yaml
Practical guidance¶
- Give each member a different reason to exist: implementation, critique, literature review, risk analysis, or an alternative model/provider.
- Ask the organizer to report consensus and disagreement, not just a polished answer.
- Use member-specific model configs when you want different models to catch each other's mistakes.
- Keep artifacts in dedicated workspaces when members can write or run code.
- Inspect
initial_writeups,reviews, andfinal_writeupsfor important decisions; do not rely only on the final synthesis for high-stakes work.