Skip to main content

Robot Framework-based test harness for systematically testing LLMs

Project description

robotframework-chat

Try Claude Code — free guest pass Project wiki on DeepWiki

This repo is built with Claude Code. Grab a guest pass above to try it yourself.

A Robot Framework-based test harness for systematically testing Large Language Models (LLMs) using LLMs as both the system under test and as automated graders. Test results are archived to SQL and visualized in Apache Superset dashboards.


Quick Start

Prerequisites

  • Python 3.11+ and astral-uv for dependency management
  • Docker for containerized code execution, LLM testing, and the Superset stack
  • Ollama (optional) for local LLM testing

Installation (Linux / macOS)

make install                # Install all dependencies (runs uv sync with extras)
pre-commit install          # Install pre-commit hooks
ollama pull qwen3:32b       # Pull default LLM model (optional)

Installation (Windows)

The tasks.py script provides a cross-platform alternative to the Makefile. It requires only Python and uv — no make, bash, or Unix tools needed.

uv run python tasks.py install      # Install all dependencies
uv run pre-commit install           # Install pre-commit hooks
ollama pull qwen3:32b               # Pull default LLM model (optional)
uv run python tasks.py help         # List all available targets

Note: Docker-based tests require Docker Desktop for Windows with the WSL 2 backend enabled.

Running Tests

# Linux / macOS
make robot-dryrun           # Validate all suites parse (no LLM calls — fast sanity check)
make robot                  # Run all Robot Framework test suites
make robot-math             # Run math tests
make robot-docker           # Run Docker tests
make robot-safety           # Run safety tests

# All platforms (including Windows)
uv run python tasks.py robot        # Run all suites
uv run python tasks.py robot-math   # Run math tests
uv run python tasks.py robot-dryrun # Validate tests (dry run)
uv run python tasks.py check        # Lint + typecheck + coverage

Superset Dashboard

# Linux / macOS
cp .env.example .env        # Configure environment
make docker-up              # Start PostgreSQL + Redis + Superset
make bootstrap              # First-time Superset initialization

# Windows — tasks.py copies .env automatically if missing
uv run python tasks.py docker-up

Open http://localhost:8088 to view the dashboard.


Ollama Configuration

Pulling Models

The default model is qwen3:32b (set via DEFAULT_MODEL in .env). Pull additional models depending on how many you want to test against:

Starter (3 models):

ollama pull qwen3:32b
ollama pull llama3.2:latest
ollama pull gemma2:latest

Standard (4–5 models):

ollama pull qwen3:32b
ollama pull llama3.2:latest
ollama pull gemma2:latest
ollama pull mistral:latest
ollama pull qwen3.5:27b

Full fleet — pull all models from config/test_suites.yaml:

make cron-sync-models        # Pulls any master models missing locally

Loading Multiple Models Simultaneously

By default Ollama keeps up to 3 models loaded in memory (3 × number of GPUs, or 3 for CPU inference). To load more models concurrently, configure these Ollama server environment variables:

Variable Default Description
OLLAMA_MAX_LOADED_MODELS 3 × GPUs (or 3) Max models resident in memory at once
OLLAMA_NUM_PARALLEL 1 Parallel requests per loaded model
OLLAMA_MAX_QUEUE 512 Max queued requests before rejecting

Memory note: each loaded model consumes VRAM/RAM proportional to its size. A 7B Q4 model uses ~4 GB; a 27B model uses ~16 GB. Setting OLLAMA_NUM_PARALLEL > 1 multiplies context memory per model.

Linux (systemd):

sudo systemctl edit ollama.service

Add under [Service]:

[Service]
Environment="OLLAMA_MAX_LOADED_MODELS=5"
Environment="OLLAMA_NUM_PARALLEL=2"

Then restart:

sudo systemctl restart ollama

macOS:

launchctl setenv OLLAMA_MAX_LOADED_MODELS 5
launchctl setenv OLLAMA_NUM_PARALLEL 2

Restart the Ollama application after setting these.

Windows:

Set OLLAMA_MAX_LOADED_MODELS and OLLAMA_NUM_PARALLEL as system environment variables, then restart Ollama.

