LangChain Is a Pipeline Controller, Not a Magic Brain
Suitable readers: Know basic Python, understand that LLMs can converse, but haven't actually used LangChain yet.
Version note: This article follows the current approach of LangChain v1; examples require Python 3.10 or higher. Old tutorials'
LLMChain,ConversationChain, etc. have been moved tolangchain-classic; don't mix old and new APIs when copying code.
It's normal to be overwhelmed by terminology at first 😵
When I first encountered LangChain, my mind was roughly like this:
"Chain is a chain, Agent is an intelligent agent, Memory is memory... I understand each English word individually, so why can't I understand them when put together?"
What's more confusing is that online examples may come from different versions. For the same requirement of "remembering chat history", some use the old Memory class, some use message history, and others jump straight to LangGraph. The more code you search for, the more tangled the threads become.
This article doesn't plan to take you through memorizing APIs. Let's do something more important first: build a global map. After reading, you should be able to answer three questions:
- What problems do Model, Chain, Agent, Memory, and Tool each solve?
- In what scenarios should you use a fixed Chain, and when do you need an Agent?
- How do you write your first runnable LangChain document Q&A flow?
Figure 1: LangChain handles "orchestration", while the model handles understanding and generation.
First, a human-language definition of LangChain
Imagine you run a content processing factory. A user sends in a question, and the factory needs to look up materials, organize prompts, ask a model to generate content, check the output format, and finally deliver the result.
If you write all the code by hand, you can certainly do it. But as steps multiply and models change, error handling, state saving, streaming output, and monitoring all become troublesome.
LangChain is a set of LLM application orchestration tools: it connects models, prompts, data, tools, and state into executable flows.
It is not a new large model, nor does it magically make models smarter. It's more like "glue" and a "pipeline controller". LangChain officially positions it as an open-source framework for building LLM applications and Agents; when you need a more low-level, controllable graph-based workflow, you can continue using LangGraph.
Five core concepts, translated clearly once and for all
1. Model: The "brain" that does the thinking 🧠
Model is the language model your application calls, such as chat models provided by OpenAI, Anthropic, or Google. It is responsible for understanding input and generating output.
What LangChain does here is provide a relatively unified calling interface. You can think of different vendors' models as different brands of appliances, and LangChain tries its best to give them similar sockets.
from langchain.chat_models import init_chat_model
model = init_chat_model("openai:gpt-4.1-mini")
response = model.invoke("Explain what LangChain is in one sentence")
print(response.content)
Note: a unified interface does not mean model capabilities are identical. Context window, tool calling, structured output, price, and latency still depend on the specific model.
2. Chain: A fixed-route "factory assembly line" 🏭
Chain strings multiple steps together in a predetermined order. The output of the previous station becomes the input of the next.
For example, a document Q&A Chain:
User question
Read or retrieve documents
Assemble Prompt
Call Model
Parse output
Return answer
In modern LangChain, many Chains are essentially combinations of Runnables. The most intuitive way to write them is using | to connect:
chain = prompt | model | output_parser
Reads like: "Prompt goes to model, model result goes to parser." Its biggest advantage is clear order, easy to test, predictable cost.
3. Agent: The "on-site supervisor" that decides its own route 🤖
Chain's route is predetermined by the developer; an Agent dynamically decides what to do next based on the goal.
For example, a user asks: "Is the current weather in Beijing suitable for running?" The Agent might:
- Determine that real-time weather is needed;
- Call a weather tool;
- Read temperature, precipitation, and air quality;
- Then have the model give a suggestion;
- Continue calling other tools if information is insufficient.
External info needed
Info sufficient
User goal
Agent
Model decides next step
Call Tool
Return observation
Final answer
This is equivalent to giving the "brain" hands and eyes. However, the higher the autonomy, the more uncertain the path, and the harder debugging and cost control become.
If a problem can be solved with a Chain, don't use an Agent first. Fixed flows suit stable business; only when steps genuinely require the model to dynamically choose does an Agent have value.
In LangChain v1, create_agent is the standard entry point for creating an Agent. It uses LangGraph underneath to provide looping execution, state, and persistence capabilities.
4. Memory: Not "infinite memory", but manageable state 🗂️
The model API itself usually does not automatically remember the previous request. So-called Memory is the application saving necessary history or user information and providing it back to the model in subsequent calls.
Modern LangChain distinguishes memory more clearly:
- Short-term memory: Belongs to the current session thread, such as recent chat rounds and current tool results; Agents can save state via a checkpointer.
- Long-term memory: Saved across sessions, such as user preferences, profiles, or long-term facts; usually requires persistent storage.
from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver
agent = create_agent(
model="openai:gpt-4.1-mini",
tools=[],
checkpointer=InMemorySaver(), # only suitable for local demos
)
config = {"configurable": {"thread_id": "demo-user-1"}}
Memory is not about stuffing the entire chat history into the Prompt forever. The longer the context, the higher the cost, and old information can also interfere with the model. Production environments typically require trimming, summarization, retrieval, and database persistence.
5. Tool: "External capabilities" connected to the model 🛠️
LLMs excel at understanding and generating language, but they don't know today's real-time inventory, nor should they rely on guessing for precise calculations. A Tool is a callable function with a name, description, and parameter structure.
from langchain.tools import tool
@tool
def query_inventory(product_id: str) -> int:
"""Query the real-time inventory quantity of a specified product."""
# In a real project, this would call a database or business API
return 42
The function description is very important because the Agent will judge "when to use this tool" based on it. Tools can query search engines, databases, and internal APIs, and can also perform calculations or trigger business actions.
But remember: Letting an Agent call a tool means granting it the ability to act. For high-risk operations involving payments, deletions, or sending messages, add permission checks, parameter validation, and human confirmation.
Chain vs. Agent: how to choose?
| Comparison Item | Chain | Agent |
|---|---|---|
| Execution route | Predetermined by developer | Dynamically decided by model |
| Predictability | High | Relatively lower |
| Debugging difficulty | Lower | Higher, need to observe each step |
| Cost & latency | Easy to estimate | May involve multiple rounds of calls |
| Suitable scenarios | Summarization, classification, fixed RAG, structured extraction | Multi-tool research, open-ended tasks, dynamic troubleshooting |
A simple judgment question: If you can determine every step in advance when drawing a flowchart, prefer Chain; if "what's the next step" must depend on the result the model just saw, then consider Agent.
Minimum runnable example: building a document Q&A Chain
Let's not introduce a vector database first. The goal is simple: give a small piece of internal documentation and a user question to the model, and require it to answer based only on the document.
Figure 2: The | in the code is the conveyor belt of this assembly line.
Step 1: Prepare the environment
LangChain currently requires Python 3.10 or higher. Create a virtual environment and install the core package and OpenAI integration:
python -m venv .venv
# macOS / Linux
source .venv/bin/activate
# Windows PowerShell
# .venv\Scripts\Activate.ps1
python -m pip install -U langchain langchain-openai
Set the API Key. Do not write the key directly into code or commit it to Git:
# macOS / Linux
export OPENAI_API_KEY="your API Key"
# Windows PowerShell
# $env:OPENAI_API_KEY="your API Key"
Step 2: Create app.py
import os
from langchain.chat_models import init_chat_model
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
# 1. Check environment early to avoid discovering missing key only after request is sent
if not os.getenv("OPENAI_API_KEY"):
raise RuntimeError("Please set the OPENAI_API_KEY environment variable first")
# 2. This is our "small document"; in a real project, replace with file content
document = """
《Team Travel Handbook》
1. Meal allowance for business trips on working days is 120 yuan per day.
2. Hotel expense cap is 600 yuan per night; first-tier cities can float up by 20%.
3. All reimbursements should be submitted within 30 days after the trip ends.
""".strip()
# 3. Prompt defines the rules and reserves slots for document and question
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"You are a corporate policy Q&A assistant. Only answer based on the given document;"
"if the document has no answer, explicitly say 'Not stated in the document'.\n\n"
"Document:\n{document}",
),
("human", "Question: {question}"),
]
)
# 4. Model is the "brain" in the assembly line
# If account cannot use this model, replace with available model via LANGCHAIN_MODEL
model = init_chat_model(
os.getenv("LANGCHAIN_MODEL", "openai:gpt-4.1-mini"),
temperature=0,
)
# 5. Parser converts the message object returned by the model into a plain string
parser = StrOutputParser()
# 6. Use | to string three Runnables into one Chain
chain = prompt | model | parser
# 7. invoke makes the input pass through Prompt, Model, and Parser in sequence
answer = chain.invoke(
{
"document": document,
"question": "When on a business trip to Shanghai, what is the maximum reimbursable hotel expense per night?",
}
)
print(answer)
Run:
python app.py
Expected output
Model wording may vary slightly, but the result should be close to:
Shanghai is a first-tier city, so the hotel expense cap can float up 20% on the 600 yuan base,
therefore the maximum reimbursable per night is 720 yuan.
What exactly happened in this code?
ChatPromptTemplateorganizes the policy, restrictions, and question into messages;init_chat_modelcreates a unified model object;StrOutputParserconverts the model message into a string convenient for program use;prompt | model | parsergenerates aRunnableSequence;invoke()triggers the entire assembly line.
This is not yet a complete RAG, because the document is placed entirely into the Prompt. When the document is very small, this approach is easiest to understand; when materials grow, upgrade to:
Document loading → Text splitting → Embedding → Vector storage → Retrieve relevant chunks → Generate answer
Don't pack all components in from the start. First, get the minimum closed loop running, then gradually replace one station at a time.
The 5 pitfalls beginners are most likely to step into
Pitfall 1: Copying old tutorials, all import paths error out
LangChain v1 streamlined the main package; old-style Chain and other capabilities were moved to langchain-classic. When learning, first check the article's publication date and target version, and prioritize using the current official documentation.
Pitfall 2: Making every requirement into an Agent
Agents look more "intelligent", but multi-round decision-making increases latency, cost, and uncertainty. Tasks like classification, summarization, and fixed document Q&A are usually more stable with Chain.
Pitfall 3: Treating Memory as infinite chat history
The context window is limited; longer history doesn't necessarily mean smarter. Trim messages, summarize, and retrieve long-term information based on business needs, and use thread_id to isolate different sessions.
Pitfall 4: Assuming that connecting documents means no hallucination
Prompt injection, irrelevant retrieval, and document conflicts can still cause errors. Important answers should display sources, and a test question set should be established, rather than judging based on a single demo result.
Pitfall 5: Only looking at the final answer, not the intermediate process
When an Agent errs, the problem may come from model decisions, tool parameters, tool results, or state. Use tracing tools like LangSmith to observe each step; locating issues will be much more efficient.
Three-stage learning path: from being able to call to being able to deliver
Stage 1: Getting started — get fixed flows running first
The goal is to understand Model, Prompt, Parser, and Runnable.
- Complete a summarization Chain, a classification Chain, a document Q&A Chain;
- Practice
invoke,batch, andstream; - Learn to switch models via environment variables, never hardcode keys in code;
- Be able to explain what type the input and output are at each step.
Stage 2: Advancing — let the application touch the external world
The goal is to master Retrieval, Tool, Agent, and Memory.
- Use text splitting, Embedding, and vector storage to complete a 2-Step RAG;
- Write two real tools, such as weather query and database read-only query;
- Use
create_agent, observe how the model chooses tools; - Use checkpointer to save short-term state, and understand the boundary between short-term and long-term memory.
Stage 3: Real-world practice — from Demo to reliable system
The goal is not "features can run", but "results are controllable".
- Establish inputs, expected answers, and evaluation criteria for key questions;
- Add timeouts, retries, rate limiting, permission checks, and human confirmation;
- Record latency, Tokens, tool calls, and failure reasons;
- Use deterministic code for high-risk actions; Agent is only responsible for suggestions or controlled decisions;
- When complex loops, branching, and human intervention are needed, then dive deeper into LangGraph.
Recommended learning resources
- LangChain Official Documentation: Start with Overview, Models, Tools, Agents, and Memory.
- LangChain Retrieval Guide: Systematically understand the retrieval flow and the difference between 2-Step RAG and Agentic RAG.
- LangChain Academy: Official courses, suitable for gradually transitioning from basic Agents to LangGraph and LangSmith.
- LangChain Official GitHub: Check source code, release notes, and real Issues; especially useful when encountering API differences.
- DeepLearning.AI: LangChain for LLM Application Development: Short course aimed at beginners. Some APIs in the course may predate v1; it's recommended to use it for understanding concepts and check code against the official migration guide.
Conclusion: LangChain's value is not in the name "Chain"
Now look at these five concepts again:
- Model provides understanding and generation capability;
- Chain executes predetermined steps;
- Tool connects the external world;
- Agent dynamically chooses the next step;
- Memory saves and manages state.
LangChain's real value is orchestrating them into a replaceable, observable, evolvable system. It is not the model itself, but the "glue" between the model and real business.
If you are just getting started, do only one thing today: run the minimal example above, then personally add one more question. Once you can clearly explain the input and output of each step, connecting vector databases, Agents, and long-term memory will be much easier.
Finally, a question to leave you with: When learning LangChain, which concept or version difference tripped you up first? Feel free to share your pitfall in the comments; it might just help the next reader.