An agent is a closed loop, not a one-way pipeline.
It chooses one action, reads the result, updates its state, and chooses again until the goal is reached, judged impossible, or stopped.
A plan written before any evidence arrives is only a guess. Live tools return prices, errors, empty results, and policy failures that were impossible to know in advance.
The agent therefore plans a little, acts, and then plans again from the new information.
| Step | Simple question |
|---|---|
| Think | What information or action is needed next? |
| Act | Which allowed tool should be called? |
| Observe | What actually came back? |
| Remember | What changed, and what remains unfinished? |
| Stop check | Is the goal satisfied, impossible, or awaiting approval? |
The plan is regenerated after each observation. That is what makes the loop different from a pipeline.
Goal:
Plan a four-day Paris trip from Mumbai within company policy and ₹80,000.
Think: I cannot judge any flight or hotel until I know the rules. Act: retrieve_policy("international flights, Paris hotels") Observe:
Remember: Add these three items as hard constraints.
Think: The cabin is now known, so search economy fares. Act: search_flights("BOM", "CDG", "15 Aug", "economy") Observe: Four fares from ₹38,400 to ₹61,200.
Remember: The cheapest fare leaves ₹41,600 for hotel and other trip costs.
Think: Search four nights below the policy cap and remaining budget. Act: search_hotels("Paris", nights=4, max_per_night=8000) Observe: Six hotels from ₹5,900 to ₹7,800 per night.
Choose a ₹6,800 option:
Flight ₹38,400
Hotel 4 × ₹6,800 ₹27,200
Total ₹65,600
Budget remaining ₹14,400
The trip is affordable. It is not yet valid.
Think: Price is only one constraint. Check the complete itinerary against policy. Act: check_policy(itinerary) Observe: FAIL — departure is five days away; policy requires seven days.
This is the moment that explains why an agent is needed. The budget was never the problem. New evidence invalidated an earlier plan.
Think: Keep the destination and policy-compliant cabin, but move the dates. Act: search_flights("BOM", "CDG", "22 Aug", "economy") Observe: ₹34,900, departing in eight days.
Think: The updated trip satisfies booking notice and remains under budget. Act: draft_itinerary() Observe: A compliant plan, ₹17,900 below budget.
The agent presents it to the user. It does not purchase anything without approval.
This is control-flow pseudocode, not a production agent:
state = {"goal": goal, "steps": 0}
while state["steps"] < 8:
action = model.choose_next_action(state, allowed_tools)
observation = run_validated_tool(action)
state = update_state(state, action, observation)
if goal_is_satisfied(state):
return ask_user_to_approve(state)
return {"status": "stopped", "reason": "step budget reached"}
The important logic is outside the model:
Set a step budget, time limit, and cost ceiling. Without limits, a confused agent can retry forever.
Log each action, its arguments, the result, duration, and state change. A run should be replayable during debugging.
Treat a tool failure as an observation, not an application crash. The agent may retry, select another tool, ask for help, or stop.
An agent repeatedly thinks, acts, observes, and remembers; the Paris example becomes agentic when a failed compliance check causes a new search.