Skip to main content

Multi-agent debate framework with structured consensus scoring and dissent tracking

Project description

forumkit

The only Python multi-agent framework with a structured debate protocol: fan-out → challenge → rebuttal → consensus scoring.

from forumkit import ForumModeratorBase, ResearcherBase, AgentConfig, AgentRole

class MyAnalyst(ResearcherBase):
    async def analyze(self, data):
        # Independent analysis
        return {"position": "...", "confidence": 0.8}

    async def respond_to_challenge(self, challenge, context):
        # Defend your position
        return "Here's why I disagree..."

class MyForum(ForumModeratorBase):
    def _synthesize(self, analyses, consensus, data):
        # Domain-specific consensus logic
        if consensus.agreement_pct >= 66:
            return "accepted", {"action": "approve"}
        return "conditional", {"action": "review"}

# Run a debate
forum = MyForum(config, researchers=[analyst1, analyst2, analyst3])
result = await forum.run_debate_round({"question": "Is X good?"})

print(f"Consensus: {result.consensus.agreement_pct}% agree")
print(f"Dissent: {result.consensus.strongest_dissent}")
print(f"Anomaly?: {result.consensus.unanimous_anomaly}")  # Detects groupthink

Why forumkit?

The problem: CrewAI, PraisonAI, AutoGen, and others assume agents reach consensus by averaging opinions. In reality, minority views often reveal blind spots.

The solution: forumkit enforces dissent:

  • Every agent analyzes independently
  • Agents actively challenge each other's positions
  • Minority opinions are surfaced, not discarded
  • Suspicious unanimity is flagged (unanimous_anomaly detection)
  • Outcomes are tied to consensus strength, not just majority vote

The result: Better decisions with traceable dissent.

Quick Start

Install

pip install forumkit

5-minute example

import asyncio
from forumkit import ForumModeratorBase, ResearcherBase, AgentConfig, AgentRole, PersonaContext

class Analyst(ResearcherBase):
    async def analyze(self, data):
        # Your LLM call here
        return {
            "persona_id": self.persona.persona_id,
            "position": f"Analysis from {self.persona.name}",
            "confidence": 0.75
        }

    async def respond_to_challenge(self, challenge, context):
        return "I maintain my position because..."

class DebateBoard(ForumModeratorBase):
    def _synthesize(self, analyses, consensus, data):
        synthesis = f"Consensus at {consensus.agreement_pct:.0f}%"
        outcome = "approved" if consensus.agreement_pct >= 50 else "rejected"
        return synthesis, outcome, None

async def main():
    config = AgentConfig(
        agent_id="board-1", team_id=1, role=AgentRole.HEAD,
        model_alias="gpt-4"
    )

    # Create 3 analysts with different personas
    analysts = [
        Analyst(AgentConfig(...), PersonaContext(
            persona_id="p1", name="Optimist", system_prompt="..."
        )),
        # ... more analysts
    ]

    board = DebateBoard(config, analysts)
    result = await board.run_debate_round({"question": "Approve proposal X?"})

    print(f"Outcome: {result.outcome}")
    print(f"Agreement: {result.consensus.agreement_pct}%")
    print(f"Dissent: {result.consensus.dissent_count} voices disagree")
    print(f"Anomaly: {result.consensus.unanimous_anomaly}")

asyncio.run(main())

Concepts

The Forum Protocol

  1. Fan-out — Every analyst independently evaluates the question
  2. Challenge — Analysts see each other's views and attack weak points
  3. Rebuttal — Each analyst responds to challenges
  4. Score — Consensus metrics computed: agreement %, confidence, dissent count
  5. Synthesize — Domain-specific outcome logic applied

Key Types

  • BaseAgent — Foundation for all agents. Role-gated: HEAD can delegate to children, JUNIOR cannot call LLM
  • ResearcherBase — Expert with persona, implements analyze() and respond_to_challenge()
  • ForumModeratorBase — Orchestrates the debate, computes consensus, applies domain logic
  • ConsensusScore — Result includes agreement_pct, dissent_count, unanimous_anomaly (detects suspicious unanimity)

Memory Backends

forumkit supports three memory types:

Backend Use Backend
Working In-session cache Redis (TTL)
Episodic Long-term experience PostgreSQL
Semantic Vector embeddings Qdrant

All are optional. Use the facade:

from forumkit.memory import MemoryManager

memory = MemoryManager(
    redis_url="redis://localhost:6379",
    pg_url="postgresql://localhost/mydb",
    qdrant_url="http://localhost:6333"
)

await memory.initialize()
# Use: memory.working.set(), memory.episodic.store(), memory.semantic.search()

Docs

Testing

pytest tests/unit/ -v
pytest tests/integration/ -v  # Requires Docker (Redis, PostgreSQL)

Security

forumkit includes prompt injection defense:

from forumkit.security import sanitize_for_prompt

clean = sanitize_for_prompt(user_input)
# Applies: NFKC normalize, strip BiDi/control chars, remove injection patterns

Status

v0.1.0 — Alpha. API is stable; docs are being refined. Not yet open source (private beta).

License

MIT

Contact

Issues: GitHub Issues Questions: vinitpai@anthropic.com

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

forumkit-0.1.0.tar.gz (35.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

forumkit-0.1.0-py3-none-any.whl (23.1 kB view details)

Uploaded Python 3

File details

Details for the file forumkit-0.1.0.tar.gz.

File metadata

  • Download URL: forumkit-0.1.0.tar.gz
  • Upload date:
  • Size: 35.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for forumkit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9107a1d9dab1ee9a2bc0e220d9cd0eedeac81a1f812e4fb3c4827fb5102e6ad0
MD5 ff1173c63d9e9b41b928952c76843fe0
BLAKE2b-256 0cd8a22041a78757612b35efb3264efe13ddcd6063fdd36eb9fdf0ba8895a7c4

See more details on using hashes here.

File details

Details for the file forumkit-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: forumkit-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for forumkit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d1f08f782d80d7abb237869bf2b8c10250d34d8b3b3b4b8b18752f89565d3262
MD5 e4c766746be4909689649bf7a766dfee
BLAKE2b-256 59915584213ae0b1d9ad61c042f653568bf93b67114f615e66086aba675b5ce0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page