Generative AI

How to Build Contract-First Decision Systems with PydanticAI's Risk-Aware, Policy-Compliant Business AI

In this tutorial, we show how to design an agent-first decision system using PydanticAIit treats structured schemas as negotiable governance contracts rather than voluntary output formats. We show how to define a robust decision model that encodes policy compliance, risk assessment, confidence estimation, and next steps directly into the agent's output schema. By combining Pydantic's validators with PydanticAI's try-and-correct mechanisms, we ensure that the agent cannot generate inconsistent or non-compliant logical decisions. Throughout the work, we focus on building an enterprise-grade decision agent that reasons under constraints, making it suitable for real-world risk, compliance, and management scenarios instead of toy-based demos. Check it out FULL CODES here.

!pip -q install -U pydantic-ai pydantic openai nest_asyncio


import os
import time
import asyncio
import getpass
from dataclasses import dataclass
from typing import List, Literal


import nest_asyncio
nest_asyncio.apply()


from pydantic import BaseModel, Field, field_validator
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai import OpenAIProvider


OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
if not OPENAI_API_KEY:
   try:
       from google.colab import userdata
       OPENAI_API_KEY = userdata.get("OPENAI_API_KEY")
   except Exception:
       OPENAI_API_KEY = None
if not OPENAI_API_KEY:
   OPENAI_API_KEY = getpass.getpass("Enter OPENAI_API_KEY: ").strip()

We set up the execution environment by installing the required libraries and configure the Google Colab synchronous operation. We securely load the OpenAI API key and ensure that the runtime is ready to handle async calls. This establishes a stable basis for running the first contract agent without environmental related problems. Check it out FULL CODES here.

class RiskItem(BaseModel):
   risk: str = Field(..., min_length=8)
   severity: Literal["low", "medium", "high"]
   mitigation: str = Field(..., min_length=12)




class DecisionOutput(BaseModel):
   decision: Literal["approve", "approve_with_conditions", "reject"]
   confidence: float = Field(..., ge=0.0, le=1.0)
   rationale: str = Field(..., min_length=80)
   identified_risks: List[RiskItem] = Field(..., min_length=2)
   compliance_passed: bool
   conditions: List[str] = Field(default_factory=list)
   next_steps: List[str] = Field(..., min_length=3)
   timestamp_unix: int = Field(default_factory=lambda: int(time.time()))


   @field_validator("confidence")
   @classmethod
   def confidence_vs_risk(cls, v, info):
       risks = info.data.get("identified_risks") or []
       if any(r.severity == "high" for r in risks) and v > 0.70:
           raise ValueError("confidence too high given high-severity risks")
       return v


   @field_validator("decision")
   @classmethod
   def reject_if_non_compliant(cls, v, info):
       if info.data.get("compliance_passed") is False and v != "reject":
           raise ValueError("non-compliant decisions must be reject")
       return v


   @field_validator("conditions")
   @classmethod
   def conditions_required_for_conditional_approval(cls, v, info):
       d = info.data.get("decision")
       if d == "approve_with_conditions" and (not v or len(v) < 2):
           raise ValueError("approve_with_conditions requires at least 2 conditions")
       if d == "approve" and v:
           raise ValueError("approve must not include conditions")
       return v

We define a core decision contract using robust Pydantic models that accurately describe a valid decision. We encode logical constraints such as confidence-risk alignment, compliance-driven rejections, and conditional permissions directly into the schema. This ensures that any agent output must satisfy business logic, not just syntactic structure. Check it out FULL CODES here.

@dataclass
class DecisionContext:
   company_policy: str
   risk_threshold: float = 0.6




model = OpenAIChatModel(
   "gpt-5",
   provider=OpenAIProvider(api_key=OPENAI_API_KEY),
)


agent = Agent(
   model=model,
   deps_type=DecisionContext,
   output_type=DecisionOutput,
   system_prompt="""
You are a corporate decision analysis agent.
You must evaluate risk, compliance, and uncertainty.
All outputs must strictly satisfy the DecisionOutput schema.
"""
)

We inject the business context with a typed dependency and implement an OpenAI agent supported by PydanticAI. We configure the agent to produce only deterministic decisions that conform to a predefined contract. This step formalizes the separation between business context and model thinking. Check it out FULL CODES here.

@agent.output_validator
def ensure_risk_quality(result: DecisionOutput) -> DecisionOutput:
   if len(result.identified_risks) < 2:
       raise ValueError("minimum two risks required")
   if not any(r.severity in ("medium", "high") for r in result.identified_risks):
       raise ValueError("at least one medium or high risk required")
   return result




@agent.output_validator
def enforce_policy_controls(result: DecisionOutput) -> DecisionOutput:
   policy = CURRENT_DEPS.company_policy.lower()
   text = (
       result.rationale
       + " ".join(result.next_steps)
       + " ".join(result.conditions)
   ).lower()
   if result.compliance_passed:
       if not any(k in text for k in ["encryption", "audit", "logging", "access control", "key management"]):
           raise ValueError("missing concrete security controls")
   return result

We add output verifiers that act as governance checkpoints after the model generates a response. We require agents to identify reasonable risks and clearly reference applicable security controls when seeking compliance. If these constraints are violated, we initiate an automatic retry to force them to be repaired. Check it out FULL CODES here.

async def run_decision():
   global CURRENT_DEPS
   CURRENT_DEPS = DecisionContext(
       company_policy=(
           "No deployment of systems handling personal data or transaction metadata "
           "without encryption, audit logging, and least-privilege access control."
       )
   )


   prompt = """
Decision request:
Deploy an AI-powered customer analytics dashboard using a third-party cloud vendor.
The system processes user behavior and transaction metadata.
Audit logging is not implemented and customer-managed keys are uncertain.
"""


   result = await agent.run(prompt, deps=CURRENT_DEPS)
   return result.output




decision = asyncio.run(run_decision())


from pprint import pprint
pprint(decision.model_dump())

We use the agent for the actual decision request and capture the programmed verified output. We show how the agent evaluates risk, policy compliance, and confidence before making a final decision. This completes the end-to-end decision workflow in a production style setup.

In conclusion, we show how to move from free-form LLM results to controlled, reliable decision systems using PydanticAI. We show that by enforcing strong contracts at the schema level, we can automatically align decisions with policy requirements, risk tolerance, and reliability without rapid tuning. This approach allows us to build agents that fail safely, repair themselves when boundaries are violated, and produce testable, systematic results that downstream systems can trust. Finally, we show that the design of a contract-first agent enables us to use agent AI as a reliable decision-making layer within a manufacturing and business environment.


Check it out FULL CODES here. Also, feel free to follow us Twitter and don't forget to join our 100k+ ML SubReddit and Subscribe to Our newspaper. Wait! are you on telegram? now you can join us on telegram too.


Asif Razzaq is the CEO of Marktechpost Media Inc. As a visionary entrepreneur and engineer, Asif is committed to harnessing the power of Artificial Intelligence for the benefit of society. His latest endeavor is the launch of Artificial Intelligence Media Platform, Marktechpost, which stands out for its extensive coverage of machine learning and deep learning stories that sound technically sound and easily understood by a wide audience. The platform boasts of more than 2 million monthly views, which shows its popularity among viewers.

Source link

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button