Skip to main content
BlogAI

LangChain vs Building Your Own LLM Orchestration: When to Use Each

An honest assessment of LangChain in 2025 — when it saves time, when it gets in the way, and how to decide if you need it at all.

Matthews Wong

Software Engineer

June 202510 min read
AI

I've built LLM applications both ways: using LangChain as the orchestration layer, and building custom orchestration from scratch. My AI Gymbro fitness app started with LangChain and was rewritten as custom orchestration six weeks in.

DimensionLangChain / LangGraphCustom Orchestration
Best forMulti-provider apps, fast RAG prototypesSimple workflows, 1-3 LLM calls per request
Setup speedRAG pipeline in about 50 lines of PythonSame pipeline takes about 200 lines, more upfront work
DebuggingStack traces run through 5 layers of internalsErrors surface directly from your own code
Provider switchingSwap OpenAI, Anthropic, Bedrock with no code changesEach provider integration is hand-written
Complex stateful agentsLangGraph handles branching, multi-turn state wellGets harder to manage past a few states
Token and latency controlAbstraction layer adds overheadAbout 30% fewer tokens, about 25% lower latency in practice
Version stabilityBreaking changes across major versions, pin carefullyNo framework upgrades to manage

What LangChain Actually Is (and Isn't)

LangChain is a Python/JavaScript framework that provides abstractions for common LLM patterns: chains (sequences of LLM calls), agents (LLM + tools + loop), retrieval (vector store integration), and memory (conversation history management). The value proposition: a unified interface across multiple LLM providers, built-in implementations of common patterns, and a growing ecosystem of integrations.

The Abstraction Tax

Every abstraction layer adds debugging distance between your code and the underlying API. When a LangChain chain fails, you get a stack trace through 5 layers of LangChain internals before you see the actual API error. I spent 3 hours debugging a SequentialChain that was silently dropping outputs.

Where LangChain Genuinely Saves Time

LangChain is valuable for three use cases: rapid prototyping (get a RAG pipeline running in 50 lines of Python vs 200+ lines custom), multi-provider support (switch between OpenAI, Anthropic, and Bedrock without code changes), and complex agent workflows via LangGraph.

LangChain vs Custom: Decision Framework

  Start
    │
    ▼
  Do you need to switch LLM providers often?
    ├── Yes → LangChain (unified interface)
    └── No  → Continue...
                │
                ▼
  Is your workflow > 4 states with branching?
    ├── Yes → LangGraph
    └── No  → Continue...
                │
                ▼
  Do you have > 5 integrations (vector stores,
  document loaders, custom tools)?
    ├── Yes → LangChain ecosystem
    └── No  → Continue...
                │
                ▼
  How many LLM calls per user request?
    ├── 1-3  → Custom orchestration (simpler, faster)
    └── 4+   → Evaluate LangGraph
                │
                ▼
  Do you need sub-200ms latency?
    ├── Yes → Custom (no abstraction overhead)
    └── No  → Either works

  Verdict:
  Simple app (1-3 calls, < 5 integrations) → Custom
  Complex agent (many states, multi-provider) → LangChain/LangGraph

If you're using LangChain, integrate LangSmith from day one. It captures full trace data — every LLM call, every chain step, every token count — and makes debugging dramatically easier. The free tier is generous enough for development and small-scale production.

When to Build Custom Orchestration

Build custom orchestration when: your workflow is simple (1-3 LLM calls per user request); you need precise control over token usage and caching; you need streaming output with specific UI behavior; or your team is more comfortable debugging JavaScript/Python than framework internals.

LangGraph for Complex Workflows

LangGraph is worth separating from LangChain proper. The graph-based workflow model (nodes are actions, edges are state transitions) is genuinely useful for complex multi-step agent workflows that have branching paths, conditional execution, and state that needs to persist across multiple turns.

# LangChain RAG — 50 lines, fast to prototype
from langchain_anthropic import ChatAnthropic
from langchain_community.vectorstores import PGVector
from langchain.chains import RetrievalQA

llm = ChatAnthropic(model="claude-3-5-haiku-20241022")
vectorstore = PGVector.from_existing_index(connection_string=DB_URL)
chain = RetrievalQA.from_chain_type(llm=llm, retriever=vectorstore.as_retriever())
result = chain.invoke({"query": "What exercises target the lats?"})

# Custom RAG — 200 lines, full control
async def custom_rag(query: str) -> str:
    # 1. HyDE — generate hypothetical answer for better embedding
    hyp_answer = await llm.generate(f"Write a brief answer to: {query}")
    embedding = await embed(hyp_answer)

    # 2. Vector search with metadata filter
    chunks = await db.search(embedding, filter={"type": "exercise"}, limit=20)

    # 3. Rerank
    reranked = await cohere_rerank(query, chunks, top_n=5)

    # 4. Generate with precise prompt + caching
    context = "

".join(c.content for c in reranked)
    return await llm.generate(
        system=CACHED_SYSTEM_PROMPT,  # prompt caching
        user=f"Context:
{context}

Question: {query}"
    )
# Custom is more work but: 30% fewer tokens, 25% lower latency, easier to debug

The Decision Framework

Use LangChain/LangGraph if: you're building a RAG application and want fast iteration on retrieval strategies; you need multi-provider support; you're building complex stateful agent workflows; or your team already knows LangChain. Skip LangChain if: your workflow has fewer than 3 LLM calls; you need precise token control; or debuggability is critical.

LangChain has had numerous breaking changes between major versions. If you build production systems on LangChain, pin your versions strictly in requirements.txt and budget time for version migration work every 6-12 months. I've seen teams lose entire weekends to LangChain upgrade problems.

What I'd Do Now If Starting Fresh

For a new LLM project in 2025, I'd start with direct API calls using Anthropic or OpenAI's official SDK (both are excellent), add LangSmith for observability (it works without LangChain), and introduce LangGraph only if the workflow complexity genuinely warrants it.

The Ecosystem Factor

One genuine advantage of LangChain in 2025 is the ecosystem: 600+ integrations, a large community, and LangSmith for observability. If you need to integrate with specific vector databases, LangChain's pre-built connectors save real time. The question is whether the ecosystem value outweighs the abstraction cost for your specific use case.

Sources & Further Reading

FAQ

Frequently Asked Questions

Short answers to what readers ask most about this topic.

What is the main trade-off between using LangChain and building custom LLM orchestration?

LangChain accelerates prototyping — a RAG pipeline can be up in 50 lines of Python versus 200+ lines of custom code — but every abstraction layer adds debugging distance from the underlying API. When something breaks, you get a stack trace through 5 layers of LangChain internals before seeing the actual API error, which can turn a simple bug into a multi-hour investigation.

When should you skip LangChain and write direct API calls instead?

Skip LangChain when your workflow involves fewer than 3 LLM calls per user request, when you need precise control over token usage and caching, or when streaming output with specific UI behavior is required. In those cases, the abstraction cost outweighs the convenience, and direct calls using Anthropic's or OpenAI's official SDKs are simpler to debug and maintain.

Is LangGraph worth using even if you avoid the rest of LangChain?

Yes — the post treats LangGraph separately from LangChain proper. Its graph-based model (nodes as actions, edges as state transitions) is genuinely useful for complex multi-step agent workflows that have branching paths, conditional execution, and state that must persist across multiple turns, even if you otherwise prefer custom orchestration.

What does the post recommend for observability when building LLM applications?

The post recommends integrating LangSmith from day one, regardless of whether you use LangChain. LangSmith captures full trace data — every LLM call, every chain step, every token count — and its free tier is described as generous enough for development and small-scale production. Importantly, it works independently of LangChain, so it can add observability to custom-built pipelines as well.

How should teams handle LangChain's frequent breaking changes in production?

Pin versions strictly in requirements.txt and budget dedicated time for version migration every 6–12 months. The post warns that LangChain has had numerous breaking changes between major versions and that teams have lost entire weekends to upgrade problems, so version discipline and planned migration windows are essential for production systems.