-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
Internal design of rvrb-verify. For users — no need to read this unless contributing or debugging.
src/rvrb_verify/
__init__.py # verify() function, public API
cli.py # Typer CLI entry point
engine.py # VerificationEngine (two-phase pipeline)
models.py # Verdict, Evidence, Source, MediaModality, MediaInput, MediaOutput
provider.py # ModelProvider Protocol, get_provider(), DEFAULT_MODEL
tools.py # ToolGateway, MockToolGateway
mcp.py # MCP server (FastMCP)
strategies/ # Verification strategies
__init__.py # REGISTRY, list_strategies()
fact_check.py
legal.py
research.py
CLI (cli.py)
│
├── verify() function (__init__.py)
│ │
│ ├── Resolves strategy from REGISTRY
│ ├── Resolves search_provider and judge_provider
│ ├── Creates VerificationEngine
│ └── Calls engine.verify()
│ │
│ ├── Search phase
│ │ ├── Build search messages from strategy.search_prompt()
│ │ ├── Call search_provider.complete_with_tools()
│ │ ├── Execute tool calls via tool_gateway
│ │ └── Collect evidence
│ │
│ ├── Judge phase
│ │ ├── Build judge messages from strategy.judge_prompt()
│ │ ├── Call judge_provider.complete_structured()
│ │ └── Parse Verdict from structured output
│ │
│ └── Return Verdict
│
└── Output: text or JSON
Pydantic v2 model. The core output type.
class Verdict(BaseModel):
verdict: VerdictValue
confidence: float
summary: str
evidence: list[Evidence]
sources: list[Source]
model: str
provider: str
tokens_used: int | NoneVerdictValue is an enum: true, false, partially_true, inconclusive.
Two-phase verification pipeline.
class VerificationEngine:
def __init__(
self,
search_provider: ModelProvider,
judge_provider: ModelProvider,
tool_gateway: ToolGateway,
): ...
def verify(self, claim: str, strategy: VerificationStrategy) -> Verdict:
# Phase 1: Search for evidence
# Phase 2: Judge claim based on evidence
...Phase 1 — Search:
- Build messages from
strategy.search_prompt(claim) - Call
search_provider.complete_with_tools(messages, strategy.tools) - Execute tool calls via
tool_gateway.execute() - Collect evidence from tool responses
Phase 2 — Judge:
- Build messages from
strategy.judge_prompt(claim, evidence) - Call
judge_provider.complete_structured(messages, Verdict) - Return parsed
Verdict
Structural Protocol for LLM providers.
class ModelProvider(Protocol):
model: str
base_url: str
def complete(self, messages: list[dict], **kwargs) -> str: ...
def complete_structured(self, messages: list[dict], output_type: type, **kwargs) -> BaseModel: ...
def complete_with_tools(self, messages: list[dict], tools: list[dict], **kwargs) -> ToolResult: ...Abstract interface for tool execution.
class ToolGateway(Protocol):
def execute(self, tool_name: str, arguments: dict) -> str: ...MockToolGateway returns mock data for testing. Implement RealToolGateway for production use.
Base class for verification strategies.
class VerificationStrategy:
name: str
description: str
tools: list[ToolSpec]
model_search: str
model_judge: str
def search_prompt(self, claim: str) -> list[dict]: ...
def judge_prompt(self, claim: str, evidence: list) -> list[dict]: ...Strategies are registered in REGISTRY and looked up by name.
The verification uses a two-phase pipeline for accuracy:
Phase 1 — Search:
- Uses
complete_with_tools()to search for evidence - Tools: web search, news search, statute search, case law search, paper search, arXiv search
- Returns structured evidence with sources
Phase 2 — Judge:
- Uses
complete_structured()to produce aVerdict - Takes claim + evidence as input
- Returns verdict, confidence, summary
This separation allows different models for each phase (e.g., fast model for search, smart model for judge).
| Layer | Error type | Handling |
|---|---|---|
| CLI | ValueError |
Exit 1, message to stderr |
| CLI | Other exceptions | Exit 2, message to stderr |
| Engine | Provider errors | Exception propagates to caller |
| Engine | Tool errors | Logged, search continues with available evidence |
| Package | Purpose |
|---|---|
openai>=2.0.0 |
OpenAI-compatible API client |
pydantic>=2.0 |
Data models (Verdict, Evidence, Source) |
typer>=0.12 |
CLI framework |
| Package | Extra | Purpose |
|---|---|---|
mcp |
[mcp] |
MCP server (FastMCP) |
rvrb-verify does NOT require n3rverberage at runtime. The provider.py module follows the satellite-protocol-v2 pattern with a fallback provider.
rvrb-verify follows satellite-protocol-v2:
-
Mandatory kernel:
__init__.py,models.py,provider.py,engine.py✓ -
No
io.py: Text-only satellite, no file I/O ✓ -
CLI: Typer-based with
--strategy,--json,--model,--provider,--output✓ -
MCP: Gated import,
FastMCP, stdio transport ✓ -
MockProvider: In
tests/conftest.pyfor offline testing ✓
rvrb-verify — Part of the reverberage ecosystem.
Composable MCP-native toolkits for audio, video, and text.
- rvrb-transcriber — Audio/video transcription
- rvrb-verify — Claim verification
- rvrb-transform — Text transformation
- rvrb-hear — Audio comprehension
- rvrb-see — Image understanding
License: Apache-2.0