Podesta. Talk to us

n8n, LangGraph, Akribes: an honest comparison.

When each tool is the right call for AI workflow automation, and where they break down.

By Podesta, Applied AI team

Most "X vs Y" posts in this space pick a winner in the first paragraph and back-fill the rest. After shipping production work on all three of n8n, LangGraph, and our own Akribes, the honest take is that there is no universal winner — there are three different shapes of problem, and the tools sort cleanly onto them once you stop pretending they're competitors. This post is an attempt to be specific about which is which.

Three shapes of problem.

The shape of the problem decides the tool. Three shapes show up most often:

  1. Glue between SaaS tools. "When a Stripe charge succeeds, post a message in Slack, write a row to Notion, and email the customer." A long tail of integrations, each individually trivial. LLMs do show up as one node in the chain — n8n has perfectly good LangChain integration — but they are not the centre of gravity; the work is plumbing.
  2. A custom agent a single developer fully understands and maintains. "Inside our Python service, scripted by one of our engineers, build a multi-step agent for a job we already know how we want done — pull a row, call a tool, branch on the result, iterate until done. We are the only consumers, we wrote it, we maintain it the same way we maintain the rest of the service."
  3. A domain-expert AI workflow you ship as part of your product. "We are productising something that requires real subject-matter expertise — legal analysis, claims adjudication, regulatory triage, underwriting. The value of the workflow IS the embedded domain knowledge. The domain experts who supply that knowledge need to be able to read and edit the workflow. The quality of the output has to be measurable on a real case set, not vibes-checked. And it ships behind our own product, not as a generic chatbot."

Most of what people argue about online is people in problem (1) telling people in problem (3) to just use n8n, and vice versa. Both sides are wrong.

n8n, fairly.

n8n is the right answer for problem (1), and it isn't close.

The connector library is enormous — hundreds of integrations covering the obvious SaaS surface (Slack, Notion, Postgres, Stripe, Salesforce, HubSpot, every major queue and storage system) and a long tail beyond that. If your job is "wire X to Y on event Z," n8n already has X, Y, and Z as nodes. You'll spend your time on the business rule, not on HTTP plumbing.

The visual editor is also a genuine asset, and not in a hand-wavy way. Non-engineers can read it, sometimes modify it, and definitely audit it. For an ops or growth team that owns the workflow but doesn't own the platform, that matters more than any language-design argument.

n8n is also fair-code and self-hostable, which is a real differentiator once you start moving customer data around.

Where n8n is awkward is once the problem stops looking like "glue" and starts looking like software. Workflows are JSON graphs, so version control sees opaque blobs, code review is mostly reading screenshots, and refactoring a node used in fifteen workflows is a manual exercise. The Code node exists as an escape hatch, and its existence is itself a signal: when the visual surface stops being expressive enough, you drop into JavaScript with no type system bridging the two sides. n8n's LangChain integration is mature, but multi-step LLM orchestration with branching, retries, and sub-workflow composition starts to feel like fighting the medium. That's fine — it just isn't the medium's job.

LangGraph, fairly.

LangGraph is the right answer for problem (2), and it's also not close.

If you are a developer building an agent for something you fully understand — your own internal automation, a tool you'll maintain end-to-end, a workflow whose audience is yourself and your team — and your stack is already Python, LangGraph is what you reach for. The library gives you state, branching, checkpoint/resume, and a way to stream events as the agent runs, all expressed as code. You define the nodes, you define the edges, you debug it the same way you debug the rest of your service. LangSmith gives you tracing for free if you opt in. For developer-controlled agents in a developer-controlled codebase, that surface is the right shape.

A minimal LangGraph node graph is roughly this:

from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import InMemorySaver

graph = StateGraph(AgentState)
graph.add_node("analyze", analyze)
graph.add_node("chatbot", chatbot)
graph.add_edge(START, "analyze")
graph.add_edge("analyze", "chatbot")
graph.add_edge("chatbot", END)

app = graph.compile(checkpointer=InMemorySaver())

That's a real ergonomic win for a real class of problem. The checkpointer is genuinely useful — you can resume a long-running agent across process restarts and inspect intermediate states. The streaming model (stream_mode="updates" / "values") is mature.

Where LangGraph gets awkward is the moment the workflow has to be readable, evaluable, or shippable as a product feature in its own right. The workflow IS Python. Refactoring it is refactoring Python. Asking a non-engineer subject-matter expert to read or edit it is asking them to read Python. Versioning the workflow separately from the surrounding service is whatever you build yourself. The eval story is whatever you stitch together with LangSmith plus your own harness. None of this is a flaw — LangGraph is a library, not a platform — but the gap shows up the moment you have to defend the quality of a workflow with a number rather than a vibe, or hand the workflow to the domain experts who actually know what good output looks like.

