Skip to main content

ai-critic

Audit machine-learning models by what they do—not just by their algorithm.

Task-aware evaluation across performance, robustness, explainability, calibration, data quality, fairness, and complexity.

PyPI version Python versions MIT License

ai-critic is an extensible model-auditing library built around an AuditPipeline, a BaseEvaluator interface, and seven reusable evaluators. You declare the task type; the library selects task-specific evaluation strategies and reports both measurements and limitations.

Get started

Install the library:

python -m pip install ai-critic

Audit a model with an explicit task type:

import ai_critic
from ai_critic import EvaluationConfig

report = ai_critic.audit(
    model,
    (X_test, y_test ),
    task_type="classification",
    evaluation=EvaluationConfig(cv_folds=5, random_state=42),
)

print(report.overall_score)
print(report.overall_verdict.value)
print(report.dimensions["performance"].to_dict())

model should be a fitted, scikit-learn-compatible estimator (or another object supported by the selected strategy). X_test and y_test should be the evaluation data—not the data used to fit the model—unless your evaluation protocol intentionally says otherwise.

Choose a task type

"regression"
"classification"
"clustering"
"anomaly_detection"
"dimensionality_reduction"
"reinforcement_learning"

For clustering, anomaly detection without labels, and dimensionality reduction, a target is optional, but the task type is required:

report = ai_critic.audit(
    clusterer,
    X,
    task_type="clustering",
)

The legacy supervised call ai_critic.audit(model, X, y) is still supported for compatibility. New code should pass task_type explicitly. An algorithm does not determine its task: a tree, linear model, SVM, or neural network may be used for different task types. Logistic regression is usually a classifier.

Read the report

# Full JSON-serializable report
payload = report.to_dict()

# Compact terminal report
from ai_critic.reporters import print_report
print_report(report)

# Optional self-contained HTML report
from ai_critic.reporters import save_html_report
save_html_report(report, "audit.html")

Each dimension contains a score, status, verdict, summary, details, and suggestions. A score is None when a dimension is not applicable or the available evidence is insufficient; check status to distinguish those cases.

30-second mental model

Declare task type + provide model and evaluation data
                         │
                         ▼
                 Select task strategy
                         │
                         ▼
       Run the seven existing dimension evaluators
                         │
             ┌───────────┴───────────┐
             ▼                       ▼
   Task-appropriate metrics   Explicit limitations/status
             └───────────┬───────────┘
                         ▼
       Report metrics, protocol, weights, and verdict

Interpretation: Dimension scores are task-specific indicators—not universal measurements of model quality, and not necessarily comparable across task types. Read the metric names, protocols, score transformations, and limitations alongside any score.

Task types and metric choices

The strategy is selected by task type, not by model family. Metrics are only reported when their interpretation is supported by the task and available data.

Task type Example performance evidence Additional task-specific evidence
regression Cross-validated R², MAE, RMSE, MAPE Perturbation impact on R²; permutation importance scored by R²
classification Cross-validated macro F1, accuracy, precision, recall, MCC; ROC-AUC for binary classification Out-of-fold probability calibration when predict_proba is available; group F1 comparisons
clustering Adjusted Rand Index (ARI) and normalized mutual information when reference labels are supplied; otherwise silhouette ARI stability under perturbations; feature-to-cluster separation diagnostics
anomaly_detection Average precision / ROC-AUC when reference anomaly labels are supplied; F1 from predicted labels Agreement of anomaly flags under perturbations; score sensitivity where supported
dimensionality_reduction Reconstruction error when inverse_transform is available; otherwise trustworthiness Pairwise-distance stability and component-loading diagnostics where available
reinforcement_learning Episode returns; a normalized performance score only when a target or baseline is declared Action stability under observation perturbations and action sensitivity

The seven dimensions

