If you're asking how to build an AI agent with ChatGPT, there are two honest answers, and picking the wrong one wastes a week. The no-code path builds the agent inside ChatGPT — a Custom GPT for a simple configured assistant, or a Workspace Agent (OpenAI's newer, autonomous successor to Custom GPTs) for something that runs on its own. The code path builds the agent inside your own product with the OpenAI Agents SDK — you define the agent, give it tools, and run the loop. The deciding question isn't your skill level; it's where the agent has to live.
Here's the whole decision in one screen:
- Lives inside ChatGPT, run by a non-engineer → Workspace Agent (no-code, autonomous) or a Custom GPT (no-code, simplest).
- Lives inside your app, needs custom tools and data control → OpenAI Agents SDK (
pip install openai-agents). - Wants a code-level loop but not the ops → the managed Agents API (public beta since Sept 10, 2026 — OpenAI runs the harness).
- Skip OpenAI's visual Agent Builder — it's being deprecated (shutdown Nov 30, 2026).
The rest of this guide takes each path far enough to act on, gives you a working Python agent you can run today, and ends with the cost math so the loop doesn't surprise you on the bill.
The no-code path: build the agent inside ChatGPT#
If the agent will live inside ChatGPT and a non-engineer will run it, you may not need to write anything.
A Custom GPT is the fastest start: ChatGPT configured with your instructions, some uploaded knowledge files, and optional Actions (calls to an external API via an OpenAPI schema). It's genuinely useful for a focused assistant — a support triager, a style-guide checker, a doc Q&A bot. Its limit is structural: a Custom GPT answers one turn at a time and doesn't own a real loop, so it can't reliably chew through a multi-step task on its own. One practical note for 2026: which plans can create new Custom GPTs has been in flux, so check what your tier allows before you build around it.
A Workspace Agent is the more capable no-code option, and OpenAI positions it as the ChatGPT-native successor to Custom GPTs. The difference that matters is autonomy and persistence: a Workspace Agent can run in the background, keep going after you close the browser, use multiple tools across a task, and follow schedules — with memory and governance built in. That's much closer to what people mean by "agent." If the job is "watch this inbox and draft replies" or "every morning summarize these dashboards," a Workspace Agent does it without code.
When to graduate to code: the moment the agent has to live inside your product, expose your UX, run your tool logic, or control where data is stored and how approvals work. No-code stops where your own runtime begins.
The code path: the OpenAI Agents SDK#
For a real, embeddable agent, the most direct route on OpenAI is the Agents SDK — an open-source Python (and TypeScript) framework, openai-agents, at v0.22.x as of September 2026. It gives you the six primitives every agent needs, documented in the SDK's own repo:
- Agents — a model plus instructions, a set of tools, and optional guardrails.
- Tools — your own Python functions, OpenAI's hosted tools, or remote MCP servers.
- Handoffs — one agent delegating a sub-task to another (agents-as-tools).
- Guardrails — input/output validation that can stop a run.
- Sessions — automatic conversation-history management across turns.
- Tracing — built-in run tracking so you can see every step and debug it.
It's also provider-agnostic: the same code can route to 100+ models via LiteLLM, so choosing the SDK doesn't weld you to OpenAI. The default model is gpt-5.6-luna (a cheap tier, since v0.20.0), and you can override it per-run.
A working agent in ~20 lines
Install the SDK, set your key, and this is a complete tool-using agent — one custom function tool plus OpenAI's hosted web search:
# pip install openai-agents (0.22.x as of Sept 2026)
# export OPENAI_API_KEY=sk-...
import asyncio
from agents import Agent, Runner, WebSearchTool
from agents.decorators import tool # current docs use @tool;
# older tutorials show: from agents import function_tool
@tool
def get_weather(city: str) -> str:
"""Get the current weather for a city.
Args:
city: The city to look up.
"""
# a real tool would call a weather API here
return f"It's sunny in {city}."
agent = Agent(
name="Assistant",
instructions="You are a concise assistant. Use tools when they help.",
model="gpt-5.6-luna", # SDK default since v0.20.0; override per run if needed
tools=[get_weather, WebSearchTool()],
)
async def main():
result = await Runner.run(agent, "What's the weather in Lisbon, and any news there today?")
print(result.final_output)
if __name__ == "__main__":
asyncio.run(main())
Runner.run executes the whole loop — the model decides when to call get_weather or search the web, reads the results, and keeps going until it has a final answer. (Runner.run_sync(agent, "...") is the blocking variant if you're not in async code.) A note on the decorator: current docs lead with @tool from agents.decorators, while plenty of older tutorials still use the @function_tool alias — both work, so don't be thrown when you see the other one.
From here you add the pieces you need: OpenAI's hosted tools — WebSearchTool, FileSearchTool (over your Vector Stores), CodeInterpreterTool (sandboxed code), HostedMCPTool (a remote MCP server) — plus Handoffs to specialist agents and Guardrails to validate inputs and outputs. If you're deciding whether a capability belongs as a function tool, a hosted tool, or an MCP server, our guide to agent skill vs. MCP server frames that call.
The three API surfaces underneath (and which to use)#
The SDK is built on OpenAI's API, and it helps to know the layers, because "how do I build an agent" often really means "which API do I call":
- Chat Completions — the legacy, stateless, message-array API. Still supported, but not where you start a new agent in 2026.
- Responses API — the recommended primitive. It keeps server-side state (so follow-ups send only the new input) and can call multiple hosted tools and your functions inside one request. If you want the raw building block, this is it — see our Responses vs. Assistants vs. Chat Completions breakdown. (The older Assistants API was sunset in August 2026.)
- Agents API — new in public beta since Sept 10, 2026. This is the managed runtime: OpenAI operates the Codex harness for you — session management, context compaction, failure recovery, multi-agent coordination — and you pay for tokens and tools with no separate platform fee.
The clean mental model: Workspace Agents (no code) → Agents API (OpenAI runs the loop) → Agents SDK (you run the loop, your infra) → Responses API (the rawest primitive). We took the managed-vs-self-run trade apart in who runs your agent loop; the short version is that the managed API buys velocity at the cost of holding your session state, so keep your prompts and tools portable behind a gateway either way.
What it costs — and how to keep it down#
Agents are token-hungry: the loop re-sends context on every step, and each tool call adds its own round trip. Two levers do most of the cost control. First, run the loop on a cheap model — the SDK already defaults to gpt-5.6-luna for exactly this reason — and reserve a stronger model for the genuinely hard steps via a router. Second, use prompt caching so the large, unchanging head of your prompt (system instructions, tool definitions) bills at a fraction of the base rate on repeat calls.
Because model prices move monthly, don't trust a hard-coded estimate. Put your real numbers — requests per month, tokens per step, how many steps a task takes — into our LLM API pricing calculator and price the workload before you scale it. Then meter cost per successful task, not per token, so a chatty agent that needs three retries shows its true cost.
The one rule under both paths#
Whether you build no-code or in code, the durable move is the same: keep it swappable. On the no-code side, that means not welding a business process to a single vendor's hosted workflow you can't export. On the code side, it means putting your prompts, tools, and state behind a thin gateway so you can change the model — or the framework — without a rewrite. Start on whichever path matches where your agent lives, ship the smallest version that does one real job, and let the loop earn its next tool before you add it.



