The transition from prompt engineering to agentic workflows marks a fundamental shift in how we deploy large language models. For years, the industry focused on improving the quality of individual completions, treating the LLM as a sophisticated search engine or text generator. However, the current landscape requires systems that do not just talk, but act. An AI agent is essentially a reasoning engine wrapped in a loop, capable of decomposing complex goals, selecting tools, and observing the environment to correct its own path. For the data scientist, this means moving away from static pipelines and toward dynamic, stateful systems that manage their own execution flow.
Building these systems involves more than just selecting a high-performing model. It requires a rigorous understanding of control theory, memory management, and tool abstraction. We are seeing a move toward 'small models for small tasks' where a central orchestrator delegates specific sub-problems to specialized agents. This article breaks down the actual mechanics of these systems, focusing on the interface between deterministic code and probabilistic models. We will bypass the marketing hype to look at the latency trade-offs, the reality of agentic loops, and the architectural patterns that differentiate a fragile demo from a production-ready autonomous system.
The core loop: Observation, thinking, and action
At the heart of every AI agent is a loop. While basic RAG systems follow a linear Retrieve -> Augment -> Generate flow, agents utilize a recursive cycle often referred to as the ReAct pattern (Reasoning and Acting). The process begins when the agent receives a high-level objective. Instead of generating a final answer, the model is prompted to generate a 'Thought' about the current state, followed by an 'Action' using a predefined set of tools. Once the action is executed by the environment, the result is fed back into the model as an 'Observation', and the cycle repeats until the agent determines it has sufficient information to provide a final answer.
This loop introduces significant latency compared to standard inference. If an agent requires five steps to solve a problem, the end-user waits for five separate LLM calls, plus the execution time of the tools. In production, developers mitigate this by using smaller, faster models for the 'thought' generation and only involving larger frontier models for the final synthesis. The architectural challenge lies in ensuring the agent does not fall into a 'loop of death' where it repeats the same unsuccessful action. Implementing a max_iterations constraint and a robust state-machine-based fallback is mandatory for any system designed to run unattended.
From a data science perspective, managing this loop requires monitoring the trajectory of the agent. This is not just about logging the final output, but tracing the sequence of thoughts and actions. If an agent fails, you need to know if the failure was due to a faulty tool call, a hallucinated observation, or a breakdown in the model's reasoning logic. We treat these trajectories as datasets in their own right, using them to fine-tune future iterations of the agent through reinforcement learning from human feedback or direct preference optimization.

Planning mechanisms and task decomposition
Planning is the process by which an AI agent breaks down a monolithic user request into manageable sub-tasks. Without a distinct planning phase, agents often suffer from 'myopia', focusing on the immediate next word rather than the long-term objective. Advanced agents utilize strategies like Chain-of-Thought (CoT) or Tree-of-Thoughts to explore different execution paths. In a Tree-of-Thought architecture, the agent might generate three different potential plans, evaluate the feasibility of each, and prune the branches that lead to high-cost or low-probability outcomes.
There are two main types of planning: static and dynamic. Static planning involves generating a complete sequence of steps before taking any action. This is computationally cheaper but brittle; if the second step fails, the rest of the plan is often rendered useless. Dynamic planning, or reactive planning, updates the plan after every observation. This is far more resilient but increases the token cost significantly. Modern agent frameworks like LangGraph or AutoGPT-style systems often implement a hybrid approach, where a high-level roadmap is created initially, but the specific tool-use parameters are determined in real-time.
The effectiveness of planning is highly dependent on the model's context window and its ability to maintain a coherent state. When an agent decomposes a task, it must track which sub-tasks are completed, which are in progress, and which are pending. We represent this state using a structured object—often a JSON or a dedicated Pydantic model—which is passed through each iteration of the loop. If the state becomes too bloated with historical observations, the agent's reasoning ability degrades due to 'lost in the middle' phenomena, making context compression and summarization essential components of the planning engine.
Tool use and the execution environment
Tools are the hands of the AI agent. They are essentially API wrappers or local functions that the model can invoke by generating a specific string, usually in JSON format. The model is provided with a 'tool library'—a set of function signatures including names, descriptions, and parameter schemas. The agent does not 'know' how to use a SQL database or a web search engine; it simply understands that if it outputs {"tool": "search", "query": "AI trends"}, the underlying system will execute that code and return the result.
The bottleneck in tool use is rarely the execution itself, but the 'action selection' accuracy. If you provide an agent with 50 tools, the probability of it selecting the wrong tool or hallucinating a parameter increases. We call this 'tool confusion'. To solve this, practitioners use tool-pruning strategies, where a separate classifier or vector search identifies the 3-5 most relevant tools for the current context before the agent sees them. Furthermore, tools must be idempotent wherever possible. If an agent retries an add_user tool call because of a network timeout, the system should not create duplicate records.
Security is a paramount concern in the execution environment. Allowing an LLM to generate and execute Python code or SQL queries directly on production data is a significant risk. Production agents should run in sandboxed environments—such as Docker containers or serverless functions with restricted network access—and use a principle of least privilege. Data scientists must implement a validation layer that checks the output of the model against a strict schema before the action is ever executed by the host operating system.
Comparison of tool invocation methods
| Method | Pros | Cons | Use Case |
|---|---|---|---|
| Function Calling | Structured, reliable schema | Limited to specific models | Standardized APIs |
| ReAct Prompting | Works on any LLM | Higher hallucination rate | Legacy model support |
| Code Interpretation | Extremely flexible | High security risk | Data analysis/plotting |

