Appearance
13. Building a Simple Agent: Architecture Procedure
This chapter gives a reusable design procedure. When asked to build a simple agent, do not start by choosing a framework. Start by defining the architecture.
Step 1: Define the Task Boundary
Answer these questions before designing components.
| Question | Why it matters |
|---|---|
| What is the exact goal? | Prevents the agent from optimizing for plausible but irrelevant output |
| What counts as success? | Enables final-answer verification |
| What is out of scope? | Limits tool selection and permission design |
| What actions may the agent take? | Defines the action space |
| What actions are forbidden? | Defines guardrails |
| Who or what approves risky actions? | Defines autonomy level |
A simple agent performs best when its task boundary is narrow and well-defined. Broad autonomy without clear scope leads to unpredictable tool selection, permission creep, and failures that are hard to diagnose.
Step 2: Choose the Autonomy Level
| Autonomy level | Design consequence |
|---|---|
| Recommend only | No automatic side effects |
| Read-only autonomy | Agent may search and inspect, but not mutate |
| Bounded mutation | Agent may modify a scoped workspace |
| External action | Agent may call external systems, with approval or strict policy |
Start with the lowest autonomy level that can solve the task (2).
Step 3: Define the Context Layout
Design the context before writing prompts.
| Context section | Content |
|---|---|
| System | Role, constraints, output protocol, safety rules |
| Task | Goal, inputs, success criteria |
| Tools | Available tools and argument contracts |
| State | Current plan, current step, known facts |
| History | Summarized prior steps |
| Observation | Latest tool result or environment feedback |
| Reserve | Space for the model’s next output |
The context layout should make the next decision easy.
Step 4: Define the Output Protocol
The model must produce intents that the harness can parse.
A minimal protocol needs:
| Intent | Use |
|---|---|
| Tool request | Ask the harness to execute a tool |
| Final answer | Declare task complete |
| Clarification | Ask for missing information |
| Abort | Stop because the task cannot or should not continue |
Keep the protocol small. Complex output protocols increase format-drift risk.
Step 5: Select Tools
Choose tools based on the action space.
| Design question | Guideline |
|---|---|
| Does the agent need to read information? | Add read-only retrieval tools |
| Does it need to compute? | Add computation tools |
| Does it need to mutate state? | Add scoped mutation tools |
| Does it need to produce an artifact? | Add artifact storage or final submission tools |
| Does it need human help? | Add clarification or escalation tools |
Prefer a small set of well-described tools.
Step 6: Design the Loop
A simple production loop needs:
text
Start
|
v
Build context
|
v
Call model
|
v
Parse intent
|
v
Validate intent
|
+-- tool request ----> execute tool ----> record observation
|
+-- final answer ----> verify answer ----> stop
|
+-- clarification ----> ask user ----> wait or stop
|
+-- abort -----------> record reason ----> stopAdd:
- Maximum iterations
- Token budget
- Cost budget
- Timeout
- Repeated-action detection
- Explicit stop reason
Step 7: Add Guardrails
At minimum, a simple agent needs:
| Guardrail | Purpose |
|---|---|
| Tool allowlist | Prevents hallucinated tools |
| Argument validation | Prevents invalid or unsafe parameters |
| Permission scope | Limits what tools can touch |
| Iteration cap | Prevents infinite loops |
| Cost cap | Prevents runaway spend |
| Final-answer check | Prevents unsupported completion claims |
| Audit log | Preserves evidence of decisions |
Step 8: Design Memory and State
For a simple agent, memory can start small.
| State item | Needed? |
|---|---|
| Current step | Yes |
| Goal summary | Yes |
| Known facts | Usually |
| Tool result references | Yes, if results are large |
| Error history | Yes, if retries are allowed |
| Long-term user memory | Only if the task requires it |
Do not add long-term memory until short-term context management is stable.
Step 9: Add Observability
A minimal trace should record:
- Run ID
- Step number
- Model input size
- Model output
- Parsed intent
- Validation result
- Tool name and status
- Observation summary
- Stop reason
- Token and cost totals
If a failure cannot be reconstructed from the trace, the observability design is incomplete.
Step 10: Test Failure Modes
Before trusting the agent, test:
| Failure scenario | Expected behavior |
|---|---|
| Model returns invalid output | Validator rejects and retries or stops |
| Model requests unknown tool | Tool allowlist denies |
| Tool fails transiently | Controlled retry or structured error observation |
| Tool returns huge output | Observation is summarized or stored externally |
| Agent repeats same action | Repetition detector stops or escalates |
| Context approaches limit | Summarization or truncation triggers |
| Task is impossible | Agent aborts or asks for clarification |
| Unsafe action is requested | Guardrail blocks and logs |
Minimal Reference Architecture
text
+---------------------------------------------------------------------+
| Simple Agent Harness |
| |
| +----------+ +-------------+ +----------------+ |
| | Context | --> | Model Call| --> | Intent Parser | |
| | Builder | +-------------+ +----------------+ |
| +----------+ ^ | |
| ^ | v |
| | | +----------------+ |
| +---+---------+ | | Validator / | |
| | State / | | | Guardrail | |
| | Memory | | +----------------+ |
| +---+---------+ | | |
| ^ | v |
| | | +----------------+ |
| +---+---------+ | | Tool Executor | |
| | Observation | <-------+--------------+----------------+ |
| | Recorder | | |
| +--------------+-------------------------------+ |
| |
| +----------------+ +----------------+ +----------------+ |
| | Trace Writer | | Budget Tracker | | Stop Controller| |
| +----------------+ +----------------+ +----------------+ |
+---------------------------------------------------------------------+
|
v
+------------------+
| LLM Engine |
| Stateless model |
+------------------+