Thursday, October 23, 2025

๐Ÿง  Understanding LangChain Core Components — with Real Examples

LangChain has quickly become one of the most talked-about frameworks in AI development.

It helps developers connect large language models (LLMs) with real-world tools, APIs, and data sources — essentially letting AI “do things” instead of just chatting.

But if you’re new to LangChain, the terminology can feel overwhelming: agents, runnables, memory, output parsers… what do they all mean?

This post breaks down LangChain’s core building blocks in simple terms, with real-world analogies and examples you can relate to — so you can start building smarter AI applications with confidence.


๐Ÿงฉ 1. Agent Executor (The “Brain Runner”)

What it is

In older versions of LangChain, you might have seen the term “chain.”
That’s now replaced with Agent Executor — the component that manages how an agent thinks, decides, and acts.

Think of it like a movie director:

  • The agent is the actor (decides what to do)

  • The tools are the props (things it can use)

  • The agent executor is the director who ensures everything happens in the right order

Real-world analogy

Imagine you’re using ChatGPT to plan a trip.
The agent executor is what takes your request (“Plan a 3-day trip to Japan”) and manages the entire process:

  1. Ask the model what it needs to know

  2. Call APIs for flights and hotels

  3. Combine all results into one itinerary

It’s the brain that coordinates the steps.

๐Ÿงฉ Simple Example

from langchain.agents import AgentExecutor, load_tools, initialize_agent from langchain.chat_models import ChatOpenAI llm = ChatOpenAI(model="gpt-4-turbo") tools = load_tools(["serpapi"]) # Google search API agent = initialize_agent(tools, llm, agent_type="zero-shot-react-description") agent_executor = AgentExecutor.from_agent_and_tools(agent, tools) agent_executor.invoke({"input": "Find the current weather in Tokyo"})
๐Ÿ—ฃ Explanation:

The Agent Executor handles your request, figures out it needs the search tool, calls it, and combines results into a response.


๐Ÿงฐ 2. Tools — Giving the Agent Superpowers

Tools are the actions your agent can perform — like calling APIs, searching, or running code.

๐Ÿ”ง Example

from langchain.tools import tool @tool def multiply(a: int, b: int) -> int: """Multiply two numbers.""" return a * b
Now your agent can “use” this tool during reasoning — like a human using a calculator.

๐Ÿ’ฌ 3.Messages — How the Model Communicates

LangChain structures all conversations as message objects — not plain strings — to keep context organized.

๐Ÿ’ป Example

from langchain.schema import SystemMessage, HumanMessage from langchain.chat_models import ChatOpenAI llm = ChatOpenAI(model="gpt-4-turbo") messages = [ SystemMessage(content="You are a helpful assistant."), HumanMessage(content="Explain LangChain in one sentence.") ] print(llm.invoke(messages).content)
๐Ÿ—จ️ Result

“LangChain connects language models with tools, data, and memory to build intelligent apps.”

⚙️ 4. Models — The AI Engine

The model is the LLM itself (e.g., GPT-4, Claude, Mistral).

LangChain provides unified interfaces for both chat and text models.

Example

from langchain.llms import OpenAI llm = OpenAI(model="gpt-3.5-turbo-instruct") response = llm.invoke("Summarize: LangChain helps connect LLMs to data and APIs.") print(response)

๐Ÿงฉ You can swap models easily — the interface stays consistent.


๐Ÿ” 5. Short-Term Memory — Keeping Context

Memory stores recent conversation history so the AI can “remember” previous messages.

Example

from langchain.memory import ConversationBufferMemory from langchain.chains import ConversationChain from langchain.chat_models import ChatOpenAI memory = ConversationBufferMemory() llm = ChatOpenAI(model="gpt-4-turbo") conversation = ConversationChain(llm=llm, memory=memory) conversation.invoke({"input": "Hi, my name is Sam."}) conversation.invoke({"input": "What’s my name?"})

๐Ÿง  Output

“Your name is Sam.”

