Open-Source Agent SDK Comparison: LangGraph, CrewAI, AutoGen, and More in 2026
Orchestration frameworks like LangGraph, CrewAI, and AutoGen answer one question: how do I structure the steps and control flow of a multi-step or multi-agent workflow. Ujex answers a different one: once a step in that workflow needs to send an email, remember something past the current session, get a human's sign-off, or prove what actually happened, what does the code call. Most agents that reach production use both, which is why Ujex's Python SDK ships integration extras for langchain, llamaindex, and crewai instead of asking you to replace any of them.
I get some version of this question every few weeks, usually phrased as "we're already on LangGraph, why would we also need Ujex." It's a fair question, and the confusion is understandable: agent tooling roundups tend to throw orchestration frameworks, memory libraries, and infrastructure SDKs into the same numbered list, as if they're all competing for the same slot in your stack. They aren't. A framework decides what your agent does next. Infrastructure is what happens when it decides to actually do something: send a message, wait on a human, write something down for later. Most agents that make it past a demo need both layers, not one instead of the other.
The question each layer actually answers
Ask three people what an "agent framework" does and you'll get three overlapping but not identical answers, because the category covers a few different jobs. LangGraph is generally understood as a way to structure a workflow as an explicit graph: nodes for steps, edges for control flow, branching and retries you can see rather than logic buried in nested conditionals. CrewAI leans toward defining a team of role-based agents that hand tasks off to each other, useful when the natural decomposition of a problem is "who does what" rather than "what step comes next." AutoGen leans into agents that converse with each other in a loop until a task resolves. Different shapes, same job at the category level: you're telling the system how the pieces of a multi-step or multi-agent task relate to one another.
None of that touches what happens inside a step. When a workflow decides "now send the customer an email," or "now this needs a human to sign off before it touches production," or "now check what we did last time before answering," the framework hands off to whatever code actually performs that action. That's a separate problem: how do you send agent-originated email reliably, how do you gate a risky action behind a real permission check instead of a comment that says TODO add approval later, how do you give an agent memory that survives past the current context window, how do you prove afterward what it actually did. Ujex is built specifically to answer that second set of questions. It's open-source (Apache-2.0) backend infrastructure for AI agents, not an orchestration framework, and it doesn't ask you to restructure your workflow around it.
Two layers, one stack
The cleanest way I've found to explain this to a team that's already committed to a framework is to draw the stack. The framework sits on top and decides what happens next. Ujex sits underneath and is what actually gets called when "what happens next" is a concrete action: an email, an approval gate, a memory read, a rate-limit check, a durable public endpoint for a webhook to land on.
Broken down by the question each layer answers:
| Layer | Answers | Examples |
|---|---|---|
| Orchestration | How do steps or agents hand off control to each other? | LangGraph, CrewAI, AutoGen |
| Agent infrastructure | What does a step actually call to send an email, gate on approval, or prove what happened? | Ujex (Postbox, Approvals, Audit) |
| Memory | How does an agent recall things beyond the current context window? | vector-store memory libraries, Ujex Recall |
| Multi-agent coordination | How do multiple agents communicate and divide labor? | LangGraph, CrewAI, AutoGen |
A roundup, sorted by category, not by "pick one"
Most agent-tooling roundups compare these as if you're choosing exactly one. You're not, because they don't compete for the same job. Filter the list below by category and notice that Ujex is the only row that shows up under both infrastructure and memory, and none of the orchestration frameworks show up there at all.
Why the Python SDK ships langchain, llamaindex, and crewai extras
This is the part that usually resolves the confusion fastest. Ujex's Python SDK includes integration extras specifically for langchain, llamaindex, and crewai. Those exist because Ujex is meant to be called from inside those frameworks, not instead of them. A LangGraph node that decides a wire transfer needs a second pair of eyes calls into Ujex's Approvals primitive from inside that node. A CrewAI agent that needs to check what it learned in a previous run reads it back through Ujex Recall from inside its own task logic. The extras package is thin on purpose: it wires Ujex's plain API surface into whatever object model that specific framework expects, a tool, a callback, a node function, so you're not hand-rolling that glue yourself every time you start a new project.
The reverse framing matters just as much, because Ujex doesn't require any of those extras to work at all. Everything underneath is exposed as plain HTTP APIs and SDKs, Python, Go, a JS client, a CLI, and an MCP server, so a team running AutoGen, or something entirely custom, or no framework at all, calls the same endpoints the langchain extra calls under the hood. The extras are convenience, not a dependency you're locked into.
What stacking them looks like in practice
Concretely, the framework layer and the infrastructure layer stay separate concerns in the code, even when they sit a few lines apart. The framework decides a step needs to run and what its inputs are. The infrastructure calls inside that step do the actual work: gate on a human, send the message, write the audit record. Here's the shape of it, illustrative pseudocode and not tied to any specific framework's actual API surface:
# illustrative pseudocode, not tied to any framework's actual API surface
def on_high_risk_step(state):
# the orchestration framework decided this step needs to run
decision = approvals.request(
action="wire_transfer",
payload=state["transfer_details"],
)
if decision.approved:
postbox.send(to=state["customer_email"], body=receipt)
audit.log(step="wire_transfer", result=decision)
return state
Nothing about that step cares whether the framework wrapping it is LangGraph, CrewAI, AutoGen, or a hand-rolled while loop. That's the point of keeping infrastructure calls as plain function calls into an SDK instead of framework-specific abstractions: swapping the orchestration layer later doesn't mean rewriting how approvals or audit logging work underneath it.
When you don't need a framework at all
There's a smaller case worth naming directly, because it's the one place these two layers genuinely aren't both required: a single script that calls an LLM once or twice, does one concrete thing, and exits. If your agent is a scheduled job that reads an inbox, drafts a reply, and asks a human before sending, you don't need a graph, a crew, or a conversational loop to model that control flow. It's linear already. In that case Ujex's SDKs get called directly with no framework in between at all, which is exactly the deployment shape the client-js package and the CLI are built for.
The line to watch for is when your workflow stops being "always do these steps in this order" and starts being "depending on what happens at step two, either branch to step three or hand off to a different agent entirely." That's usually the point where a framework starts paying for itself, because otherwise you'd be reimplementing its state machine by hand, badly, inside a pile of conditionals.
FAQ
Do I need both a framework and an infrastructure layer?
Not strictly. If your agent is a single script doing one linear thing, calling the infrastructure layer directly, Ujex's SDKs with no framework at all, is often simpler than reaching for a framework you don't need yet. Once you have multi-step branching logic or more than one agent that needs to coordinate, a framework usually earns its keep, and you'll still want the infrastructure layer underneath it for the concrete actions.
Which framework works with Ujex today?
Any of them, or none. Ujex is exposed as plain APIs and SDKs rather than requiring a specific framework's object model, which is the entire point of shipping integration extras for langchain, llamaindex, and crewai in the Python SDK: they're convenience wrappers around the same endpoints, not a gate on which framework you're allowed to use.
Is Ujex itself a framework?
No. Ujex is backend infrastructure, plain APIs and SDKs for things like agent email (Postbox), human approval gates (Approvals), a tamper-evident audit log (Audit), and file-based memory (Recall). It doesn't ask you to structure your whole agent around it the way an orchestration framework does. It's meant to be called from whatever structure you're already using, including none.
Can I switch orchestration frameworks without losing my infrastructure code?
That's a big part of why keeping the two layers separate matters. If your approval gates, audit logging, and memory calls are plain SDK calls rather than framework-specific abstractions, moving from one orchestration framework to another, or dropping frameworks entirely, doesn't touch that code. You're only rewriting the control-flow layer on top.
What if my agent isn't written in Python?
The langchain, llamaindex, and crewai extras are Python-specific, but the underlying capabilities aren't. Ujex also ships a Go SDK, a JS client, a CLI, and an MCP server, all calling the same plain APIs, so the framework-optional, language-flexible point holds outside Python too.