{"slug": "langchain-essentials-the-only-things-you-need-before-langgraph", "title": "LangChain Essentials — The Only Things You Need Before LangGraph", "summary": "A developer outlines the minimal LangChain concepts needed before learning LangGraph, focusing on LLM setup, prompt templates with LCEL, structured output via Pydantic, and tool calling. The guide demonstrates using ChatOpenAI with Groq for free inference and emphasizes that LangGraph automates the tool-calling loop.", "body_md": "Note:This article was written in July 2026 using LangChain 0.3.x. APIs may change in future versions — check the[LangChain docs]if something doesn't work.\n\nWhen I started learning LangChain, I got overwhelmed. There are chains, agents, memory, retrievers, output parsers — dozens of abstractions. Then I realized: **most of them are deprecated.**\n\nLangGraph (by the same team) has replaced the orchestration layer. But you still need LangChain's core building blocks inside LangGraph nodes. So I figured out the **minimum** you actually need to learn.\n\nHere's everything, in one file.\n\n| # | Topic | Why It Matters for LangGraph |\n|---|---|---|\n| 1 | LLM Setup | You need to talk to a model |\n| 2 | Prompt Templates + LCEL | The LCEL pipe syntax carries over |\n| 3 | Structured Output | Pydantic models replace the old output parsers |\n| 4 | Tool Calling |\nThis is the big one — LangGraph agents are built around the tool-calling loop |\n\nLet's walk through each one.\n\n``` python\nfrom langchain_openai import ChatOpenAI\n\nllm = ChatOpenAI(\n    model=\"llama-3.3-70b-versatile\",\n    temperature=0.0,\n    api_key=os.environ[\"GROQ_API_KEY\"],\n    base_url=\"https://api.groq.com/openai/v1\",\n)\n```\n\n`ChatOpenAI`\n\nworks with any OpenAI-compatible API. Here I'm using Groq for free, fast inference with Llama 3.3.\n\n``` python\nfrom langchain_core.prompts import ChatPromptTemplate\n\ntemplate_string = \"\"\"Translate the text that is delimited by triple backticks \\\ninto a style that is {style}.\ntext: ```\n\n{text}\n```\n\n\"\"\"\n\nprompt_template = ChatPromptTemplate.from_template(template_string)\n\nchain = prompt_template | llm\n\nresponse = chain.invoke({\"style\": \"formal English\", \"text\": \"yo what's up\"})```\n\nThe pipe (`|`\n\n) syntax is called **LCEL** (LangChain Expression Language). It replaces the old `LLMChain`\n\n, `SequentialChain`\n\n, etc. Simple and composable.\n\nThe old way required `ResponseSchema`\n\n, `StructuredOutputParser`\n\n, and injecting format instructions into your prompt. The new way is just Pydantic:\n\n``` python\nfrom pydantic import BaseModel, Field\n\nclass ReviewInfo(BaseModel):\n    \"\"\"Information extracted from a product review.\"\"\"\n    gift: bool = Field(description=\"Was the item purchased as a gift?\")\n    delivery_days: int = Field(description=\"How many days to arrive? -1 if unknown.\")\n    price_value: list[str] = Field(description=\"Sentences about value or price.\")\n\nstructured_llm = llm.with_structured_output(ReviewInfo, method=\"function_calling\")\nresult = (prompt | structured_llm).invoke({\"text\": review})\n\nprint(result.gift)           # True  (a real bool, not the string \"true\")\nprint(result.delivery_days)  # 2     (a real int)\n```\n\nWho does what:\n\n| Step | Who |\n|---|---|\n| Converting Pydantic → JSON schema | LangChain |\n| Understanding schema & producing JSON | The LLM |\n| Parsing JSON back into Pydantic obj | LangChain |\n\nNo more format instructions in your prompt. The LLM never sees \"return JSON\" — it uses function calling under the hood.\n\nThis is what LangGraph automates. Understanding it manually first makes LangGraph click instantly.\n\n**Define tools** — just Python functions with the `@tool`\n\ndecorator:\n\n``` python\nfrom langchain_core.tools import tool\n\n@tool\ndef get_current_weather(city: str) -> str:\n    \"\"\"Get the current weather for a given city.\"\"\"\n    return {\"berlin\": \"17°C, cloudy\"}.get(city.lower(), \"No data\")\n\n@tool\ndef get_population(city: str) -> int:\n    \"\"\"Get the approximate population of a city.\"\"\"\n    return {\"berlin\": 3_700_000}.get(city.lower(), -1)\n```\n\nThe `@tool`\n\ndecorator transforms these into `BaseTool`\n\nobjects. The docstring becomes the description the LLM reads to decide when to call it.\n\n**Bind tools and call:**\n\n```\ntools = [get_current_weather, get_population]\nllm_with_tools = llm.bind_tools(tools)\n\nmessages = [HumanMessage(\"What's the weather and population in Berlin?\")]\nai_response = llm_with_tools.invoke(messages)\n\nprint(ai_response.tool_calls)\n# [{\"name\": \"get_current_weather\", \"args\": {\"city\": \"Berlin\"}, \"id\": \"...\"},\n#  {\"name\": \"get_population\", \"args\": {\"city\": \"Berlin\"}, \"id\": \"...\"}]\n```\n\nThe LLM **does not execute** the tools. It returns a structured request asking *you* to run them.\n\n**Execute tools and send results back:**\n\n```\ntool_map = {t.name: t for t in tools}\n\nmessages.append(ai_response)\nfor tc in ai_response.tool_calls:\n    result = tool_map[tc[\"name\"]].invoke(tc[\"args\"])\n    messages.append(ToolMessage(content=str(result), tool_call_id=tc[\"id\"]))\n\nfinal_response = llm_with_tools.invoke(messages)\nprint(final_response.content)\n# \"The weather in Berlin is 17°C and cloudy, with a population of 3.7 million.\"\n```\n\nThis loop — **LLM decides → you execute → send result back → repeat** — is exactly what LangGraph's `ToolNode`\n\nautomates.\n\nIf you're heading to LangGraph, **don't bother learning** these legacy LangChain abstractions:\n\n`LLMChain`\n\n→ replaced by LCEL (`prompt | llm`\n\n)`SequentialChain`\n\n→ replaced by LCEL pipes`RouterChain`\n\n→ replaced by LangGraph branching`ConversationChain`\n\n→ replaced by LangGraph state`AgentExecutor`\n\n→ replaced by LangGraph agent loopLangGraph is **not** a replacement for LangChain — it builds on top of it:\n\nLangGraph came in early 2024 because LangChain's original agent/chain abstractions were too rigid — hard to customize, no support for cycles or branching, and memory was bolted on rather than built in.\n\nThe entire thing is one file: **github.com/santanu2908/langchain-essentials**\n\n```\ngit clone https://github.com/santanu2908/langchain-essentials.git\ncd langchain-essentials\nuv sync\n# add your GROQ_API_KEY to .env\nuv run main.py\n```\n\n*Next up: LangGraph. If this helped you, follow along — I'll be sharing that journey too.*\n\nI'm **Santanu Mohanta** — connect with me on [LinkedIn](https://www.linkedin.com/in/santanu29/) or check out my projects on [GitHub](https://github.com/santanu2908).", "url": "https://wpnews.pro/news/langchain-essentials-the-only-things-you-need-before-langgraph", "canonical_source": "https://dev.to/santanu_mohanta_29/langchain-essentials-the-only-things-you-need-before-langgraph-4ci8", "published_at": "2026-07-31 20:03:09+00:00", "updated_at": "2026-07-31 20:43:41.147602+00:00", "lang": "en", "topics": ["large-language-models", "developer-tools", "ai-agents"], "entities": ["LangChain", "LangGraph", "Groq", "Llama 3.3", "Pydantic", "ChatOpenAI"], "alternates": {"html": "https://wpnews.pro/news/langchain-essentials-the-only-things-you-need-before-langgraph", "markdown": "https://wpnews.pro/news/langchain-essentials-the-only-things-you-need-before-langgraph.md", "text": "https://wpnews.pro/news/langchain-essentials-the-only-things-you-need-before-langgraph.txt", "jsonld": "https://wpnews.pro/news/langchain-essentials-the-only-things-you-need-before-langgraph.jsonld"}}