LangGraph versus LangChain. A conta é cadeia, grafo ou harness
Eu ia responder LangGraph ou LangChain. Como quem escolhe React ou Vue. A pergunta que o desk me fez era outra. Este fluxo é uma cadeia (entra, sai, acabou)? É um grafo (estado, ciclo, pausa pra gente)? Ou o cérebro nem está na lib: está no Cursor, no Kiro, no Claude Code? O que você leva daqui: LangChain monta cadeia. LangGraph guarda estado e deixa voltar. Os dois se encaixam. Nenhum dos dois substitui o harness. Se o primeiro movimento do último chat foi um invoke sem ciclo, você não tem agente. Tem pipeline com LLM no meio. No meu servidor o cérebro default virou Goose. LangGraph ficou legado. Se o server cai, o desk segue: rules, busca no vault, tools. A lib do grafo não estava no caminho. Fonte: o stack que eu opero, não um ranking. Isto não é o post de RAG, MCP e fine-tuning. Lá a conta é busca, conector, jeito. A nota IA generativa gera. IA agentic age para no turno: texto ou tool. Aqui é orquestração: cadeia, grafo, desk. Um limite só: eu não rodei benchmark de latência Chain versus Graph neste laboratório. A conta abaixo é de forma, não de milissegundo. Tabela de Conteúdo 1. Nomeia o fluxo antes do logo 2. LangChain: a cadeia 3. LangGraph: estado, ciclo, pausa 4. O grafo que ainda é uma cadeia 5. Quatro perguntas antes de adicionar o grafo 6. Cole isto no seu agente 7. Se o server cai, o desk segue 1. Nomeia o fluxo antes do logo Três formas. Não são três produtos. Cadeia. Prompt, modelo, parser. Um sentido. Sem loop. LCEL: prompt | model | parser. Traduz, classifica, extrai. Acabou. Grafo. Nós, arestas, estado. Pode voltar. Pode pausar. Pode retomar depois de falha. Docs oficiais: execução durável, memória de curto e longo prazo, interrupt com gente no meio. Isso é LangGraph. Harness. O IDE chama tool, lê arquivo, espera você. Não precisa do grafo Python pra existir. Precisa de política: o que lê, o que grava, quem aprova. Se o time discute logo e o fluxo ainda é um invoke sem estado, vocês estão no item 1 fingindo que é o 2. 2. LangChain: a cadeia A forma mínima, da documentação LCEL: chain = prompt | model | StrOutputParser() chain.invoke({"text": "Hello", "input_language": "English", "output_language": "Spanish"}) Entra dict. Sai string. Não tem “tenta de novo se a tool falhar”. Não tem “espera o humano”. Não tem checkpoint. LangChain também entrega atalho de agente (create_agent no pacote atual). O detalhe está no H3 abaixo. O que você ganha: integração, LCEL, um invoke que o time lê em dez linhas. O que você paga: quando precisa de ciclo, persistência e pausa de verdade, a cadeia não chega. Você sobe de knob. Ou finge que subiu. atalho de agente versus cadeia create_agent no pacote atual não apaga o grafo. Por baixo, o runtime de agente da casa ainda é grafo. Você não desenhou os nós. O ciclo está lá. Se o pedido é traduzir e não há tool, o atalho é cadeia cara. 3. LangGraph: estado, ciclo, pausa O README lista o que a cadeia não promete: execução que sobrevive a falha, HITL, memória de trabalho e entre sessões. Ciclo: aresta condicional. O nó agent decide se chama tools ou END. Tool volta pro agent. ReAct não é marketing. É esse loop. Pausa: interrupt(). Sobe valor pro cliente. Retoma com Command. Sem checkpointer, a pausa não existe: o estado não grava. interrupt versus print("confirma?") HITL que é print("confirma?") no log não é o interrupt da lib. Sem checkpointer, a pausa some no crash. Cena pedagógica (não é log de produção): você: faz deploy da branch feature/pix cadeia: gera um YAML de pipeline. ninguém chamou o CI grafo: nó agent → nó tools → interrupt (HITL) humano: aprova grafo: retoma do checkpoint, dispara o workflow A cadeia “fez o texto do deploy”. O grafo “quase publicou”. São contas diferentes. Least privilege e HITL no que grava. Sem isso o grafo é force push com estado. O que você ganha: estado explícito, ciclo, pausa retomável. O que você paga: desenho. Cada nó a mais é um jeito de errar no mundo. Blast radius da tool. 4. O grafo que ainda é uma cadeia Atalho: from langgraph.prebuilt import create_react_agent agent = create_react_agent(model, tools) agent.invoke({"messages": [("human", "traduz isto")]}) Isso compila um StateGraph e devolve um Runnable do LangChain. Você pode invoke como cadeia. Por dentro tem ciclo se houver tool. Se a tool não existe e o pedido é “traduz”, você pagou grafo pra fazer LCEL. Estado vazio. Sem interrupt. Sem checkpointer. Logo Graph no requirements.txt. Fluxo de cadeia. O teste: o transcript tem mais de um nó, ou tem um invoke e acabou? Não usei ChargePaidHandler aqui. Essa cena é do post do grafo de código. Aqui o knob é orquestração, não dump do repo. 5. Quatro perguntas antes de adicionar o grafo Copia. Cola no PR do agente. ## Cadeia, grafo ou harness 1. O fluxo é um sentido só (gera, classifica, extrai)? Cadeia. LCEL chega. 2. Precisa voltar (tool falhou, tenta de novo) ou parar pra gente (push, pagar, deploy)? Grafo. Checkpointer. `interrupt` no que grava. 3. O “agente” é o Cursor/Kiro neste pedido, não o Python? Harness. Não invente um StateGraph pra duplicar o que o IDE já faz. 4. Se o servidor do grafo cair, o time ainda trabalha? Se não, você acoplou o desk num processo. HITL, least privilege, blast radius: a tool que grava não anda no mesmo cano da que só lê. Se a resposta da 1 for sim e você mesmo assim abriu StateGraph, você comprou ciclo pra um invoke. O prompt da seção seguinte monta a arquitetura no teu repo. Sem pular pra StateGraph no escuro. 6. Cole isto no seu agente Isto não é receita de instalar LangChain e LangGraph. É o contrato das três formas, pra colar numa conversa nova. Arquiteto, não gerador de código. Se você não tem nada, ele assume cadeia (LCEL) e semana 1 no README. Se tem tool que grava, pergunta HITL e espera. Conversa nova. Cinco linhas do seu repo. Ele lê README e o que já existe (LCEL, StateGraph, create_agent). Sem stack: default cadeia. Stack complexa: até 8 perguntas, aí para. Se devolver um StateGraph pra traduzir texto, você pulou as perguntas. Manda o trecho no comentário. You are an architect, not a code generator. I am designing a LangChain + LangGraph setup for a software team. I may paste repo context, a stack description, or a messy Slack thread. Do not assume Cursor, LangSmith Cloud, or any host. Talk in terms of three shapes: chain, graph, harness. Do not write application code in the first reply. Do not invent tools, models, or vendors I did not mention. Do not open a StateGraph because the hype asked. First pass, before any questionnaire: inspect what I pasted. If the harness can see the repo, look only at README, existing chains/graphs (LCEL, StateGraph, create_agent / create_react_agent), tools, checkpointer config. A handful of Reads. Not ten. Not dump. Cite what you found. Then classify from that evidence: chain-only vs needs-graph vs harness-already-does-it. Do not pick 3 or 8 questions before this pass. If the pass shows nothing (no LangChain, no LangGraph, no tools): ask at most 3 short questions: (1) one-way generate/classify/extract, or a loop with tools, (2) does anything write (push, pay, deploy, email), (3) is the “agent” this Python process or an IDE chat. If I skip them, assume: one-way chain; no writes; one IDE for daily work; no StateGraph this week. Then output the sections below in this same reply. Week-1 bullets must be doable with LCEL in that repo. They are the first correct setup, not a shopping list of integrations. If the pass already has enough, skip questions and output. If the pass shows a complex stack (tools that mutate, existing graph, checkpointer, or I proposed “add LangGraph for everything”) and something material is still missing, ask up to 8 short questions, then stop and wait. The 8 are for that case. Not for the nothing-case. Mental model (non-negotiable): - LangChain vs LangGraph is the wrong fight. Chain = one-way compose (LCEL: prompt | model | parser). Graph = state, cycles, durable execution, interrupt for humans. They fit: a compiled StateGraph is a LangChain Runnable. create_react_agent / create_agent is a shortcut that still compiles a graph. A shortcut with no tools and no interrupt is a chain you overpaid for. - Harness (Cursor, Claude Code, Codex, Kiro) is a third shape. Do not duplicate the IDE with a Python graph if this request already lives in the chat with tools. - interrupt() without a checkpointer is not HITL. print("confirm?") is not interrupt. - Read tools ≠ write tools. Push, pay, deploy, email: HITL. Least privilege. Blast radius. No unbounded shell “to make the demo work”. - Checkpointer memory is not a knowledge-base contract. Retrieval/RAG is another layer. Do not stuff the repo or OpenAPI into graph state. - Start with the smallest shape that matches the flow. Chain first. Graph when you need to come back or pause. Harness policy always. Also respect: - If I said LangGraph or LangChain as alternatives, correct me and classify my flow as chain, graph, or harness. - If I asked to “add LangGraph” to a translate/classify pipeline, refuse the graph and specify the LCEL chain. - LangSmith is optional observability. Not a layer that replaces chain/graph/harness. After you have enough answers, output exactly these sections in my language (pt-BR unless I write in English): 1. Diagnosis — for MY flow: chain vs graph vs harness. One paragraph. If I treated LangGraph as a competitor to LangChain, say so. 2. Chain (LangChain / LCEL) — what stays a one-way invoke. What must never become a node. 3. Graph (LangGraph) — “not now”, or nodes / edges / state fields / checkpointer / interrupt points. Table: node, read vs write, blast radius, HITL yes/no. 4. Shortcut — create_react_agent / create_agent: allowed only if the table needs a tool cycle. Otherwise forbid. 5. Harness — what stays in the IDE and must not be copied into Python this week. 6. Week-1 plan — 5 bullets in the repo. No new logo unless I already have it. If I had nothing, bullets are LCEL only. End with 3 risks if I skip the diagnosis and jump to StateGraph. O prompt já dá pra colar. O gist vive sem o artigo: 7. Se o server cai, o desk segue No meu setup o cérebro do servidor defaultou pra Goose. LangGraph ficou legado. Confirmei no stack, não num slide. Quando o server está down, o Cursor continua: rules, vault, MCP. Doctor reclama. O trabalho não para. A lib do grafo não era o harness. Era um cérebro atrás de um HTTP. Isso não mata LangGraph. Mata a ideia de que escolher Graph ou Chain é montar o agente. Montar o agente é política no desk +, se você precisa de processo longo no servidor, um runtime com estado. Goose, Graph, o que for: o knob 3 (harness) continua existindo. A memória é outra porta. Retrieve não é o checkpointer do Graph. Não misture as duas. No último fluxo que você subiu: foi prompt | model | parser, foi grafo com interrupt, ou foi o chat do IDE sem Python no meio?
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to