A multi-agent system for finding and verifying statistics from reputable web sources using Go, built with Google ADK (Agent Development Kit) and Eino.
This project implements a sophisticated multi-agent architecture that leverages LLMs and web search to find verifiable statistics, prioritizing well-known and respected publishers. The system ensures accuracy through automated verification of sources.
The system implements a 4-agent architecture with clear separation of concerns:
Architecture: Built with Google ADK for LLM-based operations. Two orchestration options available: ADK-based (LLM-driven decisions) and Eino-based (deterministic graph workflow). See 4_AGENT_ARCHITECTURE.md for complete details.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User Request β
β "Find climate change statistics" β
βββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ORCHESTRATION AGENT β
β (Port 8000 - Both ADK/Eino) β
β β’ Coordinates 4-agent workflow β
β β’ Manages retry logic β
β β’ Ensures quality standards β
βββββββ¬ββββββββββββββ¬βββββββββββββββββ¬βββββββββββββββββββββ
β β β
βΌ βΌ βΌ
ββββββββββββββ ββββββββββββ βββββββββββββββββββ
β RESEARCH β βSYNTHESIS β β VERIFICATION β
β AGENT β β AGENT β β AGENT β
β Port 8001 β βPort 8004 β β Port 8002 β
β β β β β β
β β’ Search ββββ’ Fetch ββββ’ Re-fetch URLs β
β Serper β β URLs β ββ’ Validate text β
β β’ Filter β ββ’ LLM β ββ’ Check numbers β
β Sources β β Extract β ββ’ Flag errors β
ββββββββββββββ ββββββββββββ βββββββββββββββββββ
β β β
βΌ βΌ βΌ
URLs only Statistics Verified Stats
- No LLM required - Pure search functionality
- Web search via Serper/SerpAPI integration
- Returns URLs with metadata (title, snippet, domain)
- Prioritizes reputable sources (
.gov,.edu, research orgs) - Output: List of
SearchResultobjects - Port: 8001
- LLM-heavy extraction agent
- Built with Google ADK and LLM (Gemini/Claude/OpenAI/Ollama)
- Fetches webpage content from URLs
- Extracts numerical statistics using LLM analysis
- Finds verbatim excerpts containing statistics
- Creates
CandidateStatisticobjects with proper metadata - Port: 8004
- LLM-light validation agent
- Re-fetches source URLs to verify content
- Checks excerpts exist verbatim in source
- Validates numerical values match exactly
- Flags hallucinations and discrepancies
- Returns verification results with pass/fail reasons
- Port: 8002
- Built with Google ADK for LLM-driven workflow decisions
- Coordinates: Research β Synthesis β Verification
- Implements adaptive retry logic
- Dynamic quality control
- Port: 8000
- Deterministic graph-based workflow (no LLM for orchestration)
- Type-safe orchestration with Eino framework
- Predictable, reproducible behavior
- Faster and lower cost
- Workflow: ValidateInput β Research β Synthesis β Verification β QualityCheck β Format
- Port: 8000 (same port as ADK, but they don't run simultaneously)
- Recommended for production use
- β Multi-agent pipeline - Full verification workflow (Research β Synthesis β Verification) β RECOMMENDED
- β Real web search - Google search via Serper/SerpAPI (30 URLs searched by default) π
- β Comprehensive extraction - Processes 15+ pages, reads 30K chars per page for thorough coverage
- β Source verification - Validates excerpts and values match actual web pages
- β Human-in-the-loop retry - Prompts user when partial results found
- β Reputable source prioritization - Government, academic, research organizations
- β
Direct LLM mode - Fast but uses LLM memory (
β οΈ not recommended for statistics) - β
Hybrid mode - LLM discovery + web verification (
β οΈ low verification rate) - β OpenAPI documentation - Interactive Swagger UI for Direct agent (port 8005)
- β Multi-LLM providers - Gemini, Claude, OpenAI, Ollama, xAI Grok via unified interface
- β Google ADK integration - For LLM-based agents
- β Eino framework - Deterministic graph orchestration β Recommended
- β A2A Protocol - Agent-to-Agent interoperability (Google standard) π
- β LLM Observability - OmniObserve integration (Opik, Langfuse, Phoenix) ποΈ
- β Huma v2 - OpenAPI 3.1 docs for Direct agent
- β MCP Server - Integration with Claude Code and other MCP clients
- β Docker deployment - Easy containerized setup π³
The system returns verified statistics in JSON format:
[
{
"name": "Global temperature increase since pre-industrial times",
"value": 1.1,
"unit": "Β°C",
"source": "IPCC Sixth Assessment Report",
"source_url": "https://www.ipcc.ch/...",
"excerpt": "Global surface temperature has increased by approximately 1.1Β°C since pre-industrial times...",
"verified": true,
"date_found": "2025-12-13T10:30:00Z"
}
]- name: Description of the statistic
- value: Numerical value (float32)
- unit: Unit of measurement (e.g., "Β°C", "%", "million", "billion")
- source: Name of source organization/publication
- source_url: URL to the original source
- excerpt: Verbatim quote containing the statistic
- verified: Whether the verification agent confirmed it
- date_found: Timestamp when statistic was found
- Go 1.21 or higher
- LLM API key for your chosen provider:
- Gemini (default): Google API key (set as
GOOGLE_API_KEYorGEMINI_API_KEY) - Claude: Anthropic API key (set as
ANTHROPIC_API_KEYorCLAUDE_API_KEY) - OpenAI: OpenAI API key (set as
OPENAI_API_KEY) - xAI Grok: xAI API key (set as
XAI_API_KEY) - Ollama: Local Ollama installation (default:
http://localhost:11434)
- Gemini (default): Google API key (set as
- Optional: API keys for search provider (Google Search, etc.)
- Clone the repository:
git clone https://github.com/agentplexus/stats-agent.git
cd stats-agent- Install dependencies:
make install
# or
go mod download- Configure environment variables:
# For Gemini (default)
export GOOGLE_API_KEY="your-google-api-key"
# For Claude
export LLM_PROVIDER="claude"
export ANTHROPIC_API_KEY="your-anthropic-api-key"
# For OpenAI
export LLM_PROVIDER="openai"
export OPENAI_API_KEY="your-openai-api-key"
# For xAI Grok
export LLM_PROVIDER="xai"
export XAI_API_KEY="your-xai-api-key"
# For Ollama (local)
export LLM_PROVIDER="ollama"
export OLLAMA_URL="http://localhost:11434"
export LLM_MODEL="llama3:latest"
# Optional: Create .env file
cp .env.example .env
# Edit .env with your API keys- Build the agents:
make buildYou can run the system either with Docker (containerized) or locally. Choose the method that best fits your needs.
| Method | Best For | Command |
|---|---|---|
| Docker π³ | Production, quick start, isolated environment | docker-compose up -d |
| Local π» | Development, debugging, customization | make run-all-eino |
The fastest way to get started:
# Start all agents with Docker Compose
docker-compose up -d
# Test the orchestration endpoint
curl -X POST http://localhost:8000/orchestrate \
-H "Content-Type: application/json" \
-d '{"topic": "climate change", "min_verified_stats": 5}'
# View logs
docker-compose logs -f
# Stop
docker-compose downSee DOCKER.md for complete Docker deployment guide.
make run-all-einomake run-all# Terminal 1: Research Agent (ADK)
make run-research
# Terminal 2: Verification Agent (ADK)
make run-verification
# Terminal 3: Orchestration Agent (choose one)
make run-orchestration # ADK version (LLM-based)
make run-orchestration-eino # Eino version (deterministic, recommended)The CLI supports three modes: Direct LLM search (fast, like ChatGPT), Direct + Verification (hybrid), and Multi-agent verification pipeline (thorough, verified).
Direct mode uses a single LLM call to find statistics from memory - similar to ChatGPT without web search:
# Start direct agent first
make run-direct
# Then query (fast but uses LLM memory)
./bin/stats-agent search "climate change" --directWhy Not Recommended for Statistics:
- β Uses LLM memory - Not real-time web search (training data up to Jan 2025)
- β Outdated URLs - LLM guesses URLs where stats came from
- β Low accuracy - Pages may have moved, changed, or be paywalled
β οΈ 0% verification rate - When combined with--direct-verify, most claims fail
When to Use:
- β General knowledge questions
- β Concept explanations
- β Quick brainstorming (accept unverified data)
For statistics, use Pipeline mode instead (see below)
Combines Direct mode with verification, but suffers from the same LLM memory issues:
# Start both agents
make run-direct-verify
# Then query
./bin/stats-agent search "climate change" --direct --direct-verifyWhy Not Recommended:
- β Low verification rate - Typically 0-30% of LLM claims verify
- β Same LLM memory problem - URLs are guessed, not from real search
β οΈ Slow with poor results - Verification overhead but few verified stats
For reliable statistics, use Pipeline mode instead
For verified, web-scraped statistics (requires agents running):
# Start agents first
make run-all-eino
# Then in another terminal:
# Basic search with verification pipeline
./bin/stats-agent search "climate change"
# Request specific number of verified statistics
./bin/stats-agent search "global warming" --min-stats 15
# Increase candidate search space
./bin/stats-agent search "AI trends" --min-stats 10 --max-candidates 100
# Only reputable sources
./bin/stats-agent search "COVID-19 statistics" --reputable-only
# JSON output only
./bin/stats-agent search "renewable energy" --output json
# Text output only
./bin/stats-agent search "climate data" --output textAdvantages of Multi-Agent Mode:
- β Verified sources - Actually fetches and checks web pages
- π Web search - Finds current statistics from the web
- π― Accuracy - Validates excerpts and values match
- π Human-in-the-loop - Prompts to continue if target not met
stats-agent search <topic> [options]
Options:
-d, --direct Use direct LLM search (fast, like ChatGPT)
--direct-verify Verify LLM claims with verification agent (requires --direct)
-m, --min-stats <n> Minimum statistics to find (default: 10)
-c, --max-candidates <n> Max candidates for pipeline mode (default: 50)
-r, --reputable-only Only use reputable sources
-o, --output <format> Output format: json, text, both (default: both)
--orchestrator-url Override orchestrator URL
-v, --verbose Show verbose debug information
--version Show version informationMode Comparison:
| Mode | Speed | Accuracy | Agents Needed | Client Needs API Key? | Best For |
|---|---|---|---|---|---|
--direct |
β‘β‘β‘ Fastest | Direct agent only | β No | Quick research, brainstorming | |
--direct --direct-verify |
β‘β‘ Fast | β Web-verified | Direct + Verification | β No | Balanced speed + accuracy |
| Pipeline (default) | β‘ Slower | β β Fully verified | All 4 agents | β No | Maximum reliability |
---
### Using with Claude Code (MCP Server)
The system can be used as an MCP server with Claude Code and other MCP clients:
```bash
# Build the MCP server
make build-mcp
# Configure in Claude Code's MCP settings (see MCP_SERVER.md)
See MCP_SERVER.md for detailed setup instructions.
You can also call the agents directly via HTTP (works with both Docker and local deployment):
# Call orchestration agent (port 8000 - supports both ADK and Eino)
curl -X POST http://localhost:8000/orchestrate \
-H "Content-Type: application/json" \
-d '{
"topic": "climate change",
"min_verified_stats": 10,
"max_candidates": 30,
"reputable_only": true
}'| Variable | Description | Default |
|---|---|---|
LLM_PROVIDER |
LLM provider: gemini, claude, openai, xai, ollama |
gemini |
LLM_MODEL |
Model name (provider-specific) | See defaults below |
LLM_API_KEY |
Generic API key (overrides provider-specific) | - |
LLM_BASE_URL |
Base URL for custom endpoints (Ollama, etc.) | - |
Provider-Specific API Keys:
| Variable | Description | Default |
|---|---|---|
GOOGLE_API_KEY / GEMINI_API_KEY |
Google API key for Gemini | Required for Gemini |
ANTHROPIC_API_KEY / CLAUDE_API_KEY |
Anthropic API key for Claude | Required for Claude |
OPENAI_API_KEY |
OpenAI API key | Required for OpenAI |
XAI_API_KEY |
xAI API key for Grok | Required for xAI |
OLLAMA_URL |
Ollama server URL | http://localhost:11434 |
Default Models by Provider:
- Gemini:
gemini-2.5-flash(orgemini-2.5-pro) - Claude:
claude-sonnet-4-20250514(orclaude-opus-4-1-20250805) - OpenAI:
gpt-4o(orgpt-5) - xAI:
grok-4-1-fast-reasoning(orgrok-4-1-fast-non-reasoning) - Ollama:
llama3:8b(ormistral:7b)
See LLM_CONFIGURATION.md for detailed LLM setup.
| Variable | Description | Default |
|---|---|---|
SEARCH_PROVIDER |
Search provider: serper, serpapi |
serper |
SERPER_API_KEY |
Serper API key (get from serper.dev) | Required for real search |
SERPAPI_API_KEY |
SerpAPI key (alternative provider) | Required for SerpAPI |
Note: Without a search API key, the research agent will use mock data. See SEARCH_INTEGRATION.md for setup details.
| Variable | Description | Default |
|---|---|---|
OBSERVABILITY_ENABLED |
Enable LLM observability | false |
OBSERVABILITY_PROVIDER |
Provider: opik, langfuse, phoenix |
opik |
OBSERVABILITY_API_KEY |
API key for the provider | - |
OBSERVABILITY_ENDPOINT |
Custom endpoint (optional) | Provider default |
OBSERVABILITY_PROJECT |
Project name for grouping traces | stats-agent-team |
Supported Providers:
- Comet Opik - LLM tracing and evaluation
- Langfuse - Open-source LLM observability
- Arize Phoenix - ML observability platform
| Variable | Description | Default |
|---|---|---|
RESEARCH_AGENT_URL |
Research agent URL | http://localhost:8001 |
SYNTHESIS_AGENT_URL |
Synthesis agent URL | http://localhost:8004 |
VERIFICATION_AGENT_URL |
Verification agent URL | http://localhost:8002 |
ORCHESTRATOR_URL |
Orchestrator URL (both ADK/Eino) | http://localhost:8000 |
Each agent exposes both HTTP and A2A (Agent-to-Agent) protocol endpoints:
| Agent | HTTP Port | A2A Port | Description |
|---|---|---|---|
| Orchestration (ADK/Eino) β | 8000 | 9000 | Graph-based workflow coordination |
| Research (ADK) | 8001 | 9001 | Web search via Serper/SerpAPI |
| Verification (ADK) | 8002 | 9002 | LLM-based verification |
| Synthesis (ADK) | 8004 | 9004 | LLM-based statistics extraction |
| Direct (Huma) β | 8005 | - | Direct LLM search with OpenAPI docs |
A2A Endpoints per Agent:
GET /.well-known/agent-card.json- Agent discoveryPOST /invoke- JSON-RPC execution
Enable A2A with: A2A_ENABLED=true
stats-agent/
βββ agents/
β βββ direct/ # Direct search agent (Huma + OpenAPI, port 8005) β NEW
β β βββ main.go
β βββ orchestration/ # Orchestration agent (Google ADK, port 8000)
β β βββ main.go
β βββ orchestration-eino/ # Orchestration agent (Eino, port 8000) β
β β βββ main.go
β βββ research/ # Research agent (port 8001)
β β βββ main.go
β βββ synthesis/ # Synthesis agent (Google ADK, port 8004) β
β β βββ main.go
β βββ verification/ # Verification agent (Google ADK, port 8002)
β βββ main.go
βββ pkg/
β βββ config/ # Configuration management
β βββ direct/ # Direct LLM search service
β βββ llm/ # Multi-provider LLM factory (OmniLLM + OmniObserve)
β β βββ adapters/ # OmniLLM adapter for ADK integration
β βββ models/ # Shared data models
β βββ orchestration/ # Orchestration logic
βββ main.go # CLI entry point
βββ Makefile # Build and run commands
βββ go.mod # Go dependencies
βββ .env.example # Environment template
βββ README.md # This file
make buildmake testmake clean- Language: Go 1.21+
- Agent Frameworks:
- Google ADK (Agent Development Kit) - LLM-based agents + A2A protocol β
- Eino - Deterministic graph orchestration β
- LLM Integration:
- OmniLLM - Multi-provider LLM abstraction
- Supports: Gemini, Claude, OpenAI, xAI Grok, Ollama
- Observability:
- OmniObserve - Unified LLM observability
- Supports: Comet Opik, Langfuse, Arize Phoenix
- Protocols:
- HTTP - Custom security, flexibility (ports 800x)
- A2A - Agent-to-Agent interoperability (ports 900x)
- Search:
- OmniSerp - Unified serp API abstraction
- Supports: Serper.dev, SerpAPI
- User Request: User provides a topic via CLI or API
- Orchestration: Orchestrator receives request and initiates workflow
- Research Phase: Research agent searches web for candidate statistics
- Verification Phase: Verification agent validates each candidate
- Quality Control: Orchestrator checks if minimum verified stats met
- Retry Logic: If needed, request more candidates and verify
- Response: Return verified statistics in structured JSON format
The research agent prioritizes these source types:
- Government Agencies: CDC, NIH, Census Bureau, EPA, etc.
- Academic Institutions: Universities, research journals
- Research Organizations: Pew Research, Gallup, McKinsey, etc.
- International Organizations: WHO, UN, World Bank, IMF, etc.
- Respected Media: With proper citations (NYT, WSJ, Economist, etc.)
- Source Unreachable: Marked as failed with reason
- Excerpt Not Found: Verification fails with explanation
- Value Mismatch: Flagged as discrepancy
- Insufficient Results: Automatic retry with more candidates
- Max Retries Exceeded: Returns partial results with warning
See ROADMAP.md for planned features including Perplexity integration, multi-language support, and browser extension.
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
- Built with Google ADK (Agent Development Kit)
- Uses Eino for deterministic orchestration
- Multi-LLM support via OmniLLM
- LLM observability via OmniObserve
- A2A protocol for agent interoperability
- Inspired by multi-agent collaboration frameworks