Dimension What it evaluates Examples of task-specific choices
Performance Task outcome using validation data or a declared reference F1-macro for classification; R² for regression; silhouette/ARI for clustering; episode return for RL
Robustness Change under reproducible feature or observation perturbations F1/R² degradation, cluster-label agreement, anomaly-label agreement, embedding geometry, or policy-action stability
Explainability Feature contribution, separation, component loading, or policy sensitivity Permutation importance for supervised prediction; cluster separation; anomaly score sensitivity; embedding loadings
Calibration Agreement between predicted probabilities and observed event rates Out-of-fold ECE/MCE/Brier-style evidence for classifiers; not applicable to tasks without a probabilistic event target
Data quality Dataset-level issues such as missing values, duplicates, constants, outliers, and classification imbalance Target-independent checks also work for unsupervised inputs
Fairness Differences across explicitly supplied sensitive groups Group F1/R², anomaly rates, cluster composition, representation geometry, or episode returns depending on task
Complexity Structural heuristics and measured single-input latency when supported Feature/sample ratio, estimator parameters, tree depth, and prediction/transform/action latency

These are audit diagnostics, not guarantees of fairness, safety, causality, or production performance. In particular, a disparity check is only as meaningful as the sensitive attributes, data coverage, and metric provided.

Inputs and evaluation configuration

Supervised tabular data

Pass either the legacy three-argument form or a feature/target pair:

report = ai_critic.audit(
    model,
    X_test,
    y_test,
    task_type="regression",
)

# Equivalent data-pair form
report = ai_critic.audit(
    model,
    (X_test, y_test),
    task_type="regression",
)

NumPy arrays and pandas DataFrames/Series are supported. DataFrame column names are carried into reports where a strategy can use them.

Unsupervised tabular data

cluster_report = ai_critic.audit(
    clusterer,
    X,
    task_type="clustering",
)

embedding_report = ai_critic.audit(
    reducer,
    X,
    task_type="dimensionality_reduction",
)

When you have reference labels for an unsupervised output, pass them as a pair. For example, cluster labels can then be compared with external ground truth using ARI/NMI rather than relying only on internal validity metrics:

cluster_report = ai_critic.audit(
    clusterer,
    (X, reference_labels),
    task_type="clustering",
)

Anomaly-detection labels

For supervised anomaly evaluation, y should identify the anomaly class. The default supports binary labels 0/1 and -1/1 (with -1 interpreted as the anomaly for the latter convention). For another positive label, declare it:

config = EvaluationConfig(anomaly_label="fraud")
report = ai_critic.audit(
    detector,
    (X, labels),
    task_type="anomaly_detection",
    evaluation=config,
)

Without reference labels, the predicted anomaly rate is descriptive only. The performance dimension is inconclusive; it does not invent an accuracy or ranking score.

Reinforcement-learning episodes

The general API accepts a mapping containing observations and episode rewards. A policy should expose act, predict, or be callable for action-based diagnostics.

from ai_critic import EvaluationConfig

report = ai_critic.audit(
    policy,
    {
        "observations": observations,
        "episodes": [
            {"rewards": episode_1_rewards},
            {"rewards": episode_2_rewards},
        ],
    },
    task_type="reinforcement_learning",
    evaluation=EvaluationConfig(
        target_return=100.0,
        return_baseline=0.0,
        random_state=42,
    ),
)

Returns are environment-specific. Without target_return (or a declared baseline/target reference), the library reports observed return statistics but leaves the normalized performance score inconclusive. Supply observations aligned with the policy inputs; supply group attributes aligned with episodes if you want group-return diagnostics.

EvaluationConfig reference

EvaluationConfig exposes evaluation protocol choices. Defaults are shown below.

Field Default Purpose
cv_folds 5 Number of folds where the task protocol uses cross-validation
random_state 42 Seed for splits and deterministic perturbations
n_repeats 5 Repeats for permutation-importance estimates
n_bins 10 Number of bins used for calibration diagnostics
noise_levels (0.01, 0.05, 0.10, 0.20) Relative noise magnitudes for robustness checks
dropout_fraction 0.30 Fraction of features dropped in applicable robustness checks
outlier_fraction 0.05 Fraction of rows perturbed in applicable checks
sensitive_features None Sensitive feature names or column indices for group diagnostics
metrics None Reserved metric-selection input; task strategies determine the valid metrics
anomaly_label None Positive anomaly label when it is not inferred from 0/1 or -1/1
target_return None Declared target return for normalized RL performance
return_baseline None Optional RL reference return used in the normalization
group_column None Optional group metadata for caller-defined protocols
max_samples None Optional sample-limit metadata for caller-defined protocols

Example:

