Skip to main content

MiniCrit-7B: Adversarial AI Validation for Autonomous Systems

MiniCrit Logo

🛡️ Catch AI reasoning flaws before they become failures

PyPI HuggingFace Tests License MCP

Quick Start • MCP Integration • OpenAI API • LangChain • Training • Benchmarks


🎯 The Problem

Autonomous AI systems fail silently. They produce confident-sounding outputs with hidden flaws—overconfidence, missing risks, logical errors, hallucinations. By the time you notice, it's too late.

Traditional testing catches bugs. MiniCrit catches bad reasoning.

💡 The Solution

MiniCrit is a specialized AI "devil's advocate" that validates reasoning before actions are taken. It integrates with any AI system via MCP (Model Context Protocol) to provide real-time adversarial critique.

Your AI Agent → MiniCrit Validation → Safer Decisions
     ↓                   ↓                    ↓
  "Buy AAPL,         "Overconfidence:      Execute with
   95% confident"     only 2 data points,   reduced size
                      missing earnings       or skip
                      risk"

📊 Results and evaluation status

Read this before relying on any MiniCrit output.

  • The checkpoint published at wmaousley/MiniCrit-7B (Qwen2-7B-Instruct base) is a research checkpoint at 9.8% of planned training and has not been evaluated on held-out benchmarks.
  • Antagon's only measured MiniCrit result (21/21 seeded flaws detected, 0/21 false positives on a 42-item set, greedy decoding) belongs to a different, unpublished adapter on mistralai/Mistral-7B-v0.1. It does not describe this package's default model.
  • Performance figures previously shown here (F1, false-positive rate, latency, Sharpe-ratio and false-signal improvements, live-validation counts, and comparisons with other models) have been withdrawn until they can be republished with the measurement record they came from: model artifact, dataset, decoding settings and method.
  • In responses, confidence is null (not yet produced by the model), valid is null, and severity comes from a keyword heuristic over the critique text (severity_basis: "keyword_heuristic"). See Output Format.

🚀 Quick Start

pip install minicrit
from minicrit import MiniCrit

# Initialize (downloads model automatically)
critic = MiniCrit()

# Validate reasoning
result = critic.validate(
    "Stock will rise because it rose yesterday",
    domain="trading"
)

print(result.valid)      # False
print(result.severity)   # "high" 
print(result.critique)   # "This reasoning exhibits recency bias..."
print(result.flags)      # ["overconfidence", "insufficient_evidence"]

Option 2: CLI

# Single validation
minicrit "Buy AAPL, 95% confident" --domain trading

# From file
minicrit --file rationales.txt --output results.json

# JSON output
minicrit "MACD crossover signals buy" --json

Installation Extras

# Core only
pip install minicrit

# With MCP server support
pip install minicrit[mcp]

# With training utilities
pip install minicrit[training]

# Everything
pip install minicrit[all]

Option 3: Docker

cd docker
docker-compose up -d
curl http://localhost:8000/critique \
  -H "Content-Type: application/json" \
  -d '{"rationale": "Buy signal based on MACD crossover", "domain": "trading"}'

Option 4: MCP (Claude Desktop / Claude Code)

// ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "minicrit": {
      "command": "python3",
      "args": ["/path/to/MiniCrit-7B/src/mcp/server.py"],
      "env": {
        "MINICRIT_ADAPTER": "wmaousley/MiniCrit-7B",
        "MINICRIT_BASE_MODEL": "Qwen/Qwen2-7B-Instruct"
      }
    }
  }
}

Then in Claude: "Use validate_reasoning to check: Buy AAPL, RSI shows oversold"


🔌 MCP Integration

MiniCrit implements the Model Context Protocol (MCP)—the industry standard for AI tool integration, backed by Anthropic, OpenAI, Google, and Microsoft.

Any MCP-compatible AI can call MiniCrit:

┌─────────────────┐         ┌─────────────────┐
│  Claude / GPT   │         │    MiniCrit     │
│  Gemini / etc.  │◄───────►│   MCP Server    │
└─────────────────┘   MCP   └─────────────────┘
         │                           │
         │    Tool: validate_reasoning
         │    Input: {rationale, domain}
         │    Output: {valid, severity, critique, flags}
         │
         ▼
   Safer AI Decisions

MCP Server Options

Server Use Case Command
server.py Claude Desktop / Claude Code (stdio) python -m src.mcp.server
server_http.py Basic HTTP API python -m src.mcp.server_http
server_prod.py Production with auth & rate limiting python -m src.mcp.server_prod

Claude Desktop Setup

// ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "minicrit": {
      "command": "python3",
      "args": ["-m", "src.mcp.server"],
      "cwd": "/path/to/MiniCrit-7B",
      "env": {
        "MINICRIT_ADAPTER": "wmaousley/MiniCrit-7B",
        "MINICRIT_BASE_MODEL": "Qwen/Qwen2-7B-Instruct",
        "MINICRIT_PRELOAD": "true"
      }
    }
  }
}

Production HTTP Server

# Start with API key authentication
export MINICRIT_API_KEYS="key1,key2,key3"
export MINICRIT_RATE_LIMIT=60  # requests per minute
python -m src.mcp.server_prod

# Or with gunicorn for production
gunicorn src.mcp.server_prod:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000

Production endpoints:

Endpoint Method Description
/health GET Health check (no auth)
/info GET Server info and rate limits
/validate POST Validate single reasoning
/batch POST Batch validate (up to 100 items)
/sse GET MCP Server-Sent Events stream
/admin/keys POST Create API key (admin only)
/admin/audit GET View audit log (admin only)
/admin/stats GET Usage statistics (admin only)

MCP Tools

Tool Description
validate_reasoning Validate AI reasoning, returns critique with severity
batch_validate Validate multiple items efficiently (max 100)
get_model_info Get model status, device, and statistics

Programmatic Usage

from src.mcp import (
    ModelManager,
    CritiqueGenerator,
    CritiqueResult,
    InputSanitizer,
    get_model_manager,
    get_critique_generator,
)

# Singleton model manager (thread-safe)
manager = ModelManager.get_instance()

# Generate critiques
generator = CritiqueGenerator(manager)
result = generator.generate(
    rationale="AAPL will rise because momentum is positive",
    domain="trading",
    context="Portfolio allocation decision"
)

print(result.valid)       # False
print(result.severity)    # "high"
print(result.critique)    # "This reasoning exhibits..."
print(result.flags)       # ["overconfidence", "insufficient_evidence"]
print(result.latency_ms)  # 42.3

# Async version
result = await generator.generate_async(
    rationale="Buy signal based on MACD crossover",
    domain="trading"
)

Supported Domains

trading • finance • defense • cybersecurity • medical • risk_assessment • resource_allocation • planning_scheduling • general

Output Format

{
  "valid": null,
  "valid_keyword_heuristic": false,
  "severity": "high",
  "severity_basis": "keyword_heuristic",
  "critique": "This reasoning exhibits recency bias. A single day's price movement has no predictive power...",
  "confidence": null,
  "confidence_source": "not_emitted",
  "flags": ["overconfidence", "insufficient_evidence", "missing_consideration"],
  "domain": "trading",
  "decoding": {"max_new_tokens": 256, "do_sample": false, "repetition_penalty": 1.15},
  "latency_ms": 42.3,
  "request_id": "req_abc123"
}

confidence will be populated from the model once it emits the structured format defined in Antagon's output contract v1. Until then it is null rather than an estimate. severity is matched from keywords in the critique without handling negation ("no critical flaw" matches critical), so treat it as a hint, not a verdict.

Severity Levels: pass → low → medium → high → critical

Common Flags:

  • overconfidence - Certainty without sufficient evidence
  • missing_consideration - Key factors not addressed
  • logical_inconsistency - Contradictions in reasoning
  • insufficient_evidence - Claims lack support
  • unaddressed_risk - Potential risks not considered

🌐 OpenAI-Compatible API

MiniCrit provides an OpenAI-compatible API server, allowing drop-in replacement for any OpenAI client:

Start the Server

# Start the OpenAI-compatible server
python -m src.openai_compat_server

# Or with uvicorn for production
uvicorn src.openai_compat_server:app --host 0.0.0.0 --port 8080

Use with Any OpenAI Client

from openai import OpenAI

# Point to MiniCrit server
client = OpenAI(
    base_url="http://localhost:8080/v1",
    api_key="minicrit"  # Any string works
)

response = client.chat.completions.create(
    model="minicrit-7b",
    messages=[
        {"role": "user", "content": "AAPL is bullish because momentum is positive"}
    ],
    temperature=0.7,
    max_tokens=512
)

print(response.choices[0].message.content)

Endpoints

Endpoint Description
GET /health Health check with model status
GET /v1/models List available models
GET /v1/models/{id} Get specific model info
POST /v1/chat/completions Generate critique (streaming supported)

Streaming

# Stream responses
stream = client.chat.completions.create(
    model="minicrit-7b",
    messages=[{"role": "user", "content": "Validate this reasoning..."}],
    stream=True
)

for chunk in stream:
    print(chunk.choices[0].delta.content, end="")

🦜 LangChain Integration

MiniCrit integrates seamlessly with LangChain for building AI pipelines:

Installation

pip install minicrit langchain-core

Basic Usage

from langchain_minicrit import MiniCritLLM, MiniCritChat, MiniCritValidator

# As an LLM
llm = MiniCritLLM(base_url="http://localhost:8080/v1")
critique = llm.invoke("Stock will rise due to momentum")
print(critique)

# As a Chat Model
from langchain_core.messages import HumanMessage, SystemMessage

chat = MiniCritChat(base_url="http://localhost:8080/v1")
response = chat.invoke([
    SystemMessage(content="You are a financial reasoning critic."),
    HumanMessage(content="Buy AAPL because it went up yesterday")
])
print(response.content)

Validation Chain

from langchain_minicrit import MiniCritValidator

validator = MiniCritValidator(
    base_url="http://localhost:8080/v1",
    threshold=70.0  # Minimum score to pass
)

result = validator.validate("MACD crossover signals a buy opportunity")

print(f"Valid: {result.is_valid}")
print(f"Score: {result.score}")
print(f"Critique: {result.critique}")
print(f"Flaws: {[f.antagon_flaw_id for f in result.flaws]}")

In LangChain Pipelines

from langchain_core.runnables import RunnablePassthrough
from langchain_minicrit import MiniCritValidationChain

# Create validation chain
validator = MiniCritValidationChain(threshold=70.0)

# Compose with other runnables
pipeline = RunnablePassthrough() | validator

result = pipeline.invoke("High confidence trade based on sentiment analysis")

🔍 What MiniCrit Detects

Cognitive Biases

  • ⚠️ Overconfidence - Certainty without evidence
  • ⚠️ Survivorship Bias - Ignoring failures
  • ⚠️ Confirmation Bias - Cherry-picking data
  • ⚠️ Anchoring - Over-relying on first info
  • ⚠️ Recency Bias - Overweighting recent events

Logical Flaws

  • 🚫 False Causation - Correlation ≠ causation
  • 🚫 Hasty Generalization - Small sample size
  • 🚫 Missing Risks - Unaddressed threats
  • 🚫 Circular Reasoning - Assuming the conclusion
  • 🚫 False Dichotomy - Ignoring options

Example

Input:

"AAPL long: The stock has risen 3 days in a row, momentum is clearly bullish. 95% confident this continues."

MiniCrit Output:

⚠️ HIGH SEVERITY - Multiple reasoning flaws detected:

  1. Overconfidence: 95% confidence is not supported by the evidence provided
  2. Recency Bias: 3 days of price movement has minimal predictive value
  3. Missing Risk Factors: No consideration of upcoming earnings, macro events, or sector rotation

Flags: overconfidence, insufficient_evidence, unaddressed_risk


🏗️ Architecture

┌──────────────────────────────────────────────────────────────────┐
│                      MiniCrit-7B System                          │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌────────────┐    ┌─────────────┐    ┌───────────────────────┐ │
│  │ AI System  │───▶│   MiniCrit  │───▶│   Validated Output    │ │
│  │ (Any LLM)  │    │   Server    │    │                       │ │
│  └────────────┘    └──────┬──────┘    │ • valid: null (interim)│ │
│                           │           │ • severity: enum      │ │
│                    ┌──────▼──────┐    │ • critique: string    │ │
│                    │  Qwen2-7B   │    │ • flags: list         │ │
│                    │    Base     │    │ • confidence: null    │ │
│                    └──────┬──────┘    └───────────────────────┘ │
│                           │                                      │
│                    ┌──────▼──────┐                              │
│                    │   LoRA      │  40.4M trainable params      │
│                    │  Adapter    │  LoRA on CritiqueBank-11M (9.8% of planned steps)  │
│                    └─────────────┘                              │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘

📈 Training

Model Specifications

Parameter Value
Base Model Qwen/Qwen2-7B-Instruct
Method LoRA (r=16, α=32)
Trainable Params 40.4M / 7.6B (0.5%)
Dataset CritiqueBank-11M
Hardware Lambda Labs H100 PCIe (80GB)
Training Loss 3.19 → 0.44 (86% reduction)

Dataset: CritiqueBank-11M

Property Value
Rows 11,674,598
Distinct rationales 215 (43 tickers x 5 indicator templates)
Domain Financial trading signals, long only
Labelled critique styles 6 (timing, contrarian, logical_flaw, adversarial, risk_emphasis, contextual)
Generator Google Gemini Flash. No human annotation

The variation is on the critique side; the rationale side is a closed set of 215 inputs. A model trained on this has seen 215 distinct inputs and should not be assumed to generalise to unseen rationale forms without evaluation on independently generated data. See the dataset card for the full composition.

Correction. Earlier versions of this README described the dataset as five named components (LogicFlaw, FactCheck, BiasDetect, RiskMissing, DomainSpecific) spanning trading, defense and medical domains. No such components or domains exist in the deposited data, which is single-domain. The table above is the measured composition.

Published: DOI 10.5281/zenodo.23091964 (supersedes 10.5281/zenodo.18159342)

Training Progress

Loss
3.2 │██
2.4 │  ████
1.6 │      ██████
0.8 │            ████████████
0.4 │                        ████████████████  ← Current
    └─────────────────────────────────────────
    0%        25%        50%        75%     100%

Run Training

# Lambda Labs (H100)
python train_minicrit_7b.py --config configs/7b_lora.yaml

🧪 Benchmarking

Compare MiniCrit models head-to-head:

python src/benchmark/benchmark_models.py \
  --eval-data data/eval_holdout.jsonl \
  --model-1 wmaousley/MiniCrit-1.5B \
  --model-2 wmaousley/MiniCrit-7B \
  --judge-sample 200  # Optional: LLM-as-judge comparison

Metrics Computed

Metric Description
False Positive Rate Valid reasoning incorrectly flagged
Detection F1 Precision/recall on flaw detection
Latency (p50/p95/p99) Inference speed percentiles
LLM Judge Score Claude rates critique quality

🔧 Advanced: Improve Your Model

Generate Hard Training Examples

# Uses Claude Sonnet (~$30 for 5K examples)
export ANTHROPIC_API_KEY=your-key
python src/training/generate_hard_examples.py --count 5000

