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:
| Feature | Description |
|---|---|
tool_call_rate | Tool calls per unit time in a session |
avg_session_duration_s | Average session duration in seconds |
model_invoke_frequency | Model invocations per unit time |
token_usage_ratio | Tokens used as a fraction of context window |
policy_eval_count | Number 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.