Foundations of Agentic AI Systems
An autonomous agent, in the most rigorous sense, is not merely a model that produces outputs in response to prompts. It is a system that persistently perceives its environment, maintains an internal representation of that environment, reasons about a goal, and commits to actions that alter the world in pursuit of that goal, with the entire cycle capable of repeating without external intervention. The question this chapter sets out to answer is whether the LLM-driven systems now entering enterprise production—AutoGPT-class planners, tool-using copilots, multi-agent crews—constitute a genuine architectural departure from the classical AI agents of the 1990s, or whether they are simply a new neural substrate executing essentially the same perceive-think-act logic that BDI architectures encoded three decades ago. The answer, as we will see, is that modern agentic systems are a hybrid: they preserve the symbolic scaffolding of classical agents while replacing the brittle hand-engineered reasoning components with learned neural approximations whose failure modes and capabilities are categorically different from those of their predecessors. Understanding this continuity-and-discontinuity is the prerequisite for engineering agents that work in production.
The Formal Agent Definition: The ⟨S, A, P, R, O⟩ Tuple
A precise definition of "agent" requires us to commit to a formalism, because the term has been overloaded by marketing copy, research papers, and product teams to the point where almost any system with a chat interface is now called an "AI agent." The formalism we adopt here is a deliberately minimal tuple that captures the four things an agent must have—state, action, perception, reasoning, and an objective—without committing to a particular implementation. We write an agent as a 5-tuple:
$$\mathcal{A} = \langle S, A, P, R, O \rangle$$
where each component has a specific role. The state space $S$ is the set of all configurations the agent can internally represent. In a vacuum-cleaning robot, $S$ is the cross-product of room locations and dirt sensors; in a chess engine, $S$ is the $10^{120}$ board positions reachable under the rules of the game; in an LLM agent, $S$ is the (effectively unbounded) space of all context-window states, which include conversation history, retrieved documents, scratchpad content, and tool outputs. The action space $A$ is the set of atomic interventions the agent can perform. This is critically implementation-dependent: $A$ may be discrete and small (four cardinal directions for a robot, one of 64 squares for a chess move) or combinatorial and vast (the set of all syntactically valid tool invocations and their parameter instantiations, easily exceeding $10^9$ in a real LLM agent connected to a thousand APIs). The perception function $P: \mathcal{E} \to S$ maps an environment $\mathcal{E}$ to a state, deciding what subset of the world's information enters the agent's working memory. For an LLM agent, $P$ is the pipeline of document loaders, web scrapers, and tool result parsers that converts external signals into tokens. The reasoning function $R: S \to \pi(A)$ maps a state to a distribution over actions—essentially, the agent's policy. In classical AI this is a hand-coded inference engine; in reinforcement learning it is a learned value network or policy gradient; in LLM agents it is the conditional next-token distribution given the context. Finally, the objective function $O: S \to \mathbb{R}$ defines what the agent is optimizing. In an MDP this is the reward function; in a goal-directed agent it is a satisfaction criterion; in a BDI agent it is a set of desires to be achieved.
The tuple is intentionally implementation-agnostic, but it is not vacuous. It rules out at least three things commonly mislabeled as agents. It rules out a frozen language model with no perception or action channel—what we should call a completion engine rather than an agent, because it has $A = \{\text{emit text}\}$ and no $P$ operating over an external $\mathcal{E}$. It rules out a pure reflex system whose $R$ is a stateless lookup table, because the absence of memory means it cannot engage with the temporal credit assignment that distinguishes agents from controllers. And it rules out an agent whose $O$ is undefined, because a system optimizing nothing is, in the technical sense, not behaving—its outputs are epiphenomenal rather than goal-directed. Every "agent" we encounter in production should be evaluable against this tuple: if you cannot identify $P$, $R$, and $O$ concretely, the system in question is probably not yet an agent, regardless of how it is marketed.
The perceive–think–act loop is the dynamic counterpart of the static tuple. Over discrete time steps $t = 0, 1, 2, \ldots$, the agent:
1. Observes $o_t = P(e_t)$, a percept derived from the environment at time $t$. 2. Updates its state $s_t = f(s_{t-1}, o_t)$ by integrating the new observation with prior state. 3. Selects an action $a_t \sim R(s_t)$, sampled from the reasoning/policy function. 4. Acts on the environment, producing $e_{t+1} = g(e_t, a_t)$, and receives any associated reward $r_t = O(s_t)$. 5. Reflects on the outcome, updating internal models and memory.
The loop is closed because the agent's action changes the environment, which changes the next observation, which feeds back into the next state. The agent is autonomous in the precise sense that the loop can continue indefinitely without a human in the loop, as long as the agent has a non-trivial $R$ and a non-degenerate $O$. The autonomy is partial to the extent that the human still specifies $O$, the action space $A$ is bounded, or the agent can be paused or redirected mid-loop. This framing is not new—it is essentially the Russell and Norvig agent function $f: \mathcal{P}^* \to \mathcal{A}$ restricted to a particular form—but it is useful because it forces us to articulate the components explicitly before arguing about whether a given system is "really" an agent.
A subtle but important point: the tuple makes no commitment to whether the environment is fully or partially observable. In a fully observable setting, $P$ is the identity function and $s_t$ is a complete description of the world; in a partially observable setting, $P$ is lossy and the agent must reason under uncertainty. Most real LLM agents operate in partially observable environments in two distinct senses. First, the LLM context window is a lossy projection of the agent's total memory—the early parts of a long conversation are effectively outside $S$ once the window overflows. Second, the external world is partially observable because the agent's tools (web search, file system, databases) return partial views. This means that even sophisticated LLM agents are, in the formal sense, POMDP solvers, and they inherit all the well-known pathologies of POMDPs: belief-state divergence, brittleness under unmodeled dynamics, and difficulty with credit assignment over long horizons. We will return to these failure modes repeatedly in the engineering chapters that follow.
From Symbolic BDI to Neural-Symbolic Hybrids: A Historical Trajectory
The history of agent architectures is a history of the field's changing answer to the question of how $R$—the reasoning function—should be implemented. We can identify five major eras, each defined by a different answer.
Era 1: Classical symbolic agents (1960s–1980s). The earliest "agents" were hand-coded expert systems that operated in narrow domains. SHRDLU (Winograd, 1968) was perhaps the canonical example: a robot-arm simulator that could be instructed in natural language to manipulate blocks on a table. SHRDLU's reasoning was a rule-based parser connected to a procedural planner, and its state representation was a symbolic world model. ELIZA (Weizenbaum, 1966) is sometimes called an agent but is more accurately a pattern-matcher with no persistent state and no