Where Akribes lives.

Akribes is what we built for problem (3): AI workflows shipped as part of a product, where the value lives in the embedded domain expertise and "did this change make the system better" has to be a question you can answer with a number rather than a feeling.

The first thing that has to be true is that the workflow is readable by the domain experts who supply the expertise. Akribes' syntax is small on purpose — a script declares its inputs, declares a few agents, declares a few tasks, and a workflow body that wires them together. A patent attorney, a regulatory lead, or an underwriter can read an Akribes script; the type system catches what they would miss. That is not a nicety. When the value of the workflow IS the encoded domain knowledge, you cannot afford to translate it into Python and lose the only people who would notice if it were subtly wrong.

Concretely, the same "summarize and pass through another model" task looks roughly like this:

use summarize

input topic: str

agent Analyst:
  model: gpt_4o_mini
  system: "You are a market analyst who turns topics into structured notes."

task expand(t: str) -> str:
  agent: Analyst
  prompt: "Expand this topic into 3 bullet points of analyst notes: {t}"

workflow
  raw = expand(topic)
  short = summarize(text=raw)
  return short

That use summarize line is the load-bearing part. summarize is a separate script, owned independently, published independently, versioned independently. The analyzer resolves its ScriptSignature (inputs and workflow -> T return type) at parse time. If summarize changes its workflow return from str to a record, every script that uses it fails to compile, not at the next eval run.

The same "summarize, then have a follow-up model shape JSON" task that needs six-ish nodes plus a Code node in n8n, and around thirty lines of StateGraph plus a TypedDict in LangGraph, is on the order of fifteen lines of two task blocks and a workflow in Akribes. The savings show up once "summarize" is one of forty shared sub-scripts across five teams.

The second thing that has to be true is that you can tell, with a number, whether a change made the workflow better. Akribes' eval harness is part of the platform — cases live as fixtures, the judge is written as another Akribes script (multi-axis rubrics are normal: outcome correctness, cited authorities, reasoning route, calibration on hard cases), and the score moves visibly when you change the workflow. The same score that drives our internal go/no-go on a prompt change is the one a customer can be pointed at when they ask whether the system is getting better. This is the part most "ship an AI feature" projects do not have, and it is the part that separates "we have an AI feature" from "we have an AI feature whose quality we can defend."

The other things that fall out of treating workflows as first-class artifacts:

  • Modularity, properly. Scripts import each other with use, share record types, and version independently. The same shared-sub-script pattern that makes a single team productive scales across teams when an analyzer enforces the contract.
  • A real LSP. akribes-lsp is a proper language server — go to definition across script boundaries, hover types on used workflows, find references on a task. Not Python's LSP being helpful about a Python file that happens to contain a graph.
  • MCP in both directions. A workflow consumes external MCP servers as typed tools (databases, third-party SaaS, anything that speaks the protocol). A workflow can also be exported as an MCP tool, which means an Akribes script you wrote for your own pipeline becomes a tool another team's agent — or another company's, if you publish it — can call without touching your code.
  • An SDK for the client side. Studio is the editor; the SDKs (TypeScript, Python, Rust) are how a workflow gets called from a real application. The same workflow that runs from an internal cron, a Studio test panel, and a customer's frontend speaks the same event protocol on all three.
  • A streaming event model that is the protocol, not an afterthought. The engine emits WorkflowStart, NodeStart, TaskStart, TaskPrompt, AgentOutput (token-streaming), TaskEnd, Suspended, Resumed, WorkflowEnd, Error. Every SDK consumes the same stream; Studio renders it; your service can subscribe to it.
  • Checkpoints as a language feature. A task that fails structured output validation can route directly to a checkpoint block, which suspends the workflow, emits Suspended, and waits for a typed resume payload. The shape of the resume value is checked by the analyzer before publish.
  • Input resolvers. A workflow declares input sources: SourceSet by fetch_sources(...), and the caller never threads sources through — the server resolves it from another script's output at execution time. Composite chains keep their public surface to two or three scalars even when the underlying graph pulls from a dozen upstream documents.

A more recent addition: a visual benchmark builder in Studio. The premise is that the people with the test cases — domain experts — are not always the people with the patience to write a workflow language. Upload a set of example input/output pairs, Studio drafts a workflow and a starter judge, scores the workflow against the examples, and suggests refinements that would move the score on those specific cases. Domain experts get faster iteration; engineers get a starting point that already passes the cases the expert cares about most.

