Building on your definition, I'd say an agent is is a collection of LLM calls with structured outputs.
You can give an LLM some context and ask "what's the next step?". And agent does that recursively, with some exit condition.
Those structured outputs inform the control flow of the agent, so much so that at the end of the execution, you can argue that the agent has "written its own control flow".
The structured outputs may produce: - Function calls, and their inputs (tool calling) - Some reasoning text (for the context) - An exit condition evaluation (done=true)
Hope that helps!