Direct Preference Optimization (DPO)

# Generate preference pairs
python src/training/generate_dpo_data.py \
  --input eval_holdout.jsonl \
  --model wmaousley/MiniCrit-7B \
  --output dpo_pairs.jsonl

# Run DPO training
python src/training/train_dpo.py \
  --model wmaousley/MiniCrit-7B \
  --data dpo_pairs.jsonl \
  --output minicrit-7b-dpo

See docs/MODEL_EXCELLENCE_GUIDE.md for the full improvement roadmap.


📁 Repository Structure

MiniCrit-7B/
├── src/
│   ├── mcp/                    # MCP Server Implementation
│   │   ├── core.py             # Thread-safe ModelManager, CritiqueGenerator
│   │   ├── server.py           # Local stdio (Claude Desktop)
│   │   ├── server_prod.py      # Production HTTP + auth + rate limiting
│   │   └── server_http.py      # Basic HTTP server
│   ├── benchmark/              # Model Evaluation
│   │   └── benchmark_models.py
│   ├── training/               # Training Utilities
│   │   ├── generate_hard_examples.py
│   │   ├── generate_dpo_data.py
│   │   └── train_dpo.py
│   ├── openai_compat_server.py # OpenAI-compatible API
│   ├── config.py
│   ├── data.py
│   ├── model.py
│   ├── training.py
│   ├── evaluation.py
│   └── api.py
├── langchain_minicrit/         # LangChain Integration
│   ├── __init__.py
│   ├── llm.py                  # LLM wrapper
│   ├── chat.py                 # Chat model
│   ├── validator.py            # Validation chain
│   └── callbacks.py            # Callback handlers
├── docker/
│   ├── Dockerfile
│   ├── docker-compose.yml
│   └── requirements.txt
├── configs/
│   ├── claude_desktop_config.json
│   ├── 7b_lora.yaml
│   └── deepspeed_gh200.json
├── scripts/
├── tests/                      # 489 tests
├── docs/
│   ├── DEPLOYMENT_GUIDE.md
│   └── MODEL_EXCELLENCE_GUIDE.md
└── CHANGELOG.md

🐳 Deployment Options

cd docker
cp .env.example .env
# Edit .env with your settings
docker-compose up -d

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: minicrit
spec:
  replicas: 2
  template:
    spec:
      containers:
      - name: minicrit
        image: antagoninc/minicrit:latest
        resources:
          limits:
            nvidia.com/gpu: 1

Production HTTP Server

# With authentication & rate limiting
export MINICRIT_API_KEYS="key1,key2,key3"
python src/mcp/server_prod.py

See docs/DEPLOYMENT_GUIDE.md for complete instructions.


⚙️ Configuration

Environment Variables

Model Configuration:

Variable Default Description
MINICRIT_ADAPTER wmaousley/MiniCrit-7B HuggingFace adapter path
MINICRIT_BASE_MODEL Qwen/Qwen2-7B-Instruct Base model path
MINICRIT_DEVICE auto Device: auto, cuda, mps, cpu
MINICRIT_QUANTIZATION none Quantization: none, 8bit, 4bit
MINICRIT_MAX_LENGTH 512 Max input sequence length
MINICRIT_INFERENCE_TIMEOUT 120 Inference timeout in seconds
MINICRIT_PRELOAD false Preload model on server startup
MINICRIT_LOG_LEVEL INFO Logging level

Production Server (server_prod.py):

Variable Default Description
MINICRIT_PORT 8000 Server port
MINICRIT_API_KEYS - Comma-separated valid API keys
MINICRIT_MASTER_KEY (random) Admin master key
MINICRIT_RATE_LIMIT 60 Requests per minute per key
MINICRIT_CORS_ORIGINS localhost:3000,8080 Allowed CORS origins
MINICRIT_LOG_REQUESTS true Log all requests
REDIS_URL - Redis URL for distributed rate limiting

Rate Limit Tiers:

