Agents Overview
Purpose and Scope
The Agents documentation area explains when an application should move beyond a single model call and use an agent loop. In this SDK, an agent is a large language model that can use tools repeatedly until it completes a task. That definition matters because the extra behavior is not only tool availability; it also includes loop orchestration, context management, and stopping conditions. If a request can be answered by one generation call, AI SDK Core functions are often enough. If the model must inspect intermediate results, call multiple tools, and decide what to do next, an agent abstraction gives that behavior a reusable home.
Sources: content/docs/03-agents/01-overview.mdx, content/docs/03-ai-sdk-core/01-overview.mdx
The most important distinction is between three levels of control. AI SDK Core gives you lower-level functions such as generateText and streamText, which standardize prompts, settings, tool calls, and structured output across providers. ToolLoopAgent builds on those ideas by encapsulating a model, tools, and repeated execution into a class you can define once and invoke across routes or jobs. HarnessAgent is a different abstraction for established agent runtimes, such as coding harnesses, where the runtime owns broader behavior like workspace access, native session state, permission flows, and sandboxed execution.
Sources: content/docs/03-ai-sdk-core/01-overview.mdx, content/docs/03-agents/01-overview.mdx, content/docs/03-ai-sdk-harnesses/01-overview.mdx
Core Agent Primitives
Agents combine three primitives: an LLM, tools, and a loop. The LLM reads the current input and decides the next action. Tools extend the model beyond text generation by letting it read files, call APIs, write to databases, or perform other typed operations. The loop controls how those pieces repeat: it decides what context the model sees at each step, applies stopping conditions, and accumulates the steps that led to the final answer. This is why the agent pages focus on behavior over individual prompts: the central design problem is managing repeated model-tool interaction safely and predictably.
Sources: content/docs/03-agents/01-overview.mdx
runtimeContext and toolsContext are the state boundaries called out in the agent overview. Use runtimeContext for server-side state that should travel through the agent loop but should not be pasted into the prompt, such as tenant settings, request IDs, feature flags, credentials, or task progress. It is available in prepareStep and lifecycle callbacks and can be updated between steps. Use toolsContext for per-tool values, such as an API key or scoped permission object, so each tool receives only the typed context allowed by its own contextSchema.
Sources: content/docs/03-agents/01-overview.mdx
import { ToolLoopAgent, tool } from 'ai';
import { z } from 'zod';
const weatherAgent = new ToolLoopAgent({
model,
tools: {
weather: tool({
description: 'Get the weather in a location',
inputSchema: z.object({ location: z.string() }),
execute: async ({ location }) => ({ location, temperature: 72 }),
}),
},
});
const result = await weatherAgent.generate({
prompt: 'What is the weather in San Francisco?',
});
console.log(result.text);
console.log(result.steps);ToolLoopAgent Versus Core Calls
Use ToolLoopAgent when the same model settings, tools, prompt behavior, and loop rules should be reused throughout your application. The overview describes it as the recommended starting point for most agent use cases because it reduces boilerplate, manages loops and message arrays, improves reuse, and provides a single place to update agent configuration. The weather example demonstrates this: the agent can call a weather tool, then call a conversion tool, then produce the final answer. Application code asks for the result rather than manually coordinating every intermediate tool call.
Sources: content/docs/03-agents/01-overview.mdx
Use generateText or streamText when the reader problem is closer to direct model orchestration than reusable agent behavior. AI SDK Core describes generateText as suitable for non-interactive automation, text generation, and agents that use tools, while streamText is suitable for interactive cases such as chatbots and streamed content. Both can participate in tool usage and structured output, so choosing core functions does not mean giving up capability. It means you want explicit control over the call, response handling, and each step of a more custom workflow.
Sources: content/docs/03-ai-sdk-core/01-overview.mdx
A practical rule is to start with the simplest surface that matches the control boundary. For a summary job, extraction task, or single chat response, call a core function. For a reusable assistant that owns instructions, tools, and repeated execution, define a ToolLoopAgent. For an existing coding-agent runtime with its own workspace behavior, session lifecycle, and permissions, use HarnessAgent. This keeps application code aligned with the actual runtime model instead of forcing every task into either a single generation call or a hand-built agent loop.
Sources: content/docs/03-agents/01-overview.mdx, content/docs/03-ai-sdk-core/01-overview.mdx, content/docs/03-ai-sdk-harnesses/01-overview.mdx
HarnessAgent and Established Agent Runtimes
HarnessAgent is for cases where the agent runtime already exists and should not be recreated with provider calls and local tools. The harness overview defines a harness as a complete runtime, such as Claude Code, Codex, or Pi, that owns capabilities larger than a model call: workspace access, built-in coding tools, native session state, compaction, permission flows, and runtime-specific configuration. Harnesses are separate from providers and models. Providers expose models to core functions; harness adapters expose agent runtimes to HarnessAgent.
Sources: content/docs/03-ai-sdk-harnesses/01-overview.mdx
Harnesses still integrate with familiar AI SDK surfaces where possible. The overview states that HarnessAgent.generate() returns an AI SDK GenerateTextResult, and HarnessAgent.stream() returns an AI SDK StreamTextResult. Consumers can use familiar fields such as result.text, result.stream, result.steps, result.usage, and result.responseMessages. Harness-specific events are translated into compatible stream parts when possible, while events without a first-class AI SDK part are represented as dynamic provider-executed tool parts. This compatibility lets UI and streaming code consume harness runs without treating them as ordinary model providers.
Sources: content/docs/03-ai-sdk-harnesses/01-overview.mdx
Sessions are a major difference from one-shot calls and from a simple tool loop. A harness session owns the runtime, sandbox, working directory, native conversation history, and pending approvals. The docs show creating a session before running turns, passing that session to agent.generate, and destroying it afterward. For server routes, the same concept extends to stable session identifiers and persisted resume state. This is why harnesses are useful for multi-turn coding tasks: the runtime carries workspace and conversation state that would be awkward to reconstruct as plain prompt text.
Sources: content/docs/03-ai-sdk-harnesses/01-overview.mdx
System-to-Code Mapping
| Reader need | Public surface | Source-backed role |
|---|---|---|
| Build a reusable model-and-tools loop | ToolLoopAgent | Encapsulates model configuration, tools, loop execution, context management, and stopping conditions. |
| Make a direct model call | generateText | Generates text and tool calls for non-interactive automation or explicit orchestration. |
| Stream an interactive response | streamText | Streams text and tool calls for chatbot and content-streaming use cases. |
| Carry request or task state through an agent | runtimeContext | Holds server-side state that flows through the agent loop and lifecycle callbacks. |
| Provide scoped values to individual tools | toolsContext | Supplies per-tool typed context based on each tool's contextSchema. |
| Run an established coding-agent runtime | HarnessAgent | Connects an application to a harness runtime while projecting output into AI SDK-compatible results and streams. |
| Preserve harness workspace state | Session | Owns sandbox, working directory, native history, runtime state, and pending approvals. |
Relevant Source Files
content/docs/03-agents/01-overview.mdx— Defines agents as LLMs using tools in a loop, introducesToolLoopAgent, explainsruntimeContextandtoolsContext, and positionsHarnessAgentrelative to custom tool-loop agents.content/docs/03-ai-sdk-core/01-overview.mdx— Defines AI SDK Core as the lower-level standardized API surface and namesgenerateTextandstreamTextas the core text, tool-call, and streaming functions to compare against agents.content/docs/03-ai-sdk-harnesses/01-overview.mdx— Explains harnesses as complete agent runtimes, documents theHarnessAgentabstraction, compatible stream/result types, sandboxed operation, and session lifecycle concepts.
Execution Flow
A typical ToolLoopAgent flow begins when application code calls agent.generate with a prompt. The agent sends the current model-visible context to the LLM, receives either text or a tool call, executes the selected tool with validated input, adds the result to the conversation state, and repeats until the stopping condition is satisfied. The final result exposes the agent's final text and the steps taken. The key advantage is that the loop lives with the agent definition instead of being rewritten in every API route or background job that needs the same behavior.
Sources: content/docs/03-agents/01-overview.mdx
A typical harness flow begins earlier, with session creation. Application code creates a harness-backed agent, starts or resumes a session, then runs a turn through generate or stream. The harness runtime executes inside a sandbox and may use its native tools, state, and permission model. The AI SDK-facing result is projected into standard result and stream shapes, but the underlying runtime remains a harness rather than a provider model. Treating sessions as first-class is the safest way to preserve state while cleaning up sandbox resources when the task is complete.
Sources: content/docs/03-ai-sdk-harnesses/01-overview.mdx
API Components Reference
ToolLoopAgent— Agent class for building your own model-and-tools loop with reusable configuration.tool— Helper used in the overview example to define typed tools with descriptions, input schemas, andexecutefunctions.agent.generate({ prompt })— Runs an agent turn and returns a result with final text and step details in the documented example.runtimeContext— Shared runtime state for the agent loop,prepareStep, and lifecycle callbacks.toolsContext— Per-tool context boundary; each tool receives its own typed context based oncontextSchema.generateText— Core function for text generation and tool calls when explicit orchestration is preferred.streamText— Core function for streamed text and tool calls in interactive experiences.HarnessAgent— Agent implementation for established harness runtimes rather than provider/model calls.HarnessAgent.generate()— Returns an AI SDKGenerateTextResultaccording to the harness overview.HarnessAgent.stream()— Returns an AI SDKStreamTextResultaccording to the harness overview.session.destroy()— Cleanup step shown in the harness session example after a run completes.
Next Steps
After this overview, read the agent-building guide when you want to define a ToolLoopAgent with instructions, tools, streaming, and call options. Read the loop-control and runtime-context material when the hard part is deciding what state belongs in prompts, runtime context, tool context, or stopping conditions. If your use case is a coding agent or another established runtime, continue into the harness documentation before designing your own loop. If your use case is still a single response, start with AI SDK Core and only promote the code to an agent once reuse or multi-step tool behavior becomes the main concern.
Sources: content/docs/03-agents/01-overview.mdx, content/docs/03-ai-sdk-core/01-overview.mdx, content/docs/03-ai-sdk-harnesses/01-overview.mdx