Gallery

Contacts

405 W. Greenlawn Ave Lansing, Michigan 48910

contact@techjacksolutions.com

+1-616-320-4064

LANGCHAIN

LangChain Tutorial: Build Your First AI Agent

LangChain gives you a composable Python framework for connecting large language models to external tools, data sources, and multi-step reasoning workflows. This tutorial walks through every core concept: installing the libraries, composing your first chain with the LCEL pipe operator, wiring up tools, building a reasoning agent, adding conversation memory, orchestrating complex flows with LangGraph, and debugging everything with LangSmith. By the end, you will have a working agent that searches the web, reasons about results, and carries context across turns.

What you will build: A tool-calling agent that uses web search to answer questions, maintains conversation history, and logs every step to LangSmith for debugging.


MIT
License (Free & Open Source)
|
LCEL Pipe Operator
2
Memory Types
3.9+
Python Required

Setup and Installation

Prerequisites Checklist
Python 3.9 or higher installed and accessible from your terminal (python --version to verify)
pip or uv package manager ready (uv is faster but pip works fine)
OpenAI API key (or another supported LLM provider key: Anthropic, Google, etc.)
A code editor (VS Code, PyCharm, or any editor with Python support)
Tavily API key (free tier available) for the web search tool in later sections

Start by creating a project directory and a virtual environment. Isolating dependencies prevents version conflicts with other Python projects on your machine.

Terminal # Create project directory mkdir langchain-agent && cd langchain-agent # Create and activate virtual environment python -m venv .venv # macOS/Linux: source .venv/bin/activate # Windows: .venv\Scripts\activate # Install LangChain and LangGraph pip install langchain langgraph langchain-openai

That single pip install pulls in the core LangChain library, LangGraph for stateful orchestration, and the OpenAI integration. Both LangChain and LangGraph are MIT licensed, so there is no cost for the framework itself. You will pay only for the LLM API calls your agent makes.

Next, set your API keys as environment variables. Never hardcode API keys in source files.

.env OPENAI_API_KEY=sk-your-key-here TAVILY_API_KEY=tvly-your-key-here # Optional: enable LangSmith tracing (recommended) LANGSMITH_TRACING=true LANGSMITH_API_KEY=lsv2-your-key-here

Load these variables at the top of your Python files with python-dotenv:

Python pip install python-dotenv # At the top of your script: from dotenv import load_dotenv load_dotenv()

Tutorial Progress
0 of 8 sections complete

Your First Chain with LCEL

Before building an agent, understand how LangChain composes operations. The LangChain Expression Language (LCEL) lets you chain components together using the pipe operator (|). Each component receives the output of the previous one, creating a declarative pipeline.

A chain is a fixed sequence: prompt template goes in, formatted prompt feeds the model, model output gets parsed. No decisions at runtime, just data flowing through a pipeline.

Python - first_chain.py from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser # 1. Define the prompt template prompt = ChatPromptTemplate.from_messages([ ("system", "You are a helpful technical writer."), ("human", "Explain {topic} in three sentences.") ]) # 2. Initialize the model model = ChatOpenAI(model="gpt-4o", temperature=0) # 3. Compose with LCEL pipe operator chain = prompt | model | StrOutputParser() # 4. Run the chain result = chain.invoke({"topic": "vector databases"}) print(result)

The LCEL pipe operator is the foundation of everything in LangChain. Chains, agents, retrieval pipelines, and even LangGraph nodes use this same composition pattern. Once you internalize prompt | model | parser, every other concept builds on top of it.

Key insight: Chains are predictable and fast because the execution path is fixed at build time. Agents, which we build next, decide their own path at runtime.


Adding Tools

Tools are how agents interact with the outside world. A tool is a Python function with a name, a description (so the LLM knows when to use it), and typed inputs. LangChain includes built-in tools for web search, file operations, code execution, and dozens of API integrations. You can also define your own.

Built-in Web Search Tool

Terminal pip install langchain-community tavily-python
Python - tools.py from langchain_community.tools.tavily_search import TavilySearchResults # Create a search tool (uses TAVILY_API_KEY from env) search_tool = TavilySearchResults( max_results=3, search_depth="advanced" ) # Test it directly results = search_tool.invoke("LangChain latest release 2026") print(results)

Custom Tool with the @tool Decorator

When built-in tools do not cover your use case, define a custom tool. The @tool decorator turns any Python function into something an agent can call. The function docstring becomes the description the LLM reads to decide whether to invoke it.

Python - custom_tool.py from langchain_core.tools import tool @tool def calculate_cost(tokens: int, price_per_million: float) -> str: """Calculate the API cost for a given number of tokens. Use this when the user asks about pricing or costs.""" cost = (tokens / 1_000_000) * price_per_million return f"Cost for {tokens:,} tokens: ${cost:.4f}"

Tools can call external APIs, query databases, read files, execute code in sandboxes, or interact with any system your agent needs. The key constraint: every tool must have clear type hints and a descriptive docstring so the LLM can reason about when and how to use it.


Building an Agent

