Topology — independent_analysis → weighted_synthesis (chair).
Members analyse the input in parallel; the chair synthesizes with per-member weights surfaced in its prompt input. Weights are pulled from (in order):
- Static
:weightopt declared on the member tuple :confidencefield on the member's%MemberResult{}(populated byCouncilEx.Confidencewhen the member sets:confidence)- Equal weight as fallback
Weights are normalized to sum to 1.0 across :ok members. The chair
receives the digest of each prior round with :weight and
:confidence attached per member, so chair prompts can prioritize
high-weight contributions.
Inspired by Wu et al. Council Mode (arXiv:2604.02923) — the paper's "Consensus Engine" that weights agent contributions by reliability metrics rather than equal-weight or majority vote.
Usage
council =
CouncilEx.Councils.WeightedConsensus.new(
as: MyApp.WeightedPanel,
members: [
{:expert, MyApp.Members.Expert,
[provider: :openai, model: "gpt-4o", weight: 0.6]},
{:generalist, MyApp.Members.Gen,
[provider: :openai, model: "gpt-4o-mini", weight: 0.4]}
],
chair: {MyApp.Members.Synth, [provider: :openai, model: "gpt-4o"]}
)
CouncilEx.run(council, %{topic: "..."})With member self-reported confidence
Omit :weight and let confidence drive the weighting:
members: [
{:a, MyApp.A, [provider: :openai, model: "gpt-4o-mini", confidence: :self_report]},
{:b, MyApp.B, [provider: :openai, model: "gpt-4o-mini", confidence: :self_report]}
]Each member self-rates and the synthesis round normalizes those into weights.
Summary
Functions
Build the WeightedConsensus topology as a generated council module.
Opts
:expose_confidence(boolean, defaulttrue) — forwarded toRounds.WeightedSynthesis. See its moduledoc for the Wu 2025 conformity-mitigation rationale.
@spec new_dynamic(keyword()) :: CouncilEx.DynamicCouncil.t()
Build the same WeightedConsensus topology as new/1 but as a
data-only %CouncilEx.DynamicCouncil{}.