AFP engineering series · Chapter 22 of 25

Choose metrics that reveal both missed harm and unnecessary friction, with explicit denominators and production assumptions.

A block rate is not a safety score

If a guardrail blocks 20% of requests, it may be detecting abuse, rejecting legitimate work, or failing on unsupported inputs. The percentage alone cannot distinguish those explanations. Metrics need labels, denominators, and a connection to the effect the control is meant to prevent.

Maintain separate counters for content violations, authorization denials, review decisions, unavailable dependencies, and completed actions. Track attempts and effects independently. An unauthorized action proposal rejected by the backend is a model-level failure and an application containment success; flattening it into one score hides useful information.

Use a confusion matrix for labeled decisions

Reality / decisionFlaggedAllowed
Fraud or policy violationTrue positiveFalse negative
LegitimateFalse positiveTrue negative

Precision is true positives divided by all flagged cases. Recall is true positives divided by all actual positive cases. False-positive rate is false positives divided by legitimate cases. These denominators answer different questions and should not be exchanged because the resulting percentage looks better.

For a deployed workflow, also measure escape rate at the effect boundary: how often a prohibited outcome actually occurred. A detector can miss an attempt while another control prevents the effect. Keep the relationship visible so teams know whether they are improving detection, containment, or both.

Translate rates into user and operator impact

Suppose a synthetic evaluation estimates a 1% false-positive rate, and the service handles 100,000 legitimate tasks per day. That implies roughly 1,000 false flags under those assumptions. If each requires five minutes of review, the queue would consume about 83 reviewer-hours. These are illustrative planning numbers, not a staffing recommendation.

Measure the actual review-time distribution and customer delay. High-impact cases may require specialized reviewers and cannot be averaged together with quick content checks. A threshold change that improves recall can still be operationally unacceptable if it creates a backlog that delays legitimate account recovery.

Compute metrics without hiding undefined cases

Illustrative python; adapt the persistence and identity adapters to your service.

def ratio(numerator, denominator):
    return numerator / denominator if denominator else None

def metrics(tp, fp, fn, tn):
    return {
        "precision": ratio(tp, tp+fp),
        "recall": ratio(tp, tp+fn),
        "false_positive_rate": ratio(fp, fp+tn),
        "flagged": tp+fp,
    }

assert metrics(0,0,0,100)["precision"] is None

An undefined metric should remain undefined, not become zero or one by convenience. If no cases were flagged, precision says nothing about the detector's quality. Include raw counts beside percentages, especially for rare events. Small denominators can make a dramatic percentage change correspond to one additional case.

Keep measurement windows and label delays explicit. A case approved today may be confirmed fraudulent weeks later. Recompute historical metrics when labels mature, and distinguish provisional dashboards from settled analysis.

Segment by meaningful operating conditions

Compare languages, task types, input formats, tool capabilities, and model versions where you have enough data. A global average can hide a serious failure in one workflow. Avoid collecting unnecessary sensitive attributes or using inferred personal traits merely to populate a dashboard.

Track coverage as well as accuracy. Unsupported images, truncated documents, and skipped checks should have their own rates. A detector can look excellent on the subset it inspected while the application routes a large amount of uninspected traffic through another path.

Measure latency and cost at the tail

Guardrails affect user experience through latency, retries, and review delays. Report median and tail latency for each mandatory check and for the complete journey. Separate provider time from queueing and application processing. A fast average can hide occasional long pauses that trigger client retries and duplicate work.

Measure cost per completed legitimate task, including blocked generations and evaluation calls. A cheaper model with more retries and review can cost more at the workflow level. Compare complete outcomes rather than isolated token prices or classifier-call latency.

Worked dashboard: distinguish attacks, bugs, and outages

A dashboard reports that blocked requests doubled after a release. Drill down and discover three causes: a new content policy blocks more legitimate quotations, a tool rename triggers unknown-operation denials, and a screening outage produces unavailable results. Treating all three as increased attack volume would send the team toward the wrong response.

Create separate panels for policy violations, authorization denials, invalid requests, unsupported coverage, and unavailable dependencies. Include denominators such as completed inspections, attempted actions, and legitimate labeled tasks. Show raw counts alongside percentages. Correlate changes with model, policy, tool-inventory, and parser versions.

For content decisions, inspect a labeled sample of newly blocked cases. For tool denials, compare the deployed inventory with policy mappings. For unavailable results, examine dependency latency and error rates. Each category has a different owner and remediation path. The same high-level user symptom, “the assistant refused,” can originate in very different systems.

Add an effect panel: unauthorized records returned, duplicate operations, unapproved deliveries, and released-before-block output incidents. These should not be inferred from refusal counts. Resource services and release adapters emit the authoritative observations. A detector miss contained by a backend check should remain visible as a miss and a containment success.

Finally, connect review volume to capacity and age. A stable number of flags can still create harm if handling time increases and the oldest cases wait days. Track appeals and correction outcomes so false positives remain visible after the initial decision. The resulting dashboard supports decisions about policy, engineering reliability, and staffing without pretending that one percentage measures the entire AFP system.

Use a balanced release scorecard

A useful scorecard includes hard-invariant violations, unsafe output releases, legitimate completion, false-positive burden, review backlog, dependency availability, and containment time. Give hard transaction invariants explicit pass/fail treatment rather than averaging them into a favorable composite score.

The threshold lab makes the base-rate and review arithmetic inspectable. Its rates are user-controlled assumptions, not empirical detector performance. In production, attach data provenance and uncertainty to every estimate. Metrics improve AFP when they reveal tradeoffs clearly enough for owners to make accountable decisions.

Sources and implementation scope

Primary references checked October 15, 2026. Framework details follow the linked documentation; the Northstar cases, policy contracts, and test designs are original illustrative designs. Python snippets labeled illustrative are not complete production integrations. ADK package metadata checked for this series reported 2.12.0; pin and test the version used by your application.

Protect the action boundary with verified evidence, and test both containment and legitimate use.