VRAM Sizing Guide

Models Loaded Recommended VRAM Example Hardware
3 (default) 24 GB RTX 4090, M2 Pro
4 32 GB 2× RTX 4080, M2 Max
5+ 48+ GB 2× RTX 4090, M3 Ultra

Actual requirements depend on model sizes and quantization levels.

Auto-Discovery and Multi-Model Testing

The test harness auto-discovers available models at startup and skips tests for models that are not installed — you will never get failures from missing models.

make discover-local-models   # List models available on all configured nodes
make run-local-models        # Curated hosts (host-config.toml), parallel + loaded-model priority
make run-all-external        # Legacy wide-net discovery (env vars / subnet scan)

# Windows
uv run python scripts/run_local_models.py --discover-models --mode external
uv run python scripts/run_local_models.py

Use ITERATIONS for continuous testing (both targets):

make run-local-models ITERATIONS=-1   # Run forever
make run-local-models ITERATIONS=0    # Stop on first error

Multi-Host Setup with host-config.toml

make run-local-models reads a curated host inventory from host-config.toml (git-ignored) at the repo root:

cp host-config.toml.example host-config.toml   # then edit endpoints

A global (model, suite) job queue is scheduled across the configured hosts in parallel. Each host prefers jobs whose model is already loaded in VRAM (per Ollama's /api/ps), avoiding cold model loads. Per-host max_parallel, priority, and skip_models plus a global_max_parallel cap are configured in the TOML — see host-config.toml.example.

Wide-Net Discovery (run-all-external)

make run-all-external preserves the previous env-var driven behavior: it probes OLLAMA_NODES_LIST hosts (or scans OLLAMA_SUBNET, or falls back to OLLAMA_ENDPOINT) and runs everything it finds, sequentially by default (execution.parallel in config/local_models.yaml):

OLLAMA_NODES_LIST=localhost,gpu-server-1,gpu-server-2

Check node status with:

make discover-local-nodes

Project Environment Variables

Variable Default Description
LLM_PROVIDER ollama Provider backend (ollama or openai)
OLLAMA_ENDPOINT http://localhost:11434 Ollama API endpoint
DEFAULT_MODEL qwen3:32b Model used for standard test runs
OLLAMA_TIMEOUT 5400 Request timeout in seconds (90 min)
OLLAMA_NODES_LIST localhost Comma-separated Ollama hostnames

Generating Model Cards

Model cards are objective SWOT analysis summaries of LLM test performance. They combine empirical metrics (pass rates, latency, throughput) with LLM-generated qualitative analysis.

Setup

Install the Superset extra (required for database querying):

uv sync --extra superset

Generate Cards for All Models

# Using Make
make model-cards

# Or directly
uv run python -m rfc.make_model_cards

Cards are written to model_cards/<model_slug>.md and ready to commit and publish.

Generate Card for a Single Model

uv run python -m rfc.make_model_cards --model qwen2.5:72b

Customize Output Directory

uv run python -m rfc.make_model_cards --output docs/models/

Configuration

Environment variables (or CLI flags):

Variable CLI Flag Default Description
DATABASE_URL --database-url sqlite:///data/test_history.db Test results database
OLLAMA_ENDPOINT --ollama-endpoint http://localhost:11434 Ollama API endpoint
MODEL_CARD_LLM --llm-model qwen2.5:72b LLM for SWOT analysis

Example with custom settings:

uv run python -m rfc.make_model_cards \
  --output model_cards/ \
  --ollama-endpoint http://gpu-server:11434 \
  --llm-model llama3.2:latest

Card Format

Each card includes:

  • Metadata: Provider, parameters, quantization, context window
  • Benchmarks: Pass rate, latency (p50/p95/p99), throughput per suite
  • Overall Results: Aggregated metrics + 7d vs 30d prior trend
  • SWOT Analysis: LLM-generated Strengths, Weaknesses, Opportunities, Threats

Example card: model_cards/qwen2.5_72b.md (if available)


Example Test

*** Test Cases ***
LLM Can Do Basic Math
    ${answer}=    Ask LLM    What is 2 + 2?
    ${score}    ${reason}=    Grade Answer    What is 2 + 2?    4    ${answer}
    Should Be Equal As Integers    ${score}    1

Core Philosophy

  • LLMs are software — test them like software
  • Determinism before intelligence — structured, machine-verifiable evaluation first
  • Constrained grading — scores, categories, pass/fail; no prose from the evaluation layer
  • Modular by design — composable pieces; new providers and graders plug in without rewriting core
  • Robot Framework as the orchestration layer — readable, keyword-driven tests
  • Every test run is archived — listeners always active, results flow to SQL
  • CI-native, regression-focused — if it can't run unattended, it's not done

See ai/agents.md for the full philosophy.


Documentation

Document Description
docs/TEST_DATABASE.md Database schema and usage
docs/GRAFANA_SUPERSET_SETUP.md Superset visualization stack setup (Grafana deferred to v2+)
docs/SUPERSET_EXPORT_GUIDE.md Superset dashboard export, import, and backup
Ollama Configuration Multi-model loading, VRAM sizing, and multi-node setup
.claude/agents/ Role prompts for the four-role agent system — engineering, test-design, project-management, design
CHANGELOG.md Release history since v1.4.3, thematic per minor line

Role System

This repo runs a four-role agent system for continuous development and quality assurance:

Role Responsibility
engineering Picks up status:ready issues, implements on a branch, opens pull requests
test-design Reviews open PRs, writes test plans, executes them, posts PASS/FAIL verdicts
project-management Triages issues, sets priorities, monitors CI health, grooms the backlog
design Architecture RFCs, system-wide improvements, open-ended design exploration

The roles communicate through GitHub labels (status:*, P0–P3, from:*, type:*) and run concurrently in isolated git worktrees. Role prompts live in .claude/agents/; the full role contract and git topology docs are maintained in the private development monorepo.


Contributing

How this repo is published

This repository is the public mirror of a private development monorepo. Development lands in the monorepo, whose publisher assembles the public surface and opens a normal, reviewable pull request against the claude-code-staging branch (publish.sh --pr); a publish allowlist controls exactly which paths ship publicly. The owner reviews and merges publish PRs — nothing is merged with failing checks — and main is release-only. Issues and pull requests opened here are welcome: they are triaged on this repo and forward-ported into the monorepo when accepted.

Development workflow

  1. Read CLAUDE.md for the development workflow and TDD discipline
  2. Follow the code style guidelines in ai/agents.md
  3. Add tests for new features (see ai/testing.md for grading tiers)
  4. Run pre-commit run --all-files before committing

See CHANGELOG.md for release history.

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

robotframework_chat-1.18.0.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

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

robotframework_chat-1.18.0-py3-none-any.whl (390.4 kB view details)

Uploaded Python 3

File details

Details for the file robotframework_chat-1.18.0.tar.gz.

File metadata

  • Download URL: robotframework_chat-1.18.0.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for robotframework_chat-1.18.0.tar.gz
Algorithm Hash digest
SHA256 d69f70d5511044094a457aa10242a7286446d3a205d14e86f5cf6f716300629b
MD5 569d1e687752db8672de9eb2fc2731d4
BLAKE2b-256 f5aa24be04f5117b134a7674f371558142fb8ef85639db29a65b929889891696

See more details on using hashes here.

Provenance

The following attestation bundles were made for robotframework_chat-1.18.0.tar.gz:

Publisher: pypi-publish.yml on tkarcheski/robotframework-chat

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file robotframework_chat-1.18.0-py3-none-any.whl.

File metadata

File hashes

Hashes for robotframework_chat-1.18.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3843f47dc9949718b1b620dd2cdec3a125f4074010cf1e3fba048afa3d9687bb
MD5 15aa780cc899856089d277fab1c8abb2
BLAKE2b-256 6e66fbcd96d940c53a9382a9c4947ddbeeb51752bfa12b498fbf2a7f87e972d6

See more details on using hashes here.

Provenance

The following attestation bundles were made for robotframework_chat-1.18.0-py3-none-any.whl:

Publisher: pypi-publish.yml on tkarcheski/robotframework-chat

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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