An AI agent is a program that uses a large language model to decide what to do next. You give it a goal. It figures out the steps, calls tools along the way, and keeps going until the job is done. No hard-coded control flow. No pre-planned sequence. The model reasons through each step at runtime.
This is fundamentally different from a chatbot. A chatbot responds to a single prompt and stops. An agent receives an objective, breaks it into subtasks, executes them, observes the results, and course-corrects if something goes wrong. It loops until the goal is met or it determines the goal is unreachable.
Most agents follow the ReAct (Reason + Act) pattern. It is a loop with three phases:
Then the loop repeats. The model reasons again with the new information, picks the next action, observes the result, and continues.
Here is a simplified version of the loop:
async function agentLoop(goal: string, tools: Tool[]) {
const messages: Message[] = [
{ role: "system", content: "You are a helpful agent." },
{ role: "user", content: goal },
];
while (true) {
const response = await llm.chat(messages);
if (response.type === "text") {
// No tool call means the agent is done
return response.content;
}
if (response.type === "tool_call") {
const result = await executeTool(response.toolName, response.args);
messages.push({ role: "tool", content: result });
}
}
}
The entire architecture is just a while loop, an LLM call, and tool execution. Everything else is an optimization on top of this.
Tools are what separate agents from chat completions. A tool is a function the model can invoke. You define the function signature and describe what it does. The model decides when to call it based on the current goal and context.
Common tool categories:
In TypeScript, you define tools as objects with a name, description, parameter schema, and an execute function. Both major SDKs follow this pattern.
The Vercel AI SDK provides generateText and streamText with built-in tool support. The maxSteps parameter controls how many reason-act-observe loops the agent can take.
import { generateText, tool } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { z } from "zod";
const result = await generateText({
model: anthropic("claude-sonnet-4-5-20250514"),
maxSteps: 10,
tools: {
getWeather: tool({
description: "Get current weather for a location",
parameters: z.object({
city: z.string().describe("City name"),
}),
execute: async ({ city }) => {
const res = await fetch(`https://wttr.in/${city}?format=j1`);
return res.json();
},
}),
searchWeb: tool({
description: "Search the web for information",
parameters: z.object({
query: z.string().describe("Search query"),
}),
execute: async ({ query }) => {
// Your search implementation
return await search(query);
},
}),
},
prompt: "What's the weather in Tokyo and what events are happening there this week?",
});
Each step is one iteration of the ReAct loop. The model might call getWeather first, then searchWeb for events, then synthesize both results into a final answer. Setting maxSteps: 10 gives it room to chain multiple tool calls without running forever.
Get the weekly deep dive
Tutorials on Claude Code, AI agents, and dev tools - delivered free every week.
The Claude Agent SDK takes a different approach. Instead of wrapping tool calls in a text generation function, it gives you a full agent runtime with built-in support for delegation, handoffs, and guardrails.
import { Agent, tool } from "@anthropic-ai/agent";
import { z } from "zod";
const researchAgent = new Agent({
name: "researcher",
model: "claude-sonnet-4-5-20250514",
instructions: "You research topics thoroughly using web search.",
tools: [
tool({
name: "search",
description: "Search the web",
parameters: z.object({ query: z.string() }),
execute: async ({ query }) => searchWeb(query),
}),
],
});
const response = await researchAgent.run(
"Find the top 5 TypeScript ORMs by GitHub stars and compare their query APIs"
);
The SDK handles the ReAct loop internally. You define the agent's identity, tools, and constraints. The runtime manages context, retries, and tool execution.
Single agents hit a ceiling on complex tasks. The context window fills up. The model loses focus. Errors compound. Multi-agent architectures solve this by splitting work across specialized agents, each with its own context and toolset.
Three patterns dominate:
A central orchestrator agent breaks a task into subtasks and delegates each to a specialized worker. The orchestrator synthesizes results. This is the most common pattern for complex, multi-domain problems.
const orchestrator = new Agent({
name: "orchestrator",
instructions: "Break tasks into subtasks. Delegate to specialists.",
tools: [
delegateTo(researchAgent),
delegateTo(codingAgent),
delegateTo(reviewAgent),
],
});
Agents execute in sequence. The output of one becomes the input of the next. Good for workflows with clear stages: research, then draft, then review, then publish.
const research = await researchAgent.run(topic);
const draft = await writerAgent.run(`Write about: ${research}`);
const final = await editorAgent.run(`Review and improve: ${draft}`);
Multiple agents work on independent subtasks simultaneously. Results are collected and merged. Best for tasks where subtasks do not depend on each other.
const [apiDocs, examples, benchmarks] = await Promise.all([
docsAgent.run("Extract API reference"),
exampleAgent.run("Generate usage examples"),
benchmarkAgent.run("Run performance benchmarks"),
]);
For a deeper look at these patterns with production examples, see the patterns guide and the frameworks comparison.
Not everything needs an agent. If the steps are known in advance and never change, a deterministic chain is simpler and more predictable. Use an agent when:
A good rule: if you can draw a fixed flowchart, use a chain. If the flowchart has conditional branches that depend on runtime data, use an agent.
Token costs add up. Every iteration of the ReAct loop is a full LLM call. A 10-step agent run with a large context can cost 10x a single completion. Set reasonable maxSteps limits and use smaller models for simple subtasks.
Observability matters. Agents make opaque decisions. Log every tool call, every intermediate result, every reasoning step. When an agent produces a wrong answer, you need to trace which step went sideways.
Guardrails prevent runaway agents. Set timeout limits. Restrict tool access to the minimum required. Validate tool inputs before execution. An agent with unrestricted shell access and no timeout is a production incident waiting to happen.
Start simple. Build a single-agent system with two or three tools. Get it working reliably. Then add agents and complexity only when you hit real limitations. Most tasks that seem to need multi-agent coordination can be solved with a well-prompted single agent and good tools.
The fastest way to internalize this is to build something. Start with a research agent that searches the web and writes structured summaries. Add a code agent that can read files and run tests. Wire them together with an orchestrator. You will learn more about agent design in one afternoon of building than in a week of reading.
The TypeScript ecosystem for agents is maturing fast. Vercel AI SDK, Claude Agent SDK, LangChain.js, and others all provide solid foundations. Pick one, build something real, and ship it.
Technical content at the intersection of AI and development. Building with AI agents, Claude Code, and modern dev tools - then showing you exactly how it works.
The TypeScript toolkit for building AI apps. Unified API across OpenAI, Anthropic, Google. Streaming, tool calling, stru...
View ToolAnthropic's Python SDK for building production agent systems. Tool use, guardrails, agent handoffs, and orchestration. R...
View ToolGives AI agents access to 250+ external tools (GitHub, Slack, Gmail, databases) with managed OAuth. Handles the auth and...
View ToolNew tutorials, open-source projects, and deep dives on coding agents - delivered weekly.

Getting Started with OpenAI's New TypeScript Agents SDK: A Comprehensive Guide OpenAI has recently unveiled their Agents SDK within TypeScript, and this video provides a detailed walkthrough...

In this video, learn how to leverage convex components, independent modular TypeScript building blocks for your backend. This tutorial focuses on one of the latest integrations with the Resend...

Check out Trae here! https://tinyurl.com/2f8rw4vm In this video, we dive into @Trae_ai a newly launched AI IDE packed with innovative features. I provide a comprehensive demonstration...
Two popular frameworks for building AI apps in TypeScript. Here is when to use each and why most Next.js developers shou...
From swarms to pipelines - here are the patterns for coordinating multiple AI agents in TypeScript applications.
The AI SDK is the fastest way to add streaming AI responses to your Next.js app. Here is how to use it with Claude, GPT,...