You know tools. You know loops. You know state and graphs. You know what frameworks are for.
This chapter is the payoff: one working agent that solves a real (tiny) job.
The job
ShopTiny support:
- Customer: “Order 4412 arrived broken — please refund me.”
- Fake order store in memory (no real database)
- Two tools: get_order, refund_order
- Rule: refund only if amount is under $100 (large orders stay “needs human,” like earlier chapters)
The model must call tools. A plain chat reply that invents a refund is not enough.
Customer message
│
▼
┌─────────────────┐
│ Framework agent │ ← LLM + tool loop (framework owns the runner)
└────────┬────────┘
│ get_order / refund_order
▼
Fake order store
│
▼
Final reply to customerSame contract — best framework per language
Patterns stay the same. The library changes so you use what each ecosystem actually ships well:
| Language | Framework | Why here |
|---|---|---|
| Python | LangGraph (+ Gemini via LangChain) | You already mapped graphs → LangGraph; strongest Py graph/agent stack |
| TypeScript | LangGraph.js (+ Gemini) | Same mental model as Python |
| Java | LangChain4j (AiServices + @Tool) |
Best plain-Java agent toolkit (no Spring Boot required) |
| Go | Google ADK | Official Go agent kit; Gemini-native; tools + runner |
Install notes live in each Code file. Put your API key in the practice file (fine for local learning). Do not publish a real key.
Where is the graph?
You will not see add_node / add_edge in this lab’s Code.
That is intentional. The framework already builds the ReAct-style graph:
START → agent (LLM) → tools? → agent → … → END
| You write | Framework owns |
|---|---|
Tools (get_order, refund_order) |
The agent ↔ tools loop |
| System / instruction prompt | When to stop and return a final reply |
| One customer message + run | Nodes, edges, and the runner |
Same ideas as Branching and Graphs — less plumbing. Comments in the Code panel show the hidden shape for each language.
Where are state, updates, and persistence?
Three different “state” ideas show up. Only some are in this lab’s Code.
1. Agent / graph state (conversation)
The framework keeps a message list while the run is alive:
| Turn | What gets appended |
|---|---|
| Start | Customer (human) message |
| Model wants a tool | AI message with a tool call |
| Tool finishes | Tool result message |
| Done | AI message with the final reply |
You do not declare state = { order_id, amount, … } like in Explicit State.
create_react_agent / AiServices / ADK use messages as state. Each step updates that list by appending.
When the run ends, that in-memory list is gone (unless you add persistence — see below).
2. Shop data (your tools)
ORDERS is separate: a tiny fake database.
refund_order modifies it (status = "refunded"). That is normal app data, not LangGraph checkpoint state.
3. Persistence (save / resume) — not wired here
Persistence and Human-in-the-Loop taught save → exit → load → continue.
This lab does not save checkpoints to a file or pause for a human. One invoke / chat / Run, then done.
Frameworks can do that (LangGraph checkpointers, ADK sessions on disk, etc.). We left it out on purpose so this chapter stays “real agent, one happy path.” Comments in Code point to where you would plug persistence later.
| Chapter idea | In this lab? |
|---|---|
| Explicit refund fields you update by hand | No — replaced by message list + tools |
| Message list growing each step | Yes — framework owns it |
ORDERS updated by refund_order |
Yes — your tool code |
| Save JSON / resume tomorrow | No — see ch 19; optional next step |
What “done” looks like
For order 4412 ($12 laptop stand):
- Agent calls get_order
- Sees a small amount → calls refund_order
- Replies that the refund went through
Try order 5501 ($900) yourself: refund should refuse and say a human is needed.
What you should remember
- A real agent is LLM + tools + a runner — not a chat demo with fake confidence.
- Frameworks differ by language; the job (lookup → decide → act) does not.
- After this, multi-agent and MCP are about teams and how tools are plugged in — not about inventing the basic agent loop again.
See it in Code
Open the Code panel. Run the sample for your language. Watch tool calls in the logs, then the final customer reply.