Composable safety primitives
Tuteliq isn’t a set of independent detectors — it’s a platform where detectors enrich each other. Thedetect_vulnerability_exploitation endpoint returns two fields, cross_endpoint_modifier and vulnerability_profile, that agents use to amplify risk verdicts from sibling detectors and route to vulnerability-appropriate intervention workflows.
This page explains the primitive and shows how to compose with it.
Why this matters
Most safety APIs return per-call classifications: is this content X? That’s enough if every harm is independent. But real harm rarely is. A grooming pattern targeting an emotionally vulnerable minor is structurally different from the same pattern targeting an emotionally stable adult — and an effective safety system has to weight signals by who the target is, not just what the content says. Tuteliq exposes that weighting as a primitive your agents compose, rather than burying it inside opaque score adjustments.The fields
cross_endpoint_modifier
A numeric multiplier (typical range 1.0–2.0) you apply to another endpoint’s risk_score when both endpoints detect a pattern in the same content.
A modifier of 1.6 means: “the vulnerability signals here amplify any concurrent grooming, scam, or coercion signal by 60%.”
vulnerability_profile
A four-dimensional decomposition of the target’s vulnerability, each scored 0.0–1.0:
Agents route differently based on which dimension is highest — a high
emotional_vulnerability plus a romance_scam signal calls for a slower, gentler intervention; a high situational_vulnerability plus a financial_grooming signal might trigger an immediate transaction hold.
Example response
Composing with another detector
The intended pattern is: rundetect_vulnerability_exploitation in parallel with the harm-specific detector for the same content, then combine.
When to use this primitive
- You’re building an agent that takes graduated actions based on combined risk, not single-detector verdicts.
- You’re moderating populations where target vulnerability is highly variable — mixed-age platforms, fintech, dating apps, AI companion products.
- You want intervention workflows that adapt to the user, not just the content.
When not to use it
- You’re running a fixed-threshold per-message classifier and only need a single binary verdict —
recommended_actionfrom each endpoint is enough. - You’re moderating content at the corpus level (e.g. AI training data) rather than per-user signals — vulnerability doesn’t apply.
Notes on safe composition
- Cap the compound risk at 1.0 (
Math.min(scam.risk_score * modifier, 1.0)) so amplification never produces an out-of-band value downstream consumers don’t expect. - The modifier is only meaningful when both endpoints actually
detect— ifvuln.detected === false, treat the modifier as1.0. - Cache the profile per-conversation, not per-message — a vulnerability read stays roughly stable across a single conversation, so re-running it on every message adds latency without changing the answer. This is guidance about your caching layer, not a Tuteliq-side store — see Privacy and data handling below. Refresh periodically or on context changes (e.g. a major life event surfaced in subsequent messages), and apply your own retention limits.
- Don’t expose the raw modifier to end users. It’s an integrator-level signal designed for routing logic, not for display. Surface the resulting route and the human-readable rationale instead.
Privacy and data handling
detect_vulnerability_exploitation, like every Tuteliq detection endpoint, is stateless and server-to-server:
- No persistent identifier. No request or response field in this API — or anywhere in Tuteliq’s detection surface — asks for or returns a
user_id,device_id, or other end-user identifier.vulnerability_profileis computed fresh from thecontent(and optionalconversation_history) submitted in that one call; it is not looked up against, or written to, a stored profile of any individual. - No server-side profiling. Tuteliq does not build, persist, or accumulate a vulnerability profile per user across calls. Each response reflects only what was in that request. If you want profile continuity across a conversation, that’s the client-side caching described above — a decision (and a data-retention obligation) that belongs to you as the integrator, not something Tuteliq does on your behalf.
- Server-to-server only. Detection runs on Tuteliq’s infrastructure. SDK calls (
tuteliq.safety.vulnerabilityExploitation(...)) are thin clients that call the hosted API — nothing in this composition pattern, or in any Tuteliq SDK, runs inference on the end user’s device. - The
age_group/ age fields elsewhere in the API are optional inputs, not requirements. Detectors that accept an age or age-bracket field (e.g.detect_grooming’scontext.child_age) work without it; supplying it sharpens the analysis but is never mandatory.
vulnerability_profile results (per the caching guidance above), that data lives in your systems under your own privacy and retention policies — Tuteliq’s involvement ends at the response of each stateless call.
Carrying a signal forward
Some findings are about a person rather than a message, and stay true on that person’s next request. Tuteliq does not keep such a finding against the user between calls (see Stateless by Design), so the platform carries the signal forward itself. The clearest case isminor_disclosure:
a speaker on an adult platform who says they are under 18.
The pattern:
- Store the suggestion on your side. When a response carries
minor_disclosure, saveminor_disclosure.suggested_age_groupagainst that user in your own records. - Send it back as the declared age. On that user’s later requests, pass the stored
value as
context.age_group. It is always a minor band (under 18,under 13,13-15or16-17), so the detectors apply a minor’s protections. - A declared child beats an adult setting. With
conversation_typedating,adult_communityorworkplace, a declared minor age group means the adult audience is not used for that request. You do not need to change your platform-wide setting.
- The check does not repeat. Once a request declares a minor, it no longer declares an
adult, so
minor_disclosure_checkdoes not run andminor_on_adult_platform_raisedis not returned again. The declared age group is now the signal, and the account decision (asking the user to verify their age again, for example) belongs to your own process. - On
/safety/grooming, which takes ages rather than an age group, declare the user’s messages with a childsender_role, or pass their age, instead ofage_group. - Decide how long to keep it. The stored value is your data, in your systems, under your own retention and review rules. Tuteliq’s involvement ends with each response.
- Let a person decide. A finding is a reason to review an account, not proof of age. Route it to a person before you restrict anyone.
Related
detect_vulnerability_exploitation— full endpoint referenceanalyse_multi— batch multi-endpoint analysis (applies modifier internally when both fire)- AI agents — composing Tuteliq primitives from an agent
- Incident logging — routing and reviewing what composition surfaces