Imagine you ask a new co-worker to summarize the risks of a complex project. Sometimes they send you a neat bulleted list. Other times, they send a rambling paragraph, a haiku, or a completely irrelevant meme. This unpredictability is frustrating—and it's exactly what happens when you plug raw Large Language Model (LLM) output directly into critical software.
Problem framing: Why "raw LLM calls" are not enough
Most teams begin by calling APIs like openai.chat.completions.create directly, hoping the LLM will produce reliable outputs. However, this approach quickly runs into issues: inconsistent response formats, potential policy violations, and crucially, no centralized logging or validation. Without controls, the outputs can vary wildly, causing huge risks in enterprise workflows. This is where the Guard object comes into play—it acts as a "gateway" that wraps these calls, enforces a specification, and provides a uniform, validated output along with history and validation status for observability.
What is a Guard object in simple terms
A Guard is essentially a Python object that wraps LLM API calls, validates the outputs against a user-defined schema or specification (such as RAIL or Pydantic), can automatically re-ask the LLM to correct invalid responses, and logs all calls for auditing. It can operate with no configuration for simple string outputs or with structured specs that enforce strict data formats, enhancing reliability in production environments.
Architecture: Where Guard fits in an enterprise/agentic stack
Visualize the flow as:
This means every interaction with the LLM or connected tools is mediated through the Guard. Guard centralizes validation logic, error handling and retry mechanisms, and maintains a detailed history, making it easier to audit and troubleshoot AI behavior in complex workflows.
Core flow 1 – wrapping LLM calls with Guard.call
The most common usage involves calling Guard.__call__ where you provide the model name and messages. The Guard internally calls the LLM, validates the output against the spec, and returns a GuardResponse object that contains: the raw LLM text output, the validated and typed output, and a flag indicating if validation was successful. This ensures that downstream systems, such as trading workflows, ticketing systems, or CRM updates, receive "checked and typed" outputs they can depend on without manual intervention.
Example: Basic guarded chat call
from guardrails import Guard
# Initialize the Guard object (defaults to string outputs)
guard = Guard()
response = guard(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "Summarize the key risks of high-frequency trading in 3 bullet points."}],
)
print("Raw LLM output:\n", response.raw_llm_output)
print("\nValidated output:\n", response.validated_output)
print("\nValidation passed:", response.validation_passed)
This simple integration makes every LLM response safer and more predictable, transforming raw, best-effort text into reliable data your enterprise applications can trust.
Conclusion
By wrapping raw LLM calls with a Guard object that performs validation, logging, and error recovery, enterprises significantly reduce the unpredictability risks and move towards scalable, auditable agentic AI deployments.