LangChain (LCEL): editorial guidance
For API reference (full Runnable list, parser types, retriever interfaces), use the mcpdoc MCP tools: fetch_docs("https://docs.langchain.com/oss/python/langchain/..."). This skill is the opinions layer.
When to use LCEL vs create_agent
LCEL is for non-agentic flows: deterministic pipelines (RAG, summarization, classification, structured extraction). The pipeline runs once, end-to-end, no loop, no tool-calling LLM driving control flow.
If the task involves an LLM deciding which tools to call, don't use LCEL — use create_agent(...) + middleware. Trying to bolt agentic behavior onto an LCEL chain is the most common mistake here. The dividing line: does the LLM choose what happens next, or does the code? If LLM, agents. If code, LCEL.
Things the docs won't warn you about
chain.invoke(x) where x is a string but the chain expects a dict will silently coerce in some configurations and fail in others — pass a dict explicitly.
init_chat_model reads provider creds from env (OPENAI_API_KEY, ANTHROPIC_API_KEY). It will not prompt; missing env raises at first call, not at construction.
- Parsers are part of the chain.
chat_model.invoke(...) returns an AIMessage; pipe through StrOutputParser() to get a plain string.
- Middleware does NOT apply to LCEL chains. Middleware is
create_agent-only. For chains, use chain-level chain.with_retry(...) and chain.with_fallbacks([...]) instead.
with_structured_output does not stream — it accumulates the full response and returns the validated object. If you need streaming AND typed output, you can't have both via this API.
Production rules of thumb
- Always wrap production chains with
.with_retry(stop_after_attempt=3, wait_exponential_jitter=True) for resilience to transient model failures.
- For provider redundancy, use
.with_fallbacks([cheaper_model_chain]) — fallback chains run if the primary raises. The fallback is a full chain, not just a model.
- For typed output, use
model.with_structured_output(PydanticModel) before composing into the chain. Validation is automatic; you get the Pydantic instance, not a dict.
- For RAG, add a guardrail stage that returns "I don't know" when
len(context) == 0. Without it, the LLM hallucinates from empty context.
- For RAG, consider a reranker between retriever and prompt. Recall@k improves substantially. The retriever's first 20 results passed through a reranker that picks the top 5 outperforms a retriever that fetches 5 directly.
When to reach for what
| Need |
Tool |
| LLM + tools, deciding what to do next |
create_agent (NOT LCEL) |
| Deterministic transformation (text → structured) |
LCEL with with_structured_output |
| RAG over a vector store |
LCEL with RunnableParallel of retriever + question |
| Multi-step pipeline with branches |
LCEL with RunnableBranch or upgrade to StateGraph if branches need state |
| Streaming token output |
LCEL chain (most parsers stream); NOT with_structured_output |
| Async at scale |
LCEL .ainvoke / .astream |
Doc URLs to fetch with mcpdoc
https://docs.langchain.com/oss/python/langchain/lcel.md — LCEL primer
https://docs.langchain.com/oss/python/langchain/structured-output.md — with_structured_output
https://docs.langchain.com/oss/python/langchain/runnables.md — Runnable types and methods
https://docs.langchain.com/oss/python/langchain/retrievers.md — retriever interfaces
https://docs.langchain.com/oss/python/langchain/chat-models.md — init_chat_model and provider model names
When you need a specific class signature or kwarg, fetch from these. Don't guess at constructor args.
Source: cwijayasundara/agent_cli_langchain — distributed by TomeVault.
1---2name: langchain-agents-langchain-code3description: Use when editing a non-agentic LCEL pipeline — composing Runnables, retrievers, embeddings, chat models, parsers, or building a RAG chain. For agents (LLM + tools loop), use the middleware skill instead.4---56# LangChain (LCEL): editorial guidance78For API reference (full Runnable list, parser types, retriever interfaces), use the **`mcpdoc` MCP tools**: `fetch_docs("https://docs.langchain.com/oss/python/langchain/...")`. This skill is the *opinions* layer.910## When to use LCEL vs `create_agent`1112LCEL is for **non-agentic flows**: deterministic pipelines (RAG, summarization, classification, structured extraction). The pipeline runs once, end-to-end, no loop, no tool-calling LLM driving control flow.1314If the task involves an LLM deciding which tools to call, **don't use LCEL** — use `create_agent(...)` + middleware. Trying to bolt agentic behavior onto an LCEL chain is the most common mistake here. The dividing line: *does the LLM choose what happens next, or does the code?* If LLM, agents. If code, LCEL.1516## Things the docs won't warn you about1718- `chain.invoke(x)` where `x` is a string but the chain expects a dict will silently coerce in some configurations and fail in others — pass a dict explicitly.19- `init_chat_model` reads provider creds from env (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`). It will not prompt; missing env raises at first call, not at construction.20- Parsers are part of the chain. `chat_model.invoke(...)` returns an `AIMessage`; pipe through `StrOutputParser()` to get a plain string.21- **Middleware does NOT apply to LCEL chains.** Middleware is `create_agent`-only. For chains, use chain-level `chain.with_retry(...)` and `chain.with_fallbacks([...])` instead.22- `with_structured_output` does **not** stream — it accumulates the full response and returns the validated object. If you need streaming AND typed output, you can't have both via this API.2324## Production rules of thumb2526- **Always wrap production chains with `.with_retry(stop_after_attempt=3, wait_exponential_jitter=True)`** for resilience to transient model failures.27- **For provider redundancy, use `.with_fallbacks([cheaper_model_chain])`** — fallback chains run if the primary raises. The fallback is a *full chain*, not just a model.28- **For typed output, use `model.with_structured_output(PydanticModel)`** before composing into the chain. Validation is automatic; you get the Pydantic instance, not a dict.29- **For RAG, add a guardrail stage** that returns "I don't know" when `len(context) == 0`. Without it, the LLM hallucinates from empty context.30- **For RAG, consider a reranker between retriever and prompt.** Recall@k improves substantially. The retriever's first 20 results passed through a reranker that picks the top 5 outperforms a retriever that fetches 5 directly.3132## When to reach for what3334| Need | Tool |35|---|---|36| LLM + tools, deciding what to do next | `create_agent` (NOT LCEL) |37| Deterministic transformation (text → structured) | LCEL with `with_structured_output` |38| RAG over a vector store | LCEL with `RunnableParallel` of retriever + question |39| Multi-step pipeline with branches | LCEL with `RunnableBranch` or upgrade to `StateGraph` if branches need state |40| Streaming token output | LCEL chain (most parsers stream); NOT `with_structured_output` |41| Async at scale | LCEL `.ainvoke` / `.astream` |4243## Doc URLs to fetch with mcpdoc4445- `https://docs.langchain.com/oss/python/langchain/lcel.md` — LCEL primer46- `https://docs.langchain.com/oss/python/langchain/structured-output.md` — `with_structured_output`47- `https://docs.langchain.com/oss/python/langchain/runnables.md` — Runnable types and methods48- `https://docs.langchain.com/oss/python/langchain/retrievers.md` — retriever interfaces49- `https://docs.langchain.com/oss/python/langchain/chat-models.md` — `init_chat_model` and provider model names5051When you need a specific class signature or kwarg, fetch from these. Don't guess at constructor args.5253---54> Source: [cwijayasundara/agent_cli_langchain](https://github.com/cwijayasundara/agent_cli_langchain) — distributed by [TomeVault](https://tomevault.io).55<!-- tomevault:4.0:skill_md:2026-05-23 -->