Skip to main content
All AI journeys
A4 · Agent Engineer

Build your first agent (ReAct)

Reasoning + acting + observation loop

From API caller to agent — build a ReAct loop with tools that actually ships to prod.

1 chapter authored

12-chapter journey · 1 chapters authored so far

  1. 0The ReAct loop that turns an LLM into an agentThe pattern behind Cursor, Devin, Copilot, Claude Code, and every autonomous system in 202510 min read

11 more chapters queued for follow-on sessions — this is a multi-session flagship at URL Shortener template quality (~90K chars total target). What's here today is fully authored and reference-quality.

Chapter 0
beginner
10 min read

The ReAct loop that turns an LLM into an agent

The pattern behind Cursor, Devin, Copilot, Claude Code, and every autonomous system in 2025

You finished A1 (your first LLM call). Maybe you finished A3 (your first RAG). You can now ask an LLM a question and get an answer.

But you still can't build Cursor.

You can't build the thing that opens a file, reads it, runs a search, sees the search failed, tries a different search, reads three more files, edits one of them, runs the tests, sees the tests fail, reads the failure message, fixes the bug, re-runs the tests, and reports back to you when it's done.

That thing is not "an LLM." That thing is an agent — an LLM in a loop, with tools, driving toward a goal.

The pattern behind every 2025 agentic product (Cursor, Devin, Claude Code, GitHub Copilot Workspace, ChatGPT with Code Interpreter, Perplexity Pro Search) is one loop. Once you see it, you cannot un-see it. Every one of those products is a variation of the same 4 boxes.

The ReAct loop — the visual that unlocks everything

ReAct = Reasoning + Acting. Yao et al. published the paper in October 2022 (arxiv.org/abs/2210.03629) and every serious agent framework since has been a refinement of this diagram:

flowchart TD Start([User goal:<br/>Find bugs in this repo related to auth]) --> Thought1 Thought1[1 THOUGHT round 1<br/>&quot;I should start by searching<br/>for auth across the codebase&quot;] Thought1 --> Action1[2 ACTION round 1<br/>grep --recursive auth ./src] Action1 --> Obs1[3 OBSERVATION round 1<br/>src/auth.js 47 matches<br/>src/middleware/authCheck.js 22 matches<br/>src/routes/login.js 15 matches] Obs1 --> Thought2[1 THOUGHT round 2<br/>&quot;3 files. auth.js looks most relevant.<br/>Let me read it.&quot;] Thought2 --> Action2[2 ACTION round 2<br/>read_file src/auth.js lines 1-200] Action2 --> Obs2[3 OBSERVATION round 2<br/>200 lines of auth.js content] Obs2 --> Decision{Reached goal or<br/>max_iterations?} Decision -->|no continue| Thought1 Decision -->|yes| Final([N FINAL ANSWER<br/>Found 3 bugs with citations]) classDef thoughtNode fill:#dbeafe,stroke:#2563eb,color:#1e3a8a classDef actionNode fill:#dcfce7,stroke:#16a34a,color:#14532d classDef obsNode fill:#fef3c7,stroke:#d97706,color:#78350f classDef decisionNode fill:#fce7f3,stroke:#db2777,color:#831843 class Thought1,Thought2 thoughtNode class Action1,Action2 actionNode class Obs1,Obs2 obsNode class Decision decisionNode

Four node types. Thought (blue) is the LLM reasoning. Action (green) is the tool call. Observation (orange) is the tool result. Decision (pink) is the LLM deciding whether to loop or emit the final answer. That is it. Four kinds of boxes. Repeat until the LLM decides it has reached the goal (or a `max_iterations` safety limit fires).

Read this diagram until you can draw it from memory. Every agent — from a 50-line ReAct loop you write tomorrow to Anthropic's Claude Code that ships with Claude 3.5 — is a variation of these four box types. The complexity comes from tool design, memory, error recovery, and safety — but the loop is fixed.

What's fundamentally different from a base LLM call

If A1 taught you to call the LLM API (one request → one response) and A3 taught you RAG (retrieve → augment → generate — still one round-trip), an agent adds these four properties that a single-shot LLM call cannot deliver:

