LangChain and LangGraph

The most widely adopted frameworks for building production AI applications - and the ones we use for most client engagements. Here's what they do, how they differ, where they break, and how to use them correctly.


LangChain vs. LangGraph: The Key Distinction

LangChain provides composable building blocks for LLM workflows - prompt templates, chains, retrievers, tool integrations. It excels at predictable, multi-step workflows where the execution path is fixed.

LangGraph models workflows as stateful graphs. Nodes are computation steps, edges are transitions - conditional or unconditional. It enables loops, branching, retry logic, human-in-the-loop interrupts, and time-travel debugging. For anything agent-like, LangGraph is the right choice for production.


LangChain Core Abstractions

Chains & LCEL

Chains encode sequences of component calls - prompt template, LLM, output parser. LangChain Expression Language (LCEL) composes these with a pipe syntax. Best for predictable, fixed-path workflows where the execution sequence doesn't change based on results.

Agents

Replace fixed chains with dynamic decision-making. The LLM decides which tool to call next, evaluates the result, and continues until the task is complete. Agent quality depends almost entirely on tool definition quality - specific descriptions, precise schemas, graceful error handling.

Retrievers

The core of RAG systems - accept a query, return relevant documents from a vector store. LangChain supports Pinecone, Weaviate, Qdrant, pgvector, Chroma, FAISS. The abstraction makes it straightforward to swap backends without rewriting retrieval logic.

Tools

The interface between agents and the external world. Search the web, query a database, call an API, execute code. Good tools have precise descriptions, validated parameter schemas, and explicit error handling. Bad tools are the leading cause of agent failure.


LangGraph Core Concepts

State

The central TypedDict or Pydantic model that persists across graph steps. Every node reads from and writes to state. Getting state design right - minimal, well-typed, correct reducers - is the foundation of a reliable application. State should hold what's needed to resume execution, not everything that happened.

Nodes & Edges

Nodes are Python functions that transform state. Edges connect nodes - unconditional or conditional (routing based on current state). Conditional edges implement branching, retry logic, and human-in-the-loop checkpoints.

Checkpointers

Persist graph state to storage after each node. InMemorySaver for development, PostgresSaver or RedisSaver for production. Enables recovery from failures, time-travel debugging, and human-in-the-loop interrupts where execution pauses for review.

Human-in-the-Loop

Interrupt nodes pause execution and serialize state, waiting for human input before continuing. The human can approve, modify the proposed action, or redirect the agent. Essential for any workflow that takes consequential actions in external systems.


RAG Best Practices

Chunking strategy is the most underestimated decision in RAG. Use semantic chunking that respects document structure - preserving heading hierarchies, keeping related content together. Start with 1,000-token chunks and 200-token overlap, then tune based on measured retrieval quality. Hybrid retrieval (dense vector + sparse keyword search, then reranking) consistently outperforms pure vector similarity for enterprise knowledge bases.

Build an evaluation baseline before deployment: a test set of representative questions with expected answers, measuring answer correctness, context relevance, and hallucination rate. Continue monitoring in production - retrieval quality drifts as documents are updated and embedding models improve.


Real Community Issues & How We Handle Them

Outdated Examples & Deprecated APIs

LangChain's API surface has changed significantly across versions. Many tutorials reference deprecated classes that behave differently in current versions.

Our approach: We treat only the official docs and source code as authoritative. Pin versions in production and review changelogs before any update.

Debugging Opacity

Errors at step 4 may originate at step 1. The exact prompt sent to the LLM, tool call arguments, and intermediate state are not visible by default.

Our approach: Instrument every production application with LangSmith from day one. Log input/output of each step explicitly for critical workflows.

Performance Overhead

Abstraction layers add 100–500ms latency per API call vs. direct SDK calls. Default memory implementations consume unnecessary tokens.

Our approach: Profile before and after. Use streaming for user-facing applications. Implement context window management. Benchmark LangChain overhead for very high-volume simple operations.

LangGraph State Reducer Errors

Incorrect reducer function usage produces subtle bugs: values accumulating incorrectly, state not updating as expected, type errors at runtime.

Our approach: Define schemas explicitly with TypedDict. Test state transitions in isolation before integrating LLM calls. Use operator.add for list fields, no reducer for fields that should be replaced.

Memory Class Inconsistencies

ConversationBufferMemory behaves differently with ConversationChain vs. AgentExecutor. These inconsistencies cause subtle state management bugs that are hard to diagnose.

Our approach: For production, replace LangChain memory classes with LangGraph-managed state and a persistent checkpointer. Reserve built-in memory classes for simple prototyping only.

Prototype Patterns in Production

InMemorySaver, default error handling, no cost monitoring, single-threaded execution all work in demos but fail under real usage.

Our approach: Design for production from sprint one: persistent checkpointers, structured Pydantic outputs, explicit error handling for every tool, cost tracking per operation.


Related Technology Pages

FAQ

For simple single-step LLM calls, use the raw SDK. For multi-step chains without dynamic branching, LangChain LCEL works well. For anything with agents, conditional logic, loops, or human-in-the-loop requirements, use LangGraph. LangGraph is the production-grade choice for most real applications.

Building with LangChain or LangGraph?

Talk to Us