Screening Agent Conversations
The /v2/guard endpoint screens every
step of an agent loop — user inputs, model outputs, tool calls, and tool responses —
with a single API call per step. The message roles in your request determine where
content is screened; your policy determines which detectors run there.
This page walks through each role: what to put in it, which detectors can run on it, and what the response looks like. For general request guidance (project IDs, metadata, streaming), see the Guard API endpoint page.
Message roles and screening locations
Each message role maps to a screening location, and a detector runs at a location only if your policy binds it there. The table below lists which detectors are available per location — what actually runs, and therefore what can appear in your response, is defined by your policy (see policy configuration).
An assistant message can carry both content and tool_calls; the two are screened
at their own locations, independently.
Tool definitions are the one entry in that table that is not a message role. They travel
in the request’s top-level tools array, and tool_definition is not a valid value for
messages[].role — a request that sets it is rejected with invalid role. See
Tool definitions.
What gets screened: the last interaction
AI Guardrails screens the last interaction in the messages array — the most recent
exchange that ends the conversation. Earlier messages provide context but are not
re-screened: they should already have been screened by previous Guard API calls. Call
the Guard API at every step of the agent loop so each interaction is screened as it
occurs.
This rule covers messages. Tool definitions are screened differently: every entry in
the tools array is screened on every call.
This design keeps detections actionable: a threat is flagged at the step where your application can still act on it — before a tool call executes or output reaches the user — instead of resurfacing on every later call once it is part of the history. Each call screens only the new interaction, on the expectation that past interactions were screened when they occurred. Some detectors also read the earlier messages as context — for example, to judge whether a tool call is consistent with the user’s request — but detections are only raised on the new content.
Consider a full agent turn:
Here the last interaction is the tool response and the final assistant message. In the
response breakdown, each detection carries a message_id: the zero-based index of the
message it applies to in your messages array — 3 for the tool response, 4 for the
final assistant message in this example.
Worked examples
Each example below sends one request with the target message last, mirroring how you
would call the Guard API at that step of an agent. The lead-in of each example states
which detectors it assumes your policy binds at that location; if your policy does not
bind a detector there, it will not appear in the breakdown. All examples request
"breakdown": true for per-detector results, and the responses are abridged to the
detections — entries with "detected": false and per-entry project_id/policy_id
fields are omitted.
User input
Screens the end-user’s message before (or as) it reaches the model. Assumes Prompt
Defense on user::content.
Model output
Screens the model’s response before it is returned to the user or passed downstream. The
assistant message is last, after the user turn it responds to. Assumes Data Leakage
Prevention on assistant::content.
To mask detected content rather than block the interaction, request "payload": true —
the response then includes the string locations of each match. See
masking using payloads.
Tool calls
Screens the tool call an agent is about to make — after the model produces it, before
your application executes it. The assistant message carrying tool_calls is last; the
content field may be empty, but the conversation history must be included so the call
can be judged against the user’s request. Assumes the Dangerous Deviation detector and
Data Leakage Prevention on assistant::tool_call.
The arguments field is a JSON-encoded string, matching the OpenAI chat completions
format.
The tool call is not warranted by the user’s request and sends customer data to an external destination — so the Dangerous Deviation detector fires, and Data Leakage Prevention detects the IBAN and SSN in the arguments:
Detections on tool calls also carry a source identifying which entry in the message’s
tool_calls array the detection applies to — each tool call in the message is screened
individually.
The Dangerous Deviation detector flags a tool call when the action is dangerous — data
leakage, access or privilege escalation, or system destruction — and nothing in the
trusted messages (user and system roles) warrants the call. A call that is merely
off-topic but not dangerous is not flagged. See
Agent Behavior Defense for the full flagging criteria,
explanation fields, and rollout guidance.
Three requirements for Dangerous Deviation screening:
- Include the conversation history — the detector judges the call against the user’s request.
- The tool call must be in the final
assistantmessage of the request. - Pass tool definitions in the top-level
toolsfield — missing definitions may degrade prediction quality and limit the explanations the detector can emit.
Tool responses
Screens the content a tool returns before the agent consumes it. Tool results are
untrusted: a compromised or poisoned tool can leak data or carry an indirect prompt
injection that hijacks the agent. The tool message is last and references the call it
answers via tool_call_id. Assumes Prompt Defense and Data Leakage Prevention on
tool::content.
Tool definitions
Tool definitions act as instructions to the model, including definitions supplied by
external systems such as third-party MCP servers. A poisoned definition can therefore
become a persistent prompt attack: malicious instructions can be hidden anywhere in its
JSON and influence the model whenever the tool is available. This example assumes Prompt Defense on
tool_definition::content, the only detector available there.
Definitions go in the request’s top-level tools array using the OpenAI function-calling
format. Each definition included in a request is screened as a single unit — the complete
JSON object, including its name, description, parameters, and any other fields. Tool
definitions do not follow the last-interaction rule: they are screened each time they are
sent.
You can send tools without messages. We recommend screening definitions before
exposing them to the model — for example, during the initial MCP handshake — and again
whenever they change. When a request contains both tools and messages, Guard screens
both according to the active policy.
Tool definition results come back in their own top-level tools object, separate from the
message-level breakdown. Each detection carries tool_id — the zero-based index of the
definition in your tools array — in place of message_id.
Prompt Defense judges a definition on its wording, so a legitimate tool can be flagged
for language that reads like an injection. To keep one, add it to the detector’s
allowed_tools list, either from the flagged request in the platform or through your
policy configuration. Although
the complete definition is screened, an allow-list entry matches only the tool’s name
and description. A matched definition is skipped by the detector entirely. Editing the
description ends the match, so the exemption stays tied to the definition you reviewed.
Other fields, including parameters, are not part of the exemption match, and an
exemption applies only to the policy that carries it.
Detections depend on your policy
A detector only runs — and only appears in the breakdown — if your policy binds it to
the relevant screening location. An empty breakdown for a message you expected to be
screened means the policy does not run that detector at that location; it is a
configuration matter, not a problem with your request. Review the policy’s
advanced settings to see which
detectors are bound where, and cross-reference the detector_id values in the breakdown
with the policy configuration and the platform logs.