PropertyBase LLM callRAGAgent
Multi-step reasoning1 step1 step + retrievalN steps (typical 3-20)
Tool usenonefixed retrieve stepdynamic — LLM picks any tool per step
State across stepsnonenonefull history accumulates in context
Goal-directedresponds to promptresponds to promptdrives toward user-specified outcome
Failure recoverygive upgive upcan retry, try a different tool, ask for clarification
Cost per query1 LLM call (~$0.01)1 LLM call + embed (~$0.011)N LLM calls (~$0.01 × N steps = $0.05-$1)

The single most important row is cost per query. Agents are 5-100× more expensive than single-shot LLM calls because each Thought/Action/Observation round consumes tokens (the accumulated context grows every step). Understanding this is the difference between "we shipped an agent that costs $0.30/query" and "we shipped an agent that costs $30/query." Chapter 2 does the math.

The whole journey at a glance — L4 → L7 agent evolution

Same discipline as URL Shortener and RAG. Corpus of tools + iteration depth + concurrency drives each 10× in complexity:

text
═══════════ AGENT ARCHITECTURE ACROSS 4 SCALES ═══════════ L4 L5 L6 L7 Single-tool ReAct Multi-tool + memory Orchestrator + workers Multi-agent federation 100 queries/day 10K queries/day 1M queries/day 100M queries/day 1 tool (search) 10 tools 50+ tools 1000+ tools + skills marketplace 2 weeks · $100/mo 2 months · $5K/mo 6 months · $200K/mo ongoing · $10M/yr ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌──────────────────┐ │ User goal │ │ User goal │ │ User goal │ │ User goal + │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ policy context │ │ │ │ └────────┬─────────┘ ▼ ▼ ▼ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────▼────────┐ │ Simple │ │ Agent with │ │ Orchestrator│ │ Router agent │ │ ReAct loop │ │ - short-term│ │ Agent picks │ │ reads policy │ │ │ │ memory │ │ which worker│ │ + intent │ │ GPT-4o │ │ - long-term │ │ - Research │ │ → dispatches │ │ + 1 tool │ │ RAG memory│ │ - Coding │ │ to sub-orgs │ │ │ │ - 10 tools │ │ - Analysis │ └───────┬────────┘ └──────┬──────┘ └──────┬──────┘ │ - Writing │ │ │ │ │ │ │ │ │ │ Each worker │ ┌─────────┼─────────┐ │ │ │ = own ReAct │ │ │ │ │ │ │ loop │ ▼ ▼ ▼ ▼ ▼ └──────┬──────┘ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────────────┐ ┌─────────────┐ │ │Team │ │Team │ │Team │ │ ONE tool │ │ 10 tools: │ │ │A org│ │B org│ │C org│ │ │ │ - search │ ┌──────▼──────┐ │(15 │ │(30 │ │(50 │ │ e.g. │ │ - read_file │ │ Worker │ │agts)│ │agts)│ │agts)│ │ web_search │ │ - grep │ │ pool: 5-10 │ │ │ │ │ │ │ │ (Serper, │ │ - shell │ │ concurrent │ │Own │ │Own │ │Own │ │ Brave, │ │ - HTTP GET │ │ workers per │ │tool │ │tool │ │tool │ │ Google) │ │ - Python │ │ user query │ │set │ │set │ │set │ │ │ │ - RAG search│ └──────┬──────┘ │+ ACL│ │+ ACL│ │+ ACL│ └─────────────┘ │ - calendar │ │ └──┬──┘ └──┬──┘ └──┬──┘ │ - email │ │ │ │ │ │ - Slack │ │ └─────────┼─────────┘ │ - custom │ │ │ │ MCP tools │ │ ▼ └──────┬──────┘ │ ┌──────────────┐ │ │ │ Global │ │ ┌──────▼──────┐ │ aggregator │ │ │ Result │ │ agent │ │ │ synthesizer │ │ + safety │ │ │ agent │ │ + audit log │ │ └──────┬──────┘ └──────┬───────┘ │ │ │ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Response + │ │ Response │ │ Response + │ │ trace log │ │ streaming + │ │ compliance │ │ + eval hook │ │ eval + cost │ │ audit trail │ └─────────────┘ │ per worker │ │ + policy │ └─────────────┘ │ receipt │ └─────────────┘ ↑ ↑ ↑ ↑ Cursor's MCP-enabled Devin, Claude Code Enterprise original assistants Copilot Workspace multi-tenant ReAct. (Sep 2024+). (Salesforce Boring works. Agentforce, Microsoft Copilot Studio) Key insight: agent COMPLEXITY grows with tool count and organizational ACL boundaries, NOT with query volume. A 10-tool agent serving 1M queries is architecturally L5, not L6. What forces L6 is the need for multiple SPECIALIZED agents that coordinate.