LangChain remembered that from earlier thanks to memory.


6. Streaming — See the Response in Real Time

Streaming sends the model’s response token by token — great for live chat apps.

Example

from langchain.chat_models import ChatOpenAI def on_token(token): print(token, end="", flush=True) llm = ChatOpenAI(model="gpt-4-turbo", streaming=True, callbacks=[{"on_llm_new_token": on_token}]) llm.invoke("Explain LangChain in 10 words.")

๐Ÿง  Output:

 You’ll see text appear word by word, like ChatGPT typing.


๐Ÿงฑ 7. Middleware (Runnable Lambda) — Custom Logic Blocks

Runnable Lambda lets you wrap any custom logic into a reusable block.

Example

from langchain.schema.runnable import RunnableLambda uppercase = RunnableLambda(lambda text: text.upper()) reverse = RunnableLambda(lambda text: text[::-1]) workflow = uppercase | reverse print(workflow.invoke("langchain"))

๐Ÿงฉ Output:

“NIAHCGNAL”

Think of Runnable Lambdas as LEGO blocks — each does one thing, but you can snap them together to build workflows.


๐Ÿ”ง8. Piping Components(Connecting the Pieces)

LangChain allows you to pipe runnables together using the | operator — just like connecting pipes.

Example

clean_text = RunnableLambda(lambda x: x.strip()) uppercase = RunnableLambda(lambda x: x.upper()) workflow = clean_text | uppercase print(workflow.invoke(" hello world ")) # Output: HELLO WORLD

This makes it easy to chain multiple transformations, just like a data pipeline for text.

๐ŸŒ 9. LangChain Hub — The Community Library

LangChain Hub is a public repository where developers share reusable prompts, agents, and chains.

It’s like GitHub for AI workflows — browse, copy, and reuse tested components.


๐Ÿงฉ 10. Agent Models & RAG Applications

LangChain applications typically fall into two buckets:

  • Agents: AI systems that can decide which tools to use (search, API calls, etc.)

  • RAG (Retrieval-Augmented Generation): AI that pulls external knowledge before answering.

Example

  • Agent: “Find today’s weather and summarize it.”

  • RAG: “Summarize our internal Q2 financial report.”

Together, these cover ~80% of real-world LLM apps.


๐Ÿ”Œ 11. Runnable Interface — Consistency for Developers

Anything that can be “run” (a model, tool, or lambda) implements the same Runnable Interface — making LangChain modular and composable.

Think of it as the USB port of LangChain — any compatible part fits.


๐Ÿง  12. Memory Types

LangChain offers multiple memory types:

  • ConversationBufferMemory – remembers everything

  • ConversationBufferWindowMemory – remembers the last N messages

  • ConversationKGMemory – builds a mini knowledge graph

Analogy

Like chat history — it helps the model keep context.


13. Structured Output — Making AI Results

Developer-Friendly

Structured output ensures model results are machine-readable — JSON, Pydantic, or tables.

Example

from langchain.output_parsers import PydanticOutputParser from pydantic import BaseModel class CityInfo(BaseModel): name: str country: str parser = PydanticOutputParser(pydantic_object=CityInfo) result = parser.parse('{"name": "Tokyo", "country": "Japan"}') print(result.name) # Tokyo


๐Ÿ” ReAct Agent Core Concepts

⚙️ Core Components of a LangChain ReAct Agent

ComponentDescriptionAnalogy
๐Ÿง  LLM    The brain that reasons and plans    The thinker
๐Ÿงฐ Tools    APIs or functions for data/actions    The hands
๐Ÿงพ Prompt        The structured reasoning format    The script

Example ReAct Prompt Template

You are a helpful agent that can reason and act. Use this format: Thought: reason about what to do Action: tool to use Action Input: tool input Observation: result of that action Repeat until you have the Final Answer.


๐Ÿ” The Thought–Action–Observation Loop

The ReAct agent’s reasoning loop:

Thought → Action → Observation → (repeat) → Final Answer

Thought → Action → Observation → (repeat) → Final Answer

