Files
zeekay 08b0828cc3 docs(lib): add core library documentation
- lib/index.md: Overview of all core utility packages
- lib/async.md: High-performance async I/O with uvloop
- lib/consensus.md: Metastable consensus protocol for multi-agent agreement
- lib/network.md: Agent network orchestration
- lib/aci.md: Agent-Computer Interface for development agents
- lib/repl.md: Interactive REPL with voice and LLM integration
2026-01-05 17:39:35 -08:00

286 lines
8.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# hanzo-consensus
Metastable consensus protocol for multi-agent agreement.
## Installation
```bash
pip install hanzo-consensus
```
## Overview
The metastable consensus protocol enables multiple AI agents to reach agreement through a two-phase process:
1. **Phase I (Sampling)**: Agents propose responses and refine based on peer feedback
2. **Phase II (Finality)**: Agreement threshold determines winner and synthesis
Reference: [github.com/luxfi/consensus](https://github.com/luxfi/consensus)
## Quick Start
```python
from hanzo_consensus import Consensus, run, State, Result
# Define execution function
async def execute(agent_id: str, prompt: str) -> Result:
# Call your LLM here
response = await call_llm(agent_id, prompt)
return Result(
id=agent_id,
output=response,
ok=True,
ms=100 # Response time in ms
)
# Run consensus
state = await run(
prompt="What's the best approach for error handling?",
participants=["gpt-4", "claude-3", "gemini"],
execute=execute,
rounds=3,
k=3,
alpha=0.6,
beta_1=0.5,
beta_2=0.8,
)
print(f"Winner: {state.winner}")
print(f"Finalized: {state.finalized}")
print(f"Synthesis: {state.synthesis}")
```
## Protocol Parameters
| Parameter | Default | Description |
|-----------|---------|-------------|
| `rounds` | 3 | Number of sampling rounds |
| `k` | 3 | Sample size per round |
| `alpha` | 0.6 | Agreement threshold (0-1) |
| `beta_1` | 0.5 | Preference threshold (Phase I) |
| `beta_2` | 0.8 | Decision threshold (Phase II) |
### Parameter Tuning
**Higher `rounds`**: More refinement, better consensus, slower
```python
run(..., rounds=5) # More thorough consensus
```
**Higher `k`**: More peers sampled, broader agreement
```python
run(..., k=5) # Sample more peers per round
```
**Higher `beta_2`**: Stricter finality requirement
```python
run(..., beta_2=0.9) # Require strong agreement
```
## Classes
### Result
Represents a participant's response:
```python
@dataclass
class Result:
id: str # Participant ID
output: str # Response text
ok: bool # Success flag
error: Optional[str] # Error message if failed
ms: int = 0 # Response time (affects luminance)
round: int = 0 # Round number
```
### State
Consensus state throughout the protocol:
```python
@dataclass
class State:
prompt: str # Original query
participants: List[str] # Participant IDs
rounds: int # Total rounds
k: int # Sample size
alpha: float # Agreement threshold
beta_1: float # Preference threshold
beta_2: float # Decision threshold
# State (updated during protocol)
responses: Dict[str, List[str]] # Responses per participant
confidence: Dict[str, float] # Confidence scores
luminance: Dict[str, float] # Performance scores
finalized: bool # Whether consensus reached
winner: Optional[str] # Winning participant
synthesis: Optional[str] # Final synthesized response
```
### Consensus
Main consensus class:
```python
consensus = Consensus(
participants=["agent-1", "agent-2", "agent-3"],
execute=my_execute_fn,
rounds=3,
k=3,
alpha=0.6,
beta_1=0.5,
beta_2=0.8,
)
state = await consensus.run("Your question here")
```
## MCP Mesh Integration
For MCP-based agents, use the MCPMesh:
```python
from hanzo_consensus import MCPMesh, MCPAgent, run_mcp_consensus
# Create MCP agents
agents = [
MCPAgent(id="agent-1", endpoint="http://localhost:8001"),
MCPAgent(id="agent-2", endpoint="http://localhost:8002"),
]
# Create mesh
mesh = MCPMesh(agents)
# Run consensus through MCP
state = await run_mcp_consensus(
mesh=mesh,
prompt="Design an API for user authentication",
rounds=3,
)
```
## Protocol Flow
```
┌─────────────────────────────────────────────────────────────┐
│ PHASE I: SAMPLING │
├─────────────────────────────────────────────────────────────┤
│ Round 0: Initial Proposals │
│ Agent-1 ───► "Use try/except blocks..." │
│ Agent-2 ───► "Implement error types..." │
│ Agent-3 ───► "Use Result types..." │
│ │
│ Round 1-N: Refinement │
│ Sample k peers (weighted by luminance) │
│ Share peer responses as context │
│ Each agent refines response │
│ Update confidence scores │
│ │
│ if max(confidence) >= β₁: proceed to Phase II │
├─────────────────────────────────────────────────────────────┤
│ PHASE II: FINALITY │
├─────────────────────────────────────────────────────────────┤
│ Calculate final scores: confidence × luminance │
│ Winner = agent with highest score │
│ if score >= β₂: finalized = True │
│ Synthesis = winner's final response │
└─────────────────────────────────────────────────────────────┘
```
## Key Concepts
### Luminance
Luminance measures agent performance based on response time:
```python
luminance = 1.0 / (1.0 + response_time_ms / 1000.0)
```
Faster agents get higher luminance, increasing their influence in peer sampling.
### Confidence
Confidence measures agreement with sampled peers:
```python
confidence = previous_confidence * 0.5 + current_agreement * 0.5
```
Agreement is calculated using word overlap (Jaccard similarity).
### Finalization
Consensus is finalized when the winner's combined score exceeds β₂:
```python
score = confidence * luminance
finalized = score >= beta_2
```
## Example: Multi-LLM Consensus
```python
import asyncio
from hanzo_consensus import run, Result
async def call_openai(prompt: str) -> str:
# Your OpenAI API call
...
async def call_anthropic(prompt: str) -> str:
# Your Anthropic API call
...
async def call_google(prompt: str) -> str:
# Your Google API call
...
PROVIDERS = {
"openai": call_openai,
"anthropic": call_anthropic,
"google": call_google,
}
async def execute(agent_id: str, prompt: str) -> Result:
import time
start = time.time()
try:
output = await PROVIDERS[agent_id](prompt)
return Result(
id=agent_id,
output=output,
ok=True,
ms=int((time.time() - start) * 1000),
)
except Exception as e:
return Result(
id=agent_id,
output="",
ok=False,
error=str(e),
)
async def main():
state = await run(
prompt="What's the most efficient way to sort a list in Python?",
participants=list(PROVIDERS.keys()),
execute=execute,
)
print(f"Consensus reached: {state.finalized}")
print(f"Winner: {state.winner}")
print(f"Answer: {state.synthesis}")
asyncio.run(main())
```
## Best Practices
1. **Diverse Participants**: Use different LLM providers for better consensus
2. **Appropriate Rounds**: Start with 3 rounds, increase for complex queries
3. **Tune Thresholds**: Lower β₂ for faster consensus, higher for stricter agreement
4. **Handle Failures**: Always check `result.ok` in your execute function
5. **Monitor Latency**: Response time affects luminance and peer selection