The five checks
A guard has one method per point where text crosses a trust boundary.
| Method | Stage | Checks | Context available to policies |
|---|---|---|---|
check_input(text, *, redactions=None, history=()) | input | The user message | Earlier turns |
check_untrusted(text, *, question=None, redactions=None) | untrusted | A retrieved page or document | The user question it was retrieved for |
check_tool_call(name, arguments, *, prompt, redactions=None) | tool_call | The tool name and arguments the model chose | The tool name, and the user turn for context-aware judgments |
check_tool_result(text, *, name, prompt=None, redactions=None) | tool_result | The tool's response | The user turn, and the tool name |
check_output(text, *, prompt, sources=(), redactions=None, history=()) | output | The complete reply | The prompt, retrieved sources, and earlier turns |
Tool calls have their own guide: Tool calls and agents.
Forward onward
Every result has onward: the sanitized text when the check is ok, and a
refusal when it isn't. Pass it to the next step without branching:
incoming = guard.check_input(user_text)
reply = call_model(incoming.onward) # the model sees sanitized text, or the refusal
onward has the exact rules.
A retrieval-augmented turn
from jes import Guard
from jes.policies import (
hazards,
indirect_injection,
injection,
invisible_text,
pii,
secrets,
token_limit,
topics,
)
guard = Guard(
[
invisible_text(),
secrets(),
pii(),
token_limit(4096),
injection(threshold=0.8),
indirect_injection(threshold=0.8),
hazards(threshold=0.8),
topics(["medical advice"], threshold=0.7),
],
model="jev-1.13.0",
)
def answer(user_text: str, retrieved: list[str]) -> str:
incoming = guard.check_input(user_text)
if not incoming.ok:
return incoming.onward
documents = [guard.check_untrusted(doc, question=incoming) for doc in retrieved]
safe_documents = [d for d in documents if d.ok]
context = [d.onward for d in safe_documents]
reply = call_model(incoming.onward, context) # your model call
outgoing = guard.check_output(reply, prompt=incoming, sources=safe_documents)
return outgoing.onward
The thresholds above are example choices, not recommendations.
Pass incoming and safe_documents as context, not their strings. A result
that shares the check's Redactions store is reused as is, and a blocked one
adds a blocking context_not_ok finding. A raw string, or a result from
another store, is sanitized again. See the Guard reference.
The runnable version of this flow is The model call cookbook page.