Every small business runs on the same busywork: sorting email, summarizing documents, rewriting content for different channels, typing invoice numbers into spreadsheets, and turning meeting chaos into action items. None of it needs a human anymore.
In this guide I'll show you the pattern behind AI workflow automation, build one complete tool with you — an email classifier that triages your inbox and drafts replies — and then show you how the same pattern handles four more workflows. Everything runs on a free API. Total cost: ₹0 / $0.
The pattern behind every AI automation
Every tool in this post is the same three moves:
- Read — load files (emails, PDFs, notes) with plain Python
- Ask — send the content to an LLM with a carefully written instruction
- Write — save the structured answer somewhere useful (CSV, Markdown, text files)
No frameworks, no servers, no "agent platforms." A script, a prompt, and a loop. Once you've built one, you can build a dozen.
Prerequisites
- Python 3.10+
- A free API key from console.groq.com (their free tier runs fast open models — perfect for this)
pip install openai python-dotenv
We use the openai library pointed at Groq — same API, zero cost.
Build it: the email triage tool
Point this script at a folder of emails (as .txt files). For each one it decides the category, judges urgency, writes a one-line summary, and drafts a reply. You get a CSV you can open in Excel, plus a ready-to-edit reply for every email.
Create email_classifier.py:
"""Email Classifier & Reply Drafter.
Usage: python email_classifier.py emails_folder --out results
"""
import argparse
import csv
import json
import os
from pathlib import Path
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(
api_key=os.getenv("LLM_API_KEY"),
base_url=os.getenv("LLM_BASE_URL") or None,
)
MODEL = os.getenv("LLM_MODEL", "openai/gpt-oss-20b")
CATEGORIES = [
"sales_inquiry", "support_request", "billing_question",
"complaint", "partnership", "spam_or_irrelevant", "other",
]
SYSTEM = f"""You are an email triage assistant for a small business.
Classify the email, judge its urgency, and draft a short, professional,
friendly reply. Categories: {', '.join(CATEGORIES)}.
Return JSON: {{"category": "...", "urgency": "high|medium|low",
"summary": "one line", "draft_reply": "the reply text"}}
Respond with valid JSON only."""
def ask_json(email_text: str) -> dict:
resp = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": SYSTEM},
{"role": "user", "content": f"Email:\n\n{email_text}"},
],
response_format={"type": "json_object"},
max_tokens=800,
temperature=0.2,
)
return json.loads(resp.choices[0].message.content)
def process(folder: Path, out_dir: Path) -> None:
out_dir.mkdir(parents=True, exist_ok=True)
rows = []
for path in sorted(folder.glob("*.txt")):
print(f"Processing {path.name} ...")
result = ask_json(path.read_text(encoding="utf-8")[:6000])
rows.append({
"file": path.name,
"category": result.get("category", "other"),
"urgency": result.get("urgency", "medium"),
"summary": result.get("summary", ""),
})
reply = result.get("draft_reply", "")
(out_dir / f"reply_{path.stem}.txt").write_text(reply, encoding="utf-8")
with open(out_dir / "email_triage.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["file", "category", "urgency", "summary"])
writer.writeheader()
writer.writerows(rows)
print(f"Done: {out_dir}/email_triage.csv + draft replies")
if __name__ == "__main__":
ap = argparse.ArgumentParser()
ap.add_argument("folder", type=Path)
ap.add_argument("--out", type=Path, default=Path("results"))
args = ap.parse_args()
process(args.folder, args.out)
Create a .env file next to it:
LLM_API_KEY=your-groq-key
LLM_BASE_URL=https://api.groq.com/openai/v1
LLM_MODEL=openai/gpt-oss-20b
Run it:
python email_classifier.py my_emails --out results
When I tested this on three sample emails — a bulk-order inquiry, an angry damaged-order complaint, and a confused double-charge question — it categorized all three correctly, flagged only the complaint as high-urgency, and drafted a reply to the angry customer that apologized, asked for a photo, and offered a replacement or refund. A reply I'd actually send.
The two details that make it reliable
JSON mode. response_format={"type": "json_object"} forces the model to return parseable JSON instead of chatty prose. Structured output is what separates automation from a toy.
A strict system prompt. Notice the prompt lists the exact categories and the exact JSON shape. Vague prompts produce vague data. When you want different categories — "wholesale," "press," "refund" — you edit one line of English, not code.
The other four workflows (same pattern)
2. Document summarizer. Read a PDF with pypdf, send the text, ask for: executive summary, key points, action items. For long documents, split into ~9,000-character chunks, summarize each, then summarize the summaries. Output: a one-page Markdown brief.
3. Content repurposer. One blog post in, four outputs out — a LinkedIn post, an X thread, an Instagram caption, a newsletter blurb. The whole tool is one prompt describing each format's rules ("first tweet is a hook, each under 260 characters…").
4. Invoice → spreadsheet. The highest-ROI one for most businesses. Same JSON-mode trick: ask for vendor, invoice_number, date, subtotal, tax, total, append each result to a CSV. A folder of invoices becomes accounting-ready data in one command. One rule matters in the prompt: "Never guess amounts — copy them exactly from the document."
5. Meeting notes → action items. Paste your messy notes in, get decisions, an action-item table with owners and deadlines, and open questions out. The prompt's key rule: "Only include what is actually in the notes — never invent owners or dates." An AI that admits what it doesn't know is the difference between useful and dangerous.
What this costs to run
On Groq's free tier: nothing. On paid APIs: each email or invoice costs a fraction of a cent, because these scripts send only what's needed and cap the output length. Automating a hundred emails costs less than the electricity to read them.
Common issues
model_not_found — providers retire model names; check your provider's current list and update .env.
Invalid JSON errors — some models occasionally wrap JSON in code fences. Strip backticks before parsing, or use a model that supports strict JSON mode.
Garbage from scanned PDFs — pypdf extracts digital text. Scanned-image PDFs need OCR first (or skip them — the script should warn, not crash).
Want all five, ready to run?
I packaged all five tools — tested, documented, with sample inputs so each produces results in your first minute, and every behavior customizable by editing plain-English prompts:
AI Workflow Automation Pack — 5 Ready-to-Run Python Tools ($19)
I'm Sammishra — an AI engineer and published researcher. I build chatbots, RAG pipelines, and custom automations for businesses. See my work at *sammishra.hashnode.dev/work-with-me*, or email me at sammishrakh.freelancer@gmail.com.
Top comments (0)