Writing & Ideas
Thoughts on AI engineering, LLM systems, and building software that scales.

Building an MCP Server in Python
Most MCP tutorials show you a “hello world” tool — one function, two arguments, a print statement — and stop right where the actual …

Human-in-the-Loop Agents with LangGraph
The pitch for autonomous agents is always “it handles the whole task end to end.” The reality of shipping one is that almost nobody …

LangChain vs LangGraph: When You Actually Need a Graph
Ask a team why they moved from LangChain to LangGraph and you’ll usually get a shrug and “the agent kept doing weird stuff.” That …

Multi-Tenant RAG: Metadata Filtering Without Leaking Data
A multi-tenant RAG system has a failure mode that single-tenant systems don’t: it can produce an answer that’s fluent, well-cited, and …

Why Your RAG Retrieves the Wrong Chunks
“The model is hallucinating” is the default diagnosis when a RAG system gives a wrong answer, and it’s usually the wrong one. …

Evaluating a RAG Pipeline: Recall@k, MRR, Faithfulness
Most teams “evaluate” their RAG pipeline by asking it a handful of questions, reading the answers, and deciding whether it feels right. …

Reranking in RAG: When It's Worth the Latency
“Add a reranker” has become the default answer to “our RAG answers aren’t great,” in roughly the same way “add an …

Hybrid Search: Combining BM25 and Vectors in Postgres
The pitch for vector search is that it understands meaning, not just keywords — ask about “canceling a subscription” and it’ll find …

Jev by TypeSafe: Typed AI Decisions for Backends
Most of the LLM calls in a production backend aren’t asking for prose. They’re asking for a decision: which queue does this ticket go to, …

Chunking Strategies for RAG, Benchmarked on Real Documents
Most RAG postmortems start in the wrong place. Someone swaps the embedding model, adds a reranker, tunes the prompt, and the retrieval quality barely …

Celery + Redis Gotchas Nobody Warns You About
Redis is the default broker for most new Celery projects, and for good reason — it’s already in the stack for caching, it’s fast, and …

Celery Retries, Backoff, and Dead-Letter Queues
The default retry behavior most teams ship with Celery is max_retries=3 and nothing else — no backoff, no jitter, no distinction between “the …