How I Collaborate with AI When Developing RobustMQ
Over the past year+ developing RobustMQ, AI-assisted programming has become an important part of my workflow. Honestly, AI has significantly improved my coding efficiency, and I recommend every developer try it. But I also learned that you need clear boundaries and your own way of using it. Here are some of my experiences and takeaways.
How I Collaborate
My collaboration style with AI may be different from many people. I don’t ask AI to write code for me; I ask it to review code.
Specifically: when I implement a new feature, I spend time thinking about design first. I clarify module structure, interface definitions, and data flow. Then I write code, starting from core data structures and gradually implementing main methods and logic. This part is fully my own; AI doesn’t participate.
When I’m done, I hand the code to AI for review. AI points out logic bugs, missed edge cases, poor error handling, and possible performance issues. The feedback is usually valuable and catches things I’d overlook—e.g., a function that can return None but isn’t handled, a panic under some edge condition, resources not released correctly.
After reviewing AI’s feedback, I handle complex logic issues myself; for simple syntax or style issues, I let AI fix them directly. This division feels natural: I own anything that needs design intent; AI handles mechanical fixes.
Why I Don’t Let AI Write Core Code
When I first started with AI, I also tried having it write some feature modules. I soon found I wasn’t satisfied with the code it produced. Not that it was wrong, but it was verbose, redundant, and didn’t match my design intent.
I later understood why. AI only sees the context I give it, not the full architecture in my head. Its code might work but integrate poorly with other modules, have inconsistent abstraction levels, and inconsistent naming. More importantly, it doesn’t understand my long-term plans for the project, so its code could block future extensions.
This shows up even more in Rust. When AI writes Rust code, it often overuses clone, Arc<Mutex>, and unwrap_or_default. It doesn’t fully grasp Rust’s ownership semantics; it just uses the safest way to get code to compile. That’s not good Rust. Good Rust should leverage the type system and ownership model for zero-cost abstractions.
For RobustMQ’s storage engine, concurrency control, offset management, and other core modules, I need maximum clarity and performance. Every line should have a clear purpose; every abstraction should have clear value. AI-generated code doesn’t meet that bar. And these core areas get refined repeatedly; if they start as opaque AI code, maintenance will be painful.
So I decided: core code must be written by me. It’s not only about keeping my coding skills; it’s about long-term maintainability.
Test Case Handling
Tests are where AI helps the most. After writing core code, I ask AI to generate tests. AI-generated tests are usually broad and cover many scenarios, quickly building basic coverage.
But AI tests have a flaw: they’re verbose. It tends to write a separate test for every small detail, sometimes longer than the implementation. I often tell it "keep it concise," with limited effect. So I usually trim what it generates, keep the necessary tests, and remove redundancy.
More importantly, I check whether AI missed critical scenarios—concurrency safety, extreme edge cases, recovery from failures. AI often doesn’t think of these. I add these manually based on my understanding of the system. For storage and concurrency control, I pay extra attention that tests cover all important scenarios.
Sometimes I use a trick: one model generates tests, another reviews them. Two models checking each other can catch obvious gaps. I know it’s only auxiliary; critical tests still need my review. I spend less time on test review than on implementation, but that doesn’t mean I undervalue it. For critical scenarios, I review carefully.
Real-World Impact
This workflow has improved my efficiency a lot. AI handles a lot of repetitive checking so I can focus on design and core implementation. Check right after writing, fix immediately, test immediately—this quick feedback loop catches most bugs early.
I’m also satisfied with code quality. Because the core is mine, style is consistent and logic is clear; I can always understand and change it. Because AI helps with detail checking, reliability is high. So far, RobustMQ’s core modules have shown very few bugs in short timeframes.
In this process, the cycle of AI pointing out issues and me analyzing and fixing has steadily improved my coding. I see which mistakes I make often and which scenarios I miss, then avoid them next time. That learning effect is better than letting AI write code directly.
My Principles
After using AI for a while, I set some principles for myself.
Architecture and design: always do it myself. That’s the soul of the project; I don’t delegate it to AI. I may describe ideas to AI and ask questions, but decisions are mine.
Core code: must be written by me. Storage layer, concurrency control, protocol implementation—this code must be concise, efficient, and understandable. Letting AI write for speed will cost later.
Checking and testing: AI can participate a lot. But I review, especially critical scenarios. AI boosts efficiency; it doesn’t replace my judgment.
AI suggestions: think independently. Not every issue AI raises is real; its fixes aren’t always optimal. I need to understand each issue and decide whether to accept and how to fix.
Reflections
AI is a powerful tool, but it’s a tool, not a partner. Tools help you work more efficiently; they don’t make decisions for you.
I see two common extremes. One is avoiding AI, thinking "AI code isn’t reliable." The other is over-relying on AI, having it write large chunks or whole modules. The first misses efficiency gains; the second hurts code quality and your own skills.
My approach is in the middle: own the core, use AI for details. That balance works for me. I keep understanding and control while using AI for checking efficiency.
For people building infrastructure software, I’d say: don’t expect AI to write high-quality core code. AI can produce "working" code, but infrastructure needs "elegant" code. That gap requires deep thinking and iteration by humans.
But don’t reject AI either. Used well, it can significantly improve efficiency. Checking logic, generating tests, fixing simple issues—these are AI’s strengths. The key is finding the right boundary: let AI do what it’s good at, and you do what you’re good at.
One of RobustMQ’s goals is for code quality to approach Kafka’s. That takes time and accumulated quality. My approach: insist on writing core code myself, keep it concise and clear, use AI to improve checking and testing efficiency. So far it’s working well, and I’ll keep at it.
Tools should serve people, not the other way around. That’s my deepest takeaway from AI-assisted programming.
