<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Priyansh Singhal</title>
    <description>The latest articles on DEV Community by Priyansh Singhal (@priyansh_singhal_5975e7d3).</description>
    <link>https://dev.to/priyansh_singhal_5975e7d3</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4124032%2Fed3aefc8-e71b-4c63-aaeb-68084cfc8d0b.jpg</url>
      <title>DEV Community: Priyansh Singhal</title>
      <link>https://dev.to/priyansh_singhal_5975e7d3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/priyansh_singhal_5975e7d3"/>
    <language>en</language>
    <item>
      <title>The LangChain You Learned in 2024 Doesn't Exist Anymore</title>
      <dc:creator>Priyansh Singhal</dc:creator>
      <pubDate>Wed, 23 Sep 2026 09:23:46 +0000</pubDate>
      <link>https://dev.to/priyansh_singhal_5975e7d3/the-langchain-you-learned-in-2024-doesnt-exist-anymore-2p95</link>
      <guid>https://dev.to/priyansh_singhal_5975e7d3/the-langchain-you-learned-in-2024-doesnt-exist-anymore-2p95</guid>
      <description>&lt;p&gt;&lt;em&gt;LLMChain and its siblings moved to a legacy package. The new core is one function, create_agent, plus middleware.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Open a LangChain tutorial from 2024, follow it against a fresh install, and the imports fail before you write any logic. &lt;code&gt;LLMChain&lt;/code&gt; is not in the main package anymore. Neither is &lt;code&gt;initialize_agent&lt;/code&gt;, nor most of the chain zoo that tutorials spent two years teaching. That is not deprecation drift. It was a deliberate rebuild: in October 2025 LangChain shipped 1.0 and cut the framework down to what its team calls essential abstractions, moving everything else into a separate legacy package.&lt;/p&gt;

&lt;p&gt;I hit this wall while working through the agentic AI stage of my own learning roadmap, with a browser full of tutorials describing a library that no longer matches what pip installs. This article is the map I wanted that week: what actually changed, what the new core looks like, and how to read older material without getting burned.&lt;/p&gt;

&lt;h2&gt;
  
  
  What 1.0 actually changed
&lt;/h2&gt;

&lt;p&gt;LangChain 1.0 went generally available on October 22, 2025, alongside LangGraph 1.0. Two changes matter more than the version number.&lt;/p&gt;

&lt;p&gt;First, the scope cut. The main &lt;code&gt;langchain&lt;/code&gt; package no longer tries to be a warehouse of every chain pattern from the last three years. It focuses on agents, models, messages, and tools. Everything legacy, including &lt;code&gt;LLMChain&lt;/code&gt; and the old pre-built chains, moved to a package literally named &lt;code&gt;langchain-classic&lt;/code&gt; (&lt;code&gt;@langchain/classic&lt;/code&gt; in JavaScript). Old code did not stop existing, it changed address. In current code the old import reads &lt;code&gt;from langchain_classic.chains import LLMChain&lt;/code&gt;, and that rename is doing honest work: the framework is telling you this is the museum wing.&lt;/p&gt;

&lt;p&gt;Second, a stability promise. 1.0 commits to no breaking changes until 2.0. That sounds boring, but for a library famous for breaking tutorials every few months it is arguably the biggest feature in the release. What you learn on the 1.x core should keep compiling for a while.&lt;/p&gt;

&lt;p&gt;The reason for the cut is visible in what survived. Chains were LangChain's answer to a 2023 question: how do I glue prompts together? The 2026 question is different, how do I run a model in a loop with tools, safely. Agents won, and the package now says so.&lt;/p&gt;

&lt;h2&gt;
  
  
  The new core is one function
&lt;/h2&gt;

&lt;p&gt;Here is a complete working agent on the current API, straight from the quickstart shape in the docs. One prerequisite the snippet itself won't remind you of: export the API key for whichever provider you're calling first (&lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;, &lt;code&gt;OPENAI_API_KEY&lt;/code&gt;, and so on), or the agent has nothing to authenticate with.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_agent&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Get weather for a given city.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;It&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s always sunny in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic:claude-sonnet-4-6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a helpful assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s the weather in San Francisco?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;content_blocks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;create_agent&lt;/code&gt; is the whole story. You hand it a model, a list of plain Python functions as tools, and a system prompt. The model argument is a provider-prefixed string (&lt;code&gt;"anthropic:claude-sonnet-4-6"&lt;/code&gt;, &lt;code&gt;"openai:gpt-5.5"&lt;/code&gt;, or any &lt;code&gt;"ollama:"&lt;/code&gt; model tag), which makes trying your agent against a local model a one-line experiment. At runtime it loops: the model reads the messages and either emits tool calls or a final answer. Tool calls get executed, their results are appended to the message list as tool messages, and the model runs again. A response with no tool calls ends the loop.&lt;/p&gt;

