Catalog PyPI
PACKAGE EXPLORERView in registry

ai-critic

PyPI

Task-aware ML model auditing across performance, robustness, fairness, calibration, explainability, data quality and complexity.

ai-criticcalibrationexplainabilityfairnesslightgbmmachine-learningmlopsmodel-evaluationresponsible-airobustnessscikit-learnxgboost
Versions collected1
Direct dependencies7From release 5.0.0
Last observed21 Oct, 10:20 UTC

README

Version 5.0.0 documentation

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 typeExample performance evidenceAdditional task-specific evidence
regressionCross-validated R², MAE, RMSE, MAPEPerturbation impact on R²; permutation importance scored by R²
classificationCross-validated macro F1, accuracy, precision, recall, MCC; ROC-AUC for binary classificationOut-of-fold probability calibration when predict_proba is available; group F1 comparisons
clusteringAdjusted Rand Index (ARI) and normalized mutual information when reference labels are supplied; otherwise silhouetteARI stability under perturbations; feature-to-cluster separation diagnostics
anomaly_detectionAverage precision / ROC-AUC when reference anomaly labels are supplied; F1 from predicted labelsAgreement of anomaly flags under perturbations; score sensitivity where supported
dimensionality_reductionReconstruction error when inverse_transform is available; otherwise trustworthinessPairwise-distance stability and component-loading diagnostics where available
reinforcement_learningEpisode returns; a normalized performance score only when a target or baseline is declaredAction stability under observation perturbations and action sensitivity

The seven dimensions

DimensionWhat it evaluatesExamples of task-specific choices
PerformanceTask outcome using validation data or a declared referenceF1-macro for classification; R² for regression; silhouette/ARI for clustering; episode return for RL
RobustnessChange under reproducible feature or observation perturbationsF1/R² degradation, cluster-label agreement, anomaly-label agreement, embedding geometry, or policy-action stability
ExplainabilityFeature contribution, separation, component loading, or policy sensitivityPermutation importance for supervised prediction; cluster separation; anomaly score sensitivity; embedding loadings
CalibrationAgreement between predicted probabilities and observed event ratesOut-of-fold ECE/MCE/Brier-style evidence for classifiers; not applicable to tasks without a probabilistic event target
Data qualityDataset-level issues such as missing values, duplicates, constants, outliers, and classification imbalanceTarget-independent checks also work for unsupervised inputs
FairnessDifferences across explicitly supplied sensitive groupsGroup F1/R², anomaly rates, cluster composition, representation geometry, or episode returns depending on task
ComplexityStructural heuristics and measured single-input latency when supportedFeature/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.

FieldDefaultPurpose
cv_folds5Number of folds where the task protocol uses cross-validation
random_state42Seed for splits and deterministic perturbations
n_repeats5Repeats for permutation-importance estimates
n_bins10Number of bins used for calibration diagnostics
noise_levels(0.01, 0.05, 0.10, 0.20)Relative noise magnitudes for robustness checks
dropout_fraction0.30Fraction of features dropped in applicable robustness checks
outlier_fraction0.05Fraction of rows perturbed in applicable checks
sensitive_featuresNoneSensitive feature names or column indices for group diagnostics
metricsNoneReserved metric-selection input; task strategies determine the valid metrics
anomaly_labelNonePositive anomaly label when it is not inferred from 0/1 or -1/1
target_returnNoneDeclared target return for normalized RL performance
return_baselineNoneOptional RL reference return used in the normalization
group_columnNoneOptional group metadata for caller-defined protocols
max_samplesNoneOptional 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:

StatusMeaningScore
okThe dimension produced an interpretable measurementNumeric value, normally in [0, 1]
not_applicableThe dimension has no valid interpretation for this task/protocolnull
inconclusiveThe dimension could apply, but required data or capabilities are missingnull

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 auditGet started
Choose a task and understand its metricsTask types and metric choices
Configure evaluation protocolsInputs and evaluation configuration
Interpret null scores and aggregate weightsStatuses, scores, and aggregation
Audit group disparitiesFairness and sensitive features
Extend an evaluatorWeights, parallel execution, and custom evaluators
Export or gate resultsReports and CI gates
Understand caveatsScope and limitations

License

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

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
5.0.011 Oct 20267

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
your_user/ai-critic

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 21 Oct, 10:20 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:ac2e60b038ec6d2d6f292458249cddf73442df581b9a0fb766a44b5522740834