Skip to main content
ReasonBlocks evaluates trajectory health with six trajectory monitors that run server-side on POST /monitors/evaluate. task_profile selects which weight preset the server applies; the weighted sum of the monitor scores is the composite that drives steering injection.
These weights live in rb-api, not the SDK. The SDK forwards your task_profile (and any monitor_weights override) to the server, which owns the resolution. There is no local monitor suite to weight on the client.

The six monitors

Each monitor returns a score in [0, 1] where 1 is maximum badness. A monitor “fires” when its individual score crosses the fire threshold; the weighted sum across all six is the composite.
MonitorWhat it detects
claim_contradictionThe agent’s stated conclusions contradict each other or earlier findings. The only detector that examines what the agent concluded, not what it called.
semantic_loopThe same action or search repeated with reworded inputs (embedding-based, so “session timeout” / “session expiry” / “session token expiration” count as one loop).
verification_skipThe agent reaches a conclusion without verifying its work (no test run, no re-read of the changed file).
cyclic_compressionRepeated re-summarization / context churn — the agent compresses and re-derives the same state in cycles.
late_sprawlThe trajectory sprawls late: new tools and tangents introduced deep into a run that should be converging.
silent_topic_driftThe agent quietly drifts off the original task without acknowledging the change.

Built-in profiles

Three profiles are defined in rb-api/app/scoring/monitors.py (WEIGHTS_BY_PROFILE). Select one with task_profile:
from reasonblocks import ReasonBlocks

rb = ReasonBlocks(
    api_key="rb_live_...",
    task_profile="coding",   # or "pr_review", "qa"
)

coding (default)

Standard weights for an agent that edits code, runs tests, and may loop. claim_contradiction leads.
MonitorWeight
claim_contradiction0.30
semantic_loop0.25
verification_skip0.15
cyclic_compression0.10
late_sprawl0.10
silent_topic_drift0.10

pr_review

Read-only review agent. semantic_loop leads — review agents most often fail by re-explaining the same diff — and cyclic_compression / late_sprawl are raised for runs that sprawl across files.
MonitorWeight
claim_contradiction0.20
semantic_loop0.30
verification_skip0.10
cyclic_compression0.15
late_sprawl0.15
silent_topic_drift0.10

qa

QA / tutoring agent. claim_contradiction and silent_topic_drift dominate (wrong or off-topic answers are the primary failure mode); verification and compression matter less.
MonitorWeight
claim_contradiction0.40
semantic_loop0.15
verification_skip0.05
cyclic_compression0.05
late_sprawl0.10
silent_topic_drift0.25
Resolution order on the server: defaults ← named profile preset ← per-call monitor_weights overrides. Unknown monitor names in overrides are dropped; negative weights are clamped to 0; each weight is capped at 1.0.

Per-call weight overrides

Pass monitor_weights on ReasonBlocksConfig to override individual weights on top of the chosen profile. The override is forwarded into MonitorSteeringInjection and rides on every POST /monitors/evaluate request.
from reasonblocks import ReasonBlocksConfig

config = ReasonBlocksConfig(
    monitor_task_profile="coding",
    monitor_weights={
        "semantic_loop": 0.40,    # raise — catch loops sooner
        "verification_skip": 0.05,  # lower — your agent verifies elsewhere
    },
)
Partial dicts are fine — unspecified monitors fall through to the profile, then to server defaults.
monitor_weights is only a field on ReasonBlocksConfig. The simpler ReasonBlocks(...) constructor doesn’t expose it — use the config + build_middleware path when you need per-call weight overrides.

Custom profiles

You can create and manage named profiles per organization through the dashboard or the REST API (GET/POST /v1/monitor/profiles). A custom profile referenced by task_profile resolves the same way as a built-in. The set of valid monitor names is returned by GET /v1/monitor/scorers.