PythonTypeScriptHigh — roles/crews/agents out of the box
LangChain
A common interface over many LLM providers, vector stores, document loaders, and tools, so a pipeline can be composed from interchangeable parts.
Architecture
- Runnables / LCEL: every component (prompt, model, parser, retriever) implements
invoke/stream/batchand is composed with|into a chain. - Integrations: hundreds of adapters (
langchain-openai,langchain-anthropic,langchain-community) behind shared base classes such asBaseChatModelandVectorStore. - Tools and agents:
@toolwraps functions with a schema;create_agent/create_react_agentproduce a tool-calling loop (in current versions this is LangGraph underneath). - Output parsers and structured output:
with_structured_output(Schema)maps a Pydantic/Zod model onto the provider's native structured-output or tool-call mechanism.
Best use cases
- Prototypes that must try several providers, embedding models, or vector stores quickly.
- RAG pipelines assembled from standard loaders, splitters, and retrievers.
- Teams that want an ecosystem (LangSmith tracing, templates, community integrations) more than minimal code.
Weaknesses
- Abstraction leakage: provider-specific features (caching headers, extended thinking, tool-choice modes) often need escape hatches or are unavailable.
- Hidden prompts: some agent and chain helpers inject their own system text and formatting instructions you did not write and will not see without tracing.
- API churn: the
chains→ LCEL → LangGraph migrations left many tutorials and Stack Overflow answers stale; deprecation warnings are a constant. - Stack traces run through many layers of Runnable wrappers; debugging a malformed prompt is harder than in straight SDK code.
- The dependency graph is large; import time and transitive version conflicts are real costs.
When NOT to use it
- A single provider and a single vector store — the adapter layer buys nothing.
- You need precise control over every token in the prompt (long-lived production agents, cost-critical paths).
- You want a durable workflow runtime — go directly to LangGraph rather than through LangChain agents.
Code example
Illustrative — APIs change between versions.
1from langchain_core.prompts import ChatPromptTemplate2from langchain_core.tools import tool3from langchain_openai import ChatOpenAI # any langchain-* chat model works here4from pydantic import BaseModel5 6class Answer(BaseModel):7 summary: str8 confidence: float9 10@tool11def search_docs(query: str) -> str:12 """Search internal documentation."""13 return index.search(query)14 15llm = ChatOpenAI(model="gpt-4.1-mini") # model id is version-sensitive16prompt = ChatPromptTemplate.from_messages([17 ("system", "Answer from the provided context only."),18 ("human", "{question}\n\nContext:\n{context}"),19])20# LCEL: prompt | model-with-structured-output21chain = prompt | llm.with_structured_output(Answer)22result = chain.invoke({"question": q, "context": search_docs.invoke(q)})23print(result.summary, result.confidence)