Engineering lab
Small, focused experiments — and what each one taught me.
This is where I test ideas before they reach client work. Every entry shows its architecture, what was learned, and an honest implementation status. Source links appear as repositories are published.
15 experiments
- Generative AIImplemented
Schema-constrained document extraction
Extracting structured fields from long documents by pairing section-level prompts with strict Pydantic output schemas, so malformed responses fail fast.
Architecture
- Document
- Sectioner
- LLM + schema
- Validator
- Structured JSON
Learning outcomes
- Smaller, focused prompts beat one large prompt on both accuracy and cost.
- Validation errors are the most useful signal for improving prompts.
- Python
- Azure OpenAI
- Pydantic
- FastAPI
Source: not yet public - RAG SystemsImplemented
Hybrid retrieval: vectors plus fuzzy matching
Combining embedding similarity with lexical and fuzzy string scores to match short, domain-specific phrases where either signal alone is unreliable.
Architecture
- Query
- Embedding search
- Fuzzy scorer
- Score fusion
- Ranked matches
Learning outcomes
- Semantic search alone confidently matches look-alike terms; a lexical signal corrects this.
- Thresholds must be calibrated on labelled examples, not intuition.
- LangChain
- ChromaDB
- Sentence Transformers
- RapidFuzz
Source: not yet public - RAG SystemsIn progress
Chunking strategies compared
Measuring how fixed-size, structure-aware and semantic chunking affect retrieval quality on the same document set and question set.
Architecture
- Corpus
- Chunkers (×3)
- Index
- Retrieval eval
- Comparison
Learning outcomes
- Structure-aware chunking helps most on documents with clear headings and tables.
- Python
- FAISS
- Hugging Face
Source: not yet public - MCPImplemented
A read-only MCP server for a data source
Exposing a database to an LLM through the Model Context Protocol with read-only tools, parameter validation and row limits.
Architecture
- LLM client
- MCP client
- MCP server
- Query guard
- Database
Learning outcomes
- Tool descriptions matter as much as tool code — the model only knows what the schema tells it.
- Separate read and write capabilities from the first version.
- MCP
- Python
- PostgreSQL
Source: not yet public - Agentic AIIn progress
Recoverable tool-calling errors
Designing tool error messages so that a model can correct its own arguments and retry, instead of the whole run failing.
Architecture
- Agent
- Tool router
- Validator
- Tool
- Structured error → Agent
Learning outcomes
- A precise error message is often enough for the model to fix the call on the next step.
- Python
- Pydantic
- Tool calling
Source: not yet public - Agentic AIIn progress
Orchestrator and specialist agents
A planner that assigns scoped tasks to specialist agents and merges their output, with budgets per agent to prevent loops and runaway cost.
Architecture
- Goal
- Orchestrator
- Specialists (parallel)
- Merge & verify
- Result
Learning outcomes
- Most multi-agent problems are context-sharing problems; a shared, factual index reduces contradictions.
- Python
- LangChain
- Async
Source: not yet public - LLM EvaluationImplemented
Three-layer evaluation for LLM and agent outputs
An evaluation framework on self-hosted Langfuse that scores agent, RAG and extraction outputs in three layers: programmatic evaluators first, then an LLM judge, then human calibration of the judge.
Architecture
- Traces
- Programmatic checks
- LLM-as-judge
- Human calibration
- Scores & dashboards
Learning outcomes
- Cheap programmatic checks catch most failures before a judge model is needed.
- An LLM judge is only trustworthy once its scores are calibrated against human reviewers.
- Langfuse
- Python
- LLM-as-judge
- AWS
Source: not yet public - LLM EvaluationImplemented
Semantic caching for repeated LLM calls
Caching responses by embedding similarity so near-identical requests reuse an earlier answer, with a similarity threshold that protects correctness.
Architecture
- Request
- Embed
- Cache lookup
- LLM (on miss)
- Response
Learning outcomes
- The threshold is a correctness setting, not a performance setting — tune it conservatively.
- Python
- Vector store
- Azure OpenAI
Source: not yet public - Data EngineeringImplemented
Column standardization as a service
A REST service that manages column-naming standards and exports them as configuration consumed directly by Spark transformation jobs.
Architecture
- Spreadsheet upload
- Validation gates
- Standards store
- YAML export
- Glue jobs
Learning outcomes
- Keeping standards in one service removes a whole class of mismatch bugs between pipelines.
- FastAPI
- PostgreSQL
- AWS Glue
- PySpark
Source: not yet public - Data EngineeringImplemented
Data quality gates in PySpark
Reusable validation steps — completeness, uniqueness, referential checks — that stop a batch before bad data reaches the target.
Architecture
- Source batch
- Rules
- Gate
- Quarantine / proceed
- Target
Learning outcomes
- Quarantining failed rows with a reason is more useful than failing the whole batch.
- PySpark
- AWS Glue
Source: not yet public - Data EngineeringIn progress
Medallion layout on a Lakehouse
A reference layout for bronze, silver and gold layers, with notes on where validation and deduplication belong.
Architecture
- Sources
- Bronze (raw)
- Silver (clean)
- Gold (serving)
- Consumers
Learning outcomes
- Deciding what 'clean' means for the silver layer is a business conversation, not a technical one.
- Databricks
- Delta Lake
- PySpark
Source: not yet public - Cloud EngineeringImplemented
Containerized FastAPI service template
A starting point for Python services: multi-stage Docker build, health checks, structured logging and a CI pipeline.
Architecture
- Code
- CI build & test
- Image registry
- Kubernetes
- Observability
Learning outcomes
- A consistent template makes every new service cheaper to operate.
- Docker
- Kubernetes
- Azure DevOps
Source: not yet public - Cloud EngineeringPlanned
Event-driven pipelines with serverless components
Orchestrating small ingestion and transformation steps with managed serverless services instead of an always-on cluster.
Architecture
- Event
- Function
- Workflow
- Storage
- Notification
- AWS Lambda
- Step Functions
- S3
Source: not yet public - Python EngineeringImplemented
Bounded concurrency for LLM calls in FastAPI
Using asyncio semaphores and retries with backoff so a service can call an LLM API in parallel without hitting rate limits.
Architecture
- Request
- Task queue
- Semaphore
- LLM calls
- Aggregated result
Learning outcomes
- Unbounded concurrency looks fast in testing and fails under real rate limits.
- Python
- asyncio
- FastAPI
Source: not yet public - Python EngineeringImplemented
Dynamic column detection for messy spreadsheets
Locating the real header row and mapping columns to a target schema from names and sample values, then writing template-accurate Excel output.
Architecture
- Raw file
- Header locator
- Column mapper
- Transform
- Formatted workbook
Learning outcomes
- Flagging what could not be mapped is safer than guessing.
- Pandas
- OpenPyXL
- Regex
Source: not yet public
Have an AI or Data Engineering challenge? Let's turn it into a working product.
Taking on a limited number of AI and data engineering projects. Typical reply within 2 business days.