An agent is where LangChain stops being a pipeline and starts being a decision engine. Instead of following a fixed sequence, the agent uses the LLM to reason about which tool to call, evaluates the result, and decides whether to call another tool or return a final answer. This is the create_react_agent pattern: the LLM thinks, acts, observes, and repeats.

LangChain's create_react_agent function is the minimal harness that composes a model, tools, prompt, and middleware into a runnable agent. Under the hood, it builds a LangGraph that handles the think-act-observe loop.

Python - agent.py from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent # Model with tool-calling capability model = ChatOpenAI(model="gpt-4o", temperature=0) # Combine all tools tools = [search_tool, calculate_cost] # Create the agent agent = create_react_agent( model=model, tools=tools ) # Run the agent result = agent.invoke({ "messages": [{ "role": "user", "content": "Search for the latest LangChain release and calculate the cost of processing 500,000 tokens at $2.50 per million." }] }) # Print the final response print(result["messages"][-1].content)

When you run this, the agent will first call the search tool to find the latest LangChain release information, then call the calculate_cost tool to do the math, and finally synthesize both results into a coherent answer. You did not tell it which tool to call first. The LLM decided based on the question.

2-5x
Agents typically use 2 to 5 times more tokens than a single LLM call because each tool-calling step requires a round trip to the model. Budget accordingly.

Adding Memory

Without memory, every agent invocation starts from scratch. The agent has no idea what you asked three messages ago. LangChain supports two categories of memory:

  • Short-term memory keeps the conversation history within a single thread. The agent sees all previous messages in the current session.
  • Long-term memory persists facts and context across conversations, stored in PostgreSQL, SQLite, or vector stores. Useful for agents that need to remember user preferences or past research.

For this tutorial, we will add short-term thread-scoped memory using LangGraph's built-in checkpointing. This is the simplest path to a conversational agent.

Python - agent_with_memory.py from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from langgraph.checkpoint.memory import MemorySaver # In-memory checkpointer (use PostgresSaver for production) memory = MemorySaver() model = ChatOpenAI(model="gpt-4o", temperature=0) tools = [search_tool, calculate_cost] # Compile agent with memory agent = create_react_agent( model=model, tools=tools, checkpointer=memory ) # First turn config = {"configurable": {"thread_id": "session-001"}} result = agent.invoke( {"messages": [{"role": "user", "content": "What is LangGraph?"}]}, config=config ) print(result["messages"][-1].content) # Second turn (agent remembers the first) result = agent.invoke( {"messages": [{"role": "user", "content": "How does it handle persistence?"}]}, config=config ) print(result["messages"][-1].content)

The thread_id is how LangGraph scopes memory. Different thread IDs create separate conversation histories. The same thread ID picks up where it left off. In production, swap MemorySaver() for PostgresSaver or SQLiteSaver so state survives application restarts.

Production note: MemorySaver stores state in RAM and is lost when your process exits. For any deployment beyond local development, use a persistent checkpointer backed by PostgreSQL or SQLite.


LangGraph Orchestration

The create_react_agent function covers most use cases, but when you need fine-grained control over execution flow, LangGraph lets you build the graph yourself. LangGraph models agent workflows as stateful graphs with nodes (functions) and edges (transitions). Unlike simple chains, graphs can have cycles, conditional branching, and human-in-the-loop interrupts.

Here is a minimal custom graph that routes between a search step and a summarization step based on what the user asks:

Python - custom_graph.py from typing import TypedDict, Annotated from langgraph.graph import StateGraph, END from langgraph.graph.message import add_messages # 1. Define the graph state class AgentState(TypedDict): messages: Annotated[list, add_messages] search_results: str # 2. Define node functions def search_node(state: AgentState) -> dict: query = state["messages"][-1].content results = search_tool.invoke(query) return {"search_results": str(results)} def summarize_node(state: AgentState) -> dict: summary = model.invoke( f"Summarize: {state['search_results']}" ) return {"messages": [summary]} # 3. Build the graph graph = StateGraph(AgentState) graph.add_node("search", search_node) graph.add_node("summarize", summarize_node) graph.set_entry_point("search") graph.add_edge("search", "summarize") graph.add_edge("summarize", END) # 4. Compile and run app = graph.compile(checkpointer=memory)

LangGraph also supports human-in-the-loop workflows via the interrupt() function. You can pause execution at any node to wait for human approval before continuing. This is critical for agents that perform actions with real-world consequences, such as sending emails or modifying databases.

The Deep Agents pattern builds on LangGraph by adding automatic context compression (to stay within token limits), virtual filesystem access, and the ability to spawn subagents for subtasks. Sandbox backends like Daytona, Modal, and Runloop provide secure execution environments for code-generating agents.


Testing and Debugging with LangSmith

Agents are nondeterministic. The same input can produce different tool-call sequences on different runs. This makes debugging significantly harder than with traditional code. LangSmith solves this by capturing a complete trace of every agent execution: the prompt sent to the model, the model's reasoning, which tools it decided to call, the tool outputs, and how it synthesized the final answer.

If you set the LANGSMITH_TRACING=true environment variable during setup, your agent is already logging traces. Open smith.langchain.com to see them.

