TL;DR
In this exploration of AI-powered development, I leveraged Aider with Claude as a pair programming assistant to build a transaction categorizer. Despite the iterative process involving occasional slowdowns and needed refinements, the collaboration yielded surprisingly robust results. By containerizing Aider and integrating the Anthropic API, I developed a sophisticated tool with capabilities that would have taken significantly longer to implement independently.
Breaking Through Skepticism
Like many developers, I’ve viewed the AI revolution with a mixture of curiosity and skepticism. The endless hype around Large Language Models (LLMs) had me wondering: Could these tools genuinely assist in software development, or were they just another overhyped technology generating more problems than solutions?
My skepticism ran deep. I’d heard countless horror stories of AI-generated code—nonsensical logic, hallucinated functions, and solutions that crumbled under even mild scrutiny. Yet, a nagging question persisted: What if there was genuine utility beneath the hype?
The Project: A Practical Litmus Test
My proving ground would be my personal project I’ve been redoing for years—a transaction categorization tool for tracking financial transactions.
This wasn’t an abstract exercise, but a real-world challenge that would put AI pair programming to a genuine test. I selected Aider, an AI coding assistant, paired with Claude’s Sonnet model. My goal wasn’t to prove AI’s superiority, but to honestly assess its practical utility in a specific software development context.
Setting Up Aider
Getting started with Aider was straightforward. I ran it in a Docker container to keep things clean:
docker run -it --user $(id -u):$(id -g) --volume $(pwd):/app paulgauthier/aider --model sonnet --api-key anthropic=<your key goes here>
This setup:
- Maps the current directory to /app
- Preserves file permissions
- Connects to Claude’s Sonnet model
Unexpected Discoveries
The first breakthrough came unexpectedly. When parsing a Rabobank CSV, the AI demonstrated remarkable intuition. It didn’t just read fields like “Naam tegenpartij” (Counter party name)—it contextualized them, mapping Dutch field names to meaningful domain concepts with surprising accuracy.
Unexpected Challenges
After the initial useful code some issues arrose. The most frustrating example was that often the java imports where missing. Next to that the rule system went through several iterations. The core builder pattern worked well:
TransactionRule rule = RuleBuilder.descriptionContains("grocery")
.and(RuleBuilder.amountLessThan(new BigDecimal("100")));
However, the frontend was never capable of combining multiple rules. In stead of using the rule builder it would store a “description” rule in the database with the following content. As the API credits expired shortly after the last prompt, rendering the resulting code largely non-functional on the rule editing part.
NS' OR description contains 'Shell
Database Evolution
The database structure also needed several iterations:
-- Initial suggestion
CREATE TABLE transactions (
id TEXT PRIMARY KEY,
amount DECIMAL NOT NULL,
description TEXT NOT NULL
);
-- After realizing we needed proper relationships
CREATE TABLE transactions (
id TEXT PRIMARY KEY,
amount DECIMAL NOT NULL,
description TEXT NOT NULL,
timestamp DATETIME NOT NULL,
category_name TEXT,
category_description TEXT,
FOREIGN KEY(category_name) REFERENCES categories(name)
);
-- why the category_description is duplicated is a mystery to me
That worked quite well however not perfect when looking at the last column. With the foreign key this should not be needed.
Lessons Learned
My AI pair programming experience revealed deep insights into the current state of AI development assistance.
- Contrary to magical expectations, AI assistance demanded:
- Constant, careful guidance
- Meticulous code review
- Iterative refinement
- Speed vs. Accuracy Trade-off
- Advantages
- Quick frontend component generation
- Accelerated initial implementation
- Challenges
- Frequent manual corrections
- Inconsistent code quality
- Integration complexities
- Advantages
- Key Strategies
- Take extremely clear, small steps
- Manually verify each incremental change
Next Steps: Personal Reflections
- Learning from the Process The AI pair programming experience was enlightening. I’m eager to understand where the boundaries of AI assistance truly lie. How much can I rely on these tools? Where do they break down? These aren’t just technical questions, but practical considerations for my future development work.
- Personal Skill Development Working with Aider and Claude pushed me out of my comfort zone. I’m curious to see how I can apply these collaborative AI techniques to other personal projects. It’s not about replacing my skills, but augmenting them.
The beauty of side projects like these is that they’re never truly finished – they’re always evolving, always teaching me something new about technology, about coding, and about myself.
Conclusion
Despite feeling like working with a extremely junior developer who needed constant supervision, the AI pair programming experience was surprisingly productive. The need for constant small fixes was balanced by the speed of getting complex features implemented.
Would I use it again? Yes, but with proper expectations. It’s not a magic solution, but it can speed up development if you’re willing to work through its limitations.
The generated code is available at GitHub if you want to explore the implementation details.