Example

Thought: Need the capital of France Action: Search("Capital of France") Observation: "Paris" Thought: Now find weather in Paris Action: WeatherAPI("Paris") Observation: "21°C and clear" Final Answer: Paris, 21°C clear


๐Ÿงญ How the Agent Refines Actions

After each Observation, the agent refines its Thought and decides the next Action — a self-correcting loop.

Example

Thought: Find Elon Musk’s birth year Action: Search("Elon Musk birth year") Observation: "Born 1971" Thought: Calculate his age Action: Calculator("2025 - 1971") Observation: "54" Final Answer: Elon Musk is 54 years old.

User Input ↓ [Thought] → “I need data” ↓ [Action] → “Call search tool” ↓ [Observation] → “Got result” ↓ [Thought] → “Use calculator now” ↓ [Final Answer]


Full Example — All Components Combined

from langchain.chat_models import ChatOpenAI from langchain.agents import initialize_agent, load_tools from langchain.memory import ConversationBufferMemory from langchain.output_parsers import PydanticOutputParser from pydantic import BaseModel class CityInfo(BaseModel): city: str country: str parser = PydanticOutputParser(pydantic_object=CityInfo) memory = ConversationBufferMemory() llm = ChatOpenAI(model="gpt-4-turbo", streaming=True) tools = load_tools(["serpapi"]) agent = initialize_agent(tools, llm, agent_type="zero-shot-react-description", memory=memory) response = agent.invoke({"input": "Find the country for the city Tokyo in JSON format."}) parsed = parser.parse(response["output"]) print(parsed.country)


๐Ÿง  Step-by-Step Flow with Inputs and Outputs

๐Ÿ INPUT

User provides:

{"input": "Find the country for the city Tokyo in JSON format."}

Meaning:

You’re asking the agent to find which country Tokyo belongs to and return it in JSON.


⚙️ STAGE 1: Agent Executor

  • The Agent Executor receives your input.
  • It decides how to solve the problem (maybe it needs to use a tool).
  • It parses your request and sends it to the LLM for reasoning.

๐Ÿงฉ Intermediate Output (LLM reasoning trace)

Thought: I need to find out which country Tokyo is in. Action: Search API Action Input: "Tokyo" Observation: "Tokyo is the capital of Japan." Final Answer: {"city": "Tokyo", "country": "Japan"}

๐Ÿงฐ STAGE 2: Tools (Search API)

The serpapi tool performs a real-time web search.
Example search query:

"What country is Tokyo in?"

๐Ÿ” Intermediate Tool Output:

{ "answer": "Tokyo is the capital of Japan." }

This output goes back to the agent, which now knows the answer.


๐Ÿง  STAGE 3: Memory

Before finalizing, the ConversationBufferMemory stores the context:

User: Find the country for the city Tokyo in JSON format.

User: Find the country for the city Tokyo in JSON format. AI: {"city": "Tokyo", "country": "Japan"}

If you later ask: “Now find the country for Paris.”

The memory helps it understand you’re continuing the same pattern.


๐Ÿงฎ STAGE 4: LLM (Language Model)

The LLM generates the final formatted JSON text based on all the gathered information and your prompt requirement.

Output from model (raw text):

{"city": "Tokyo", "country": "Japan"}

This is text, not Python data — so we’ll cleanly parse it next.


๐Ÿงพ STAGE 5: Output Parser (Pydantic)

Now the PydanticOutputParser takes the model’s string output and converts it into a strongly typed Python object.

Parsing:

parsed = parser.parse('{"city": "Tokyo", "country": "Japan"}')

Parsed Object:

CityInfo(city='Tokyo', country='Japan')

Accessing a field:

print(parsed.country) # Output: Japan

๐Ÿ“š References

๐Ÿš€ ALL AI / LangChain Post

ALL LangChain Post

You may also like

Kubernetes Microservices
Python AI/ML
Spring Framework Spring Boot
Core Java Java Coding Question
Maven AWS