Skip to main content

ML Behavioral Baselining

Pavri behavioral baselines help operators compare an agent's current activity with its established operating pattern. Treat a baseline score as investigation evidence, not as an autonomous enforcement decision.

How It Works

Pavri ML baselining is intentionally scoped as anomaly scoring only. The ML layer:

  • Extracts feature vectors from agent telemetry (tool call rates, session duration, model invocation frequency, token usage, policy eval counts)
  • Trains a per-agent statistical profile (mean and standard deviation per feature)
  • Scores incoming events using z-score based anomaly detection
  • Feeds scores into the existing rule/threshold engine — it does NOT make autonomous enforcement decisions

The ML layer never blocks execution, overrides policy, or auto-resolves correlation. Scores are advisory inputs to the threat detection pipeline.

Feature Vectors

Each agent's behavioral profile is built from these features:

FeatureDescription
tool_call_rateTool calls per unit time in a session
avg_session_duration_sAverage session duration in seconds
model_invoke_frequencyModel invocations per unit time
token_usage_ratioTokens used as a fraction of context window
policy_eval_countNumber of policy evaluations per session

Training a Baseline

Baselines are trained from historical telemetry. A minimum of 3 samples is required for a meaningful profile. Below 3 samples, the detector falls back to rule-only detection.

from pavri.core.behavioral_baseline import train_baseline, FeatureVector

samples = [
FeatureVector(tool_call_rate=2.0, avg_session_duration_s=45.0,
model_invoke_frequency=1.8, token_usage_ratio=0.4, policy_eval_count=3.0),
# ... more samples from production telemetry ...
]

profile = train_baseline(
agent_id="my-agent-prod",
samples=samples,
trained_at="2026-03-25T00:00:00Z",
)

Anomaly Scoring

from pavri.core.behavioral_baseline import BaselineScorer, extract_features

scorer = BaselineScorer(threshold=0.65)
features = extract_features(event_payload)
score = scorer.score(features, profile)

print(f"Score: {score.score:.4f}")
print(f"Explanation: {score.explanation_stub}")
print(f"Model version: {score.model_version}")

The score output always includes:

AnomalyScore(
score=0.82, # 0.0 (normal) to 1.0 (highly anomalous)
features_used=[...], # feature names that contributed
explanation_stub="top anomalous features: tool_call_rate(z=4.20)",
model_version="v1.0.0",
agent_id="my-agent-prod",
baseline_available=True,
)

AnomalyDetector Integration

The AnomalyDetector class integrates the ML scorer with the rule-only fallback path:

from pavri.detectors.anomaly import AnomalyDetector
from pavri.core.behavioral_baseline import BaselineScorer

detector = AnomalyDetector(scorer=BaselineScorer(threshold=0.65))
detector.register_profile(profile)

finding = detector.detect(event_payload, agent_id="my-agent-prod")
if finding:
print(f"Anomaly detected: {finding.message}")
print(f"ML score: {finding.extensions['ml_score']}")

Fallback Behavior

When no trained baseline is available for an agent, the detector falls back to rule-only detection using pattern markers. This ensures no gaps in coverage during the bootstrapping period.

event received
├── profile exists and is_trained() → ML baseline scoring
│ ├── score >= threshold → ThreatFinding (behavioral_anomaly)
│ └── score < threshold → None (no finding)
└── no profile or insufficient samples → rule-only fallback
├── rule marker matched → ThreatFinding (baseline_available=False)
└── no marker → None

Evaluating Baseline Quality

Evaluate baseline quality against a reviewed set of representative, approved workloads before relying on scores in an operational workflow. Include both normal activity and confirmed anomalies, then compare false-positive and false-negative rates with rule-only detection. Choose thresholds that match your team's investigation capacity and risk tolerance.

Model Versioning

Every AnomalyScore and ThreatFinding from the ML path includes model_version, allowing operators to compare results across model changes.

Scope Constraints

The baseline workflow has clear operating boundaries:

  • No external ML libraries — pure Python statistics (mean, stddev, z-score)
  • No autonomous decisions — scores feed the rule engine, not enforcement
  • No ML for correlation — correlation uses confidence scores, not ML
  • No managed model-training service — export only approved, appropriately protected telemetry for analysis in your organization's chosen environment

Use your organization's approved analytics environment for modeling that requires online learning, managed model serving, or GPU inference.