AI Engineering
The model is one component. The system is the work.
Calling an API is the easy part and it is not where AI products fail. They fail on control flow, retrieval quality, output contracts, evaluation and everything that happens after deployment.
A reference architecture
This is the shape most of my AI work takes. The capabilities below are not a skills list — each one is a layer of this diagram, and they are only worth anything together.
Two layers do most of the work in practice: the orchestration layer, which decides what happens and when a person is involved, and the contracts layer, which stops a bad model response from becoming a bad application state.
Interface
Application
Server components · streaming
Channels
Chat · API · scheduled triggers
Boundary
Validation
Typed request schemas
Auth + policy
Who may ask for what
Rate limiting
Cost and abuse control
Orchestration
Agent graph
Explicit state · routing · retries
Human-in-the-loop
Escalation on low confidence
Capabilities
Reasoning
LLM with a bounded role
Retrieval
Vector search · reranking
Tools
Typed calls into real systems
Contracts
Structured output
Schema-validated at the boundary
Citations
Provenance carried with the answer
Operations
Evaluation
Fixed question set · baselines
Observability
Traces of steps and retrievals
Queues + workers
Slow work off the request path
State
Vector store
Chunks · embeddings · sources
Application data
Records and audit trail
AI Engineering
What I actually do when I build an AI system
Capability described through implementation. Every practice below exists in code, not just in a list of technologies.
AI Agents
Agents are control flow before they are prompts. I build them as explicit graphs — ordered steps, concurrent branches, and routing that depends on state — so a failing step can be identified instead of a whole prompt being suspect.
- Sequential, parallel and conditional workflow graphs, implemented rather than diagrammed
- State passed explicitly between nodes so each transition is inspectable
- Tool calls treated as a typed boundary, not as free-text the model improvises
- Concurrent execution for steps with no data dependency between them
- Escalation paths for the cases an agent should not decide alone
- LangGraph
- LangChain
- Python
- Tool calling
Retrieval-Augmented Generation
Most RAG systems fail at retrieval, not at generation. I treat ingestion, chunking and retrieval as the parts with the quality problem, and provenance as a requirement rather than a feature.
- Headless-browser ingestion so client-rendered sources are captured instead of returning empty shells
- Overlapping chunk windows so a fact spanning a boundary survives whole in at least one chunk
- Batched embedding per document, which is the difference between minutes and hours of ingestion
- Source URL stored beside every vector, captured at write time so citations are real
- Multi-query retrieval to raise recall; contextual compression to raise precision
- One embedding model on both sides of the pipeline, enforced by construction
- OpenAI embeddings
- Astra DB
- FAISS
- Chroma
- LangChain retrievers
LLM Applications
The boundary between a model and application code is where LLM products break. Anything crossing it gets a schema, so a malformed response fails at the boundary instead of propagating.
- Structured output constrained by Pydantic models and TypedDict schemas
- Validation at the boundary, so an invalid response is an error rather than a silent bad value
- Prompts held as configuration, so behaviour can be tuned without a deployment
- Context budget managed deliberately — pruning retrieved documents rather than truncating blindly
- Streaming responses on standard Node.js runtimes, no special-cased infrastructure
- OpenAI API
- Pydantic
- Zod
- Next.js route handlers
Intelligent Automation
An AI feature only creates value when it is wired into the systems where work actually happens. That means queues, schedules, webhooks and delivery — the unglamorous half that decides whether anything reaches a person.
- Slow and scheduled work moved onto Redis-backed queues, off the request path
- Scheduled jobs that run on their own clock rather than on a user's click
- Two-tier delivery: realtime sockets for connected clients, push for everyone else
- Document and export pipelines — PDF and CSV generation as background jobs
- One shared transport per integration, so a provider change touches one module
- Bull
- Redis
- Socket.IO
- Firebase Cloud Messaging
- Resend
AI Reliability
A demo has to work once. A system has to keep working while inputs, models and providers change underneath it. That difference is mostly boring engineering, and it is the part I care most about.
- Integration tests against real API surfaces backed by in-memory infrastructure
- Continuous integration that builds and tests every push before it merges
- Fail-fast configuration checks, so a misconfigured service refuses to start rather than failing later
- Validation, sanitisation and rate limiting applied at the boundary, not per handler
- Explicit failure surfaces — a missing provider produces a visible error, never a silently dropped message
- Jest
- Supertest
- GitHub Actions
- Joi
- Helmet
Production Delivery
Architecture that cannot be deployed is a proposal. I build for the constraints of the target platform from the start — stateless compute, external storage, environment-scoped secrets.
- Stateless compute with external object storage, because serverless filesystems do not persist
- One codebase that runs as a long-lived server locally and as a function in production
- Secrets read from the environment only, never bundled and never committed
- Versioned migration and seed scripts instead of manual database edits
- Idempotent provisioning, so re-running setup is safe
- Vercel
- GitHub Actions
- Cloudinary
- MongoDB
- Docker-free deploys
Engineering philosophy
I don’t build AI demos.
I build AI systems.
A demo has to work once, for someone who wants it to. A system has to keep working while inputs change, providers change and nobody is watching. Almost everything that separates the two is ordinary engineering.
Reliability
A model is a probabilistic component inside a deterministic system. The system's job is to make the unpredictable part safe: validate what comes back, constrain what it can do, and define behaviour for the case where it is wrong.
Observability
If you cannot see what an agent did, you cannot fix it. Explicit state transitions, logged tool calls and retrieval traces turn 'the answer was bad' into a specific step that misbehaved.
Security
AI systems handle credentials and private data by default. Secrets stay in the environment, inputs are validated and sanitised at the boundary, and access is enforced centrally rather than per handler.
Scalability
Slow work belongs on a queue, not in a request. Compute stays stateless so it can be replicated, and state lives where it can be shared — which is what makes growth a configuration change rather than a rewrite.
Human in the loop
The most important thing an agent can know is when to stop. Irreversible actions, low-confidence answers and unfamiliar situations should route to a person by design, not by accident.
Evaluation
Prompt changes are code changes without tests unless you measure them. A fixed question set, a retrieval quality baseline and a regression check make an improvement provable instead of anecdotal.
How I build AI systems
AI as software engineering, not experimentation alone
The order matters more than the steps. Most AI projects that fail were built correctly and aimed at the wrong problem, or shipped without any way to tell whether a change made them better.
- 01
Understand the problem
What decision or task is this actually replacing, who depends on it, and what does being wrong cost? Most AI projects that fail were correctly built and aimed at the wrong problem.
- 02
Design the architecture
Decide what the model is responsible for and what it is not. Draw the data path, name the failure modes, and pick where a human belongs — before any code exists.
- 03
Build the system
Typed boundaries, schema-constrained model output, thin handlers, secrets in the environment. The AI is one component in a system built to normal engineering standards.
- 04
Evaluate
Measure retrieval quality and answer behaviour against a fixed question set. Establish a baseline first, so later changes can be shown to be improvements rather than assumed to be.
- 05
Deploy to production
Stateless compute, external storage, environment-scoped configuration, CI that builds and tests before merge. Deployment is a property of the design, not a step at the end.
- 06
Monitor and improve
Watch what users actually ask, where retrieval misses and where the system escalates. Real usage is the only source of the next set of improvements worth making.
Technical stack
Tools I have actually shipped with
Restricted to technologies that appear in real work. A longer list would be easy to write and worth less to read.
AI
Agent orchestration, retrieval and output contracts.
- Python
- LangGraph
- LangChain
- OpenAI API
- Embeddings
- RAG pipelines
- Tool calling
- Structured output
- Pydantic
Backend
APIs, access control and asynchronous work.
- Node.js
- Express
- REST APIs
- JWT + RBAC
- Socket.IO
- Bull queues
- Joi
- PDFKit
Data
Relational, document and vector storage.
- MongoDB
- Mongoose
- Redis
- Astra DB
- FAISS
- Chroma
- Prisma
- GraphQL
Frontend
Typed, server-rendered interfaces.
- Next.js
- React
- TypeScript
- Tailwind CSS
- Vite
- shadcn/ui
- Radix UI
Infrastructure
Deployment, CI and platform services.
- Vercel
- GitHub Actions
- Git
- Supabase
- Cloudinary
- Firebase
- Resend
Quality
Proving the system still works after a change.
- Jest
- Supertest
- mongodb-memory-server
- ESLint
- Prettier
- Zod
Contact
Have an AI product or workflow worth building?
Send me the problem — not the spec. If it’s a fit I’ll tell you how I’d approach it; if it isn’t, I’ll say so.
Faisalabad, Pakistan · PKT (UTC+5) · Working remotely