Vibe Coding is a Superpower - If You’re a Sharp Architect
In my previous post, I laid out the blueprint for a zero-cost, multi-agent meal planner. Since then, I’ve been "vibe coding" the implementation using the Gemini CLI.
It’s been an incredible experience in speed, but it also proved a vital point: AI is a "Super-Junior" with a jetpack. It can write 1000 lines of code in seconds, but without a human developer acting as an Architectural Guardrail, you’ll quickly find yourself flying into a mountain of technical debt.
Here is how I navigated the transition from a "cool demo" to a robust, observable system.
The Reality Check: 20 Requests per Day
The first wall I hit wasn't technical—it was a quota. The Gemini free API tier is generous but limited to 20 requests per day. In a "vibe coding" session where you're iterating fast, 20 requests can disappear in 30 minutes.
The Human Intervention: Instead of stopping, I guided the AI to implement a Hybrid Model Strategy.
- Gemini 1.5 Pro: Reserved for the heavy lifting (complex data extraction and generating vector embeddings).
- Groq (Llama 3): Used for the fast, tactical reasoning steps (like the Analyst and Chef agents).
This bridge allowed the project to stay "zero cost" while gaining the resilience of a multi-provider setup.
The Issue: When the "Vibe" gets Soupy
As the project grew, the AI started taking the path of least resistance. It was doing what I asked, but the design was getting "soupy":
- Naming Collisions: Every function returned a generic
Result, making it impossible to tell a domain entity from an API response. - The Observability Black Box: LLM calls were happening, but I had no idea how many tokens I was burning or where the latency was hiding.
- Generic Patterns: The AI defaulted to pointers (
*Struct) for everything, cluttering the code withif res != nilchecks.
The Solution: 3 Critical Human Interventions
I had to step in and "steer the vibe." These weren't AI suggestions—they were moments where I had to stop the AI and re-frame the architecture.
1. The "Agent" Pivot
One of the most important moments was when I looked at a hardcoded prompt sitting inside a standard Go function. I asked: "Does it make sense to have a Normalization Agent for this too? Similar to the Chef and Analyst?"
The Fix: We moved to the Extractor Agent.
- Extractor Agent: A dedicated component with its own Markdown prompt and structured logic.
- NormalizedRecipe: A separate domain entity that combines the
Recipewith its vectorEmbedding.
This created a clear mental model: The Extractor produces a Recipe, which then becomes searchable.
2. Forcing Self-Identifying Metrics
I wanted to track costs. The AI initially gave me a generic Meta struct with just tokens and time. I intervened and insisted on an AgentName field.
// internal/llm/llm.go
type AgentMeta struct {
AgentName string // "Chef", "Analyst", "Extractor"
Usage TokenUsage
Latency time.Duration
}
Why it mattered: By making the metadata self-identify, my SQLite metrics store became instantly searchable. I can now see exactly which agent is my "heavy hitter" in terms of cost and latency.
3. Value Returns over Pointers
The AI loves pointers because it’s a "safe" default in many training sets. But in our ingestion loop, it was making the code noisy. I made the call to switch to Value returns for the normalized recipes.
- The experienced dev's take: For data records like this, returning a value is safer (no nil panics) and simpler. It cleaned up the "App" layer significantly.
Reflection: The Architect’s Role in the AI Era
This experiment confirmed my suspicion: Vibe coding isn't about being lazy; it's about accelerating the labor so you can focus on the design.
The LLM handled the repetitive test boilerplate and the boring Go interfaces. But it took a human eye to:
- Navigate the Quota constraints by building a hybrid bridge.
- Spot Naming collisions before they became debt.
- Ask the Architectural questions that turned a script into a system.
The takeaway? Don't treat the AI as an Autopilot. Treat it as a highly capable but slightly clumsy co-pilot. You’re still the pilot, and you better keep your eyes on the instruments.