Skip to content
back to the map
component
stage: act
4 min read

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.

LangGraphCrewAIAutoGenDeepAgents

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.

loop.tsxtypescript
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.

research-agent.tsxtypescript
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.

deepagents.pypython
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
DeepAgentsLangChain's graph agent library that combines a planning tool, a filesystem tool and subagents to solve tasks too long for a single loop. It is a practical reference for an agent that does not stall on the third tool call and the place where you learn to calibrate autonomy before releasing a real agent into production.see in glossary →

connections on the map

updated on 14/10/2026 · sources to go deeper · report an error

in other domains

Study before

Unlocks

test what you learned

Loading questions…