Memory systems: Short-term vs long-term
For an agent to be effective over a long conversation or a multi-day task, it needs memory. We divide agent memory into short-term (working memory) and long-term (archival memory). Short-term memory is simply the current conversation history and the trace of the current loop's thoughts. Because of the cost and context limits of LLMs, we cannot keep everything. We use techniques like 'sliding window' memory, where only the last N tokens are kept, or 'summarization memory', where a background process condenses the history into a concise narrative.
Long-term memory is typically implemented using a vector database (RAG). When an agent encounters a new piece of information, it is embedded and stored. Later, when the agent faces a similar problem, it can query its own history to see how it solved it previously. This 'self-reflective' memory allows agents to improve over time without retraining the base weights of the model. However, retrieving from long-term memory adds another layer of complexity: the agent must decide when to query, what to query for, and how to filter the results to ensure they are relevant to the current task.
A newer paradigm is 'Procedural Memory', where the agent stores successful sequences of tool calls as 'macros'. If the agent finds that it always performs a web search followed by a summarization and a Slack notification, it can save that specific sequence. The next time a similar request arrives, the agent doesn't have to plan from scratch; it simply executes the learned procedure. This reduces token consumption and improves the consistency of the agent's behavior across different sessions.
Multi-agent orchestration and collaboration
As tasks become more complex, a single agent often becomes overwhelmed. The 'monolithic agent' approach fails because the prompt becomes too long, and the model struggles to balance different personas or skill sets. The solution is multi-agent systems (MAS). In a MAS architecture, we divide the work among specialized agents—for example, a 'Researcher' agent, a 'Writer' agent, and a 'Reviewer' agent. Each agent has its own system prompt, its own set of tools, and its own narrow scope of responsibility.
Communication between these agents is managed through a central orchestrator or a peer-to-peer messaging protocol. A common pattern is the 'Manager-Worker' pattern, where a manager agent breaks down the task and assigns sub-tasks to workers. The workers report back to the manager, who then synthesizes the results. This modularity makes the system easier to debug. If the output is low quality, you can pinpoint exactly which agent in the chain failed, rather than trying to fix a single, massive prompt that controls everything.
The challenge with multi-agent systems is 'agentic overhead'. Every hand-off between agents involves additional tokens and latency. There is also the risk of agents getting into 'loops of disagreement' where a Writer and a Reviewer keep bouncing a document back and forth without reaching a conclusion. Implementing clear exit conditions and a maximum number of hand-offs is critical. In many cases, a well-designed single agent with a clear state machine is more efficient than a complex multi-agent swarm for simple business processes.
The reliability of an agentic system is inversely proportional to the degree of freedom granted to the model without structured validation.

