Every AI agent needs the same plumbing: a loop that calls the model, runs tools and feeds results back, plus limits, error handling and some way to see what happened. An AI agent framework is a library that provides that plumbing. This glossary page defines agent frameworks, shows what they handle by comparing a hand-written loop with a framework version, and explains when a framework is worth the dependency and when plain API calls are enough.
What is an AI agent framework?
An AI agent framework is a library that runs the agent loop for you: it sends messages and tool schemas to a model, executes the tools the model asks for, returns the results, and repeats. Around that loop it adds model access, tool connections such as MCP, limits, approvals, memory, tracing and multi-agent coordination.
Key takeaways:
The core loop is small. You can write a working agent loop in about 30 lines against a model API. Frameworks earn their place with everything around the loop.
Frameworks differ in their model of control. Some give you a single agent call, some an explicit graph of steps, some a crew of role-based agents.
You may not need one. Anthropic's Building effective agents suggests developers start by using LLM APIs directly, because many patterns take only a few lines of code.
Switching later is possible. Tools written as plain functions or MCP servers move between frameworks with little change. Control flow and state usually need rewriting.
[02]
How does an agent framework work?
A framework sits between your application and two things it talks to: model APIs and tools.
┌──────────────────────── your application ────────────────────────┐
│ instructions, tools, policies (limits, approvals, guardrails) │
└───────────────────────────────┬──────────────────────────────────┘
│ build_agent(...) / Agent(...)
┌───────────────────────────────▼──────────────────────────────────┐
│ agent framework │
│ agent loop ─ model adapters ─ tool schemas and execution │
│ limits and timeouts ─ approvals ─ guardrails ─ memory │
│ tracing and cost ─ multi-agent handoffs ─ state and resume │
└───────────┬──────────────────────────────────────┬───────────────┘
│ │
model APIs (OpenAI, Anthropic, tools (functions, MCP
Google, local models) servers, other agents)Most of what a framework does falls into five jobs:
Run the loop. Call the model, detect tool calls, run them (often in parallel), append results, and stop on an answer or a limit.
Abstract the model. One interface for many providers, so switching models is a config change, often with fallbacks between them.
Connect tools. Turn functions into JSON schemas, and connect to MCP servers so tools can live in separate services.
Control the agent. Caps on rounds, time and cost; human approval before risky tools; input and output guardrails.
Make it observable and durable. Traces of every model and tool call, token counts, and state that survives a crash or a long wait for approval.
The collection of these pieces around a model is also called an agent harness. A framework is a reusable harness that you configure instead of write.
[03]
Example: a hand-written loop vs a framework
Here is a complete agent loop written against the OpenAI SDK with one tool. It works, and it is worth writing once to see that there is no magic.
import json
from openai import OpenAI
client = OpenAI()
def get_order(order_id: str) -> dict:
return {"order_id": order_id, "status": "shipped", "carrier": "UPS"}
TOOLS = [{"type": "function", "function": {
"name": "get_order", "description": "Look up an order by its ID.",
"parameters": {"type": "object", "properties": {"order_id": {"type": "string"}},
"required": ["order_id"]}}}]
messages = [{"role": "user", "content": "Which carrier has order A-1042?"}]
for _ in range(10): # hard cap on rounds
reply = client.chat.completions.create(model="gpt-5-mini", messages=messages, tools=TOOLS)
msg = reply.choices[0].message
messages.append(msg)
if not msg.tool_calls:
print(msg.content)
break
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = get_order(**args) # no error handling, approval, timeout or tracing
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})Order A-1042 is with UPS (status: shipped).The comment on the tool call line lists what this loop doesn't do: a tool that raises crashes the run, nothing stops a $5,000 refund tool, a slow tool blocks forever, and you have no record of what happened. Each of those is a few more lines, and together they become the code you maintain.
The same agent in Promptise Foundry, with those gaps filled by configuration:
import asyncio
from langchain_core.tools import tool
from promptise import build_agent
from promptise.approval import ApprovalDecision, ApprovalPolicy
@tool
def get_order(order_id: str) -> dict:
"""Look up an order by its ID."""
return {"order_id": order_id, "status": "shipped", "carrier": "UPS"}
async def deny(request):
return ApprovalDecision(approved=False, reason="No refunds from this demo.")
async def main():
agent = await build_agent(
model="openai:gpt-5-mini", # any provider, same code
extra_tools=[get_order], # schemas generated from the function
# servers={"shop": HTTPServerSpec(url=...)}, # or tools from MCP servers
approval=ApprovalPolicy(tools=["issue_*"], handler=deny), # human approval
max_agent_iterations=10, # hard cap on rounds
max_invocation_time=60, # wall-clock limit per run
observe=True, # trace every model and tool call
)
try:
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "Which carrier has order A-1042?"}]}
)
print(result["messages"][-1].content)
stats = agent.get_stats()
print({k: stats[k] for k in ("llm_call_count", "tool_call_count", "total_tokens")})
finally:
await agent.shutdown()
asyncio.run(main())Carrier for order A-1042: UPS
{'llm_call_count': 2, 'tool_call_count': 1, 'total_tokens': 544}The tool schema is generated from the function's signature and docstring. The approval policy would pause any tool matching issue_* until a reviewer answers. The iteration and time limits stop runaway loops, and the trace shows the run took two model calls and one tool call. Swapping extra_tools for servers connects the agent to MCP servers instead of local functions.
[04]
Agent framework vs SDK, harness and related terms
Term | What it is | Example |
|---|---|---|
---|---|--- | ||
Model SDK | A client for one provider's API; you write the loop | OpenAI SDK, Anthropic SDK |
Agent framework | A library that runs the loop and the controls around it | Promptise Foundry, LangGraph, Pydantic AI, OpenAI Agents SDK, CrewAI |
Agent harness | The code around a model that makes it an agent; can be hand-written or come from a framework | A custom loop with limits and tracing |
Workflow or orchestration engine | Runs predefined steps reliably; may call LLMs as steps | Temporal, Airflow, a graph of fixed nodes |
Agent platform | A hosted service that runs agents for you | Managed agent services from model providers and clouds |
Frameworks also differ in style. LangGraph models an agent as an explicit graph of nodes and edges. CrewAI organizes agents into crews with roles and tasks. Pydantic AI and the OpenAI Agents SDK center on a typed agent object. Promptise Foundry builds an agent from one build_agent() call and pairs it with an MCP server SDK and a runtime for triggers. AutoGen, once a popular choice, is archived; Microsoft points new users to Microsoft Agent Framework. Python AI agent frameworks compared puts seven of them side by side with the same agent in each.
[05]
When do you need an agent framework?
Use plain API calls when the agent has a handful of tools, runs in one process, and you want to understand every line. Use a framework when you need several of these: tools in MCP servers, more than one model provider, human approvals, guardrails, cost limits, traces, memory, multiple agents, or runs that must survive a restart. At that point you would be writing a framework yourself.
[06]
Common misconceptions about agent frameworks
"A framework makes the agent smarter." Answer quality comes from the model, the instructions and the tools. A framework changes how reliably the loop runs and how much you can control and observe, not how well the model reasons.
"Frameworks lock you in." Tools are the most valuable part of an agent, and they port well, especially as MCP servers. What you rewrite on a switch is the control flow, the state handling and the configuration. LangGraph alternatives, CrewAI alternatives and migrating from AutoGen map those concepts across frameworks.
"All frameworks handle limits and approvals the same way." They don't. Default iteration limits, whether hitting a limit raises an error or forces an answer, and whether a pending approval survives a restart all differ. Read the docs for the defaults before you ship.
"Starting with a framework is always faster." For a first prototype it often is. For a team that doesn't yet know what its agent needs, writing the loop once makes it easier to judge which framework fits.
[07]
Frequently asked questions
What does an AI agent framework do?
It runs the agent loop: it sends messages and tool schemas to a model, runs the tools the model asks for, and feeds the results back until there is an answer. Around that loop it adds model adapters, tool connections such as MCP, limits, approvals, guardrails, memory, tracing and multi-agent support.
Do I need a framework to build an AI agent?
No. A basic agent is a loop of about 30 lines against a model API, and writing it once is a good way to learn. Use a framework when you need production features such as approvals, cost limits, tracing, MCP servers or crash recovery, which take far more code to build and maintain yourself.
What is the best AI agent framework?
There isn't one best framework. LangGraph suits teams that want explicit graphs, CrewAI role-based crews, Pydantic AI typed agents, the OpenAI Agents SDK OpenAI-first projects, and Promptise Foundry MCP-heavy agents with built-in approvals and guardrails. Pick based on the features you need and test with your own tools.
What is the difference between an agent framework and an agent harness?
An agent harness is the code around a model that turns it into an agent: the loop, context management, limits and checks. A framework is a reusable library that provides a harness you configure. You can write your own harness without a framework, or use a framework's harness and customize parts of it.
Can I switch agent frameworks later?
Yes, with some work. Tools written as plain functions or MCP servers usually move without changes. Instructions move as text. Control flow, state, memory and approval handling are framework-specific and need rewriting, so keep business logic in the tools rather than in framework code.
[08]
Next steps
Choose one: Python AI agent frameworks compared.
Write the loop yourself first: How to build an AI agent in Python.
Understand the parts: What is an agent harness?
Coming from another framework: LangGraph alternatives.
All guides on the topic: the frameworks and comparisons hub.
Reference: Building agents in the Promptise docs.