Free sample lesson ยท Engineering with Modern AI Systems
Directing Agents
Why are top software engineers writing fewer lines of code while shipping ten times faster?
Lesson 1 of the Wondering course Engineering with Modern AI Systems
From Writing Code to Directing It
Top engineers now write fewer lines by hand. They spend more time directing coding agents.
Treat an agent like a capable but fallible junior developer. It writes code fast, and it can also make confident mistakes.
Your job shifts to defining the outcome and inspecting the diff the agent produces.
- Writing every line
- Directing agents
You still own architecture, security, correctness, and release decisions.
Delegate a Bounded Task
Vague requests produce plausible but wrong code. Give the agent a narrow outcome instead.
A good brief names the relevant files and constraints, plus acceptance criteria, repository instructions, the test command, and boundaries on what it may change.
- Define outcome: State one narrow result and its acceptance criteria.
- Share context: Name the relevant files, constraints, and test command.
- Set boundaries: Say what the agent may and may not change.
- Ask for plan: On larger changes, review a plan before implementation.
- Inspect diff: Read the resulting changes before accepting anything.
Example: "Add email validation to the signup form in signup.ts. Do not touch the auth module. Done when the signup tests pass."
For larger changes, ask for a plan first. Then inspect the resulting diff.
Run Independent Tasks in Parallel
Several agents can work at once on independent tasks, such as one adding validation while another updates a report page.
Each agent needs its own isolated branch or git worktree, so their edits do not collide.

Notice that each agent edits only its own isolated line, and both lines pass a review checkpoint before rejoining main.
Speed has a cost. You must review each branch and integrate the results carefully before merging into main.
Verify Before You Trust
Verification is not optional. Agent code often looks right even when it is wrong.
Run the automated tests first. If they fail, send the task back with the error.
Next, check behavior at key edge cases and review the diff for unintended assumptions.
- Agent diff ready
- Run automated tests
- Tests pass?
- Send back to agent: Include the error or the gap you found.
- Check edge cases
- Review assumptions: Look for unintended assumptions in the diff.
- Solves user problem?
- Approve merge
- No
- Retry
- Yes
- Yes
- No
Finally, ask whether the change solves the original user problem. Plausible code is not a working feature. Only then approve the merge.
Check yourself
A coding agent produces a convincing patch. Who owns the decision to release it?
- The engineer
- The coding agent
Answer: The engineer
The agent can write code, but the engineer remains responsible for correctness, security, and release decisions.
Which brief best delegates email validation in a signup form to a coding agent?
- Add email validation in signup.ts; leave auth unchanged; run the signup tests.
- Improve signup throughout the app; change anything that seems useful.
- Review signup.ts and decide what feature the form needs.
- Add email validation wherever convenient; tests can wait until release.
Answer: Add email validation in signup.ts; leave auth unchanged; run the signup tests.
A useful brief gives a narrow outcome, relevant file, change boundary, and testable completion criterion.
Two agents are updating unrelated parts of a repository at the same time. Should they work in separate branches or worktrees?
- Yes
- No
Answer: Yes
Separate branches or worktrees isolate edits. Each result still needs review and careful integration.
Keep going
This is lesson 1 of 20 in Engineering with Modern AI Systems. Next up:
- Agent Harnesses
- Codebase Context
- Tool Selection
- Beyond Chat
- Tool Execution
Wondering turns any topic into short lessons you can read, watch, or listen to, with practice questions and an AI tutor.