The tech world right now is brimming with talk about LLM Agents. But we are still in the very early days of this new field, and there does not yet exist a clear, rigorous consensus on what LLM Agents are.
Many people, labs, and organizations have thrown their hat into the definitional Agent ring. This post is my own tossing of the hat.
I've been using LLM Agents in my projects for the better part of a year now. Most of the work has relied on the tool-calling and prefill functionalities of the Anthropic API, although I've also delved (heh) into ChatGPT and Gemini tool-calling. This post reflects what I've learned, and the takeaways that have served me best in building good, reliable agents.
To start, let's chart the two extremes of LLM possibilities. At the more basic end, we have the simple web chat interface that everyone's now familiar with. At the far more advanced end, we have something like Iron Man's Jarvis. We're currently much closer to the former, but our civilization is jointly pouring a titanic amount of time, energy, and resources into moving toward the latter.
It is fair to call Jarvis an outright Agent for our purposes. If and when we get to that level, it's not clear that he would be built solely on the back of LLMs. Realistically, a true Jarvis equivalent will hybridize some sort of symbolic system. So, we won't (can't) call Jarvis an LLM Agent.
But on our technological approach to Jarvis, there will likely be an LLM architectural pattern that gets pretty close to him. That proto-Jarvis will most certainly be an LLM Agent, either one mega-Agent that's achieved breakthrough reasoning, or a swarm of smaller coordinated Agents. The details matter, but not quite for our purposes here. The main point is that in the future there will realistically be a system, built from LLM Agents, with the abilities and capabilities we imagine Iron Man having when he closes his helmet and asks Jarvis for an impossibly complex task.
Let's start then from the more basic end, the simple chat interface, and work our way up to a definition of LLM Agents. A Basic LLM that interacts with users in a turn-based pattern, and only ever responds to direct user input, is not an Agent.
What's the first evolution of this simple interface? Well, an LLM can be given access to external tools. A tool is usually defined as a typed function, and it imbues the LLM with external capabilities via explicitly typed inputs and outputs. But an LLM with tools is not yet an Agent either. A user's certain input can trigger the tool, but the LLM still directly relies on the user's input to call its tools. And, it can only call a tool once. This is not to say LLMs with tools are limited or useless - far from it. RAG, one of the most performant and powerful LLM system architectures of the moment, is an LLM with an external tool.
A RAG engine is a tool-based LLM with a single function: find_similar_content
. This function takes four parameters: the user's request, an external text database, a text embeddings model, and the number of matches to return. It then returns the external texts most semantically similar in the embedding space to the user's request.
We can't call a RAG engine an LLM Agent yet, because there is a single-step, static, user-triggered branching from the main chat conversation. There is no "agency" here - it is closer to what Anthropic calls a "workflow." The LLM is following a recipe, not deciding what to cook. But they are still quite powerful in their won right. Let's call these Augmented LLMs.
The most natural and powerful extension is to give the LLM control over their tools. Specifically, in letting them decide and orchestrate which tools must be called to meet a user's request. This is known as a tool-loop, and is the first inkling of true LLM Agency. This is the key point where the magic happens: a tool-loop kicks off an "inner dialogue" of sorts within the LLM, where it decides the order and amount of tools to call in order to fulfill a request.
With a well-thought out prompt structure (both system + user) the models can increase their computing resources by calling the needed tools, as many times as needed, to fulfill complex user requests.
At each step in the loop, the LLM gets to decide whether it calls another tools or ends the conversation and returns the aggregated outputs to the user. The LLM is acting, with side-effects, completely separate from the user's original request. It is having an aside with itself, a self-conversation, and marks the first time it's engaging its SFT and RL turn-based conversation separately from the user.
Here is where things get interesting. Usually, an LLM's tools are deterministic, user-defined functions. What happens when the LLM can call another LLM? This could be a regular, non-tool LLM, in which case it mimics a regular chat session. Or, it could call another tool-loop LLM, that calls another set of tool-loop LLMs, and so on, and so on... At this point, you have a Multi-Agent System.
As a small aside, we can actually use tool-loops to turn any model that supports tool-calling into a bootstrapped reasoner. Anthropic recently introduced the think
tool, which goes something like:
from claudette.core import tool
@tool
def think(
thought: str, # the thought or idea to think about to solve the user's request
) -> str: # do not worry about returning anything, only think
"""Use this tool to think about the user's request. You will not obtain new information or change the user's input. It only helps you think about the task and problem to maximally, accurately, and completely solve the user's request."""
print(f"Tool Execution: think() -> {thought}")
return thought
We can then explicitly tell the LLM in its system prompt, and enforce via prefill, that it will call think
a minimum of X
times, or until it's certain that it's completely broken down and has the full relevant context for the user's request. This won't be as good as RL-trained reasoners, but it can give smaller and more focused Agents an incredible boost. This show the power of function calling and tool-loops: we are able to, in a few lines of code, bootstrap one of the most important recent advances in the LLM domain.
Going back to our proto-Jarvis, the LLM approximation of him could either be a massive Agent with a gigantic set of tools and the ability to intelligently and meaningfully chain them together, or it could be a main hub Agent calling and coordinating a swam of smaller, task-focused sub-Agents.
Think of it in a procedural fashion. Regular LLMs are back-and-forth, linear chat sessions. The model cannot leave the current past conversation or go beyond it.
Tools give LLMs a way to "branch out" of the current conversation, to follow a fork in the road before coming back. With one-off tools, like RAG engines, this is a single fork than then re-collapses back into the main conversation. Everything is guided by the user's original request.
Agent LLMs, with tool-loops, break this back-and-forth pattern. It could follow multiple branching paths, deciding it needs to take actions vastly different or unrelated to the user's original request. This ability to break the linear flow of static, back-and-forth conversations is what defines an Agent. Agents have non-linear, complex control over the nature of the conversation, and the specific actions taken over the course of an interaction.
We have three rough categories of LLMs on the path to full Agents: