What Makes This an Agent?
Botie can describe a pump, but the technician needs its actual manual. Follow the software that lets a model ask for information and use what comes back.
13 sections · 4 questions · 1 coding challenge
The arrow keys move between sections too.
Giving a Language Model a Way to Check
BOTIE
That gives us a useful place to begin: a proposed action is a request to software, and the result becomes new information. We can inspect those boundaries without asking the reader to trust an answer just because it sounds confident.
Sources for this history
The Manual Is in Another System
A technician asks Botie whether pump P7 needs an inspection. A language model can produce a plausible paragraph about pumps. It cannot establish what the current P7 manual says from that question alone. We need to give it a way to find the record.
We could always look up the manual first and ask the model to explain it. That is a useful workflow. Sometimes the reply raises another question: which revision applies, or has this fault already been inspected? An agent can choose a next step using what it has observed. Our application still decides which proposed steps are allowed.
These are invented, recorded examples. The browser runs your construction without calling a language model. Passing them checks the surrounding program, not the quality of a live model.
Step 1 of 2
A lookup changes what Botie knows
The model proposes a tool call. The application validates it and runs the lookup; the returned record goes into the next model request.
- 1
Request
- Question about P7
- Proposed lookup
- 2
Application
- Check access and arguments
- Read P7 manual
- 3
Next turn
- Observe returned record
- Propose an answer or another lookup
Step 2 of 2
Four pieces with different jobs
Keep the pieces separate so we know where a failure belongs.
| Piece | Job | P7 example |
|---|---|---|
| Model | Propose text or an action | Request the P7 manual |
| Tool | Perform an allowed operation | Read an authorised record |
| State | Retain relevant observations | The manual revision and tool result |
| Controller | Allow, run, repeat or stop | Enforce the lookup limit |
Model
- Job
- Propose text or an action
- P7 example
- Request the P7 manual
Tool
- Job
- Perform an allowed operation
- P7 example
- Read an authorised record
State
- Job
- Retain relevant observations
- P7 example
- The manual revision and tool result
Controller
- Job
- Allow, run, repeat or stop
- P7 example
- Enforce the lookup limit
The controller owns the next step
Each filter establishes a different requirement before the controller chooses a route.
Can Botie answer from what it has?
Filter the available manuals, then decide whether Botie has enough evidence for this small routing task.
BOTIE
Next controller step
answer from evidence
Follow the operations
1. Available manual records
[ { "asset": "P7", "approved": true } ]2. Keep approved manual records
[ { "asset": "P7", "approved": true } ]3. Requested asset
P7
4. Match the requested asset
[ { "asset": "P7", "approved": true } ]5. Remaining lookups
1
6. Choose answer, lookup or handoff
answer from evidence
7. Result
answer from evidence
These are invented, recorded examples. The browser runs your construction without calling a language model. Passing them checks the surrounding program, not the quality of a live model.
1. Start with a job we can finish
For this first version, Botie must return a short answer supported by the approved manual for the requested asset, or explain that it needs a person to help. It cannot book an inspection. That smaller job lets us see whether reading the right record works before we add effects outside the conversation.
Write down what would count as success and what information is missing. “Be a helpful maintenance agent” does not tell us when to stop.
An agent is useful when choosing the next operation helps the task. A fixed lookup followed by an explanation may be enough for many requests.
2. The model proposes; the tool performs
A tool definition gives the model a name, an explanation and an argument structure. A proposed call might name read_manual and supply asset P7. Our code checks that structure and the technician’s access before invoking the function.
The function returns data or an explicit error. The application associates that result with the original call and passes it back to the model. A message claiming “I checked the manual” is not evidence that any tool ran.
Proposed call: read_manual(asset="P7")
Tool observation: {"asset": "P7", "revision": "4", "approved": true}We will implement contracts and permission checks in later lessons. No prompt can replace an enforced permission check.
3. An observation can change the plan
Suppose the lookup returns no matching manual. Botie might ask which asset the technician meant, consult an authorised index, or hand the task to a person. The appropriate next step depends on the observation.
In an agent, a model may choose among permitted next steps. In a workflow, code may prescribe them. Real applications often combine both: a fixed approval step can surround a model-controlled search.
More autonomy creates more possible paths to test. We will compare those paths against a simple workflow before assuming an agent is necessary.
Check yourself
Questions on Parts 1 to 3
Question 1 of 2
What has happened?
Use the information below.
Botie emits read_manual(asset="P7"). No application function has run yet.4. Make the stopping rule executable
For the workshop, use a deliberately small controller. Keep approved records for the requested asset. If at least one remains, return answer from evidence. Otherwise request a lookup while any allowance remains, then hand off when it is exhausted.
This controller does not write the answer or validate whether a passage supports every claim. It makes one routing decision. A real run would decrement its allowance when dispatching a lookup and call the controller again with the new observation.
Matching approved evidence exists → answer from evidence
No matching evidence; lookups remaining > 0 → request manual lookup
No matching evidence; lookups remaining = 0 → hand offThe limit stops an unproductive loop. It does not turn missing evidence into permission to guess.
Keep evidence attached to its asset
Read the list of records before filtering it. The P8 record is approved, but it does not answer the P7 request.
records = [{"asset": "P8", "approved": True},
{"asset": "P7", "approved": False}]
matching = [r for r in records
if r["asset"] == "P7" and r["approved"]]
print(matching)[]An empty list means this fixture has no approved P7 evidence. A lookup is still needed.
5. A framework gives the loop a home
Pydantic AI connects typed inputs and outputs with dependency injection and tool execution. LangChain provides agent construction and integrations. LangGraph exposes graph-based control flow and state, which is useful when a task needs explicit branches or resumable execution. Their responsibilities overlap; choosing one does not settle the design of the task.
We will introduce each with the same maintenance job, so the code has a purpose before we discuss its abstractions. Follow the prompt and tool lessons first if those pieces are still unfamiliar.
Keep application state, provider message history and authoritative business records distinct. A conversation saying an inspection exists is not the work-order database.
6. What our small machine can establish
Change the requested asset and approval flag in the workshop. Then remove the remaining lookup allowance. The same construction should choose the correct route each time.
These recorded cases make control flow inspectable. Later evaluations must also measure model choices, answer quality, latency and actual tool effects. A deterministic controller test cannot supply that evidence by itself.
These are invented, recorded examples. The browser runs your construction without calling a language model. Passing them checks the surrounding program, not the quality of a live model.
Check yourself
Questions on Parts 1 to 6
Question 1 of 2
Which route follows our controller?
Use the information below.
Requested asset: P7. Records: approved P8 manual only. Remaining lookups: 1.Try it with Botie
Build with Botie
Write and run Python