writing

deep dives on the AI-engineering stuff I'm learning, one idea at a time.

Names, not boxes: Python's object model, seen from JavaOct 25, 2026Why Python variables are labels on objects, how mutability really works, and the protocols that replace Java interfaces. Taught through four mental models.Type hints don't run: how pydantic turns them into a validatorOct 25, 2026Python ignores your types at runtime. We build a tiny validator from annotations, then see how pydantic does it and why LLM apps depend on it. Taught through four mental models.asyncio for LLM calls: what the event loop is really doingOct 25, 2026We build a tiny event loop from generators, then map every asyncio idea (await, tasks, gather, semaphores, timeouts) onto it. Taught through five mental models.How tool calling actually works: from raw HTTP to an agent loopOct 25, 2026A model can only write text, so how does an agent query a database? We look at exactly what the model sees, how it "decides" to call a tool, every JSON message in the round trip, and the failures that follow from it.Why embeddings find meaning: vectors from first principlesOct 25, 2026How a list of numbers can capture what text means. We build word vectors from a co-occurrence matrix in numpy, then follow the idea all the way to semantic search. Taught through five mental models.Where retrieval breaks: chunking, BM25, hybrid search and rerankingOct 25, 2026Embeddings alone miss order IDs and exact terms. We build BM25 by hand, fuse it with dense search, and add a reranker, each one motivated by a real failure. Taught through five mental models.How to know your LLM app works: building an eval harnessOct 25, 2026"It looks better on three examples" is not a measurement. We build an evaluation harness by hand: cases, a runner, scorers, a paired bootstrap, and a CI gate that catches what averages hide. Taught through five mental models.