Structuring Agent Instructions
Right now your system prompt is one line: You are a coding agent. That's not a prompt. That's a name tag.
Your tools are doing most of the steering already. The descriptions from Module 2 are strong enough that the agent will probably pick read for read tasks and grep for searches without much help. So what's the system prompt for?
It's where you write down the policy. Not what the agent can do (that's the tools). What the agent should do, in what order, with what kind of restraint. A name tag won't carry that. A sectioned prompt will.
Outcome
instructions is a sectioned prompt with explicit Agency and Guardrails blocks. The agent acts on tasks (uses tools, reports results) instead of explaining what it would hypothetically do.
Fast Track
- Replace
You are a coding agent.with a sectioned prompt - Add an Agency section: use tools, do not explain, prefer the specialized tool over
bash - Add a Guardrails section: minimal changes, search before creating, no new deps without asking
Hands-on Exercise 3.1
Rewrite the instructions field in index.ts to use a structured, multi-section prompt.
Requirements:
- Open with a one-line statement of role and the working directory
- Add an
# Agencysection telling the agent to act, not explain - Add a
# Guardrailssection with constraints (minimal changes, reuse, no new deps) - Keep using template literals so the working directory interpolates in
Implementation hints:
- Section headers (
# Agency,# Guardrails) make the prompt scannable for both you and the model - Be explicit with negative instructions ("Do NOT explain what you would do"). Models default to explaining
- Reference your tools by name. The model already has descriptions but pointing at them in the prompt reinforces routing
The before
instructions: `You are a coding agent.\nWorking directory: ${cwd}`,This works. The agent reads files when asked, searches when asked, runs commands when asked. But there's no policy. Ask it to "find all TODO comments and fix them" and the response depends entirely on the model's mood that minute. Maybe it acts. Maybe it produces a plan and waits for you to approve it.
That ambiguity is what the prompt is for.
The after
instructions: `You are a coding agent working in: ${cwd}
# Agency
- USE your tools. Read files, search code, run commands, then answer.
- Do NOT explain what you WOULD do. Actually do it.
- Prefer grep for searching, read for viewing files.
- Use bash only for commands that aren't covered by other tools.
# Guardrails
- Prefer simple, minimal changes
- Search before creating, and reuse existing patterns
- No new dependencies without asking`,Now the policy is written down. The Agency section gives the agent permission and instruction to act. The Guardrails section sets limits.
A few things to notice:
- The "complete the task" instruction is explicit. Without it, agents drift toward explaining. Saying "actually do it" out loud is annoyingly necessary
- The tool preferences live in the prompt as well as the descriptions. The repetition is intentional. We're saying it in two places because models miss it in one
- "No new dependencies without asking" sets up the human-in-the-loop work in Module 8
What's actually changing
The agent already had the tools. It already had the descriptions. What's new is that the operating policy is now portable. You can copy this prompt to a different agent, with different tools, and the policy still applies. You can A/B test it. You can lift one section out for a subagent.
A one-line prompt can't do that. A sectioned prompt can.
| Section | Purpose |
|---|---|
| Role line | Who the agent is and where it's working |
| Agency | Permission and instruction to act on tasks |
| Guardrails | How to act: minimal, reuse-first, conservative on deps |
| Tool Usage (later) | Which tool for which job, especially in mixed-tool sessions |
| Communication (later) | How to report results back |
Start with Agency and Guardrails. The other two earn their place when the prompt grows past 20 lines or so.
Try It
Run the same prompt before and after the change to see how the agent's posture shifts:
bun run index.ts . "Find all TODO comments and tell me where they are"With the one-liner, the agent might list its plan first ("I'll use grep to search..."). With the structured prompt, it goes straight to the tool call and reports findings.
npx tsc --noEmitIf your agent was already acting with the one-line prompt (Module 2's descriptions are strong enough that it usually does), the visible change might be subtle. The durable gain is policy: you've made the operating style explicit, which means you can change it without rewriting the whole agent.
Commit
git add index.ts
git commit -m "feat(prompt): add Agency and Guardrails sections"Done-When
instructionsincludes# Agencyand# Guardrailssections- Agency tells the agent to use tools and not explain
- Guardrails constrains scope (minimal changes, reuse, no new deps)
- The working directory still interpolates into the prompt
npx tsc --noEmitpasses
Try removing the Agency section entirely. Run the same task. Does the agent slip back into explainer mode? Try removing Guardrails. Does it start adding random npm packages? Each section is doing work. Figuring out which section catches which behavior is the whole game.
Solution
const agent = new ToolLoopAgent({
model: "anthropic/claude-haiku-4-5",
instructions: `You are a coding agent working in: ${cwd}
# Agency
- USE your tools. Read files, search code, run commands, then answer.
- Do NOT explain what you WOULD do. Actually do it.
- Prefer grep for searching, read for viewing files.
- Use bash only for commands that aren't covered by other tools.
# Guardrails
- Prefer simple, minimal changes
- Search before creating, and reuse existing patterns
- No new dependencies without asking`,
tools: { read, grep, bash },
stopWhen: stepCountIs(10),
});Was this helpful?