config = EvaluationConfig(
    cv_folds=3,
    random_state=7,
    n_repeats=10,
    noise_levels=(0.02, 0.05, 0.10),
)

The report records the protocol and relevant score transformations in each dimension's details. Configuration values do not turn an unsupported metric into a valid one.

Statuses, scores, and aggregation

Every dimension reports one of these statuses:

Status Meaning Score
ok The dimension produced an interpretable measurement Numeric value, normally in [0, 1]
not_applicable The dimension has no valid interpretation for this task/protocol null
inconclusive The dimension could apply, but required data or capabilities are missing null

not_applicable and inconclusive dimensions are excluded from the overall weighted mean. They are not assigned a perfect score. Their reasons appear in the dimension result and in report.aggregation["excluded_dimensions"].

The report's aggregation object states the aggregate method, included dimensions, excluded dimensions, weights, and score-normalization convention. The aggregate is therefore inspectable, but it is still a summary of task-specific normalized diagnostics—not a universal quality score.

print(report.aggregation)

for name, dimension in report.dimensions.items():
    print(name, dimension.status, dimension.score, dimension.summary)

Fairness and sensitive features

Fairness checks need an explicit group definition. Supply column names when X is a DataFrame or indices for array inputs:

report = ai_critic.audit(
    model,
    X,
    y,
    task_type="classification",
    sensitive_features=["age_group", "region"],
)

Or include the same list in EvaluationConfig(sensitive_features=[...]).

The current input path converts tabular features to numeric arrays. Encode categorical group attributes before auditing, and verify that the resulting values preserve the intended group membership. If no group is declared or detected, fairness is reported as inconclusive, not as a passing score.

Weights, parallel execution, and custom evaluators

Override dimension weights

report = ai_critic.audit(
    model,
    (X, y),
    task_type="classification",
    weights={"performance": 2.0, "fairness": 1.5},
)

Weights are shown in report.aggregation. Dimensions with no valid score are excluded regardless of weight. Do not compare aggregates built with different weights as if they were identical measures.

Run evaluators in parallel

report = ai_critic.audit(
    model,
    (X, y),
    task_type="classification",
    parallel=True,
)

Evaluators with declared dependencies still run after their prerequisites. Parallelism can be slower for small datasets or estimators that already use their own parallel workers.

Add a custom evaluator

AuditPipeline and BaseEvaluator remain the extension points. A custom evaluator returns a DimensionResult and can use the shared context passed by the pipeline.

from ai_critic.core.base import BaseEvaluator
from ai_critic.core.types import DimensionResult, Verdict

class MyEvaluator(BaseEvaluator):
    name = "my_check"
    weight = 1.0
    depends_on = ["performance"]

    def evaluate(self, model, X, y, problem_type, context=None):
        score = 0.9
        return DimensionResult(
            name=self.name,
            score=score,
            verdict=self._score_to_verdict(score),
            summary="Custom check completed.",
            details={"task_type": context.get("task_type").value},
        )

report = ai_critic.audit(
    model,
    (X, y),
    task_type="classification",
    evaluators=[MyEvaluator()],  # Supplying this list replaces the defaults.
)

To extend one dimension across task types, prefer adding or registering a task strategy and delegating from the existing evaluator rather than creating a parallel audit library.

Reports and CI gates

JSON-serializable report

import json

with open("audit.json", "w", encoding="utf-8") as f:
    json.dump(report.to_dict(), f, indent=2)

A dimension with no meaningful score is serialized with "score": null and a status explaining why.

HTML report

from ai_critic.reporters import save_html_report

path = save_html_report(report, "audit.html")
print(f"Saved to {path}")

The reporter renders the current dimension score/status and embeds the report data. It does not add metrics that were not computed.

Gate a pipeline or deployment check

ai_critic.gate(report, min_score=0.75)

gate() raises RuntimeError when overall_score is below the supplied threshold. Choose a threshold with the task, included dimensions, weights, and declared limitations in mind. The gate does not independently validate that a report includes every dimension your release policy requires.

Command-line interface

Audit a supervised CSV with a target column:

ai-critic score model.pkl data.csv \
  --target target \
  --task-type classification \
  --json

Audit an unlabeled tabular dataset:

ai-critic score clusterer.pkl data.csv \
  --task-type clustering \
  --report audit.html

Add sensitive feature columns and a gate threshold:

