Start with a bounded engineering task
AI is most useful when the goal is clear and the surrounding context is available. “Improve this application” invites guesses; “trace how this form validates an email and identify the smallest place to add a confirmation message” gives the assistant a concrete job.
Treat the response as a proposal. Your repository, product requirements, and runtime behavior remain the source of truth.
Understand unfamiliar code before changing it
Ask for a map of the relevant flow before requesting edits. For example: “Trace this request from the route to the database. Name the files involved, the validation steps, and where errors are handled. Do not change anything yet.”
Then inspect those files yourself. Check whether the explanation matches imports, callers, tests, and actual behavior. This approach can shorten orientation while preserving your own understanding.
Compare approaches and implement incrementally
For a feature, ask for two or three implementation options with tradeoffs tied to the existing architecture. A useful comparison names files, edge cases, and migration or compatibility implications rather than declaring one approach universally best.
Choose a small step, implement it, and inspect the diff before continuing. If an edit touches unrelated files or changes a public interface, pause and understand why.
Debug with evidence
Share the exact error, the relevant code, reproduction steps, and what you expected to happen. Ask the assistant to distinguish observations from hypotheses and suggest the next diagnostic check.
For example, an intermittent API failure may come from a timeout, a rejected credential, or a race. Check timestamps, status codes, and logs before rewriting retry logic. A plausible explanation is not evidence.
Use AI to strengthen tests and maintenance
AI can suggest boundary cases, explain an existing test, draft documentation, or identify duplicated logic. Keep the tests aligned with intended behavior; generated assertions can simply encode the same mistaken assumption as the implementation.
After a refactor, compare behavior before and after. Run the focused tests, then the broader checks the project uses. Review naming, error handling, security boundaries, and maintainability yourself.
Review generated code deliberately
Read every changed line. Verify API names against installed versions and project documentation, check data validation and authorization, and consider malformed input and failure paths. Generated dependencies should be verified before installation.
Avoid sending secrets, customer data, or private source to an external service unless its terms and your organization’s policy allow it. For sensitive work, use approved tools or investigate locally.
When manual investigation is the better first move
Start with direct observation when a bug has an unclear reproduction, when production evidence is incomplete, or when a security decision depends on system-specific guarantees. Gather logs, inspect state, and reproduce the issue before asking for a fix.
AI works best as a partner in reasoning: useful for generating questions and options, but not a substitute for understanding the system or validating the result.
Keep learning
Explore the AI-Powered Developer Productivity course or read the free chapter preview.