What to Look for in a Trace

  • Tool selection errors: The agent called the wrong tool, or called a tool when it should have answered directly. Fix: improve the tool description or add examples to the system prompt.
  • Infinite loops: The agent keeps calling the same tool with the same input. Fix: set max_iterations on your agent or add a conditional edge in LangGraph that forces termination.
  • Token budget overruns: Multi-step reasoning consumed more tokens than expected. Fix: use context compression or reduce the number of messages passed to each step.
  • Hallucinated tool names: The agent tried to call a tool that does not exist. Fix: ensure all tools are properly registered and their names match what the model expects.

Every LangSmith deployment also exposes an MCP endpoint automatically, which means you can connect other tools and agents to your deployed agent using the Model Context Protocol.

Security reminder: Always sandbox code execution. Never let an agent run arbitrary code on your host machine. Use LangSmith Sandboxes, Daytona, Modal, or Runloop for production code execution. Apply least-privilege principles to every tool: give agents only the permissions they need, nothing more.


Next Steps

You now have a working LangChain agent with tool calling, conversation memory, and observability tracing. Here is where to go from here:

  • Add retrieval-augmented generation (RAG): Connect a vector store (Chroma, Pinecone, pgvector) so your agent can search your own documents before answering.
  • Build multi-agent workflows: Use LangGraph to create graphs where specialized agents hand off tasks to each other. A research agent finds information, an analysis agent evaluates it, and a writing agent produces the final output.
  • Deploy with LangServe: Wrap your agent in a REST API using LangServe, which gives you streaming, batch endpoints, and a playground UI out of the box.
  • Add guardrails: Implement input validation to reject prompt injection attempts. Add output validation to ensure your agent never returns sensitive information or harmful content.
  • Set up evaluation: Use LangSmith's evaluation framework to create test datasets and automatically score your agent's responses against expected outputs.
Token Costs Scale with Complexity
Multi-step agent reasoning can use 2 to 5 times more tokens than a single LLM call. Each tool invocation requires a round trip. Monitor costs in LangSmith and set token budgets for production agents.
Nondeterministic Behavior
Agents can produce different outputs for the same input. This is inherent to LLM-based reasoning. Use evaluation datasets and LangSmith tracing to catch regressions before they reach users.
Security: Never Run Unsandboxed Code
Agents with code execution capabilities must run in sandboxed environments. An agent that can execute arbitrary Python on your host machine is a severe security vulnerability. Use dedicated sandbox backends for production deployments.

Troubleshooting

Run pip install langchain-openai in your virtual environment. If you are using uv, run uv pip install langchain-openai. Make sure your virtual environment is activated before running pip.
Set recursion_limit when compiling your LangGraph agent: app = graph.compile(checkpointer=memory) and pass {"recursion_limit": 25} in the config. Also check that your tool descriptions clearly state when the tool should NOT be called.
Verify your .env file contains OPENAI_API_KEY=sk-... and that you call load_dotenv() at the top of your script before initializing any LangChain components. Check that the key starts with sk- and has not expired in your OpenAI dashboard.
Confirm three environment variables are set: LANGSMITH_TRACING=true, LANGSMITH_API_KEY=lsv2-..., and optionally LANGSMITH_PROJECT=your-project-name. Traces can take 10 to 30 seconds to appear in the LangSmith UI. If using a firewall or VPN, ensure outbound HTTPS to smith.langchain.com is allowed.
Make sure you pass the same thread_id in the config for both invocations: {"configurable": {"thread_id": "session-001"}}. If the thread_id changes between calls, LangGraph treats them as separate conversations. Also verify that you passed a checkpointer to create_react_agent() or graph.compile().

Verified against LangChain official documentation, May 2026
LangChain and LangGraph are trademarks of LangChain, Inc. LangSmith is a product of LangChain, Inc. This article is an independent editorial resource by Tech Jacks Solutions. Not affiliated with or endorsed by LangChain, Inc.
Before You Use AI
Your Privacy
LangChain agents send prompts and data to whichever LLM provider you configure (OpenAI, Anthropic, Google, etc.). Free-tier API keys may allow providers to use your data for model training. Enterprise API plans typically include data processing agreements that restrict training use. Review each provider's data use policy before processing sensitive information through agent workflows.
Mental Health & AI Dependency
AI agents can produce outputs that feel authoritative but may contain hallucinated facts, fabricated sources, or incorrect analysis. Over-reliance on AI-generated research without human verification introduces real risk in professional and personal decisions. If you are experiencing distress:
  • 988 Suicide & Crisis Lifeline: Call or text 988
  • SAMHSA Helpline: 1-800-662-4357
  • Crisis Text Line: Text HOME to 741741
AI systems can produce plausible-sounding but incorrect guidance. For mental health, medical, legal, or financial decisions, always consult a qualified professional.
Your Rights & Our Transparency
Under GDPR and CCPA, you have the right to access, correct, and delete your personal data held by AI service providers. Tech Jacks Solutions maintains editorial independence from all vendors reviewed on this site. Some links may be affiliate links, which help fund independent research at no extra cost to you. The EU AI Act classifies AI agent systems according to their intended use and risk level.