AI Automation with Python
A Practical Guide
Build controlled business workflows where AI understands unstructured information and Python validates, routes, executes, retries, logs, and measures the result.
What you will build
30-second explanation
AI automation is a controlled workflow where AI handles uncertain language and Python handles deterministic execution.
AI model
Understands, classifies, extracts, summarises, compares, and drafts.
Python
Validates, calculates, routes, saves, retries, logs, authorises, and executes.
Understand
Traditional automation vs AI automation
Traditional automation
↓
Fixed rules
↓
Deterministic result
Best for:
- • Calculations
- • Exact validation
- • Database updates
- • Fixed routing rules
- • Predictable transformations
AI automation
↓
AI interpretation
↓
Structured result
↓
Deterministic workflow
Best for:
- • Classification
- • Summarisation
- • Information extraction
- • Draft generation
- • Ambiguous language
Capabilities
Where AI adds value inside a workflow
LanguageUnderstand+
Interpret unstructured emails, documents, notes, forms, and user requests.
Example
Understand that “I cannot see my dashboard after changing my password” describes an access problem.
Decision supportClassify+
Assign categories, priorities, sentiment, departments, or workflow paths.
Example
Classify an incoming message as access, billing, performance, security, or other.
StructureExtract+
Convert messy language into validated fields that software can process.
Example
Extract invoice number, date, amount, supplier, and payment terms.
CompressionSummarise+
Reduce long information into concise, decision-ready summaries.
Example
Convert a long support email into a two-sentence issue summary.
DraftingGenerate+
Create reports, replies, updates, recommendations, and structured documents.
Example
Prepare a customer-response draft for a support agent to review.
WorkflowRoute+
Use structured AI output to trigger deterministic Python workflow logic.
Example
Send security issues to the security team and normal access issues to identity support.
Architecture
The complete AI automation flow
Input
Email, file, API, or database
Python
Prepare and minimise
AI task
Analyse language
Structure
Typed model output
Validate
Schema and rules
Execute
API or workflow action
Review
Human when required
Build
Implementation roadmap
Define
Document the manual process, expected outcome, inputs, rules, risks, and success metrics.
Isolate
Identify the specific language task where AI adds value.
Structure
Define a typed schema for the information the workflow requires.
Generate
Ask the model to analyse the input and return structured output.
Validate
Apply schema validation and deterministic business rules.
Execute
Perform approved actions using Python, APIs, queues, and integrations.
Measure
Track quality, cost, latency, manual review, failures, and business value.
Practical project
Automate support-ticket intake
The automation will receive a support message and produce a validated analysis containing summary, category, priority, sentiment, recommended team, and whether human review is required.
Message
Customer issue
Analyse
AI understands content
Structure
Typed result
Validate
Python checks rules
Route
Select team
Review
Escalate if needed
Step 1
Set up the Python environment
mkdir ai-ticket-automation
cd ai-ticket-automation
python -m venv .venv
source .venv/bin/activate
pip install --upgrade openai pydanticStore your API key in an environment variable.
export OPENAI_API_KEY="your-api-key"
# Confirm that the variable exists without printing the secret.
python -c "import os; print(bool(os.getenv('OPENAI_API_KEY')))"Step 2
Define the structured output
The schema becomes the contract between the AI model and the Python workflow.
from typing import Literal
from pydantic import BaseModel, Field
class TicketAnalysis(BaseModel):
summary: str = Field(
description="A concise description of the customer issue."
)
category: Literal[
"access",
"billing",
"performance",
"security",
"other",
]
priority: Literal[
"low",
"medium",
"high",
"critical",
]
sentiment: Literal[
"positive",
"neutral",
"frustrated",
"angry",
]
recommended_team: Literal[
"identity-support",
"billing-support",
"application-support",
"security-operations",
"general-support",
]
requires_human_review: bool
suggested_next_action: strStep 3
Analyse the ticket with Structured Outputs
import os
from openai import OpenAI
MODEL = os.getenv("OPENAI_MODEL", "gpt-5.6")
client = OpenAI()
def analyse_ticket(ticket_text: str) -> TicketAnalysis:
cleaned_text = ticket_text.strip()
if not cleaned_text:
raise ValueError("ticket_text cannot be empty")
response = client.responses.parse(
model=MODEL,
input=[
{
"role": "system",
"content": (
"You analyse incoming software support tickets. "
"Classify only from the allowed schema values. "
"Use critical priority only for severe business impact, "
"security incidents, or complete service unavailability. "
"Set requires_human_review to true for security issues, "
"critical priority, unclear requests, or sensitive cases. "
"Do not invent facts that are not present in the ticket."
),
},
{
"role": "user",
"content": cleaned_text,
},
],
text_format=TicketAnalysis,
)
result = response.output_parsed
if result is None:
raise RuntimeError(
"The model did not return a structured ticket analysis."
)
return resultStep 4
Apply deterministic Python rules
The AI recommends a structured interpretation. Python remains responsible for policy and workflow decisions.
TEAM_BY_CATEGORY = {
"access": "identity-support",
"billing": "billing-support",
"performance": "application-support",
"security": "security-operations",
"other": "general-support",
}
def validate_business_rules(
analysis: TicketAnalysis,
) -> TicketAnalysis:
expected_team = TEAM_BY_CATEGORY[analysis.category]
if analysis.recommended_team != expected_team:
analysis.recommended_team = expected_team
if analysis.category == "security":
analysis.priority = "critical"
analysis.requires_human_review = True
if analysis.priority == "critical":
analysis.requires_human_review = True
return analysis
def requires_escalation(
analysis: TicketAnalysis,
) -> bool:
return (
analysis.priority == "critical"
or analysis.category == "security"
or analysis.requires_human_review
)Step 5
Route the ticket safely
from dataclasses import dataclass
from enum import StrEnum
class WorkflowStatus(StrEnum):
RECEIVED = "received"
PROCESSING = "processing"
CLASSIFIED = "classified"
VALIDATED = "validated"
HUMAN_REVIEW = "human_review"
ROUTED = "routed"
COMPLETED = "completed"
FAILED = "failed"
@dataclass
class WorkflowResult:
status: WorkflowStatus
analysis: TicketAnalysis | None = None
message: str | None = None
def route_ticket(
analysis: TicketAnalysis,
) -> WorkflowResult:
if requires_escalation(analysis):
return WorkflowResult(
status=WorkflowStatus.HUMAN_REVIEW,
analysis=analysis,
message=(
"Ticket requires human review before "
"creating or updating an external record."
),
)
# Replace this section with an approved Jira,
# ServiceNow, database, or internal API integration.
print(
f"Routing ticket to {analysis.recommended_team}"
)
return WorkflowResult(
status=WorkflowStatus.COMPLETED,
analysis=analysis,
message="Ticket routed successfully.",
)Complete implementation
Put the workflow together
import os
from dataclasses import dataclass
from enum import StrEnum
from typing import Literal
from openai import OpenAI
from pydantic import BaseModel, Field
MODEL = os.getenv("OPENAI_MODEL", "gpt-5.6")
client = OpenAI()
class TicketAnalysis(BaseModel):
summary: str = Field(
description="A concise description of the customer issue."
)
category: Literal[
"access",
"billing",
"performance",
"security",
"other",
]
priority: Literal[
"low",
"medium",
"high",
"critical",
]
sentiment: Literal[
"positive",
"neutral",
"frustrated",
"angry",
]
recommended_team: Literal[
"identity-support",
"billing-support",
"application-support",
"security-operations",
"general-support",
]
requires_human_review: bool
suggested_next_action: str
class WorkflowStatus(StrEnum):
RECEIVED = "received"
PROCESSING = "processing"
CLASSIFIED = "classified"
VALIDATED = "validated"
HUMAN_REVIEW = "human_review"
ROUTED = "routed"
COMPLETED = "completed"
FAILED = "failed"
@dataclass
class WorkflowResult:
status: WorkflowStatus
analysis: TicketAnalysis | None = None
message: str | None = None
TEAM_BY_CATEGORY = {
"access": "identity-support",
"billing": "billing-support",
"performance": "application-support",
"security": "security-operations",
"other": "general-support",
}
def analyse_ticket(ticket_text: str) -> TicketAnalysis:
cleaned_text = ticket_text.strip()
if not cleaned_text:
raise ValueError("ticket_text cannot be empty")
response = client.responses.parse(
model=MODEL,
input=[
{
"role": "system",
"content": (
"You analyse incoming software support tickets. "
"Classify only from the allowed schema values. "
"Use critical priority only for severe business impact, "
"security incidents, or complete service unavailability. "
"Set requires_human_review to true for security issues, "
"critical priority, unclear requests, or sensitive cases. "
"Do not invent facts that are not present in the ticket."
),
},
{
"role": "user",
"content": cleaned_text,
},
],
text_format=TicketAnalysis,
)
result = response.output_parsed
if result is None:
raise RuntimeError(
"The model did not return a structured ticket analysis."
)
return result
def validate_business_rules(
analysis: TicketAnalysis,
) -> TicketAnalysis:
expected_team = TEAM_BY_CATEGORY[analysis.category]
if analysis.recommended_team != expected_team:
analysis.recommended_team = expected_team
if analysis.category == "security":
analysis.priority = "critical"
analysis.requires_human_review = True
if analysis.priority == "critical":
analysis.requires_human_review = True
return analysis
def requires_escalation(
analysis: TicketAnalysis,
) -> bool:
return (
analysis.priority == "critical"
or analysis.category == "security"
or analysis.requires_human_review
)
def route_ticket(
analysis: TicketAnalysis,
) -> WorkflowResult:
if requires_escalation(analysis):
return WorkflowResult(
status=WorkflowStatus.HUMAN_REVIEW,
analysis=analysis,
message=(
"Ticket requires human review before "
"creating or updating an external record."
),
)
print(
f"Routing ticket to {analysis.recommended_team}"
)
return WorkflowResult(
status=WorkflowStatus.COMPLETED,
analysis=analysis,
message="Ticket routed successfully.",
)
def process_ticket(
ticket_text: str,
) -> WorkflowResult:
try:
analysis = analyse_ticket(ticket_text)
validated = validate_business_rules(analysis)
return route_ticket(validated)
except Exception as exc:
return WorkflowResult(
status=WorkflowStatus.FAILED,
message=str(exc),
)
if __name__ == "__main__":
ticket = """
Since this morning, nobody in our finance department
can access the dashboard after resetting their passwords.
The browser shows an authentication error.
This is blocking our month-end reporting.
"""
result = process_ticket(ticket)
print(f"Status: {result.status}")
if result.analysis:
print(
result.analysis.model_dump_json(indent=2)
)
if result.message:
print(result.message)Workflow state
Make processing visible and recoverable
RECEIVED
The input has entered the system.
PROCESSING
The Python worker is analysing the input.
CLASSIFIED
The AI result has been produced.
VALIDATED
Schema and business rules have passed.
ROUTED
The workflow destination has been selected.
COMPLETED
The approved workflow action has finished.
HUMAN_REVIEW
Output needs approval or clarification.
RETRY_REQUIRED
A temporary external failure may be retried.
FAILED
Processing stopped and needs investigation.
Reliability
Use queues for production workloads
Request
New work arrives
Queue
Store pending work
Worker
Process asynchronously
AI call
Analyse input
Retry
Handle temporary failure
DLQ
Preserve final failures
Queues are especially useful for rate limits, large documents, batch processing, model downtime, email volumes, and workflows that should continue even when one downstream service is unavailable.
Production system
AI automation is more than one Python script
Input
Email, file, API event, form, database record, message, or scheduled job.
Queue
Buffers work, supports retries, and separates user requests from long-running processing.
Worker
Python service that prepares input, calls the model, validates output, and executes workflow logic.
AI model
Handles the uncertain language task such as classification, extraction, or summarisation.
Validation
Applies schemas, allowed values, business rules, permissions, and safety checks.
Integration
Updates Jira, ServiceNow, Slack, email, databases, dashboards, or internal APIs.
Observability
Records logs, metrics, traces, quality signals, cost, and business outcomes.
Human review
Handles sensitive, uncertain, high-priority, or policy-controlled cases.
Add trusted knowledge
Where RAG fits
Ticket
Incoming issue
Retrieve
Search documentation
Evidence
Approved knowledge
Analyse
AI uses context
Validate
Python checks output
Route
Execute workflow
RAG is one context source inside the automation. Python still owns validation, routing, permissions, execution, and workflow state.
Read the complete RAG guide →Compare
AI automation vs AI agents
| Area | AI automation | AI agent |
|---|---|---|
| Workflow | Mostly predefined | May choose the next step dynamically |
| Control | Easier to predict and constrain | Requires stronger limits and policy controls |
| Testing | Clear paths and expected states | More possible action sequences |
| Best use | Repeated business processes | Uncertain multi-step work |
| Starting point | Recommended for most teams | Add only when flexibility creates real value |
Security
Secure the complete workflow
Minimise data
Send only the content required for the specific AI task.
Protect secrets
Keep credentials, API keys, and private tokens outside prompts and source code.
Validate output
Treat every model response as untrusted until checked by the application.
Restrict integrations
Use least-privilege credentials for Jira, Slack, email, databases, and other systems.
Approve risky actions
Require explicit human review before external, financial, destructive, or sensitive operations.
Control logging
Record useful operational information without retaining unnecessary sensitive content.
Measure
Evaluate AI quality and business value
Classification accuracy
How often does the automation select the expected category and priority?
Extraction accuracy
Are important fields correctly extracted from representative inputs?
Invalid-output rate
How often does processing fail schema or business validation?
Escalation accuracy
Are sensitive and high-risk cases sent to human review correctly?
Processing time
How long does the workflow take compared with the previous manual process?
Manual-review rate
What percentage of work still requires intervention?
Cost per item
What is the total cost to process one email, ticket, document, or report?
Business outcome
Does the workflow improve response time, quality, throughput, or user satisfaction?
Cost
Calculate the whole automation cost
Build next
Strong first automation projects
Support-ticket intake
Summarise, classify, prioritise, route, and flag incoming customer issues.
Document processing
Extract fields, classify content, identify missing information, and prepare records.
Meeting follow-up
Transform notes into decisions, actions, owners, deadlines, and follow-up communication.
Report generation
Convert raw metrics and operational updates into structured weekly or executive reports.
Email triage
Summarise messages, detect urgency, assign categories, and prepare reply drafts.
Knowledge-assisted workflow
Retrieve approved information with RAG before generating a recommendation or response.
Avoid
Common AI automation mistakes
Automating an unclear process
A broken or unstable manual process usually becomes a broken automated process.
Using AI for deterministic logic
Calculations, fixed validation, permissions, and exact business rules belong in normal code.
Free-form output
Long natural-language responses are difficult for downstream software to use safely.
No workflow states
Without clear states, failures and retries become difficult to diagnose and recover.
No retry strategy
Temporary rate limits and service failures should not permanently lose work.
No human review
Sensitive or uncertain decisions should not be fully automated without appropriate approval.
Ignoring business metrics
A technically working automation may still create no meaningful time or cost savings.
Building an agent too early
Dynamic autonomy adds complexity before the underlying workflow has been understood.
Production checklist
Before launching an AI automation
Key takeaway
Let AI interpret. Let Python control.
Use AI for language understanding, extraction, classification, summarisation, and drafting. Use Python for schemas, calculations, permissions, workflow states, business rules, retries, execution, logging, and approval.
Remember the production pattern:
Define the process → isolate the AI task → request structured output → validate with Python → apply business rules → execute safely → measure real value.
Continue learning
Extend automation with agents, knowledge, and security
Dynamic workflows
Build Your First AI Agent
Add controlled tool selection and execution loops when fixed automation is no longer enough.
Knowledge
RAG Explained
Add trusted documents, retrieval, metadata, permissions, and citations to your workflow.
Security
AI Security Basics
Secure model input, structured output, RAG content, integrations, and high-risk actions.