Ideas

Leveraging AI for Software Development: A Pragmatic Approach

Last year, Flower Press Interactive published an article discussing some initial reactions to AI coding assistants—and a lot has changed since then. The tools have advanced, developers have found better ways to leverage AI, and our team has evolved alongside these changes. AI is now embedded in our day-to-day development processes in ways that weren’t possible even a year ago. Here’s an update on how we’re using AI, what’s working well, and what’s still a work in progress. 

 

AI as a Coding Assistant: The New Baseline

Everyone on our team uses cursor.ai as a fundamental part of their workflow. The basic benefits are obvious: quickly generating code snippets, debugging esoteric errors, and accelerating tedious coding tasks. These capabilities are now table stakes, but that doesn’t mean AI is foolproof.

One of the biggest pitfalls we see is hallucinations—the AI making up function calls that don’t actually exist. If a developer isn’t deeply familiar with a library, it’s easy to assume that the AI is correct when it confidently suggests an API that seems plausible but isn’t real. Our best defense? Compile and test early and often. Catching AI errors quickly is the key to avoiding wasted effort.

Another issue is AI-generated explanations that sound authoritative but are just wrong. We’ve learned to interrogate the AI’s responses, asking follow-up questions and verifying explanations rather than accepting them at face value. AI is a useful assistant, but you can’t assume it’s always right.

 

Adoption Challenges and Knowledge Sharing

Our engineers are motivated to push AI beyond basic code generation, but figuring out what’s possible with more advanced usage—like automation, testing, and architecture guidance—takes time. We’ve tackled this by making AI adoption a team effort—brainstorming use cases, sharing discoveries, and assigning engineers to investigate promising techniques.

To streamline this, we maintain a centralized AI cookbook where we document effective prompts and workflows. AI is evolving so rapidly that having a shared knowledge base is invaluable. Without it, we’d all be learning in isolation, reinventing the wheel instead of building on each other’s successes.

 

Automating Style Guide Enforcement

One of the areas we’ve seen meaningful success in is enforcing our style guide. Our team follows a strict coding style guide, covering everything from naming conventions to functional programming principles. While some of this is enforced through linters, many of the more nuanced guidelines—like when to add comments or how to structure functions—require manual enforcement during PR reviews.

To cut down on review time, we encoded our style guide into a .cursorrules file. The file contains our rule descriptions as well as good and bad examples, effectively serving as a few-shot learning model for our coding standards. This allows cursor.ai to generate code that complies with our style guide and enables code review like feedback on human-generated code, reducing back-and-forth in PRs—especially valuable for a team spread across multiple time zones. AI-powered code reviews are still in beta and have appeared and disappeared from Cursor a few times, making them unreliable for consistent use, so we developed our own prompting approach for automated reviews.

Fixing style-related issues is now fast and reliable. The AI understands our preferences and provides inline suggestions. We’re now looking at integrating these checks directly into our CI/CD pipeline, but we’re still fine-tuning the precision—we don’t want to fail builds on false positives.

 

AI in Testing: Faster, Better, Cheaper

One of the biggest wins has been AI-assisted test generation. Cursor does a great job writing unit tests, but only when we provide clear guidance. Our best practices for AI-generated tests include:

  • Writing down key test cases we want to validate before generating tests.
  • Avoiding AI-generated mocks for ORM-heavy code—too much hidden context leads to unreliable tests.
  • Shifting focus from unit tests to integration tests running against a Docker-based test database. These tests are slower to execute but much more reliable.

The impact? We’ve cut our test estimate time in half. AI speeds up test generation so much that we’ve adjusted our planning process accordingly. We’ll continue to refine these estimates, but the savings are undeniable.

 

Future Opportunities

Full Feature Implementation

Right now we are actively testing whether LLMs can implement entire features based on detailed technical specs. The idea is to move beyond simple code generation and see if AI can handle full feature implementations, reducing the need for manual coding in well-defined scenarios. So far we’ve encountered a couple of key challenges:

  • Sizing tasks so that the context window isn’t exceeded.
  • Identifying the necessary project architecture details to include in the AI’s prompt.

Initial results are mixed—while AI performs well on self-contained logic, it struggles with complex dependencies and architectural nuances. Refining this process, particularly in how we structure inputs and break down work, could significantly accelerate development.

 

Emerging AI Capabilities on Our Radar

There are so many potential AI-powered changes to our development process we have found that we can’t possibly incorporate them all and continue to deliver reliably for our clients.  For many of these promising technologies we have deliberately chosen not to start investigating in earnest yet, but are keeping an eye on them.  Here are the most promising ones that we are interested in:

  • Auto-generated documentation (e.g., API docs, summaries of major code changes).
  • AI-driven code reviews beyond just style enforcement—suggesting improvements in logic, security, and architecture.
  • Interface testing to improve test coverage for complex user interactions while minimizing maintenance overhead.
  • Full agent-based coding workflows where AI autonomously writes, tests, and refines code with minimal human intervention.

We see potential in all of these areas, but given the pace of change, we’re focusing on implementations with clearer immediate ROI for our team before taking on additional complexity.

 

Scaling AI in Our Workflows 

AI is steadily becoming a core part of our development process. It helps us write better code faster, automates tedious tasks, and enables more effective collaboration. However, change is hard, fast change is even harder.  So far we’re finding the most success by taking an approach focused on deliberate experimentation, refinement, and sharing what works. By taking a pragmatic approach, we’re reshaping how we develop software, streamline processes, and push the boundaries of what our team can achieve.

AIEngineering