ai-critic score model.pkl data.csv \
  --target outcome \
  --task-type classification \
  --sensitive age_group,region \
  --report audit.html \
  --gate 0.75

The CLI currently reads tabular CSV data. For RL episode collections or other structured data, use the Python API.

Scope and limitations

  • Evaluation data matter. Use a representative held-out set or document why another protocol is appropriate. Cross-validation on supplied data does not prevent leakage that already occurred before the data reached the audit.

  • Preprocessing is part of the evaluated estimator. Pass the fitted pipeline when transformations are needed. The audit does not reconstruct your training pipeline from raw model weights.

  • Task metrics have assumptions. For example, R² can be negative; its displayed normalized score is clipped to [0, 1] and the raw metric is retained in details. Check the metric itself and its transformation.

  • Some diagnostics are heuristics. Feature-concentration and complexity scores are descriptive diagnostics, not proof of causal importance, optimal model size, or fairness.

  • Fairness requires valid groups. Incorrect encodings, small cohorts, omitted attributes, and unrepresentative data can make group comparisons misleading or inconclusive.

  • Unsupervised quality is not ground truth. Internal metrics such as silhouette measure a chosen geometric property; they do not establish that clusters are useful for a real application.

  • RL returns depend on the environment. A return has no universal good/bad scale. Declare a reference before interpreting a normalized score.

  • Model API support varies. A strategy may require methods such as predict, predict_proba, fit_predict, transform, inverse_transform, score_samples, or act. Missing methods should produce an explicit inconclusive result where applicable.

  • An audit is not a certification. The report is evidence to inform review; it is not a guarantee of safety, compliance, fairness, robustness, or deployment readiness.

Compatibility

The primary integration is with scikit-learn-style estimators. The library also works with compatible estimator wrappers where their required methods, cloning behavior, and data types are supported. Check each task strategy's available metrics when using XGBoost, LightGBM, CatBoost, a custom estimator, a dimensionality reducer, an anomaly detector, or a policy object.

Python requirement: >=3.9.

Development and tests

From the source checkout:

python -m pip install -e ".[reports]"
python -m pytest tests test -q

Run only the task-strategy contracts:

python -m pytest tests/test_task_strategies.py -q

Build local distribution artifacts:

python -m pip install build
python -m build

Documentation map

If you want to... Start with
Run the basic audit Get started
Choose a task and understand its metrics Task types and metric choices
Configure evaluation protocols Inputs and evaluation configuration
Interpret null scores and aggregate weights Statuses, scores, and aggregation
Audit group disparities Fairness and sensitive features
Extend an evaluator Weights, parallel execution, and custom evaluators
Export or gate results Reports and CI gates
Understand caveats Scope and limitations

License

This project is distributed under the MIT License. See the repository's license file for details.

Metadata

Release files for ai-critic 5.0.0

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

Source distribution (sdist)

Source distribution for ai-critic 5.0.0
File Size Uploaded
ai_critic-5.0.0.tar.gz 56.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ai-critic 5.0.0
File Interpreter ABI Platform
ai_critic-5.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 121.5 kB

Release files / ai_critic-5.0.0.tar.gz

Download URL ai_critic-5.0.0.tar.gz
Size 56.9 kB
Tags Source
SHA-256 checksum
How to use checksums
fac33a84b6f5ff82b13ce20194eb6a752fa67aee730b3e5bc5554e6cca5500fe
BLAKE2b-256 checksum
How to use checksums
154a21465e675d59d373993c83cb22239a831835a276198f356aa86ec9049e57
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release files / ai_critic-5.0.0-py3-none-any.whl

Download URL ai_critic-5.0.0-py3-none-any.whl
Size 64.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
90ca11fa867879ea4e5d7ba81049a090569e6ba5d6aee0968f1b6df8d11da6e6
BLAKE2b-256 checksum
How to use checksums
b6a3a0da1a099ec82a41c689e06df488837937add592b2981548d96212fad641
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release history Release notifications | RSS feed

This release

5.0.0 This release

2 release files

4.0.0

2 release files

3.5.1

2 release files

3.5.0

2 release files

3.4.6

2 release files

3.4.5

2 release files

3.4.1

2 release files

3.3.0

2 release files

3.2.0

2 release files

3.0.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

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