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-design3version: 1.0.04description: Design a tool-using LLM agent with clean tool schemas, a control loop, explicit stop conditions, and guardrails.5author: matrixx00706tags: [agents, tool-use, control-loop, guardrails, planning]7---89## When to use1011Use 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.1213**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`).1415## Method16171. 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.182. 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.193. Write the system prompt: the goal, the available tools, how to decide between them, and when to stop.204. Choose the control loop: call model → if tool_call, execute and append the result → repeat until a final answer or a stop condition fires.215. 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.226. Add guardrails: validate tool arguments before executing, require confirmation for destructive/irreversible actions, and sandbox side effects (see `ai-guardrails`).237. Log every step (thought, tool, args, result) for replay and evaluation (see `ai-eval-harness`).2425## Example2627Agent: "find the failing test and summarize the cause."2829```30loop (max 8 steps):31 resp = model(history, tools=[grep, read_file, run_tests])32 if resp.tool_call:33 if resp.tool == "run_tests" and !confirmed: ask_user()34 result = execute(validate(resp.tool_call))35 history += result36 else: return resp.text37```3839Step 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.4041## Pitfalls4243- **Tool soup.** 20 overlapping tools; the model picks wrong. Fewer, sharper tools with distinct "when to use" lines.44- **No stop condition.** An agent that loops until the budget explodes. Always cap iterations AND detect repeats.45- **Unvalidated tool args.** Passing `"500"` where an int is required, or a path outside scope. Validate and coerce before executing.46- **Silent destructive actions.** Deleting or spending without a confirmation gate. Guard irreversible tools.4748## Output format4950```51# Agent: <name>52GOAL: <one sentence>53TOOLS:54- <name>(<typed args>): <when to use>55CONTROL LOOP: model -> tool -> observe -> repeat56STOP: max_steps=<n> | budget=<tokens/time> | repeat-detector57GUARDRAILS: arg validation | confirm-on={destructive} | sandbox58LOGGING: step{thought,tool,args,result}59```