Statistics Agent Team

A multi-agent system for finding and verifying statistics from reputable web sources using Go, built with omniagent-worker, Google ADK (Agent Development Kit), and Eino.
Overview
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.
Architecture
The system implements a worker-based architecture using omniagent-worker with clear separation of concerns:
Architecture: Built with omniagent-worker for worker lifecycle and coordination. Workers implement the Worker interface and are orchestrated by a Coordinator with deterministic graph workflow and AgentOps tracing. See docs/architecture for complete details.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User Request β
β "Find climate change statistics" β
βββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β COORDINATOR β
β (omniagent-worker.Coordinator) β
β β’ Coordinates worker workflow β
β β’ Manages retry logic β
β β’ AgentOps tracing via OpenTelemetry β
βββββββ¬ββββββββββββββ¬βββββββββββββββββ¬βββββββββββββββββββββ
β β β
βΌ βΌ βΌ
ββββββββββββββ ββββββββββββ βββββββββββββββββββ
β RESEARCH β βSYNTHESIS β β VERIFICATION β
β WORKER β β WORKER β β WORKER β
β β β β β β
β β’ Search ββββ’ Fetch ββββ’ Re-fetch URLs β
β Serper β β URLs β ββ’ Validate text β
β β’ Filter β ββ’ LLM β ββ’ Check numbers β
β Sources β β Extract β ββ’ Flag errors β
ββββββββββββββ ββββββββββββ βββββββββββββββββββ
β β β
βΌ βΌ βΌ
URLs only Statistics Verified Stats
Worker Architecture (omniagent-worker)
The system uses omniagent-worker for worker lifecycle, coordination, and observability.
1. Research Worker (workers/research/) - Web Search Only
- No LLM required - Pure search functionality
- Implements
omniagent-worker.Worker interface
- Web search via Serper/SerpAPI integration
- Returns URLs with metadata (title, snippet, domain)
- Prioritizes reputable sources (
.gov, .edu, research orgs)
- Output: List of
SearchResult objects
- LLM-heavy extraction worker
- Implements
omniagent-worker.Worker interface
- Fetches webpage content from URLs
- Extracts numerical statistics using LLM analysis
- Finds verbatim excerpts containing statistics
- Creates
CandidateStatistic objects with proper metadata
3. Verification Worker (workers/verification/) - LLM Validation
- LLM-light validation worker
- Implements
omniagent-worker.Worker interface
- 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
4. Coordinator (coordinator/) - Workflow Orchestration
- Built with
omniagent-worker.Coordinator
- Deterministic graph-based workflow (no LLM for orchestration)
- Coordinates: Research β Synthesis β Verification
- Implements adaptive retry logic
- AgentOps tracing via OpenTelemetry
- Workflow: ValidateInput β Research β Synthesis β Verification β QualityCheck β Format
Features
Core Capabilities
- β
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
Alternative Modes
- β
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)
- β
ClaimsReport format - Export as structured-evaluation ClaimsReport via
?format=claims
- β
Source classification - Authoritative sources (WHO, CDC, NASA, etc.) classified as high reliability
Technical Stack
- β
Multi-LLM providers - Gemini, Claude, OpenAI, Ollama, xAI Grok via unified interface
- β
omniagent-worker - Go-first multi-agent worker framework
- β
Eino framework - Deterministic graph orchestration
- β
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"
}
]
Field Descriptions
- 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
Installation
Prerequisites
- Go 1.21 or higher
- LLM API key for your chosen provider:
- Gemini (default): Google API key (set as
GOOGLE_API_KEY or GEMINI_API_KEY)
- Claude: Anthropic API key (set as
ANTHROPIC_API_KEY or CLAUDE_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)
- Optional: API keys for search provider (Google Search, etc.)
Setup
- Clone the repository:
git clone https://github.com/plexusone/agent-team-stats.git
cd agent-team-stats
- 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 build
Usage
You 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 |
Quick Start with Docker π³
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 down
See DOCKER.md for complete Docker deployment guide.
Local Development Setup
Running the Coordinator
The coordinator runs all workers in-process using omniagent-worker:
# Build and run the coordinator
make build
./bin/stats-coordinator --port 8080
# With AgentOps tracing
./bin/stats-coordinator --port 8080 --agentops-dsn postgres://...
Using the CLI
The CLI supports three modes: Direct LLM search (fast, like ChatGPT), Direct + Verification (hybrid), and Multi-agent verification pipeline (thorough, verified).
Direct Mode (β οΈ Not Recommended for Statistics)
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" --direct
Why 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)
Hybrid Mode (β οΈ Also Not Recommended - Low Verification Rate)
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-verify
Why 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
Multi-Agent Pipeline Mode (Thorough Verification)
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 text
Advantages 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
CLI Options
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 information
Mode Comparison:
| Mode |
Speed |
Accuracy |
Agents Needed |
Client Needs API Key? |
Best For |
--direct |
β‘β‘β‘ Fastest |
β οΈ LLM-claimed |
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.
API Usage
You can call the coordinator via HTTP:
# Call coordinator (default port 8080)
curl -X POST http://localhost:8080/orchestrate \
-H "Content-Type: application/json" \
-d '{
"topic": "climate change",
"min_verified_stats": 10,
"max_candidates": 30,
"reputable_only": true
}'
# Get ClaimsReport format (structured-evaluation compatible)
curl -X POST "http://localhost:8080/orchestrate?format=claims" \
-H "Content-Type: application/json" \
-d '{"topic": "climate change", "min_verified_stats": 5}'
See ClaimsReport Integration for detailed usage.
Configuration
Environment Variables
LLM Configuration
| 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 (or gemini-2.5-pro)
- Claude:
claude-sonnet-4-20250514 (or claude-opus-4-1-20250805)
- OpenAI:
gpt-4o (or gpt-5)
- xAI:
grok-4-1-fast-reasoning (or grok-4-1-fast-non-reasoning)
- Ollama:
llama3:8b (or mistral:7b)
See LLM_CONFIGURATION.md for detailed LLM setup.
Search Configuration
| 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.
Observability Configuration
| 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:
Coordinator Configuration
| Variable |
Description |
Default |
COORDINATOR_PORT |
Coordinator HTTP port |
8080 |
AGENTOPS_DSN |
AgentOps tracing DSN (postgres) |
- |
Deployment Modes
Workers can run in two modes:
| Mode |
Description |
Use Case |
| In-Process (default) |
Workers run within the Coordinator process via Pool |
Development, single-process deployment |
| HTTP Services |
Workers run as separate HTTP services |
Microservices, scaling individual workers |
Default Port (Coordinator): 8080
A2A Protocol Support:
GET /.well-known/agent-card.json - Agent discovery
POST /invoke - JSON-RPC execution
Enable A2A with: A2A_ENABLED=true
Project Structure
agent-team-stats/
βββ workers/ # omniagent-worker based workers
β βββ research/ # Research worker (web search)
β β βββ worker.go
β βββ synthesis/ # Synthesis worker (LLM extraction)
β β βββ worker.go
β βββ verification/ # Verification worker (LLM validation)
β βββ worker.go
βββ coordinator/ # Workflow coordinator
β βββ coordinator.go # omniagent-worker.Coordinator implementation
βββ omniskill/ # OmniAgent skill integration
β βββ stats.go # Skill interface for omniagent
βββ cmd/
β βββ coordinator/ # Coordinator CLI entrypoint
β βββ 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
Development
Building
make build
Running Tests
make test
Cleaning Build Artifacts
make clean
Technology Stack
- Language: Go 1.21+
- Worker Framework:
- Agent Frameworks:
- Google ADK - LLM model interface + A2A protocol
- Eino - Workflow graph primitives
- LLM Integration:
- OmniLLM - Multi-provider LLM abstraction
- Supports: Gemini, Claude, OpenAI, xAI Grok, Ollama
- Observability:
- OmniObserve - Unified LLM observability
- AgentOps tracing via OpenTelemetry
- 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
How It Works
- User Request: User provides a topic via CLI or API
- Coordination: Coordinator receives request and initiates workflow
- Research Phase: Research worker searches web for candidate URLs
- Synthesis Phase: Synthesis worker extracts statistics from URLs
- Verification Phase: Verification worker validates each statistic
- Quality Control: Coordinator checks if minimum verified stats met
- Retry Logic: If needed, request more candidates and verify
- Response: Return verified statistics in structured JSON format
Reputable Sources
The research worker 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.)
Error Handling
- 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
Roadmap
See ROADMAP.md for planned features including Perplexity integration, multi-language support, and browser extension.
Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
Acknowledgments