Content moderation for Strands Agents
Arcjet content moderation detects harmful content in untrusted text before it
is stored, displayed, or forwarded. It is a Guard rule – call it from
guard() / Guard, not protect().
What is Arcjet?
Arcjet is the runtime security platform that ships with your code. Enforce budgets, stop prompt injection, detect bots, and protect personal information with Arcjet's AI security building blocks.Quick start
Section titled “Quick start”This example screens inbound text with content moderation before the agent continues.
We assume you already have a Strands Agents project set up. For helper options and denial behavior, see the Strands Agents agent guard.
Install the dependencies:
# Export your Arcjet API key from https://console.arcjet.comexport ARCJET_KEY="ajkey_..."
npm install @arcjet/guard @strands-agents/sdk zodCreate the example:
import { launchArcjet, moderateContent } from "@arcjet/guard";import { strandsAgentContext } from "@arcjet/guard/strands-agents/v1";
const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });const moderate = moderateContent();
export async function screenPrompt(conversationId: string, userText: string) { const invocationState = { sessionId: conversationId }; const decision = await arcjet.guard({ label: "message.received", rules: [moderate(userText)], ...strandsAgentContext({ invocationState }), });
if ( decision.conclusion === "DENY" && decision.reason === "MODERATE_CONTENT" ) { throw new Error("Harmful content detected – rephrase your message"); }}Then start or invoke the agent with a test prompt.
Requests appear in your Arcjet dashboard in real time.
This example screens inbound text with content moderation before the agent continues.
We assume you already have a Strands Agents project set up. For helper options and denial behavior, see the Strands Agents agent guard.
Install the dependencies:
# Export your Arcjet API key from https://console.arcjet.comexport ARCJET_KEY="ajkey_..."export ARCJET_ENV=development
pip install "arcjet[strands-agents]"Create the example:
import os
from arcjet.guard import ModerateContent, launch_arcjetfrom arcjet.guard.strands_agents import strands_agent_context
arcjet = launch_arcjet(key=os.environ["ARCJET_KEY"])moderate = ModerateContent()
async def screen_prompt(conversation_id: str, user_text: str) -> None: app_context = {"session_id": conversation_id} derived = strands_agent_context(app_context)
decision = await arcjet.guard( label="message.received", rules=[moderate(user_text)], correlation_id=derived.correlation_id, ) if ( decision.conclusion == "DENY" and decision.reason == "MODERATE_CONTENT" ): raise RuntimeError( "Harmful content detected – rephrase your message" )Then start or invoke the agent with a test prompt.
Requests appear in your Arcjet dashboard in real time.
Language examples
Section titled “Language examples”npm install @arcjet/guardimport { launchArcjet, moderateContent } from "@arcjet/guard";
const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });const moderate = moderateContent();
const decision = await arcjet.guard({ label: "tools.chat", rules: [moderate(userMessage)],});
if (decision.conclusion === "DENY" && decision.reason === "MODERATE_CONTENT") { throw new Error("Harmful content detected – rephrase your message");}
const result = moderate.result(decision);// `detected` is true when harmful content was found. Billing is undefined// when the service does not report usage. Content moderation uses text_units.console.log(result?.detected, result?.billing?.unit, result?.billing?.count);pip install arcjetimport os
from arcjet.guard import ModerateContent, launch_arcjet
arcjet = launch_arcjet(key=os.environ["ARCJET_KEY"])moderate = ModerateContent()
decision = await arcjet.guard( label="llm.output", rules=[moderate(text)],)
if decision.conclusion == "DENY" and decision.reason == "MODERATE_CONTENT": raise RuntimeError("Harmful content detected – rephrase your message")
result = moderate.result(decision)# `detected` is True when harmful content was found. Billing is None# when the service does not report usage. Content moderation uses text_units.print(result.detected if result else None)if result and result.billing: print(result.billing.unit, result.billing.count)go get github.com/arcjet/arcjet-go@latestmoderation, err := arcjet.GuardModerateContent(arcjet.GuardModerateContentOptions{ Mode: arcjet.ModeLive, // required})if err != nil { return err}
decision, err := guard.Guard(ctx, arcjet.GuardRequest{ Label: "tools.generate", Rules: []arcjet.GuardRuleInput{moderation.Text(userMessage)},})if err != nil { return err}if decision.IsDenied() && decision.Reason == arcjet.ReasonModerateContent { return errors.New("content flagged by moderation")}
// Billing is optional. Content moderation usage is measured in text_units.if result := moderation.Result(decision); result != nil && result.Billing != nil { fmt.Printf("charged %d %s\n", result.Billing.Count, result.Billing.Unit)}Set Mode on every Guard rule. An empty Mode returns ErrInvalidMode.
Keep the response generic. Do not leak detector details or explain exactly what was flagged.