Common failure modes in agentic systems
Identifying why an agent failed is one of the most difficult tasks for a data scientist. One common failure mode is 'hallucinated tool parameters'. The model may correctly identify the tool it needs to use but provide a parameter that doesn't exist in the actual API, such as a date format that the backend doesn't support. Another frequent issue is 'state drift', where the agent's internal summary of the task becomes disconnected from the actual observations, leading it to perform actions based on outdated or incorrect assumptions.
Infinite loops are also a significant risk. This occurs when an agent's observation from a tool call doesn't provide enough information to move to the next step, but the agent's reasoning logic doesn't know how to ask for help or try a different approach. For example, if a search tool returns no results, the agent might just try the exact same search query again and again. Developers must implement 'anti-looping' logic that detects repeated outputs and forces the model to change its strategy or terminate the execution.
Finally, there is the 'instruction following decay' that happens as the conversation gets longer. As the context window fills up, the model may forget the original constraints provided in the system prompt. For instance, if you told the agent to 'never use the calculator for simple addition', it might obey that for three steps but forget it by step ten. We combat this using 'system prompt injection' at each step of the loop, ensuring the most important constraints are always in the most recent part of the model's attention span.
Evaluation and testing strategies
Traditional metrics like BLEU or ROUGE are useless for evaluating AI agents. Instead, we use 'trajectory evaluation' and 'success-on-task' metrics. We create a set of reference tasks with known correct outcomes and run the agent through them, measuring not just if it got the right answer, but how efficiently it did so. Did it take 15 tool calls when it could have taken 3? Did it visit any 'forbidden' states? We often use a 'judge' model—a larger, more capable LLM—to grade the agent's reasoning steps based on a rubric.
Component-level testing is also vital. You should test the tool-selection logic separately from the reasoning logic. For example, you can create a test suite of user queries and the expected tool calls, then measure the agent's accuracy in choosing the right tool. This allows you to iterate on the tool descriptions and system prompt without having to run the full, expensive agent loop. We also perform 'adversarial testing' where the tool returns errors or nonsense to see how well the agent recovers from environment failures.
Continuous monitoring in production is the final piece of the puzzle. We track 'cost per successful task' and 'time to resolution'. In agentic systems, these costs can be highly variable. A single user request might cost $0.01 or $1.00 depending on how many steps the agent takes. Setting hard caps on token usage per session is not just a budget requirement; it is a safety mechanism to prevent runaway processes from consuming thousands of dollars in API credits overnight.
Common mistakes to avoid
- Treating agents like traditional software: Agents are probabilistic and require 'fuzzy' error handling and retry logic rather than strict catch blocks.
- Over-engineering the agent swarm: Starting with five agents when one well-prompted agent with a simple state machine would be more reliable.
- Neglecting tool descriptions: Providing vague descriptions like 'search_tool' instead of specific instructions on what parameters the tool expects.
- Ignoring the 'lost in the middle' problem: Failing to prune or summarize the context, leading to degraded reasoning as the agent loop continues.
- Lack of human-in-the-loop: Building fully autonomous systems for high-stakes tasks without a mechanism for the agent to pause and ask for confirmation.
What to practise this week
To transition from understanding the theory to building production agents, you need hands-on experience with the friction points of these systems. The following steps will help you develop the necessary intuition for agentic design and debugging.
- Build a simple ReAct loop from scratch: Avoid using frameworks like LangChain initially. Write the loop that calls an LLM, parses the JSON tool call, executes the function, and feeds the result back in.
- Implement a 'checkpointer' for your agent: Create a system that saves the agent's state to a local file or database after every step so you can resume execution if the process crashes.
- Experiment with tool-pruning: Create a mock library of 50 tools and implement a vector-search pre-filter to see how it improves the accuracy of the agent's selections.
- Create a 'Judge' prompt: Write a prompt for a frontier model that evaluates the reasoning steps of a smaller agent, focusing on identifying logical fallacies or redundant tool calls.
- Benchmark different models on the same task: Run a complex multi-step task using three different models and compare the cost, latency, and trajectory quality of each.