The same 4 tiers as clean Mermaid flowcharts

Four architectures, one per tier — the shape you'd draw when the interviewer specifies scale:

L4 · Single-tool ReAct · 100 queries/day · $100/mo · 2 weeks:

flowchart TB G([User goal]) --> R[ReAct loop<br/>Thought → Action → Observation<br/>GPT-4o] R --> T[web_search<br/>Serper/Brave/Google<br/>ONE tool] T --> R R --> Resp[Response<br/>+ trace log<br/>+ eval hook] classDef n fill:#dbeafe,stroke:#2563eb,color:#1e3a8a class R,T,Resp n

L5 · Multi-tool + memory · 10K queries/day · $5K/mo · 2 months:

flowchart TB G([User goal]) --> A[Agent<br/>+ short-term memory<br/>+ long-term RAG memory<br/>+ MCP tool router] A --> T1[web_search] A --> T2[read_file] A --> T3[grep / shell] A --> T4[HTTP GET] A --> T5[Python REPL] A --> T6[RAG search] A --> T7[calendar] A --> T8[email] A --> T9[Slack] A --> T10[custom MCP tools] T1 --> A T2 --> A T3 --> A T4 --> A T5 --> A T6 --> A T7 --> A T8 --> A T9 --> A T10 --> A A --> Resp[Streaming response<br/>+ eval + cost/tool] classDef n fill:#dcfce7,stroke:#16a34a,color:#14532d class A,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,Resp n

L6 · Orchestrator + specialized worker pool · 1M queries/day · $200K/mo · 6 months:

flowchart TB G([User goal]) --> O[Orchestrator agent<br/>picks which worker to dispatch] O --> W1[Research worker<br/>own ReAct loop] O --> W2[Coding worker<br/>own ReAct loop] O --> W3[Analysis worker<br/>own ReAct loop] O --> W4[Writing worker<br/>own ReAct loop] O --> P[Worker pool<br/>5-10 concurrent<br/>per user query] W1 --> S[Result synthesizer agent] W2 --> S W3 --> S W4 --> S P --> S S --> Resp[Response<br/>+ streaming<br/>+ eval + cost per worker] classDef n fill:#e0e7ff,stroke:#4f46e5,color:#312e81 class O,W1,W2,W3,W4,P,S,Resp n

L7 · Multi-agent federation with ACL + audit · 100M queries/day · $10M/yr:

flowchart TB G([User goal + policy context]) --> RT[Router agent<br/>reads policy + intent<br/>dispatches to sub-orgs] RT --> TA[Team A org<br/>~15 agents<br/>own toolset + ACL] RT --> TB[Team B org<br/>~30 agents<br/>own toolset + ACL] RT --> TC[Team C org<br/>~50 agents<br/>own toolset + ACL] TA --> GA[Global aggregator agent<br/>+ safety filters<br/>+ audit log] TB --> GA TC --> GA GA --> Resp[Response<br/>+ compliance audit trail<br/>+ policy receipt] classDef n fill:#fce7f3,stroke:#db2777,color:#831843 class RT,TA,TB,TC,GA,Resp n

Read the four architectures in order. L4 is one LLM call in a loop with one tool — Cursor's original shape. L5 adds tool router + memory — MCP-enabled assistants like Claude Desktop and modern Copilot. L6 adds orchestrator + specialist workers — Devin, Claude Code, Copilot Workspace. L7 adds per-team agent orgs + policy + audit — Salesforce Agentforce, Microsoft Copilot Studio. Each tier crosses a specific complexity boundary: L4→L5 crosses the "need many tools" line, L5→L6 crosses the "need specialization" line, L6→L7 crosses the "need multi-tenant ACL" line.

Read this chart before diving in. Notice the differences from RAG's scale evolution:

  • RAG scaled by corpus size. More docs → different vector DB → different index topology.
  • Agents scale by TOOL COUNT and COORDINATION need. More tools = more decision surface for the LLM. Multiple specialized agents = orchestration overhead. Corpus is not the axis.
  • The L6 → L7 jump is organizational, not just technical. L7 introduces per-team agent orgs with their own toolsets, ACLs, and audit trails. This is where Salesforce Agentforce and Microsoft Copilot Studio compete.