&lt;p&gt;Two details worth knowing before you build anything real. This function replaces &lt;code&gt;create_react_agent&lt;/code&gt; from LangGraph, which is now deprecated, so treat any tutorial teaching that name as pre-1.0. And it runs on the LangGraph runtime underneath, which matters later. Note also &lt;code&gt;content_blocks&lt;/code&gt; on the final message: 1.0's standardized way to read reasoning traces, citations, and tool calls in one consistent shape across providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Middleware is the actual headline
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;create_agent&lt;/code&gt; got the announcement-post attention. The part I think matters more day to day is middleware, which the docs describe as hooks that let you customize behavior at every step of the agent loop.&lt;/p&gt;

&lt;p&gt;Before 1.0, controlling the middle of an agent's execution meant callback handlers, subclassing, or forking a prebuilt graph. Most tutorials just skipped the problem. Now there are three obvious seams, named for exactly where they cut in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@before_model&lt;/code&gt; runs before each model call. This is where you trim context or enforce a call budget. The docs' own example counts model calls in state and jumps to the end past a limit, which is a real runaway-agent guard in about ten lines.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@after_model&lt;/code&gt; runs after each model response, before anything acts on it. Output validation and redaction live here.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@wrap_tool_call&lt;/code&gt; wraps each tool execution like an HTTP middleware wraps a request. You get the request, you own calling the handler, you can log, retry, or replace the result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are also built-ins for the three things everyone eventually hand-rolls: human-in-the-loop approval for dangerous tools, PII redaction, and conversation summarization. The human-in-the-loop one is configured per tool, so &lt;code&gt;HumanInTheLoopMiddleware(interrupt_on={"send_email": True})&lt;/code&gt; pauses the loop for approval before that one tool fires while every read-only tool runs untouched. One catch before you demo it: the pause is a LangGraph interrupt underneath, so the middleware line alone does not give you a working approval flow. You also need a checkpointer attached to the agent (&lt;code&gt;InMemorySaver&lt;/code&gt; for local work, something persistent in production) and a thread ID passed with every invoke, and resuming means calling the agent again with a &lt;code&gt;Command&lt;/code&gt; carrying the decision. Three extra lines, but the docs only make this clear once you are deep in the human-in-the-loop page, and every demo that skips them dies at the first pause. The summarization one is configured with a token threshold and a keep-last-N-messages count, and it quietly solves the failure mode where a long-running agent drowns in its own history. That used to be a weekend of custom code. My honest read: if you evaluate LangChain 1.0 by &lt;code&gt;create_agent&lt;/code&gt; alone it looks like a nicer constructor, and the middleware system is the actual argument for using the framework instead of writing the loop yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to read old tutorials without getting burned
&lt;/h2&gt;

&lt;p&gt;A practical triage, since most LangChain material online is still pre-1.0:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Date the code, not the post.&lt;/strong&gt; Anything showing &lt;code&gt;LLMChain&lt;/code&gt;, &lt;code&gt;initialize_agent&lt;/code&gt;, or &lt;code&gt;create_react_agent&lt;/code&gt; predates October 2025 in spirit, whatever its publish date says. The concepts often still transfer. The imports will not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Treat &lt;code&gt;langchain-classic&lt;/code&gt; as an escape hatch, not a destination.&lt;/strong&gt; It exists so working systems keep running, and if you maintain one, updating an import path beats a rewrite. I would not point new code at it. You would be learning the museum wing while the actual exhibit is one function with clean seams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expect some patterns to have moved into the loop.&lt;/strong&gt; Structured output is the clearest example: it now happens inside the main agent loop rather than as a separate follow-up LLM call, which is one less round trip and one less place to disagree with your own schema. If a tutorial bolts an output parser onto the end of a chain, that is the old world showing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where LangChain ends and LangGraph begins
&lt;/h2&gt;

&lt;p&gt;The framework's own framing is that you start with LangChain's high-level API and drop down to LangGraph when you need more control. In practice the boundary is shape: one model looping over tools is &lt;code&gt;create_agent&lt;/code&gt; territory, even with heavy middleware. The moment you need multiple agents, branching workflows, or explicit state machines, you are describing a graph, and pretending otherwise just means building a graph badly out of middleware.&lt;/p&gt;

&lt;p&gt;The two worlds compose rather than compete. An agent built with &lt;code&gt;create_agent&lt;/code&gt; can be added as a single node inside a LangGraph &lt;code&gt;StateGraph&lt;/code&gt;, middleware and all, so graduating to a graph does not mean rewriting the agent you already have. You wire it in next to your routing and classification nodes and it keeps behaving exactly as it did standalone.&lt;/p&gt;

&lt;p&gt;Which suggests a learning order I wish more roadmaps made explicit. Learn the loop first, then middleware, and only then LangGraph. Every graph node you will ever write is easier to reason about once you can explain what one agent loop does, because underneath, that is what is running.&lt;/p&gt;

&lt;p&gt;If you are working through this stage yourself and want to talk through any of it live, I keep a slot open on &lt;a href="https://topmate.io/priyansh_singhal10" rel="noopener noreferrer"&gt;Topmate&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;More from me: the full roadmap this article is part of is at &lt;a href="https://notes.priyanshsinghal.com" rel="noopener noreferrer"&gt;notes.priyanshsinghal.com&lt;/a&gt;, and I post shorter breakdowns of what I'm learning on &lt;a href="https://linkedin.com/in/priyanshsinghal" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>langchain</category>
      <category>ai</category>
      <category>python</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
