Building AI Agents · Part 5 of 7 · ToolLoopAgent, Skills & Subagents · Oct 2026

Quick answer: An agent runs in a loop: the model either answers or calls a tool, the tool's result is fed back, and the loop repeats until the task is done or a stop condition is reached. In the Vercel AI SDK this is the ToolLoopAgent class. Complex work can be split across subagents that a parent agent calls as tools.

The Agent Loop

Agents are built from tools and tool calling. Each pass through the loop is one step: a single model call that results in either a tool call or a text answer. If the model calls a tool, the result is added to the context and the model is called again. This continues until the model gives a final answer or a stop condition is met.

In the Vercel AI SDK, the ToolLoopAgent class wraps this loop. It bundles the model, instructions, tools and behaviour into a reusable component:

import { ToolLoopAgent, isStepCount } from 'ai';

const bookkeeper = new ToolLoopAgent({
  model: 'anthropic/claude-sonnet-5.5',
  instructions: 'You are a bookkeeping assistant for small businesses.',
  tools: {
    // getInvoice, postJournalEntry, ...
  },
  stopWhen: isStepCount(50), // raise the default limit of 20 steps
});

const result = await bookkeeper.generate({
  prompt: 'Record invoice INV-1042 as paid.',
});
console.log(result.text);

To stream the agent's output to a user, call bookkeeper.stream(...) instead of generate.

Controlling the Loop

By default, ToolLoopAgent stops after 20 steps as a safety limit. You control this with stopWhen:

ConditionStops when
isStepCount(n)The agent has taken n steps.
hasToolCall('done')A specific tool has been called, such as a "done" or "submit" tool.
isLoopFinished()Never triggers on its own: the agent runs until it finishes naturally.

You can pass an array of conditions, and the loop stops as soon as any one is met:

stopWhen: [isStepCount(50), hasToolCall('submitReport')],

Use isLoopFinished() with care. Without a step limit, a confused agent can loop for a long time and run up costs. AI SDK 6 called the step helper stepCountIs; it still works in version 7 as an alias.

Structured Output

You can make an agent return structured data that your code can use directly, rather than free text. Pass an output schema:

import { ToolLoopAgent, Output } from 'ai';
import { z } from 'zod';

const reviewAgent = new ToolLoopAgent({
  model: 'anthropic/claude-sonnet-5.5',
  output: Output.object({
    schema: z.object({
      sentiment: z.enum(['positive', 'neutral', 'negative']),
      summary: z.string(),
      keyPoints: z.array(z.string()),
    }),
  }),
});

Rules: Keeping Agents in Check

You constrain an agent's behaviour through its instructions and the rules it must follow. Rules are there to keep the AI in check. For example:

  • "Never make promises about refunds without checking the refund policy."
  • "Never post a journal entry over R50,000 without user approval."
  • "If you are unsure, ask a clarifying question instead of guessing."

For actions that matter, back rules up with code. The AI SDK supports tool approval, which requires a person to approve a tool call before it runs.

Advertisement

Agent Skills

Agent Skills are packaged instructions and resources that an agent loads when it needs them. They follow a standard folder structure:

skill-name/
├── SKILL.md       # required: name, description and instructions
├── scripts/       # optional: code the agent can run
├── references/    # optional: documentation it can read
└── assets/        # optional: templates and other files

The SKILL.md file is the only required part. The agent sees each skill's name and description up front and only reads the full instructions when a task calls for that skill, which keeps its context small.

Subagents

Subagents are part of multi-agent systems, where tasks are spread across several agents instead of asking one agent to do everything. A parent agent delegates work to a subagent by calling it as a tool, which is another example of how tools are the core of AI agents.

When to Use Subagents

  • The task spans different kinds of work, such as research, planning, writing and review.
  • One agent would need too much context or too many tools.
  • Parts of the task can run in parallel.
  • Different stages need different prompts, models or guardrails.
  • You want clear boundaries between routing, doing the work and combining the results.

The Subagent Pattern

  1. Create the subagent with its own instructions and tools.
  2. Create a tool that calls the subagent.
  3. Give that tool to the parent agent.
import { ToolLoopAgent, tool } from 'ai';
import { z } from 'zod';

// 1. The subagent
const researcher = new ToolLoopAgent({
  model: 'anthropic/claude-sonnet-5.5',
  instructions: 'Research the topic and return concise, sourced findings.',
  tools: { /* web search, web fetch, ... */ },
});

// 2. A tool that calls the subagent
const research = tool({
  description: 'Research a topic in depth and return a summary of findings',
  inputSchema: z.object({ topic: z.string() }),
  execute: async ({ topic }) => {
    const result = await researcher.generate({ prompt: topic });
    return result.text;
  },
});

// 3. The parent agent uses the subagent as a tool
const writer = new ToolLoopAgent({
  model: 'anthropic/claude-sonnet-5.5',
  instructions: 'You write articles. Always research a topic before writing.',
  tools: { research },
});

Each subagent works in its own context. The parent only sees the summary it returns, which keeps the parent focused and its context small.

What's Next

In Part 6 we add structure and reliability with workflow patterns, give agents knowledge through RAG, and look at events.

Cover photo: Danny Pérez on Unsplash

Chainbook builds intelligent business systems for African professionals, and AI agents are at the heart of how we build them.