Building Agents
This page adapts the original AI SDK documentation: Building Agents.
Building Agents
Section titled “Building Agents”The ToolLoopAgent class provides a structured way to encapsulate LLM configuration, tools, and behavior into reusable components. It handles the agent loop for you, allowing the LLM to call tools multiple times in sequence to accomplish complex tasks. Define agents once and use them across your application.
Why Use ToolLoopAgent?
Section titled “Why Use ToolLoopAgent?”When building AI applications, you often need to:
- Reuse configurations - Same model settings, tools, and prompts across different parts of your application
- Maintain consistency - Ensure the same behavior and capabilities throughout your codebase
- Simplify API routes - Reduce boilerplate in your endpoints
- Type safety - Use Swift types for your agent’s call options, tools, and outputs
The ToolLoopAgent class provides a single place to define your agent’s behavior.
Creating an Agent
Section titled “Creating an Agent”Agent is the protocol for custom implementations. Use ToolLoopAgent for the built-in tool loop; BasicAgent is its ToolLoopAgent<Never, String, String> shorthand for text output without call options:
import SwiftAISDKimport OpenAIProvider
let myAgent = try BasicAgent(.init( instructions: "You are a helpful assistant.", model: openai("gpt-4o"), tools: [:]))Configuration Options
Section titled “Configuration Options”Configure the model, instructions, tools, output, and lifecycle callbacks through ToolLoopAgentSettings:
Model and System Prompt
Section titled “Model and System Prompt”let agent = try BasicAgent(.init( instructions: "You are an expert software engineer.", model: openai("gpt-4o")))Provide tools that the agent can use to accomplish tasks:
struct CodeInput: Codable, Sendable { let code: String }struct CodeResult: Codable, Sendable { let output: String }
let runCode = tool( description: "Execute Python code", inputSchema: CodeInput.self) { payload, _ in // Execute code (omitted) and return result CodeResult(output: "Code executed successfully")}
let codeAgent = try BasicAgent(.init( model: openai("gpt-4o"), tools: ["runCode": runCode.eraseToTool()]))Loop Control
Section titled “Loop Control”By default, agents run for 20 steps (stopWhen: isStepCount(20)). In each step, the model either generates text or calls a tool. If it generates text, the agent completes. If it calls a tool, the AI SDK executes that tool.
To let agents call multiple tools in sequence, configure stopWhen to allow more steps. After each tool execution, the agent triggers a new generation where the model can call another tool or generate text:
let agent = try BasicAgent(.init( model: openai("gpt-4o"), stopWhen: [isStepCount(20)] // Allow up to 20 steps))Each step represents one generation (which results in either text or a tool call). The loop continues until:
- The model generates text instead of calling a tool, or
- A stop condition is met
You can combine multiple conditions:
let agent = try BasicAgent(.init( model: openai("gpt-4o"), stopWhen: [ isStepCount(20) // Add custom conditions as needed ]))Learn more about loop control and stop conditions.
Tool Choice
Section titled “Tool Choice”Control how the agent uses tools:
let agent = try BasicAgent(.init( model: openai("gpt-4o"), tools: ["runCode": runCode.eraseToTool()], toolChoice: .required // or .none / .auto (default)))You can also force the use of a specific tool:
let agent = try BasicAgent(.init( model: openai("gpt-4o"), tools: [ "weather": weatherTool, "cityAttractions": attractionsTool ], toolChoice: .tool(toolName: "weather") // Force the weather tool to be used))Structured Output
Section titled “Structured Output”Define structured output schemas:
struct FeedbackAnalysis: Codable, Sendable { let summary: String let priorities: [String]}
let analysisAgent = try ToolLoopAgent<Never, FeedbackAnalysis, JSONValue>(.init( model: openai("gpt-4o"), stopWhen: [isStepCount(10)], output: Output.object(FeedbackAnalysis.self)))
let result = try await analysisAgent.generate( prompt: "Analyze customer feedback from the last quarter")let output = try result.outputDefine Agent Behavior with System Prompts
Section titled “Define Agent Behavior with System Prompts”System prompts define your agent’s behavior, personality, and constraints. They set the context for all interactions and guide how the agent responds to user queries and uses tools.
Basic System Prompts
Section titled “Basic System Prompts”Set the agent’s role and expertise:
let agent = try BasicAgent(.init( instructions: "You are an expert data analyst. You provide clear insights from complex data.", model: openai("gpt-4o")))Detailed Behavioral Instructions
Section titled “Detailed Behavioral Instructions”Provide specific guidelines for agent behavior:
let codeReviewAgent = try BasicAgent(.init( instructions: """ You are a senior software engineer conducting code reviews.
Your approach: - Focus on security vulnerabilities first - Identify performance bottlenecks - Suggest improvements for readability and maintainability - Be constructive and educational in your feedback - Always explain why something is an issue and how to fix it """, model: openai("gpt-4o")))Constrain Agent Behavior
Section titled “Constrain Agent Behavior”Set boundaries and ensure consistent behavior:
let customerSupportAgent = try BasicAgent(.init( instructions: """ You are a customer support specialist for an e-commerce platform.
Rules: - Never make promises about refunds without checking the policy - Always be empathetic and professional - If you don't know something, say so and offer to escalate - Keep responses concise and actionable - Never share internal company information """, model: openai("gpt-4o"), tools: [ "checkOrderStatus": checkOrderStatus, "lookupPolicy": lookupPolicy, "createTicket": createTicket ]))Tool Usage Instructions
Section titled “Tool Usage Instructions”Guide how the agent should use available tools:
let researchAgent = try BasicAgent(.init( instructions: """ You are a research assistant with access to search and document tools.
When researching: 1. Always start with a broad search to understand the topic 2. Use document analysis for detailed information 3. Cross-reference multiple sources before drawing conclusions 4. Cite your sources when presenting information 5. If information conflicts, present both viewpoints """, model: openai("gpt-4o"), tools: [ "webSearch": webSearch, "analyzeDocument": analyzeDocument, "extractQuotes": extractQuotes ]))Format and Style Instructions
Section titled “Format and Style Instructions”Control the output format and communication style:
let technicalWriterAgent = try BasicAgent(.init( instructions: """ You are a technical documentation writer.
Writing style: - Use clear, simple language - Avoid jargon unless necessary - Structure information with headers and bullet points - Include code examples where relevant - Write in second person ("you" instead of "the user")
Always format responses in Markdown. """, model: openai("gpt-4o")))Using an Agent
Section titled “Using an Agent”Once defined, you can use your agent in three ways:
Generate Text
Section titled “Generate Text”Use generate() for one-time text generation:
let result = try await myAgent.generate(prompt: "What is the weather like?")print(result.text)Stream Text
Section titled “Stream Text”Use stream() for streaming responses:
let stream = try await myAgent.stream(prompt: "Tell me a story")for try await chunk in stream.textStream { print(chunk, terminator: "")}print()Respond to UI Messages (server)
Section titled “Respond to UI Messages (server)”Use respond() to produce a UI message stream response on the server:
let uiMessages: [UIMessage] = [ UIMessage(id: "user-1", role: .user, parts: [.text(TextUIPart(text: "Tell me a story"))])]let response = try await myAgent.respond(messages: uiMessages)// Return response.stream as SSE from your HTTP handler.Note: React hook examples (
useChat) are JS‑only and not part of the Swift AI SDK.
Next Steps
Section titled “Next Steps”Now that you understand building agents, you can:
- Explore workflow patterns for structured patterns using core functions
- Learn about loop control for advanced execution control
- See manual loop examples for custom workflow implementations