When to use
Use this when a task needs the model to take actions in a loop — call tools, observe results, decide the next step — rather than produce a single answer.
Not for: single-shot generation or classification (a plain prompt is cheaper and safer, see ai-prompt-design), or read-only Q&A over docs (see ai-rag-pipeline).
Method
- Decide if you even need an agent. Decision point: if the steps are known and fixed, write a deterministic pipeline; use an agent only when the path depends on runtime results.
- Define tools as the narrowest useful set. Each tool: a clear name, a one-line description of WHEN to use it, and a typed input schema with required fields.
- Write the system prompt: the goal, the available tools, how to decide between them, and when to stop.
- Choose the control loop: call model → if tool_call, execute and append the result → repeat until a final answer or a stop condition fires.
- Set hard stop conditions: max iterations, wall-clock/token budget, and a repeated-action detector. Decision point: on limit hit, return partial results with a reason, never loop silently.
- Add guardrails: validate tool arguments before executing, require confirmation for destructive/irreversible actions, and sandbox side effects (see
ai-guardrails).
- Log every step (thought, tool, args, result) for replay and evaluation (see
ai-eval-harness).
Example
Agent: "find the failing test and summarize the cause."
loop (max 8 steps):
resp = model(history, tools=[grep, read_file, run_tests])
if resp.tool_call:
if resp.tool == "run_tests" and !confirmed: ask_user()
result = execute(validate(resp.tool_call))
history += result
else: return resp.text
Step 1 grep "FAIL" → test name. Step 2 read_file → source. Step 3 final summary. The max-8 cap and an "identical grep twice" detector prevent a loop when a tool returns empty.
Pitfalls
- Tool soup. 20 overlapping tools; the model picks wrong. Fewer, sharper tools with distinct "when to use" lines.
- No stop condition. An agent that loops until the budget explodes. Always cap iterations AND detect repeats.
- Unvalidated tool args. Passing
"500" where an int is required, or a path outside scope. Validate and coerce before executing.
- Silent destructive actions. Deleting or spending without a confirmation gate. Guard irreversible tools.
Output format
# Agent: <name>
GOAL: <one sentence>
TOOLS:
- <name>(<typed args>): <when to use>
CONTROL LOOP: model -> tool -> observe -> repeat
STOP: max_steps=<n> | budget=<tokens/time> | repeat-detector
GUARDRAILS: arg validation | confirm-on={destructive} | sandbox
LOGGING: step{thought,tool,args,result}
1---2name: ai-agent-design3description: Design a tool-using LLM agent with clean tool schemas, a control loop, explicit stop conditions, and guardrails.4---56## When to use78Use this when a task needs the model to take actions in a loop — call tools, observe results, decide the next step — rather than produce a single answer.910**Not for:** single-shot generation or classification (a plain prompt is cheaper and safer, see `ai-prompt-design`), or read-only Q&A over docs (see `ai-rag-pipeline`).1112## Method13141. Decide if you even need an agent. Decision point: if the steps are known and fixed, write a deterministic pipeline; use an agent only when the path depends on runtime results.152. Define tools as the narrowest useful set. Each tool: a clear name, a one-line description of WHEN to use it, and a typed input schema with required fields.163. Write the system prompt: the goal, the available tools, how to decide between them, and when to stop.174. Choose the control loop: call model → if tool_call, execute and append the result → repeat until a final answer or a stop condition fires.185. Set hard stop conditions: max iterations, wall-clock/token budget, and a repeated-action detector. Decision point: on limit hit, return partial results with a reason, never loop silently.196. Add guardrails: validate tool arguments before executing, require confirmation for destructive/irreversible actions, and sandbox side effects (see `ai-guardrails`).207. Log every step (thought, tool, args, result) for replay and evaluation (see `ai-eval-harness`).2122## Example2324Agent: "find the failing test and summarize the cause."2526```27loop (max 8 steps):28 resp = model(history, tools=[grep, read_file, run_tests])29 if resp.tool_call:30 if resp.tool == "run_tests" and !confirmed: ask_user()31 result = execute(validate(resp.tool_call))32 history += result33 else: return resp.text34```3536Step 1 `grep "FAIL"` → test name. Step 2 `read_file` → source. Step 3 final summary. The max-8 cap and an "identical grep twice" detector prevent a loop when a tool returns empty.3738## Pitfalls3940- **Tool soup.** 20 overlapping tools; the model picks wrong. Fewer, sharper tools with distinct "when to use" lines.41- **No stop condition.** An agent that loops until the budget explodes. Always cap iterations AND detect repeats.42- **Unvalidated tool args.** Passing `"500"` where an int is required, or a path outside scope. Validate and coerce before executing.43- **Silent destructive actions.** Deleting or spending without a confirmation gate. Guard irreversible tools.4445## Output format4647```48# Agent: <name>49GOAL: <one sentence>50TOOLS:51- <name>(<typed args>): <when to use>52CONTROL LOOP: model -> tool -> observe -> repeat53STOP: max_steps=<n> | budget=<tokens/time> | repeat-detector54GUARDRAILS: arg validation | confirm-on={destructive} | sandbox55LOGGING: step{thought,tool,args,result}56```