Claude API Prompt Engineering for Agents
What "prompt engineering for agents" actually means
If you're searching for Claude API prompt engineering for agents, you're probably past the chatbot stage and building something that runs multiple steps, calls tools, and makes decisions without a human reading every message. That's a different problem than writing a good one-shot prompt. Agent prompting is about shaping behavior over a sequence of turns: how the model decides when to call a tool, how it recovers from a bad tool result, when it should stop and ask for clarification, and when it should just finish the task.
The short answer: you control agent behavior through four levers — the system prompt, the tool schemas, the conversation structure (what you feed back after each tool call), and explicit stop/continue rules. Get those four right and most "the agent went off the rails" problems disappear. The rest of this article walks through each lever with concrete examples you can use with the Claude API directly or through a wrapper like /docs/tools.
1. The system prompt is the agent's job description
Treat the system prompt as an onboarding doc for a new employee, not a creative writing exercise. For agents, it should cover:
- Role and scope — what the agent is allowed to do, and explicitly what it's not allowed to do.
- Tool usage policy — when to call a tool vs. answer directly, and what to do if a tool fails.
- Output contract — the shape of the final answer (plain text, JSON, a specific template).
- Stopping conditions — what "done" looks like, so the agent doesn't loop forever or ask unnecessary follow-up questions.
You are a deployment assistant with access to tools for checking
build status and restarting services.
Rules:
- Always check build status before suggesting a restart.
- Never restart a service more than once per conversation without
explicit user confirmation.
- If a tool call fails, report the raw error to the user and stop —
do not retry more than once automatically.
- When the task is complete, respond with a one-line summary starting
with "Done:".
This is more useful than a generic "be helpful and accurate" instruction because it gives the model a decision procedure, not just a tone.
2. Tool definitions are prompts too
Every field in a tool schema — the name, the description, each parameter's description — is read by the model and influences whether and how it's called. Vague tool descriptions are one of the most common causes of agents calling the wrong tool or passing malformed arguments.
{
"name": "get_order_status",
"description": "Look up the current status of a customer order by order ID. Use this before issuing any refund or cancellation. Returns status, ETA, and last update timestamp.",
"input_schema": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "The order ID exactly as given by the customer, e.g. ORD-48213"
}
},
"required": ["order_id"]
}
}
Notice the description tells the model when to use the tool relative to other tools ("use this before issuing any refund"), not just what it does. If you're wiring this up through SubToAPI, the request format matches the standard Claude messages API, so existing tool schemas port over without changes — see /docs/tools for the exact payload shape.
3. Feed back tool results like a careful colleague, not a log dump
A common mistake is pasting raw API responses back into the conversation. Agents perform better when tool results are normalized before being sent back:
const toolResult = await getOrderStatus(orderId);
messages.push({
role: "user",
content: [{
type: "tool_result",
tool_use_id: toolUseId,
content: JSON.stringify({
status: toolResult.status,
eta: toolResult.eta,
note: toolResult.status === "error"
? "Tool call failed — do not retry automatically, ask the user how to proceed."
: undefined
})
}]
});
Stripping noise (pagination metadata, internal IDs, verbose error stacks) and adding a short note field when something unusual happens gives the model exactly what it needs to decide the next step, instead of making it re-derive intent from a wall of JSON.
4. Make "stop" an explicit instruction, not an assumption
Agents left to their own judgment tend to either stop too early (after one tool call, even when more steps are needed) or loop unnecessarily (re-checking the same thing repeatedly). Fix this with explicit turn budgets and stop phrases in the system prompt:
You have a maximum of 4 tool calls per user request. If you reach
that limit without resolving the task, summarize what you've found
and ask the user how to proceed instead of continuing.
Pair this with your own orchestration logic — a hard cap in code on tool-call loops is still your responsibility, since the model's internal counting isn't a safety mechanism, it's a behavioral nudge.
5. Separate "reasoning" prompts from "action" prompts
For complex agents, it helps to run two distinct prompt styles rather than one giant system prompt trying to do both:
- A planning prompt that asks Claude to outline steps before touching any tool, useful for multi-step tasks like data migrations or multi-record lookups.
- An execution prompt that's terser and tool-call-focused, used once a plan exists.
This split reduces token overhead on simple requests (no need for a planning pass to answer a one-line question) while still giving complex tasks the structure they need.
6. Test prompts the way you test code
Prompt changes for agents should go through the same rigor as any other behavior change:
- Keep a small fixed set of representative conversations (including edge cases like tool failures and ambiguous requests).
- Re-run them whenever you change the system prompt or tool descriptions.
- Log the full request/response pair, including tool calls, so regressions are visible — not just the final text output.
If you're serving this through a managed layer like SubToAPI, usage metadata and request logs are already available per API key in the dashboard, which makes it easier to spot patterns like a specific tool being called with malformed arguments across many sessions without building your own logging pipeline. See /docs/messages for the response fields available on every call, and /docs/quickstart if you're setting this up for the first time. Plans start with a free trial at /signup, with Solo at €9/month for solo builders and Team/Scale tiers at /pricing for shared seats.
Questions
Does prompt engineering differ between a single Claude API call and an agent loop? Yes — a single call only needs a good instruction and context. An agent loop also needs rules for tool selection, stopping conditions, and how tool results get reinserted into the conversation, since those compound over multiple turns.
Should tool descriptions be long or short? Long enough to disambiguate from other tools and state preconditions (e.g., "check status before refunding"), but avoid redundant detail already captured by the parameter schema — the model reads both.
How do I stop an agent from looping on a failing tool? Add an explicit retry limit in the system prompt and enforce a hard cap in your orchestration code; also return a short note in the tool result telling the model not to retry automatically.