Where the rest of this journey goes

Chapters 1-4 — foundations:
- Ch 1 Requirements — the 6 clarifying questions specific to agents (goal type, tool budget, max iterations, autonomy vs human-in-loop, safety envelope, evaluation)
- Ch 2 Estimation — the cost math: an N-step agent at ~$0.05/step vs a $0.01 single-shot RAG
- Ch 3 Tool design — the API surface for tools (function-calling schemas, error patterns, idempotency)
- Ch 4 Memory model — short-term (conversation context) vs long-term (embedded past sessions) vs episodic (specific past runs)

Chapters 5-8 — the scale evolution shown above:
- Ch 5 L4 MVP — single-tool ReAct in ~200 lines of Python
- Ch 6 L5 — multi-tool with memory + MCP integration
- Ch 7 L6 — orchestrator + specialized worker pool
- Ch 8 L7 — multi-agent federation with ACL + audit

Chapters 9-12 — failures, evaluation, safety, production:
- Ch 9 When agents fail — infinite loops, tool errors, hallucinated tool calls, budget explosions
- Ch 10 Evaluation — trajectory eval, LLM-as-judge on the trace, human labeling
- Ch 11 Safety — prompt injection via tool output, sandboxed execution, capability gating
- Ch 12 Production — cost dashboard, streaming trace UI, guardrails, interview defense

Chapters queued (session note)

Chapters 1-12 of this journey are queued for follow-on authoring sessions. This Chapter 0 exists so you can see the whole arc and decide if agents are the right pattern for your problem. Come back as the remaining chapters ship.

Newbie mentor commentary — read this before you build

  1. Agents are not magic. They are a loop. Once you internalize the 4-box loop (Thought / Action / Observation / repeat until FINAL), every agent product on the market becomes explicable. Cursor is a ReAct loop with a fixed toolset for code editing. Perplexity Pro is a ReAct loop with search + summarizer. Devin is a ReAct loop with a broader toolset + long-term memory. There is no fifth box.
  1. Tool design is 80% of agent quality. A great LLM with badly-designed tools ships a broken agent. A mediocre LLM with well-designed tools ships a great agent. Chapter 3 will make you rewrite your first tool three times — because the JSON schema, error format, and idempotency guarantee for each tool matter more than the model choice.
  1. You will over-index on the LLM and under-index on the loop control. Every agent bug I have seen in production traces back to: "the LLM made a bad Thought" (solvable by better prompt), "the LLM called a tool with wrong args" (solvable by better tool schema), or "the LLM never decided to stop" (solvable by max_iterations + explicit termination condition). Learn to instrument all three.
  1. Cost is the shock line. An agent that averages 8 iterations at ~$0.02/iteration is $0.16 per user query. At 1000 queries/day that is $160/day = $4,800/month. At 100K queries/day it is $16K/day = $480K/month. You must build the cost dashboard in Chapter 12 BEFORE you ship, not after.
  1. Agentic AI is the SOTA (state of the art) in 2025. Every major AI lab (OpenAI, Anthropic, Google, Meta) is racing on agent quality. GPT-5 (2025), Claude 4 (2025), Gemini 2.5 all ship with dramatically improved tool-use capabilities. If you master this journey, you are qualified for the majority of NEW enterprise AI product work being funded today. RAG is table-stakes; agents are the frontier.

References for what's coming

Key takeaway

An agent is an LLM in a loop with tools. The ReAct pattern (Thought → Action → Observation → repeat) underlies every 2025 agentic product (Cursor, Devin, Claude Code, Copilot Workspace). Scale drives tool count and coordination need, not corpus size. L4 = single-tool ReAct; L5 = 10 tools + memory; L6 = orchestrator + worker pool; L7 = multi-agent federation with ACL. Agents cost 5-100× more per query than single-shot LLM calls — cost dashboard is mandatory day 1.

You can now answer
  • What is an agent in one sentence?
  • What are the 4 boxes of the ReAct loop?
  • What 5 properties does an agent deliver that RAG and base LLM calls cannot?
  • How does agent architecture evolve across L4/L5/L6/L7?
  • Why is cost 5-100× higher than a single-shot LLM call?
  • What are the 3 most common agent bug categories?
  • Why is tool design more important than model choice?