01
Define the agent loop
An agent is a controlled loop, not a magical prompt.
Start with a typed state object containing the user goal, conversation messages, tool results, remaining steps, and final answer. Each iteration asks the model whether to answer or call one of the available tools. Validate the decision, execute only approved tools, append a structured result, and stop on success, error, or a hard step limit.
- Set a maximum number of model turns and tool calls.
- Separate planning text from executable tool arguments.
- Return a stable error object instead of leaking provider exceptions to the model.
The loop should be understandable without the model. If the model disappears, your state machine should still explain the last safe state.
02
Add memory deliberately
Memory is a product decision about what the system is allowed to remember.
Keep short-term conversation state scoped to a thread. Store durable user preferences only after explicit validation and attach an owner, source, timestamp, and confidence to each memory. Retrieval should be selective: inject the smallest relevant set, cite its origin, and provide a way to forget or correct it.
- Separate working memory, user profile memory, and knowledge retrieval.
- Never store secrets, raw credentials, or unverified model claims as memories.
- Measure retrieval precision and stale-memory corrections as first-class metrics.
More context is not better memory. Useful memory is relevant, attributable, editable, and safe to discard.
03
Make tools safe and observable
Every tool is an API boundary with permissions, latency, and side effects.
Give each tool a narrow schema, explicit authentication scope, timeout, retry policy, and dry-run mode. Read-only tools can often retry automatically; write tools require idempotency and confirmation. Emit a trace span before and after execution, including a redacted argument summary and the authorization decision.
- Validate inputs server-side; never trust model-generated arguments.
- Use least-privilege credentials and per-user data scoping.
- Put destructive actions behind confirmation or a review queue.
The safest agent is not the one that refuses everything. It is the one whose capabilities are narrow, visible, and reversible.
Ship the smallest reliable workflow first. Add autonomy only when your evaluation data shows that it improves outcomes.