The shorthand contrast is with the typical "ship an AI feature" approach in 2026 — a chat box on a website, a few prompts behind it, whatever ad-hoc evaluation the engineer can fit in around the chat-box work. Four things tend to be missing from that approach. Iteration is slow, because there is no shared eval to compare versions against. Quality is hard to defend, because there is no score that captures whether the model got the underlying job right. The interaction model is exhausted by the chat turn — no checkpoints, no structured intermediate state, no human-in-the-loop for the cases that need it. And the result is, in practice, hard for the customer to distinguish from running the same query against a generic LLM chat themselves. The properties above — eval-as-platform, typed structured outputs, language-level checkpoints, typed cross-script composition — exist because each of them addresses one of those failure modes head-on.

Where Akribes is rough.

Akribes is younger. The integration zoo is smaller than n8n's — we lean on MCP for the connector surface rather than building a Slack node, a Notion node, a Stripe node, and so on. That's a deliberate bet on the MCP ecosystem reaching critical mass, but if you need "trigger when a new row appears in Airtable" today, we are not the right call yet.

The visual surface is the Studio editor — the Akribes script next to a live event stream, an inline debugger, an eval panel. It is text-forward by design. We lead with a small DSL, not a node-graph canvas, and after a year of customer work this has been less of a barrier for domain experts than we braced for. Reading a small, declarative DSL aimed at the workflow they already know is a different ask than reading a Python state machine, and after the first hour or two of orientation the language has mostly stopped being the friction.

That choice isn't accidental. We like code. The things that make code worth keeping — tests you can run against a change, iteration at typing speed, a workflow you can share by sending one file, versions you can branch and merge — keep mattering once an LLM is involved, not less. There are reasons engineers reach for code instead of a visual canvas for almost everything else they build, and those reasons didn't evaporate when generative models showed up. We would rather approach AI from the deep tooling expertise the industry already has than discard it because something else looks shinier.

A node-based editor is on our roadmap. It isn't a hard build, just one we haven't prioritised over the rest of the workflow surface yet. What we're not willing to do, in the meantime, is point production AI work toward n8n because a team wants a visual canvas. n8n's editor is genuinely good for SaaS plumbing; once the workflow has branching logic, typed sub-scripts, evals, and a customer-facing SLA on the output, the JSON-graph format plus the Code-node escape hatch is not what you reach for.

The smaller community shows in edge cases. We fix what we hit; if you need a specific provider or a specific behaviour we have not yet had a reason to write, the answer is more likely "send a PR" than "there is a maintained plugin." That is the cost of a younger tool and we own it.

The division of labour we want.

Most teams shipping production AI products have two kinds of work in front of them. One is the LLM-infrastructure layer: picking providers, abstracting their differences, building eval harnesses, writing a usable editor for the people who tune prompts, handling streaming, caching, tokens, costs. The other is the work that actually distinguishes the product — the customer-facing application, and the workflows that encode the domain knowledge.

The pitch behind Podesta is that the first layer should be shared infrastructure your team does not build. We do it. The second layer is where your engineers and your domain experts should be spending their time — your engineers shipping the application your end users pay for, your domain experts tuning the workflows that encode what their domain requires. n8n and LangGraph draw that boundary differently. n8n absorbs almost all of the integration glue and gives the workflow surface to non-engineers; LangGraph delegates almost all of it to your Python and assumes your engineers own the workflow as well. Podesta lands closer to n8n in spirit — the platform absorbs the LLM-infra layer, the workflow surface is one a domain expert can reach — but with a typed-artifact story and an SDK that lets engineers compose on top.

Which one, then.

A short decision tree, with all the usual caveats about how a decision tree is a lie:

  • Are you wiring Slack to Notion on a Stripe webhook? Use n8n.
  • Is one of your developers writing a custom agent for a job they fully understand, inside a Python service they own end-to-end? Use LangGraph.
  • Are you productising work that requires real subject-matter expertise — and you need the domain experts in the iteration loop, an eval that tells you whether changes improved the result, and the workflow shipped behind your own product? That's our target. Try Akribes.
  • If you're in two of these at once: pick the shape that is most painful today and treat the other as the thing on the other side of a queue.

What "workflow" means to each.

The useful frame for comparing these tools is not which is best but what each of them treats a workflow as. For n8n, a workflow is a node graph — a document that draws itself. For LangGraph, a workflow is a Python program — a function over a typed state. For us, a workflow is a versioned, type-checked artifact with its own language, its own analyzer, and its own publish lifecycle.

Those three bets address different parts of the same broad problem and they will likely keep coexisting. The practical question for any team is not which framework wins; it is which of the three shapes their workflow is actually closest to today, and that question is usually easier to answer than the framework debate suggests.

Talk to us

Have a workflow worth automating?

Send us a sketch and a handful of examples. We come back with scope, duration, and price — no sales calls.