Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Building a Tool-Using Agent

Welcome back. In our previous lesson, we constructed a production-ready cryptoPriceTool, defining its "contract" with Zod schemas and implementing its core logic, complete with robust error handling. You now have a reusable capability, but a tool on its own is inert.

This lesson bridges the gap between a tool and a functioning AI system. We will implement a basic agent that can autonomously select and execute the cryptoPriceTool you just built to answer a user's question. This is a foundational step in our journey, transforming a passive tool into an active, problem-solving entity. We will explore the concept of the "agentic loop" and use the Vercel AI SDK's high-level ToolLoopAgent abstraction—a pattern perfectly suited for the scalable, production-grade infrastructure you aim to build.

1. The Agentic Loop: From Tool Call to Final Answer

When you provide a tool-enabled LLM with a prompt like "What's the price of Bitcoin?", it doesn't immediately know the answer. Its first thought is not the price itself, but the process to find it. This process materializes as a "tool call"—an instruction from the model to your code, telling it which tool to use and with what arguments.

This initial tool call is just the first step. On its own, it doesn't produce a user-facing answer. To see this in action, let's watch a brief explanation from Vercel's team.

Multi-Step (Agentic) Generation with the AI SDK

This video, "Multi-Step (Agentic) Generation with the AI SDK", clearly illustrates the initial challenge.

Watch from the beginning to the tool call issue. Nico first shows an LLM unable to answer a question, then adds a weather tool. Pay close attention to the console output after he adds the tool: the script logs a lot of data, but no final text is generated. The model's turn ended after it decided to call the tool.

This reveals a crucial concept: to get a final, conversational answer, we need to create a feedback loop. The flow looks like this:

  1. User Prompt: The user asks a question.
  2. LLM Generation 1 (Tool Call): The model analyzes the prompt and generates a call to the appropriate tool (e.g., cryptoPriceTool).
  3. Tool Execution: Your application code executes the tool with the provided arguments and gets a result (e.g., { "price": 60000 }).
  4. LLM Generation 2 (Synthesis): The tool's result is sent back to the model along with the original prompt. The model now has the necessary information and generates a natural language response (e.g., "The current price of Bitcoin is $60,000.").

This multi-step interaction is what we call an agentic loop. The agent autonomously takes steps to gather information before formulating its final response.

This diagram from VoltAgent visualizes the agentic loop. The central 'weather-assistant' node acts as the agent, orchestrating the call to the 'weather' tool to fulfill the user's request.

2. Enabling the Loop with the Vercel AI SDK

Manually managing this feedback loop—checking for tool calls, executing them, and then making another API call to the LLM—would be verbose and error-prone, as Nico mentions in the video. Fortunately, the Vercel AI SDK automates this entire process.

The key is a single parameter that instructs the SDK to continue the generation process after a tool call. Let's explore this mechanism.

A Complete Guide To Vercel’s AI SDK // The ESSENTIAL Tool For Shipping AI Apps

In his "Complete Guide To Vercel’s AI SDK", Matt Pocock provides an excellent, practical demonstration of this feature.

Watch the segment from creating an agentic loop. He encounters the exact same issue of no text output and then resolves it by adding the maxSteps property to his streamText call. This single change enables the feedback loop, allowing the model to react to the tool's output.

As you saw, setting maxSteps (or its equivalent, stopWhen) tells the AI SDK to not stop after a tool call. Instead, it will automatically:

  1. Execute the tool.
  2. Package the tool's result into a new message.
  3. Send the updated message history back to the LLM for another generation step.

This continues until the model generates a text response or the maximum number of steps is reached. For a more formal explanation, you can refer to the documentation.

AI SDK Core: Tool Calling

The AI SDK Core documentation provides a clear, textual explanation of what happens under the hood.

Read the section on multi-step calls. This will solidify your understanding of how the SDK chains generations together, which is the fundamental mechanic of an agent.

3. Implementing a Worker Agent with ToolLoopAgent

While you can enable agentic behavior directly on generateText or streamText calls, a more structured and scalable approach for your production system is to encapsulate an agent's configuration into a reusable class. The AI SDK provides the ToolLoopAgent for this exact purpose.

