Projects

All personal, all built solo and end to end. Tap a card for the hard part.

QuickBites Support Bot

A support agent built and tuned against an automated grader
FastAPIPostgreSQLAnthropic / GeminipytestCloud Run
↻ the hard part

Where the LLM stops

A simulator plays an escalating customer and a grader scores the transcript on six criteria. My one-prompt version drifted on refund amounts, caved to "do it now" pressure, and dropped paired actions.

Fix: one FastAPI handler runs a deterministic pre-pipeline into classify → propose → enforce in plain Python with about 60 tests → respond. The model proposes intent and confidence, nothing that moves money. Provider-agnostic LLM layer, one env var to swap Anthropic and Gemini.

Sreshtha

Contract analysis for India's gig workers
FastAPIReact 19Gemini / Vertex AISarvam MayuraEasyOCR
↻ the hard part

Reason in English, translate at the edge

Three Gemini 2.5 Flash stages annotate the contract against Indian labour law in English, where precedent density is highest, then Sarvam Mayura translates the finished text into one of seven languages.

An Aho-Corasick idiom library (about 200 microseconds per scan) swaps known idioms for placeholder tokens before translation and splices curated equivalents back after. Batching clauses per call cut a run from 11 minutes to under one. In-house OCR keeps worker documents on my infra.

OpenAI Parameter Golf

A tokenizer experiment for OpenAI's model-training challenge
PyTorchSentencePiece8xH100MLX
↻ the hard part

A semantic BPE tokenizer

Hypothesis: standard BPE wastes vocabulary on low-entropy function words. I trained a SentencePiece BPE that downsamples function words, then ran a seed-locked, architecture-identical A/B against the SOTA config so only the tokenizer changed.

Also fixed a PyTorch 2.4 / 2.5 break in the reference trainer: enable_gqa in scaled-dot-product attention, swapped for manual KV-head expansion.

Auralis

Full-stack CX operations platform (retired)
FastAPIReact 19pgvectorCeleryGKE
↻ the hard part

The full pattern in one system

Policy written as markdown, compiled by an LLM into structured rules, simulated against sample tickets and shadow-run before going live, then served from a vector store at resolution time. Five-phase deterministic ingestion, per-module RBAC, OAuth.

Ran on GKE with Dockerised services, nginx ingress, cert-manager TLS, GitHub Actions CI/CD and OpenTelemetry. Deployment retired, but it is the most complete build of this idea I have done.

Google-ADK agents

Two agents on Cloud Run, plus a bug in Google's codelab
Google ADKGeminiMCPCloud RunBigQuery
↻ the hard part

A silently-dropped guardrail

Building a BigQuery-MCP agent I found a real bug in Google's published codelab: tool_filter was passed to the wrong constructor and silently dropped, which left a non-readonly execute_sql tool exposed to the model.

Verified it live against the deployed revision, moved the argument to the right place, and re-verified that only the four intended tools were reachable.

Crickverse / Cricket Life RPG

A deterministic cricket game engine
PythonTypeScriptUnity 6 URPVitestBlender
↻ the hard part

Engine decides, model narrates

An event-sourced cricket core in Python and a pure deterministic TypeScript match engine (no I/O, Vitest) feeding a Unity 6 URP client with a Blender / MakeHuman character pipeline.

The engine resolves every delivery. The LLM is a paid commentary layer only, and free players make zero model calls.

Before that

Local-model tooling before it was convenient: llama.cpp, GPT4All, Stable Diffusion and ComfyUI, YOLOv5, speaker-embedding and TTS pipelines, MLX on Apple Silicon. Plus geospatial work, KML/KMZ processing and GeoJSON.