Back to Blog

Learnings & Struggles with Agent-Based Development

By Jupiter Tecson 3 min read
Share

In my last post, I talked about transitioning to agent-based development and how I set up a zero-cost workflow using Antigravity CLI and Gemini. Today, I want to dive into what actually happens when you start using this approach day in and day out.

It’s not magic. You run into very real architectural and context limitations. My goal today is to share the biggest technical struggles we faced and the solutions we implemented, so that if you’re building with AI, you can avoid these same costly architectural traps.

The Architectural Struggle: Spring Modulith & Async Code Paths

I initially chose Spring Modulith because it’s fantastic for building clean, easily extensible architectures by hand. However, I quickly discovered a major friction point when introducing LLMs into the mix: Async code paths.

When you write code by hand, you can hold the asynchronous flow in your head. But for an AI agent trying to read and modify a codebase, async event-driven architectures are incredibly difficult to trace. The agent struggles to follow the execution flow from the publisher to the consumer, leading to hallucinations, broken logic, and a lot of wasted context tokens as it endlessly searches for where an event is handled.

Because of this, we made the hard decision to move away from the heavily asynchronous Event-Driven Architecture (EDA) that Spring Modulith encourages. However, we didn’t throw everything away. We still kept the core domains that we identified during our initial Domain-Driven Design (DDD) phase, but we pivoted how they communicate toward a more traditional Service-Oriented Architecture (SOA). While EDA might be elegant for human developers, SOA provides explicit, synchronous contracts that the LLM can easily follow. This pivot didn’t just reduce hallucinations - it massively improved our token efficiency because the agent no longer had to load multiple files just to figure out where an event was going. As an added bonus, these explicit synchronous contracts make it infinitely easier to audit our data flows and strictly enforce our privacy-first data boundaries, ensuring personal contact info stays decoupled from AI telemetry.

The Documentation Shift: Purging Javadocs

Another major learning was how we handle in-code documentation. When we first started, I assumed that writing aggressive, detailed Javadocs would help the agent understand the code without having to read the full implementation.

The reality was the exact opposite. We discovered that keeping Javadocs and heavy in-code documentation is actually a massive context waste. It bloats the file sizes and drastically increases both input and output token costs. Modern LLMs are incredibly adept at understanding raw, semantic code. We actively stripped out unnecessary comments and added strict rules for the agents to focus purely on the code itself. By relying on clean code rather than verbose documentation, we improved agent performance, reduced hallucinations caused by outdated comments, and slashed our token usage.

Building with AI isn’t about replacing the developer; it’s about shifting the developer’s role from writing syntax to designing systems that an AI can easily navigate.

Next month, we’ll dive into the meta-game of Agent Optimization: managing context windows, structuring subagents for quick tasks vs. high reasoning, M2M communication, and our surprising findings when comparing UI generation across different models.

🛡️ Privacy-First Habit Engine

Achieve your goals without the burnout

Get early access to our dynamic re-routing habit system. Missed days trigger automatic recalibration instead of broken streaks.

Join the Waitlist (Free 8-Wk Beta Pass)