I picked up sourdough about six months ago. I also build AI systems at work. At some point those two things had to collide.
From the start I captured the hobby the old-fashioned way: handwritten notes, photos of every loaf and crumb shot, a baking diary I actually flipped back through. That was real data — it just lived in notebooks, camera rolls, and, when I wanted a second opinion, whatever I copy-pasted into ChatGPT that day. The model could riff on the text I fed it, but it had no durable memory of last week’s bake, no schedule tied to my feeding log, and no home for the images as structured signals. I wanted all of that history in an app I controlled, not another disposable chat thread.
The result is mylevain — a baking companion that tracks your starter’s health, adapts recipes to what you have on hand, orchestrates your bake day with a dynamic schedule, and uses computer vision to analyze your finished loaf. It’s a real app I actually use. It’s also the most complete demonstration I have of how I think about agentic AI architecture.
“The best portfolio projects meet you where you already are. I was already building a real history with each bake — I needed software that could treat it like one system, not a fresh prompt every time.”
The problem worth solving
I already cared enough to document everything. What I didn’t have was infrastructure: a place where those notes, timestamps, and photos could stack up and compound instead of dissolving into a chat sidebar.
Sourdough is surprisingly data-rich. Every bake involves a starter with its own activity patterns, a recipe with precise gram weights and hydration percentages, a multi-step schedule that spans 12–24 hours, and a finished loaf you can learn from. I wanted an app that could answer three questions in real time using the trail I’d already started — without re-explaining my whole setup from scratch each time: is my starter ready to bake with? How do I adapt this recipe to what I have on hand? And what does my bake schedule look like given when I want the bread done?
The architecture: three agents, one loop
The app is built around three cooperating AI agents, each with a focused responsibility. They share state through a PostgreSQL database and communicate through a custom agent loop — no framework, just a clean while (needsToolCall) pattern that’s easy to reason about and explain in an interview.
| Agent | Responsibility |
|---|---|
| Starter agent | Tracks feeding history, computes peak time from timestamps, predicts the next peak window based on ratio, temp, and historical patterns |
| Recipe adapter agent | Takes your starter state, flour blend, loaf count, hydration target, and bake deadline — runs baker’s math and returns exact gram weights for every ingredient |
| Bake day orchestrator | Generates a timestamped step schedule, dispatches notifications, and dynamically replans all downstream steps when the baker reports a deviation |
The orchestrator is the most interesting piece. It runs a sense → plan → act loop: it generates an initial schedule, listens for user input (“bulk ferment is running 45 minutes behind”), then recalculates every downstream step and sends an updated schedule. This is the same replanning pattern used in production agentic systems — it just happens to be about bread.
A UX decision that came from domain research
Early on I built the feeding log with a “peak time” input field — asking the baker to enter how many minutes their starter took to peak. This was wrong.
After reading how sourdough feeding actually works, I realized that bakers feed their starter when it has peaked — meaning the act of logging a new feeding implies the previous cycle just finished. Peak time is therefore a derived value: the elapsed minutes between the previous feeding timestamp and the current one. The user never has to enter it. The app computes it automatically and uses it to predict the next peak window.
The lesson: domain research before building saves you from shipping a form field that asks the user to answer a question your database already knows how to answer.
Computer vision for crumb analysis
The most novel feature is the finished loaf analysis. After completing a bake, the user uploads an exterior photo and optionally a crumb shot — the interior cross-section after slicing. Claude analyzes both images and returns a structured assessment: crust color, bloom quality, crumb structure, alveoli distribution, gumminess, and an overall fermentation read (underfermented, well_fermented, overfermented).
The key implementation detail is that the AI returns structured JSON, not prose. A system prompt instructs it to respond only with a typed object matching a specific schema. This means the UI can render individual fields — a “well fermented” pill, a strengths list, an improvements list — rather than just displaying a paragraph of text. Structured output is almost always the right call when the consumer is code, not a human.
Over time, the bake history page uses this data to surface patterns: “3 of your last 5 bakes read as underfermented — your bulk ferments may be consistently short.” That’s the feedback loop closing.
How it was built
Phase 1 — Scaffold + starter tracker
Next.js 14 App Router, TypeScript, Tailwind CSS, Clerk auth, Neon PostgreSQL. Core schema for starter, feeding, and bake tables. Feeding log with gram weights (starter, flour, water), derived peak time calculation, peak history chart, and dashboard stat cards pulling from real data.
Phase 2 — Recipe adapter agent
Anthropic SDK with tool use. The agent has access to a calculate_recipe tool for baker’s math, a get_weather tool to pull ambient temperature, and a build_schedule tool to generate the bake timeline. Pulls live starter data from the feeding log — no re-entering information the app already knows. Returns structured JSON rendered as an ingredient grid and timeline strip.
Phase 3 — Bake day orchestrator
Custom while (needsToolCall) agent loop in a Next.js API route. Step notifications via web push (Vercel Cron, one-minute granularity — documented as a known limitation). Dynamic replanning via a modal with preset offset buttons (+15/+30/+45/+60 min) plus a free-text override. Replan count tracked per bake.
Phase 4 — Vision + bake history
Multimodal Claude API calls with base64-encoded images. Vercel Blob (public store) for photo storage. Loaf and crumb analysis with typed JSON output schema. Bake history with outcome data — star rating, tasting notes, bulk ferment delta, AI coaching panel that reads patterns across bakes.
What I’d tell someone building something similar
Write your own agent loop before reaching for a framework. A while (needsToolCall) loop is about 50 lines of code, fully debuggable, and something you can walk through line by line in an interview. LangGraph is powerful, but it puts framework concepts between you and the questions that matter.
Force structured output whenever the consumer is code. A final respond_to_user tool call returning typed JSON is more reliable than parsing streamed prose, and it makes your UI components dramatically simpler to write and test.
Build something you actually use. The domain knowledge you have as a genuine user surfaces design decisions you’d never find by reasoning from first principles — like realizing peak time is a derived value, not a user input.
Stack: Next.js 14 · TypeScript · Tailwind CSS · Anthropic SDK · Neon PostgreSQL · Clerk · Vercel Blob · Vercel Cron
Landing: mylevain.app · Preview: mylevain.app/preview · Source: private repository