Agent frameworks
An agent framework is the skeleton that holds the agent's loop: state, plan, tools and what happens between each call to the model. Without a framework, the agent becomes a script full of if/else that nobody can audit.
The loop: perceive, decide, act, observe
Every agent, from the simplest to the most complex, runs the same loop four times, until it exhausts a step budget or reaches a final answer:
1. perceive: the agent looks at the current state (system prompt, history, result of the last action) and what the user asked for.
2. decide: the LLM produces either a final answer to the user, or a tool call with structured arguments.
3. act: the runtime validates the arguments against the tool's schema, executes it and captures the result.
4. observe: the result goes back into the context and the loop restarts.
The reasoning part is only worth anything if the loop terminates, and that is why every framework exposes a maximum step limit and an explicit end criterion.
type Step = { kind: 'final'; answer: string }
| { kind: 'tool'; tool: string; args: unknown };
async function agentLoop(state, llm, tools, maxSteps = 8) {
for (let i = 0; i < maxSteps; i++) {
const step: Step = await llm.decide(state); // perceive + decide
if (step.kind === 'final') return step.answer; // end
const out = await tools[step.tool].run(step.args); // act
state = state.observe(step, out); // observe
}
throw new Error('loop budget exhausted');
}Why use a framework
The loop above is short, but what surrounds it is not: persisting state between steps, resuming the conversation after an error, parallelizing independent tools, validating arguments, managing retries and exposing observability. Without a framework, you reimplement this in every project, and reimplement it wrong.
An agent framework delivers three things worth paying for: an explicit execution graph (you see what can run when), a typed state that survives between steps, and ready-made integration with the model, the tool provider and the memory storage.
LangGraph: the agent as a graph of nodes
LangGraph models the agent as a state machine: each node is a function (an LLM call, a tool execution, a filter), each edge is a decision. The state is a typed channel that all nodes read and write. When the graph is cyclic, the agent can iterate; when it is acyclic, it is a pipeline.
The example below defines a research agent with two nodes (call model and run tool) and a conditional edge: if the model asked for a tool, go to tools and come back; if it returned a final answer, finish.
import { StateGraph, END } from '@langchain/langgraph';
import { ChatAnthropic } from '@langchain/anthropic';
type S = { messages: Array<{ role: string; content: string }> };
const llm = new ChatAnthropic({ model: 'claude-opus-4' });
const tools = { search: { run: async (q: string) => `result for ${q}` } };
const graph = new StateGraph<S>({ channels: { messages: { value: [] } } })
.addNode('llm', async (s) => ({ messages: s.messages.concat([await llm.invoke(s.messages)]) }))
.addNode('tool', async (s) => ({ messages: s.messages.concat([{ role: 'tool', content: 'ok' }]) }))
.addEdge('__start__', 'llm')
.addConditionalEdges('llm',
(s) => s.messages.at(-1)?.content.startsWith('CALL ') ? 'tool' : END,
{ tool: 'tool', [END]: END })
.addEdge('tool', 'llm')
.compile();
const out = await graph.invoke({ messages: [{ role: 'user', content: 'what is the capital of France?' }] });DeepAgents (2025-2026): a graph of subagents
, launched in 2025, generalize the graph model to multiple cooperating agents: each subagent is a node with its own prompt, tools and budget, and the graph describes who delegates to whom. The orchestrator decomposes the task, assigns subtasks to subagents and consolidates the result.
The practical difference from a classic framework is that the unit of composition is no longer a tool but an entire agent. When the task is 'research, analyze and write', you instantiate three subagents and connect them in a graph, instead of trying a single agent with 40 tools and a monster prompt.
from deepagents import Agent, Graph, tool as tasks
@tasks
def fetch_url(url: str) -> str:
"""Fetches the raw content of a URL."""
return requests.get(url, timeout=10).text
researcher = Agent(name='researcher', system='research primary sources', tools=[fetch_url])
analyst = Agent(name='analyst', system='synthesize findings into bullet points')
writer = Agent(name='writer', system='produce the final report')
graph = Graph()
graph.add_edge('__start__', researcher)
graph.add_edge(researcher, analyst)
graph.add_edge(analyst, writer)
graph.add_edge(writer, '__end__')
report = graph.run('report on the LLM market in 2026')CrewAI and AutoGen: neighboring styles
CrewAI focuses on teams with fixed roles (researcher, writer, reviewer) and a more opinionated delegation process; it is fast for prototypes where the division of labor is known. AutoGen, from Microsoft, generalizes to multiple agents conversing with each other, useful for exploration but with a tendency toward long loops and hard-to-control cost.
The choice between frameworks is rarely technical: it is about the level of structure you want in the graph. The more fixed each node's role, the easier to audit; the more flexible, the more powerful for ill-defined tasks and the more expensive to operate.
Strengths
- explicit loop: each framework can know how much has already run and what remains, simplifying budget and auditing
- typed state: the state channel becomes a contract, not a loose dictionary; the IDE shows errors before running
- visual graph: the agent's flow becomes a diagram, and debugging becomes looking at 'before', running the node, reading the output
Limitations
- abstraction becomes lock-in: migrating between frameworks costs rewriting the graph, not just swapping the call
- the loop budget is heuristic: without a good guard, agents get stuck in cycles or blow the cost
- LangGraph and DeepAgents are still young projects (2024-2026); APIs and contracts change between versions
connections on the map
- LLM - large language modelis the coreAgent frameworks
- Agent frameworksenablesTool calling
- Agent frameworkscoordinates withOrchestration
updated on 14/10/2026 · sources to go deeper · report an error
in other domains
- IAM - identity and accesscloudsecleast privilege applies to the agent too
Study before
Unlocks
test what you learned
Loading questions…