In the first part of this article we wrote about practical habits that make daily development a little less painful (see here), and because I still have opinions, here is part two.

AI is your rubber duck 2.0

Rubber ducking is great! You explain and describe the problem (sorry, challange) and then the duck silently judges you.

AI does the same, but instead of silent judging it goes all Slavic on you and can actually talk back!

Do not only ask AI to write code. Ask it to challenge your idea before you implement it.

A prompt I use:

Here is my challang. Here is my planned solution. Act as a skeptical senior developer/architect. What am I missing?

– Gosia

This is useful before refactoring, designing a new API, changing a database model, or touching anything in legacy code that looks peaceful but is probably haunted.

Ask it to look for:

  • overengineering
  • hidden dependencies
  • weak abstractions
  • missing edge cases
  • deployment risks
  • “this will be painful in six months” decisions

AI is not always right, of course. But sometimes it asks the annoying question that saves you two days later.

Which is rude, but useful.

Ask for multiple options, not one answer

One of the easiest ways to get better answers is to stop asking:

“How should I solve this?”

Instead ask:

“Give me three options: quick fix, clean solution, and long-term architecture improvement. Explain the trade-offs.”

This changes the conversation.

Sometimes the quick fix is the correct business decision.
Sometimes the clean solution is worth doing.
Sometimes the long-term architecture improvement is just technical debt wearing a fake moustache and pretending to be strategy.

The value is not that AI picks the answer for you. Please don’t outsource judgment to a chatbot with confidence issues.

The value is that it forces you to compare cost, risk, and maintainability before you start typing code like a caffeinated raccoon.

Ask AI to create review checklist

Before opening a PR, ask AI to generate a checklist for your specific change.

Not a generic checklist like:

“Code should be good.”

Very inspiring. Very useless.

Ask for something concrete:

“Create a PR review checklist for this change. Include tests, edge cases, security, performance, backwards compatibility, logging, observability, and deployment risks.”

Then paste your diff or describe the change and ask:

“Review this against the checklist. What should I verify before opening the PR?”

This is especially useful for large refactorings and big changes, for pretty obvious reasons – the volume. HOWEVER, small changes are oftentimes the ones who march right to production unattended. AI can help you with that.

Let AI write the first DRAFT of tests

Small confession: I let AI write my tests, but that’s not good. Not good at all.

It creates volume, that doesn’t necessery go with value. Repetitions, edge cases not being covered etc. They are not perfect,
not always beautiful tests, sometimes tests that test mocks, vibes, and the concept of sadness. But my test coverage is perfect!

It calls for switching the way of thinking.

Ask it:

“Generate test cases for this code. Include happy path, edge cases, invalid input, boundary conditions, and regression risks.”

Then do not blindly accept the result.

Ask follow-up questions:

“What does each test prove?”
“What is not covered?”
“Are these tests too coupled to implementation details?”
“Which tests would fail if the behavior changed intentionally?”

That last one is important.

Bad tests make refactoring harder.
Good tests make refactoring safer.
AI can help with both, so supervise it like a junior developer with unlimited energy drinks and no fear.

Ask it to find naming problems

If there is one thing in Computer Science, that is difficult it surely is **naming**. Naming is hard because names are tiny architecture decisions.

Bad names hide intent.
Inconsistent names create confusion.
Domain names used incorrectly slowly turn your codebase into soup.

AI is surprisingly useful here because this is low-risk work. You are not asking it to redesign your payment system. You are asking it to complain about words.

A useful prompt:

“Review these classes and method names. Where does the naming hide intent, mix concepts, or use inconsistent terminology?”

This often catches things like:

  • services that do too much
  • methods named Handle that handle the entire universe
  • DTOs that are not DTOs
  • managers managing managers
  • domain terms used in three different ways

Naming reviews are cheap and often high-value.

Also, AI has no emotional attachment to your precious ProcessDataAsync.

Brutal, but fair.

Migration plans

Legacy work is where AI becomes really useful.

Not because it magically understands everything, but because it can help you split scary work into safer steps.

Instead of asking:

“Refactor this legacy module.”

Ask:

“Create a step-by-step migration plan. Use safe increments, rollback points, compatibility checks, and tests after each step.”

This is great for:

  • moving code into packages
  • replacing old services
  • changing APIs
  • removing obsolete code
  • splitting large classes
  • migrating configuration
  • changing database access patterns

The key is to ask for safe increments.

One heroic refactor sounds impressive until it breaks authentication, invoices, and someone’s will to live.

Make AI explain the diff

After changes are done, ask AI to explain the diff as if it is writing the **PR description**.

Prompt:

“Explain this diff for a PR description. What changed, why it changed, what risks exist, and how should it be tested?”

This gives you better PR notes, but it also does something more useful:

It reveals accidental changes.

If AI says, “This also updates validation behavior,” and you did not mean to update validation behavior, congratulations. You found a problem before your reviewer did.

That is the dream.

A PR description should not be a murder mystery.

Additional bonus: you can just copy-paste the final, accepttrd result and ta da, you don’t have to write a single word yourself!

Ask what NOT to change

This one is underrated.

Before changing legacy code, ask:

“Based on this code, what should I avoid touching during this change?”

This helps identify fragile areas, unclear boundaries, shared dependencies, old compatibility behavior, and things that look unused but are probably called by a batch job from 2017.

You can also ask:

“Which parts of this code are risky to refactor without more context?”

This is how you prevent:

“I just cleaned up a small helper method.”

from becoming:

“Why is authentication on fire?”

What it is all about

For me, AI is most useful when it improves thinking, not only typing.

Writing code faster is nice.

But catching a bad idea earlier is better.

Finding edge cases before QA is better.

Creating a safer migration plan is better.

Writing a clearer PR description is better.

Knowing what not to touch is definitely better.

The developer still owns the decision.

AI can suggest, challenge, summarize, review, and generate drafts.

But you still need judgment, context, taste, and a healthy fear of legacy systems.

That is the practical version of AI I like most:

Not magic.
Not replacement.
Not hype.

Just a very fast teammate who can help you think twice before you break something once.

If you are interested in some more reads, make sure to check this GitHub Copilot article.