Tier Requests/Min Description
free 10 Anonymous/unauthenticated
standard 60 Default API key tier
premium 300 Premium API keys
admin 1000 Master key

8-bit / 4-bit Quantization

MiniCrit supports quantization via bitsandbytes to reduce memory usage:

# 8-bit quantization (~50% memory reduction)
export MINICRIT_QUANTIZATION=8bit
python -m src.mcp.server

# 4-bit quantization (~75% memory reduction, slight quality loss)
export MINICRIT_QUANTIZATION=4bit
python -m src.mcp.server

Requirements:

  • bitsandbytes>=0.41.0 (included in dependencies)
  • CUDA-capable GPU
  • Falls back to fp16 gracefully if bitsandbytes is unavailable

Input Sanitization (Security)

MiniCrit includes built-in input sanitization to protect against prompt injection attacks:

  • Injection Pattern Detection: Blocks patterns like "ignore previous instructions", "system:", etc.
  • Control Character Removal: Strips null bytes, zero-width chars, and other control characters
  • Length Validation: Enforces max 50,000 character rationales, 100 char domains
  • Domain Whitelisting: Only accepts valid domains from the supported list
from minicrit import InputSanitizer, InputSanitizationError

sanitizer = InputSanitizer()
try:
    clean_input = sanitizer.validate_rationale(user_input)
except InputSanitizationError as e:
    print(f"Blocked: {e}")

🎯 Use Cases

Domain Application
Quantitative Trading Validate signals before execution
Defense / Intelligence Audit AI threat assessments
Medical AI Review diagnostic reasoning
Autonomous Vehicles Validate planning decisions
Enterprise AI Catch hallucinations before they propagate

📜 Citation

@software{minicrit2026,
  author = {Ousley, William Alexander and Ousley, Jacqueline Villamor},
  title = {MiniCrit: Adversarial AI Validation for Autonomous Systems},
  year = {2026},
  publisher = {Antagon Inc.},
  url = {https://github.com/antagoninc/MiniCrit-7B}
}

🙏 Acknowledgments

Lambda Labs

  • Lambda Labs - GPU compute grant for H100 training
  • Anthropic - MCP standard development

No high-performance computing facility and no federal funding of any kind supported this work.


📄 License

Apache 2.0 - See LICENSE


Antagon Inc.
Making AI Systems Safer Through Adversarial Testing

Website • Contact • CAGE: 17E75 • UEI: KBSGT7CZ4AH3

William Alexander Ousley - Co-Founder & CEO
Jacqueline Villamor Ousley - Co-Founder & CTO

Metadata

Release files for minicrit 0.3.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for minicrit 0.3.3
File Size Uploaded
minicrit-0.3.3.tar.gz 125.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for minicrit 0.3.3
File Interpreter ABI Platform
minicrit-0.3.3-py3-none-any.whl Python 3 none any Details

Total release size: 246.0 kB

Release files / minicrit-0.3.3.tar.gz

Download URL minicrit-0.3.3.tar.gz
Size 125.4 kB
Tags Source
SHA-256 checksum
How to use checksums
f9a8e39d7bbfbd3cde8aabee439cb779204725a3733c9fcf36b655d1c68721ae
BLAKE2b-256 checksum
How to use checksums
bb8cde560b5b7ae87634517fedd74db08f0eecd9001cfc39e7406fc3fe5c5dad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.2

Release files / minicrit-0.3.3-py3-none-any.whl

Download URL minicrit-0.3.3-py3-none-any.whl
Size 120.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9edf2c0875cbe6e5b59377b662957f15f1afb2c8ddea7d1a863d5ad4a68f1bf9
BLAKE2b-256 checksum
How to use checksums
d17223de36844e74855cf936306635f63d1ff7fba8667899bd45b0dfa9a872d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.2

Release history Release notifications | RSS feed

This release

0.3.3 This release

2 release files

0.3.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page