What you'll build
A minimal agent loop that decides, acts, and stops.
By the end of this lab you will have a tiny runtime that keeps state,
asks decide_next_step() what to do, runs a tool, records
the result, and then asks again. There is no real LLM here on purpose.
The control flow is the lesson.
This is the smallest version of an agent that still feels like an
agent. It does not just call one function and return. It inspects what
it knows, chooses an action, observes the result, and decides whether
it has enough to answer.
Run it
cd ai_ecosystem_labs
python3 06-agent-loop/agent_loop.py
Starting here? Quick setup
git clone https://github.com/BanditF/ai_ecosystem_labs
cd ai_ecosystem_labs
python3 06-agent-loop/agent_loop.py
Requires Python 3.8+. No additional packages needed for this lab.
Time guide. Setup: ~2 min. Working through it: 20–35 min if you want to really trace the loop state by state.
Why this piece exists
Agents are not magic. They are loops with state and stopping rules.
A lot of agent talk makes the model sound like the whole system. It is
not. The model is usually just the decision-maker inside a larger loop.
Something still has to hold state, dispatch tool calls, collect results,
and decide when the run is over.
A fair real-world analog is a person doing lightweight research. They
look at the question, decide to search once, read what came back, and
then either search again or answer. Frameworks like LangGraph make that
loop explicit, but the core idea is already here in about 40 lines.
Expected output
What a successful run looks like.
Your file paths may appear as absolute paths depending on where you run the script — that's expected.
Readable trace:
decision 1:
type: tool_call
tool: term_count
arguments: {term: "agent", files: [...]}
reason: Need evidence before answering.
result 1:
ok: true
total: 3
decision 2:
type: done
answer: Found 3 mentions of 'agent' across sample docs.
Actual JSON printed by the script:
{
"goal": "Find where the docs discuss agents.",
"term": "agent",
"steps": [
{
"decision": {
"type": "tool_call",
"tool": "term_count",
"arguments": {
"term": "agent",
"files": [
"labs/sample_docs/agents.txt",
"labs/sample_docs/protocols.txt",
"labs/sample_docs/memory.txt"
]
},
"reason": "Need evidence before answering."
},
"result": {
"ok": true,
"items": [
{
"file": "labs/sample_docs/agents.txt",
"count": 2
},
{
"file": "labs/sample_docs/protocols.txt",
"count": 0
},
{
"file": "labs/sample_docs/memory.txt",
"count": 1
}
],
"summary": {
"total": 3
}
}
}
],
"final": "Found 3 mentions of 'agent' across sample docs."
}
The key thing to notice is the shape: a decision, a tool result recorded
in state, and then a final answer once the loop has enough evidence.