The ToolLoopAgent is a high-level abstraction that bundles together the LLM model, system instructions, available tools, and loop control settings. This creates a self-contained "agent definition" that you can instantiate and use throughout your application.

Let's create our first worker agent. It will use the cryptoPriceTool from the previous lesson.

import { ToolLoopAgent } from 'ai';
import { openai } from '@ai-sdk/openai';
import { cryptoPriceTool } from './crypto-price-tool'; // Assuming your tool is in this file

// Define our first worker agent
export const cryptoPriceAgent = new ToolLoopAgent({
  model: openai('gpt-4o-mini'),
  tools: {
    // The agent has access to this tool
    getCryptoPrice: cryptoPriceTool, 
  },
  // We'll explore this in detail in the next lesson.
  // For now, a simple instruction is enough.
  instructions: 'You are a helpful assistant that provides cryptocurrency prices.',
  // By default, the agent will run for a maximum of 20 steps.
  // This is usually more than enough.
});

This code defines a cryptoPriceAgent. It's configured to use the GPT-4o Mini model and knows about one tool, which it can refer to as getCryptoPrice. This encapsulation is a powerful pattern that will be essential as we build out our complex agent hierarchy.

For more details on creating and configuring agents, the official documentation is an excellent resource.

Building Agents - AI SDK

The "Building Agents" documentation introduces the ToolLoopAgent class and its configuration.

Focus on the sections Creating an Agent and providing tools. This shows the basic structure for instantiating an agent and equipping it with the capabilities it needs to perform tasks.

4. Executing the Agent and Getting a Result

Now that we have defined our agent, using it is remarkably simple. We invoke its generate() method with a user prompt. The ToolLoopAgent instance handles the entire multi-step agentic loop internally.

Here is a complete example of how you would use the cryptoPriceAgent:

import { cryptoPriceAgent } from './crypto-price-agent'; // The agent we just defined

async function main() {
  const prompt = "What is the current price of ethereum in eur?";

  console.log(`User: ${prompt}`);

  // The generate method runs the full agentic loop
  const { text } = await cryptoPriceAgent.generate({
    prompt: prompt,
  });

  console.log(`Agent: ${text}`);
}

main().catch(console.error);

When you run this code, you will see the following happen behind the scenes, all orchestrated by the cryptoPriceAgent.generate() call:

  1. The agent sends the prompt to GPT-4o Mini.
  2. The model responds with a tool call: getCryptoPrice({ cryptoId: 'ethereum', vsCurrency: 'eur' }).
  3. The AI SDK executes your cryptoPriceTool with these arguments.
  4. The tool returns a price, e.g., { price: 3200 }.
  5. The SDK sends this result back to the model.
  6. The model generates the final, user-friendly text: "The current price of Ethereum is €3,200."
  7. The text property of the result contains this final string, which we log to the console.

This demonstrates the power of the abstraction. You simply define the agent's capabilities and then ask it to handle a prompt. The complex, multi-step reasoning and execution flow is managed for you.

Conclusion

In this lesson, you have brought your first agent to life. You've progressed from having a simple tool to implementing an autonomous entity that can decide when and how to use that tool. This is the core building block for the entire agentic infrastructure.

Key Takeaways:

  • An agentic loop is a multi-step process where an LLM first decides to call a tool, receives the tool's result, and then synthesizes a final response.
  • The Vercel AI SDK automates this loop via the maxSteps or stopWhen settings, which prevent the generation from stopping after a tool call.
  • The ToolLoopAgent class is a best practice for building production systems. It provides a structured, reusable container for an agent's model, tools, and instructions.
  • Invoking an agent with the .generate() method abstracts away the entire multi-step process, allowing you to interact with the agent as a single, intelligent unit.

We have successfully built the "body" of our first worker agent—it has senses (tools) and can act. In our next lesson, we will focus on its "mind" by crafting a precise system prompt. This will allow us to define its role, behavior, and constraints, turning it from a basic tool-user into a specialized, reliable component of our hierarchical system.

Can't find a good explanation? Sign up and we'll make it for you

Sign up