A computational workbench with a human-scale inspection lens
Conceptual illustration

AI coding tools are useful at producing candidate implementations quickly. That speed changes where engineering effort belongs. Less time may go into typing a routine transformation; more attention must go into defining the problem, checking the surrounding system, and deciding which evidence is sufficient to accept the result.

A fluent explanation is not evidence that a patch fits a repository. The engineer still owns the contract, the review, and the decision to release. The goal is to make assistance improve that work rather than allow plausible output to replace it.

Write the contract before requesting code

Suppose a service needs to import customer records. “Make the import faster” leaves most of the problem undefined. Faster than which baseline? What should happen to duplicate customer identifiers? Can one invalid row reject the whole batch? Are records allowed to be partially applied?

A useful task description names the observable behavior: accept a bounded batch, validate every row, update records by a stable business key, report invalid inputs, and preserve a defined transaction boundary. Include representative examples and constraints such as supported database versions and existing repository conventions.

Ask for uncertainties before a patch when the contract is incomplete. A tool that identifies a missing duplicate policy has already contributed something valuable. Generating code around an unspoken policy only makes that decision harder to see.

Ask for a bounded change

Small patches are easier to understand because the reviewer can hold the intended behavior and the implementation in mind together. Separate an import optimization from an unrelated framework migration, logging redesign, and formatting change. A large diff can be technically coherent and still be too broad for a reliable review.

Request a short plan tied to actual files and existing interfaces. Then inspect whether the change stayed within that plan. If the tool introduces a new dependency, a new data store, or an additional background process, ask what requirement makes the new responsibility worthwhile.

Review assumptions at the boundaries

Generated code often looks strongest in the middle of a function, where the immediate transformation is visible. Pay particular attention to the edges: authorization before lookup, transaction scope, schema constraints, cancellation, request size limits, and the meaning of retries.

For the import example, replacing individual writes with a bulk operation may change validation hooks, returned identifiers, conflict handling, or signals in the framework being used. Verify the behavior in the documentation for the installed version and inspect existing tests. Do not accept a remembered API shape just because the generated call looks familiar.

GitHub's responsible-use documentation for inline suggestions describes limitations that make human review important. The practical response is to review generated changes with the same care as any contribution, including unfamiliar assumptions hidden in otherwise familiar code.

Keep verification independent of the implementation

If the same assistant writes the implementation and then copies its behavior into expected test values, the tests can preserve the mistake. Derive important assertions from the requirement, an independently calculated example, or an external contract instead.

For an import that must leave the database unchanged when any row is invalid, start with a valid existing record and a batch containing one invalid row. After the operation, query the database again and verify that the original record is unchanged. A mock asserting that a transaction method was called does not establish that observable guarantee.

Try a deliberate defect too: remove the transaction boundary or change the duplicate policy. A relevant test should expose the change. The Test Quality Lab provides small Python exercises for practicing this distinction.

Separate experiments from release decisions

It is reasonable to ask a tool for several approaches, build a temporary spike, or compare two query shapes. Those experiments need a clear boundary. A convincing prototype is not automatically a production migration, and an illustrative benchmark does not become a claim about the real workload.

Record what was actually measured, which inputs were used, and what remains unknown. Keep credentials and private customer data out of prompts and sample fixtures unless the environment and the organization's policies explicitly permit their use.

Use an acceptance note

A short acceptance note makes the final decision reviewable: the behavior changed, the alternatives considered, the checks run, and the remaining limits. Write it so a colleague can assess the patch without reading the conversation that produced it.

The important skill is not finding a prompt that always returns correct code. It is building a workflow in which requirements, evidence, and accountable review remain clear even when producing code becomes much faster.