<?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: Rushank Savant</title>
    <description>The latest articles on DEV Community by Rushank Savant (@rushanksavant).</description>
    <link>https://dev.to/rushanksavant</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F849972%2F166490e0-ca17-4eae-9854-5801fb8c39b4.PNG</url>
      <title>DEV Community: Rushank Savant</title>
      <link>https://dev.to/rushanksavant</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rushanksavant"/>
    <language>en</language>
    <item>
      <title>Beyond Keywords: Mastering HyDE for Smarter Retrieval 🧠</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Sun, 10 May 2026 17:18:01 +0000</pubDate>
      <link>https://dev.to/rushanksavant/beyond-keywords-mastering-hyde-for-smarter-retrieval-3p5c</link>
      <guid>https://dev.to/rushanksavant/beyond-keywords-mastering-hyde-for-smarter-retrieval-3p5c</guid>
      <description>&lt;p&gt;If you’ve ever built a &lt;strong&gt;RAG&lt;/strong&gt; system, you’ve likely felt the frustration of the "Mismatch Problem". You ask a perfectly reasonable question, but it returns completely irrelevant documents.&lt;/p&gt;

&lt;p&gt;Why? Because your retrieval method is searching based upon your &lt;strong&gt;question's language&lt;/strong&gt;. In the vector world, these two things often don't look alike. &lt;br&gt;
&lt;strong&gt;Eg:&lt;/strong&gt; Users asking questions to retrieve context from a technical documentation (like company's legal policies)&lt;/p&gt;

&lt;p&gt;Today, we’re going to master &lt;strong&gt;HyDE (Hypothetical Document Embedding)&lt;/strong&gt;—a technique that flips the script by &lt;u&gt;"hallucinating"&lt;/u&gt; the answer before it even touches your database.&lt;/p&gt;




&lt;h2&gt;
  
  
  📝 What is HyDE?
&lt;/h2&gt;

&lt;p&gt;Instead of taking a user's question and searching for it directly, HyDE follows a three-step dance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Hallucination:&lt;/strong&gt; It asks an LLM to write a "fake" or &lt;strong&gt;hypothetical&lt;/strong&gt; answer to the user's question in document friendly language (using few-shot prompting).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Embedding:&lt;/strong&gt; It converts that "fake" answer into a vector.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Retrieval:&lt;/strong&gt; It searches your database for &lt;strong&gt;real&lt;/strong&gt; documents that look like that fake answer.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🧩 The Problem It Solves: Asymmetric Retrieval
&lt;/h2&gt;

&lt;p&gt;In standard search, we assume &lt;code&gt;vector(Question) ~ approx vector(Answer)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But in reality, questions are short, curious, and often informal. &lt;br&gt;
Answers are long, factual, and professional. &lt;br&gt;
This is &lt;strong&gt;Asymmetric Retrieval&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;HyDE turns an Asymmetric problem into a Symmetric one by making the query "look" like the data it’s trying to find.&lt;/p&gt;




&lt;h2&gt;
  
  
  📍 A Real-World Example: The Legal "Needle"
&lt;/h2&gt;

&lt;p&gt;Imagine you are building a RAG for a law firm. A junior associate asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"What happens if a rival company takes over the vendor?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; The 5,000-page contract in your database doesn't use the word &lt;u&gt;"rival"&lt;/u&gt; or &lt;u&gt;"takes over"&lt;/u&gt;. It uses professional jargon like &lt;u&gt;"Change of Control Event"&lt;/u&gt;.&lt;/p&gt;

&lt;p&gt;A standard search might fail because these two vectors aren't close enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  💡 The HyDE Solution:
&lt;/h3&gt;

&lt;p&gt;The LLM generates a "fake" clause: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"In the event of a Change of Control to a Restricted Entity, the Successor shall..."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system searches for that text.&lt;/p&gt;

&lt;p&gt;It immediately finds the correct legal page because the "fake" answer and the "real" document speak the &lt;strong&gt;same language&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Practical Implementation (The "Professional" Way)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chat_models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;init_chat_model&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_huggingface&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HuggingFaceEndpointEmbeddings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.vectorstores&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;
&lt;span class="c1"&gt;# from langchain_classic.chains import HypotheticalDocumentEmbedder ## Not widely used, since custom functions give more flexibility
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FewShotPromptTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.documents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;

&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Prompt prep: STYLE EXAMPLES (The "Linguistic DNA")
&lt;/span&gt;&lt;span class="n"&gt;examples&lt;/span&gt; &lt;span class="o"&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;question&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;rival acquisition&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;answer&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;In the event of a Change of Control to a Restricted Entity...&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;question&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;sharing info with others&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;answer&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;Confidential Information shall not be disclosed to any third-party without prior written indemnification...&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;example_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PromptTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;input_variables&lt;/span&gt;&lt;span class="o"&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;question&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;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User: {question}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Legal Style: {answer}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;hyde_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FewShotPromptTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="c1"&gt;## Class provided by langchain for few-shot prompting
&lt;/span&gt;    &lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;example_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;example_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;prefix&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 Legal Architect. Translate the query into formal contractual prose.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User: {question}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Legal Style:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;input_variables&lt;/span&gt;&lt;span class="o"&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;question&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="c1"&gt;# 2. MODELS &amp;amp; HYDE EMBEDDER
&lt;/span&gt;&lt;span class="n"&gt;llm_groq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;init_chat_model&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;openai/gpt-oss-120b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model_provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;groq&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;base_embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HuggingFaceEndpointEmbeddings&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;sentence-transformers/all-MiniLM-L6-v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;## this model returns 384 sized vector
&lt;/span&gt;    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;feature-extraction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# 3. The DUMMY Documents
# We add diverse sections to ensure the retriever can distinguish between them.
&lt;/span&gt;&lt;span class="n"&gt;legal_docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;# THE TARGET: Change of Control
&lt;/span&gt;    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Section 45.1: Control Events. A &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Change of Control&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; occurs if a Restricted Entity acquires 51% of voting shares.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
             &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&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;source&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;Corp_Bylaws.pdf&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;section&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;Governance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="c1"&gt;# THE NOISE: Liability &amp;amp; Indemnity
&lt;/span&gt;    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Section 10.2: Limitation of Liability. Neither party shall be liable for indirect, incidental, or consequential damages.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
             &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&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;source&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;MSA_Main.pdf&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;section&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;Liability&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="c1"&gt;# THE NOISE: IP Rights
&lt;/span&gt;    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Section 5.4: Intellectual Property. All Work Product created during the Term shall be deemed &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Work Made for Hire&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; and owned by the Client.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
             &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&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;source&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;MSA_Main.pdf&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;section&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;IP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="c1"&gt;# THE NOISE: Termination
&lt;/span&gt;    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Section 12.0: Termination for Convenience. Either party may terminate this agreement upon 90 days prior written notice.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
             &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&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;source&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;Vendor_Agmt.pdf&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;section&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;Term&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="c1"&gt;# THE NOISE: Confidentiality
&lt;/span&gt;    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Section 3.1: Non-Disclosure. The Receiver shall protect Confidential Information using the same degree of care as its own proprietary data.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
             &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&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;source&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;NDA_Standard.pdf&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;section&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;Privacy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="c1"&gt;# THE TARGET: Assignment/Successors
&lt;/span&gt;    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Section 8.9: Successors and Assigns. This Agreement shall be binding upon and inure to the benefit of the Parties and their respective permitted successors.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
             &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&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;source&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;Corp_Bylaws.pdf&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;section&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;General&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})]&lt;/span&gt;


&lt;span class="c1"&gt;# 4. INITIALIZE VECTOR STORE
&lt;/span&gt;&lt;span class="n"&gt;vectorstore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;legal_docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base_embeddings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;collection_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;production_legal_vault&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 


&lt;span class="c1"&gt;# 5. TEST THE RETRIEVAL
# Note: The query is vague and uses 0 keywords from the docs.
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hyde_retrieval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="c1"&gt;# 1. Generate the Hypothetical Document (The "Fake" Answer)
&lt;/span&gt;    &lt;span class="n"&gt;formatted_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hyde_prompt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;hypothetical_doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm_groq&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="n"&gt;formatted_prompt&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&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;--- HYPOTHETICAL DOC GENERATED ---&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hypothetical_doc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Embed the "Fake" Doc and search the "Real" DB
&lt;/span&gt;    &lt;span class="c1"&gt;# We use base_embeddings here so the 'math' matches the stored data
&lt;/span&gt;    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hypothetical_doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;

&lt;span class="n"&gt;user_query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What about sensitive or important data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s protection?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;final_docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;hyde_retrieval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_query&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--- FINAL REAL DOCUMENT FOUND ---&lt;/span&gt;&lt;span class="sh"&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Source: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;final_docs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Actual Text: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;final_docs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⌚ When to Use HyDE (and When to Skip It)
&lt;/h2&gt;

&lt;h4&gt;
  
  
  ✅ Use it when:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Queries are vague or short:&lt;/strong&gt; If users type "refund" and your docs say "reimbursement protocols," HyDE will bridge that gap.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Terminology Mismatch:&lt;/strong&gt; Your users are "laymen" and your docs are "experts" (Medical, Legal, Engineering).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High-Stakes Accuracy:&lt;/strong&gt; When finding the right page is more important than saving a few pennies on API costs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ❌ Skip it when:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Factual/Number Lookups:&lt;/strong&gt; If a user asks "What was the revenue in 2023?", the LLM might hallucinate a fake number in the hypothetical doc, leading the search to the wrong year.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Latency is Critical:&lt;/strong&gt; HyDE requires an extra LLM call, which adds 1–2 seconds of "thinking time."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tight Budgets:&lt;/strong&gt; Every search now costs extra LLM tokens.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Summary: Pros &amp;amp; Cons
&lt;/h2&gt;

&lt;h4&gt;
  
  
  👍 Pros:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Superior Context:&lt;/strong&gt; Maps informal intent to formal data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero Keyword Dependence:&lt;/strong&gt; You don't need exact word matches.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalable:&lt;/strong&gt; Works across thousands of pages without manual tagging.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  👎 Cons:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Latency:&lt;/strong&gt; Adds an extra step to the search process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hallucination Risk:&lt;/strong&gt; A "too-fake" answer can derail the search.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost:&lt;/strong&gt; Increased token usage per query.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Happy coding! Have you tried HyDE in your projects? Let’s discuss in the comments below! 👇&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>rag</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Day 14: Deployment &amp; LangSmith</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Sat, 09 May 2026 18:53:01 +0000</pubDate>
      <link>https://dev.to/rushanksavant/day-14-deployment-langsmith-7k8</link>
      <guid>https://dev.to/rushanksavant/day-14-deployment-langsmith-7k8</guid>
      <description>&lt;p&gt;When your LangGraph agent runs, a lot happens under the hood. If it gives a wrong answer, you need to know: Was it a bad retrieval? Did the tool fail? Or did the LLM just misinterpret the data?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LangSmith&lt;/strong&gt; allows you to trace every single step.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tracing:&lt;/strong&gt; See the exact prompt sent and the raw JSON returned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Latency:&lt;/strong&gt; Find out which node is slowing down your app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost:&lt;/strong&gt; Track exactly how many tokens that "loop" consumed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; Simply setting two environment variables in your &lt;code&gt;.env&lt;/code&gt; file enables tracing automatically. No code changes required!&lt;/p&gt;




&lt;h2&gt;
  
  
  🌐 2. LangServe: Turning Code into an API
&lt;/h2&gt;

&lt;p&gt;You can't give your users a Python script. You need a &lt;strong&gt;REST API&lt;/strong&gt;.&lt;br&gt;
&lt;strong&gt;LangServe&lt;/strong&gt; helps you deploy your chains and graphs as a professional web service using FastAPI. &lt;br&gt;
It even gives you a built-in "Playground" UI to test your API in the browser.&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;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langserve&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add_routes&lt;/span&gt;
&lt;span class="c1"&gt;# Import your 'graph' from Day 13
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;my_agent&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt; 

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My AI Agent API&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# This creates /invoke, /stream, and /batch endpoints automatically!
&lt;/span&gt;&lt;span class="nf"&gt;add_routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;uvicorn&lt;/span&gt;
    &lt;span class="n"&gt;uvicorn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;localhost&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✅ 3. The Production Checklist
&lt;/h2&gt;

&lt;p&gt;Before you hit "Deploy," ask yourself these three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Does it have a System Prompt?&lt;/strong&gt; Ensure your agent has clear "guardrails" (e.g., "Do not answer political questions").&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Is the Memory capped?&lt;/strong&gt; Use &lt;code&gt;WindowMemory&lt;/code&gt; or &lt;code&gt;SummaryMemory&lt;/code&gt; so your database doesn't explode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Are the Tools safe?&lt;/strong&gt; If your tool can delete data, make sure there is a "human-in-the-loop" check.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🎓 Graduation: Where to go from here?
&lt;/h2&gt;

&lt;p&gt;Two weeks ago, LangChain was a mystery. Now, it’s a tool in your belt. The field of AI moves fast, but the fundamentals you learned—&lt;strong&gt;Prompts, Models, Parsers, RAG, and Graphs&lt;/strong&gt;—are the pillars of the industry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your Final Challenge:&lt;/strong&gt; Take everything you’ve built over the last 14 days and combine it. Build a "Personal Study Assistant" that can read your local PDFs (RAG), search the web (Tools), and remember your name (Memory).&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Day 14 Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LangSmith:&lt;/strong&gt; For debugging and tracing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LangServe:&lt;/strong&gt; For deploying as an API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Evaluations:&lt;/strong&gt; Testing your agent against "Golden Sets" of data to ensure it stays smart.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It has been an incredible journey. Keep building, keep breaking things, and most importantly, keep sharing your progress.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The future is agentic. And you’re ready for it.&lt;/strong&gt; ☕&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langchain</category>
      <category>langsmith</category>
      <category>langserver</category>
    </item>
    <item>
      <title>Small-to-Big RAG: Your AI Needs a Better Context 🧠</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Sat, 09 May 2026 09:55:18 +0000</pubDate>
      <link>https://dev.to/rushanksavant/small-to-big-rag-your-ai-needs-a-better-context-4cp1</link>
      <guid>https://dev.to/rushanksavant/small-to-big-rag-your-ai-needs-a-better-context-4cp1</guid>
      <description>&lt;p&gt;If your text chunks are too small, the AI misses the context. If they are too big, the search becomes "blurry" and inaccurate. To solve this, advanced developers use &lt;strong&gt;Small-to-Big Retrieval&lt;/strong&gt;. Two popular flavors are &lt;strong&gt;Sentence Window&lt;/strong&gt; and &lt;strong&gt;Parent Document Retrieval&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is the breakdown of how they work and which one you should choose.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤝 The Shared Secret: "Search Small, Read Big"
&lt;/h2&gt;

&lt;p&gt;Both techniques follow one rule: Search using a tiny, precise snippet, but give the LLM a large, context-rich block of text to read. It’s like searching a library index for a "keyword" but then pulling the whole "book" off the shelf to get the full story.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 1. Sentence Window Retrieval: The "Magnifying Glass"
&lt;/h2&gt;

&lt;p&gt;Imagine you are reading a novel. To understand a specific line of dialogue, you usually just need to know what happened a few seconds before and after.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; You break your data into individual sentences. When the AI finds a relevant sentence, it automatically grabs the 3–5 sentences immediately surrounding it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Vibe:&lt;/strong&gt; Linear and local.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Narrative text, chat transcripts, or articles where ideas flow sentence-by-sentence.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🗺️ 2. Parent Document Retrieval: The "Map"
&lt;/h2&gt;

&lt;p&gt;Imagine a Technical Manual or a Legal Contract. A single sentence like "Tighten the bolt" is useless if the safety warning is at the top of the page. You don't just need the "neighboring sentences"; you need the &lt;strong&gt;whole section&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; You create a hierarchy. You have &lt;strong&gt;Parent chunks&lt;/strong&gt; (like a full page) and &lt;strong&gt;Child chunks&lt;/strong&gt; (small paragraphs inside that page). The AI searches the "Children" but returns the "Parent" to the LLM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Vibe:&lt;/strong&gt; Structural and organized.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; PDFs, manuals, financial reports, and legal docs where sections are logically grouped.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Comparison Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Sentence Window&lt;/th&gt;
&lt;th&gt;Parent Document&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Logic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Show me what’s around this."&lt;/td&gt;
&lt;td&gt;"Show me the section this belongs to."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Structure&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Flat/Linear&lt;/td&gt;
&lt;td&gt;Hierarchical (Big &amp;amp; Small)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Context is often hidden in metadata.&lt;/td&gt;
&lt;td&gt;Parents are stored in a separate database.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best Use Case&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Books, Emails, Conversations.&lt;/td&gt;
&lt;td&gt;Technical Specs, Legal, Wiki pages.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🚀 Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Choose Sentence Window&lt;/strong&gt; if your data is "unstructured" and the context is always right next to the answer. It’s easier to set up and works great for simple Q&amp;amp;A.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose Parent Document&lt;/strong&gt; if you are building an Enterprise-grade tool. It is more "stable" because it respects document boundaries (like chapters or headers), ensuring the LLM never gets a half-finished thought from a different page.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>langchain</category>
      <category>python</category>
    </item>
    <item>
      <title>Day 13: The Self-Correcting Agent — Building Loops with LangGraph 🔄</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Fri, 08 May 2026 17:39:23 +0000</pubDate>
      <link>https://dev.to/rushanksavant/day-13-the-self-correcting-agent-building-loops-with-langgraph-l4i</link>
      <guid>https://dev.to/rushanksavant/day-13-the-self-correcting-agent-building-loops-with-langgraph-l4i</guid>
      <description>&lt;p&gt;Yesterday, we learned that &lt;strong&gt;LangGraph&lt;/strong&gt; is all about nodes and edges. Today, we’re putting that into practice by building a &lt;strong&gt;Stateful Agent&lt;/strong&gt; that can actually "think," use a tool, and then decide if it needs to do more.&lt;/p&gt;

&lt;p&gt;In the old way (Chains), if a tool returned an error, the app crashed. In the LangGraph way, we create a loop where the agent sees the error and tries a different approach.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 The Agentic Loop: Thought → Action → Observation
&lt;/h2&gt;

&lt;p&gt;To build this, we need a graph that doesn't just go in a straight line. We need it to circle back.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Agent Node:&lt;/strong&gt; The LLM decides what to do.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools Node:&lt;/strong&gt; If the LLM wants to use a tool, this node executes it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Loop:&lt;/strong&gt; The result of the tool goes back to the Agent so it can "observe" the result and decide if it's done.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🛠️ Coding the Loop
&lt;/h2&gt;

&lt;p&gt;We'll use the &lt;code&gt;ToolNode&lt;/code&gt;—a pre-built helper from LangGraph—to make this easy.&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;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph.message&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add_messages&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.prebuilt&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ToolNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools_condition&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.tools.tavily_search&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TavilySearchResults&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Define the State (Our notebook)
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;State&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# add_messages tells LangGraph to append new messages to history
&lt;/span&gt;    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add_messages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Setup Tools and Model
&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="nc"&gt;TavilySearchResults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&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="nc"&gt;ChatOpenAI&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;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Define the Nodes
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chatbot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&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="n"&gt;model&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="n"&gt;state&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="c1"&gt;# 4. Build the Graph
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chatbot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chatbot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# ToolNode automatically executes tool calls found in the messages
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ToolNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# 5. Define the Logic (The "Brain")
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chatbot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Conditional Edge: If the model called a tool, go to 'tools', 
# otherwise, go to 'END'.
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_conditional_edges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chatbot&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_condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Loop back! After using tools, go back to the chatbot to see if it's done
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools&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;chatbot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚡ Why &lt;code&gt;tools_condition&lt;/code&gt; is Magic
&lt;/h2&gt;

&lt;p&gt;This is a built-in "traffic controller." It looks at the last message from the AI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If it contains a &lt;strong&gt;tool_call&lt;/strong&gt;, it sends the flow to the &lt;code&gt;tools&lt;/code&gt; node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If it is a &lt;strong&gt;regular string&lt;/strong&gt;, it realizes the AI is finished and sends it to &lt;code&gt;END&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This prevents the AI from getting stuck in an infinite loop!&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Day 13 Summary
&lt;/h2&gt;

&lt;p&gt;Today, you built a truly autonomous agent. You learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cyclic Graphs:&lt;/strong&gt; How to point an edge back to a previous node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ToolNode:&lt;/strong&gt; Automating the execution of AI-requested actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Conditional Routing:&lt;/strong&gt; Letting the graph decide its own path.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Your Homework:&lt;/strong&gt; Imagine the search tool returns "No results found." Because of the loop we built today, the AI can see that and try a different search query automatically. Try to prompt your agent to find something obscure and watch it work!&lt;/p&gt;

&lt;p&gt;See you tomorrow! ☕&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langgraph</category>
      <category>python</category>
      <category>agents</category>
    </item>
    <item>
      <title>Day 12: Enter LangGraph — Moving from Chains to Cyclic Graphs 🕸️</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Thu, 07 May 2026 17:55:32 +0000</pubDate>
      <link>https://dev.to/rushanksavant/day-12-enter-langgraph-moving-from-chains-to-cyclic-graphs-5ano</link>
      <guid>https://dev.to/rushanksavant/day-12-enter-langgraph-moving-from-chains-to-cyclic-graphs-5ano</guid>
      <description>&lt;p&gt;Today, we leave the world of linear "Chains" and enter the most powerful evolution of the LangChain ecosystem: &lt;strong&gt;LangGraph&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you've been following along, you've noticed that Chains always go forward: &lt;strong&gt;A -&amp;gt; B -&amp;gt; C&lt;/strong&gt;. But real intelligence requires &lt;strong&gt;loops&lt;/strong&gt;. Think about how you work: you write code, you run it, it fails, so you go back and fix it. That's a cycle. LangGraph is designed to let AI agents do exactly that.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔄 Why LangGraph?
&lt;/h2&gt;

&lt;p&gt;Standard LangChain "Chains" are Directed Acyclic Graphs (DAGs). They can't loop.&lt;br&gt;
&lt;strong&gt;LangGraph&lt;/strong&gt; allows for &lt;strong&gt;cycles&lt;/strong&gt;, which are essential for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Self-Correction:&lt;/strong&gt; "I tried to search Google, but got no results. I'll try a different keyword."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-Agent Collaboration:&lt;/strong&gt; "Agent A writes the code, Agent B reviews it and sends it back for edits."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Persistence:&lt;/strong&gt; Saving the state of a conversation so you can pause and resume it days later.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  🏗️ The Core Concepts
&lt;/h2&gt;

&lt;p&gt;To build with LangGraph, you need to understand three things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State:&lt;/strong&gt; A shared "notebook" (usually a Python dictionary) that all parts of your agent can read and write to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nodes:&lt;/strong&gt; Simple Python functions that take the current &lt;code&gt;State&lt;/code&gt;, do some work, and return an update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edges:&lt;/strong&gt; The "roads" between nodes. They decide which node to go to next.&lt;/p&gt;


&lt;h2&gt;
  
  
  🛠️ Building a Basic "Smart Assistant" Graph
&lt;/h2&gt;

&lt;p&gt;Let's build a graph where the AI decides whether to use a tool or just reply.&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;import&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.graph&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Define the State
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# This stores our message history
&lt;/span&gt;    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Define a Node (The Brain)
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&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;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&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="n"&gt;state&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="k"&gt;return&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="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Build the Graph
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Add our node
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Define the flow
&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 4. Compile it
&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Run it!
&lt;/span&gt;&lt;span class="n"&gt;input_state&lt;/span&gt; &lt;span class="o"&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;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;Explain LangGraph in 10 words.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_state&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;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚡ The "Conditional" Edge: The Secret Sauce
&lt;/h2&gt;

&lt;p&gt;The real power comes when you add a &lt;strong&gt;Conditional Edge&lt;/strong&gt;. This is a function that looks at the AI's response and says:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"If the AI wants to use a tool → go to the &lt;strong&gt;Tools Node&lt;/strong&gt;."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"If the AI is finished → go to &lt;strong&gt;END&lt;/strong&gt;."&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates the "Loop" that makes agents truly autonomous.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Day 12 Summary
&lt;/h2&gt;

&lt;p&gt;Today, you caught a glimpse of the "Brain" of modern AI agents. You learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Chains vs. Graphs:&lt;/strong&gt; Why cycles are necessary for complex tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;State Management:&lt;/strong&gt; How agents keep track of their "thoughts."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nodes &amp;amp; Edges:&lt;/strong&gt; The building blocks of an agentic workflow.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Your Homework:&lt;/strong&gt; Look at the code above. How would you add a "Review" node that checks the AI's answer for typos before sending it to the user?&lt;/p&gt;

&lt;p&gt;See you tomorrow! ☕&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langgraph</category>
      <category>langchain</category>
      <category>python</category>
    </item>
    <item>
      <title>Why MCP is the "USB-C" of AI Tools</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Wed, 06 May 2026 17:57:37 +0000</pubDate>
      <link>https://dev.to/rushanksavant/why-mcp-is-the-usb-c-of-ai-tools-2gm3</link>
      <guid>https://dev.to/rushanksavant/why-mcp-is-the-usb-c-of-ai-tools-2gm3</guid>
      <description>&lt;p&gt;If you’ve been building with LangChain or OpenAI Functions, you’re used to defining tools as simple lists: &lt;code&gt;tools = [get_weather, send_email]&lt;/code&gt;. It works great for a weekend project, but what happens when your application grows?&lt;/p&gt;

&lt;p&gt;What if you want your tools to work in Claude Desktop, a custom Python script, and a TypeScript dashboard all at once? What if you need to update a tool's logic without redeploying your entire AI agent?&lt;/p&gt;

&lt;p&gt;That is where the &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; comes in. Think of it as the USB-C of the AI world—a universal standard that lets any AI "host" talk to any "tool" server.&lt;/p&gt;

&lt;p&gt;Here is a simple breakdown of when you should move past simple tools and embrace MCP.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔌 1. The "USB-C" Effect (Standardization)
&lt;/h3&gt;

&lt;p&gt;In a standard setup, your tool is often locked into a specific library (like LangChain). With MCP, your tool lives on a server. Because it follows a universal protocol, the same server can provide tools to a LangChain agent, a Claude Desktop instance, and a custom-built robot simultaneously.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔄 2. Dynamic Tool Discovery
&lt;/h3&gt;

&lt;p&gt;Normally, you must pass a fixed list of tools to your agent. If you want to add a new feature, you have to change the code and reboot the app.&lt;br&gt;
With MCP, the agent "polls" the server. If you add a new tool to the server at 2:00 PM, the agent can see and use it at 2:01 PM without you touching a single line of code in the host application.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✂️ 3. Decoupled Logic and Updates
&lt;/h3&gt;

&lt;p&gt;When your tool logic lives inside the MCP server:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Host Independence:&lt;/strong&gt; If you fix a bug in the tool's math or update an API key, the host application doesn't need to be touched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Language Agnostic:&lt;/strong&gt; You can write a heavy data-processing tool in Rust or Go for performance, while keeping your AI logic in Python.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔒 4. Security and Stability
&lt;/h3&gt;

&lt;p&gt;MCP acts as a protective layer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Firewall:&lt;/strong&gt; You can deploy tools to a remote server and wrap them in a firewall.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blast Radius:&lt;/strong&gt; If a tool has a vulnerability or crashes, it won't take down your main AI application. They are running in separate environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 5. Sharing More Than Just Functions
&lt;/h3&gt;

&lt;p&gt;Standard tools are usually just "functions" (do X, get Y). MCP allows you to share:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt; Live log files, database schemas, or documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompts:&lt;/strong&gt; Pre-written instruction templates that the server provides to the host.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚖️ The One-Line Rule
&lt;/h2&gt;

&lt;p&gt;Use &lt;strong&gt;MCP&lt;/strong&gt; when building an &lt;strong&gt;"Ecosystem"&lt;/strong&gt; that needs to scale, stay secure, and remain flexible.&lt;br&gt;
Use &lt;strong&gt;Standard&lt;/strong&gt; Tools when building a &lt;strong&gt;"Prototype"&lt;/strong&gt; where speed of development is your only priority.&lt;/p&gt;




&lt;h2&gt;
  
  
  💼 Real-World Scenarios
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;✅ Use MCP for: "The Enterprise Data Hub"&lt;/strong&gt;&lt;br&gt;
Imagine building an AI for a bank. The AI needs to check balances, pull credit scores, and generate PDFs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why:&lt;/strong&gt; You want the "Credit Score" team to manage their own tool server. If they change their logic, the AI keeps working. You also need a strict security barrier between the AI and the sensitive financial databases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;❌ Skip MCP for: "The Local PDF Summarizer"&lt;/strong&gt;&lt;br&gt;
Imagine a simple script that reads 5 PDFs on your laptop and extracts names using a regex function.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why:&lt;/strong&gt; Setting up a Client-Server architecture for a single function is massive overkill. A standard &lt;code&gt;@tool&lt;/code&gt; takes two seconds to write and requires zero infrastructure.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📝 Summary
&lt;/h2&gt;

&lt;p&gt;MCP moves us away from "hard-coding" AI capabilities and toward a world where tools are plug-and-play. If you are planning for the future of your app, start thinking in servers, not just lists.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langchain</category>
      <category>mcp</category>
      <category>agents</category>
    </item>
    <item>
      <title>Day 11: Conversational RAG — How to Chat with Your Documents 💬</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Wed, 06 May 2026 15:11:58 +0000</pubDate>
      <link>https://dev.to/rushanksavant/day-11-conversational-rag-how-to-chat-with-your-documents-43nm</link>
      <guid>https://dev.to/rushanksavant/day-11-conversational-rag-how-to-chat-with-your-documents-43nm</guid>
      <description>&lt;p&gt;Yesterday, we built a RAG chain that could answer a single question. But if you followed up with "Can you explain that further?", the AI would get confused. Why? Because it didn't have contextual history.&lt;/p&gt;

&lt;p&gt;Today, we solve the hardest part of RAG: &lt;strong&gt;Conversational Memory&lt;/strong&gt;. We'll teach the AI to understand that "it" or "that" refers to things mentioned earlier in the chat.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ The Problem: The "Query Re-writing" Challenge
&lt;/h2&gt;

&lt;p&gt;If you ask:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"How does LangChain work?"&lt;/li&gt;
&lt;li&gt;"Can you give me an example of it?"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The retriever doesn't know what "it" is. It will literally search your database for the word "it," which is useless.&lt;/p&gt;

&lt;p&gt;To fix this, we add a step called &lt;strong&gt;History-Aware Retrieval&lt;/strong&gt;. The AI takes your follow-up question and the chat history, then "re-writes" it into a standalone question that the retriever can understand.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Step 1: Contextualizing the Question
&lt;/h2&gt;

&lt;p&gt;We create a sub-chain that looks at the history and the new question to produce a "search-friendly" query.&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.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_history_aware_retriever&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MessagesPlaceholder&lt;/span&gt;

&lt;span class="c1"&gt;# The prompt that tells the AI to re-write the question if history exists
&lt;/span&gt;&lt;span class="n"&gt;contextualize_q_system_prompt&lt;/span&gt; &lt;span class="o"&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;Given a chat history and the latest user question &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;which might reference context in the chat history, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;formulate a standalone question which can be understood &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;without the chat history. Do NOT answer the question.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;contextualize_q_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_messages&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;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contextualize_q_system_prompt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;MessagesPlaceholder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chat_history&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;human&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;{input}&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="c1"&gt;# Wrap your existing retriever (from Day 9)
&lt;/span&gt;&lt;span class="n"&gt;history_aware_retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_history_aware_retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contextualize_q_prompt&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Step 2: The Full Conversational Chain
&lt;/h2&gt;

&lt;p&gt;Now, we plug this into our document chain to create the final "Conversational RAG" flow.&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.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_retrieval_chain&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chains.combine_documents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_stuff_documents_chain&lt;/span&gt;

&lt;span class="c1"&gt;# Standard Q&amp;amp;A prompt
&lt;/span&gt;&lt;span class="n"&gt;qa_system_prompt&lt;/span&gt; &lt;span class="o"&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;You are an assistant for question-answering tasks. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Use the following pieces of retrieved context to answer the question.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{context}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;qa_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_messages&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;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qa_system_prompt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;MessagesPlaceholder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chat_history&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;human&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;{input}&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;question_answer_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_stuff_documents_chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qa_prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# The final chain!
&lt;/span&gt;&lt;span class="n"&gt;rag_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_retrieval_chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;history_aware_retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;question_answer_chain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🚀 Testing it Out
&lt;/h2&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_core.messages&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AIMessage&lt;/span&gt;

&lt;span class="n"&gt;chat_history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="c1"&gt;# First Interaction
&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is LangSmith?&lt;/span&gt;&lt;span class="sh"&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;rag_chain&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chat_history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;chat_history&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;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Update History
&lt;/span&gt;&lt;span class="n"&gt;chat_history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nc"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;AIMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&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;answer&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="c1"&gt;# Follow-up (The AI now knows 'it' refers to LangSmith!)
&lt;/span&gt;&lt;span class="n"&gt;second_question&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How do I get started with it?&lt;/span&gt;&lt;span class="sh"&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;rag_chain&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;second_question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chat_history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;chat_history&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;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 Day 11 Summary
&lt;/h2&gt;

&lt;p&gt;Today, you bridged the final gap in RAG. You learned:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Contextualization:&lt;/strong&gt; Why "it" and "this" break standard retrievers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Query Re-writing:&lt;/strong&gt; Using an LLM to make search queries smarter.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;create_history_aware_retriever&lt;/code&gt;: The specific LangChain tool for this job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your Homework:&lt;/strong&gt; Try running the chain without updating the &lt;code&gt;chat_history&lt;/code&gt; list. Notice how the second answer becomes generic or fails—this proves how vital history is!&lt;/p&gt;

&lt;p&gt;See you tomorrow! ☕&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langchain</category>
      <category>rag</category>
      <category>python</category>
    </item>
    <item>
      <title>Day 10: The Full RAG Chain — From Library to Answers 🔗</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Tue, 05 May 2026 17:59:24 +0000</pubDate>
      <link>https://dev.to/rushanksavant/day-10-the-full-rag-chain-from-library-to-answers-3m9d</link>
      <guid>https://dev.to/rushanksavant/day-10-the-full-rag-chain-from-library-to-answers-3m9d</guid>
      <description>&lt;p&gt;Yesterday, we built the "Library" (Vector Store). Today, we’re going to build the "Librarian."&lt;/p&gt;

&lt;p&gt;A Librarian doesn't just point you to a shelf; they go get the right book, read the relevant page, and explain it to you. In LangChain, we do this by connecting our &lt;strong&gt;Retriever&lt;/strong&gt; to our &lt;strong&gt;LLM&lt;/strong&gt; using a &lt;strong&gt;Retrieval Chain&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ The 2-Step Architecture
&lt;/h2&gt;

&lt;p&gt;To make our AI answer questions based on our data, we need to link two distinct parts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The Retrieval Step:&lt;/strong&gt; Finding the most relevant chunks from our Vector Database.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The Generation Step:&lt;/strong&gt; Feeding those chunks into the LLM as "Context" so it can craft an answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Step 1: The "Stuffing" Chain
&lt;/h2&gt;

&lt;p&gt;First, we need a way to tell the AI: "Here is a bunch of text (the context). Use it to answer this specific question." In LangChain, this is often called the &lt;code&gt;create_stuff_documents_chain&lt;/code&gt; because it "stuffs" all retrieved documents into the prompt.&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.chains.combine_documents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_stuff_documents_chain&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;

&lt;span class="c1"&gt;# Define the "Instructional" prompt
&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Answer the user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s question based ONLY on the provided context. 
If you don&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t know the answer, say you don&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t know.

Context: {context}
Question: {input}
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&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;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# This chain knows HOW to format the documents into the prompt
&lt;/span&gt;&lt;span class="n"&gt;document_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_stuff_documents_chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Step 2: The Final Retrieval Chain
&lt;/h2&gt;

&lt;p&gt;Now, we link the "Librarian" (the document chain) to the "Library" (the retriever we built yesterday).&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.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_retrieval_chain&lt;/span&gt;

&lt;span class="c1"&gt;# 'retriever' is the object we created in Day 9
&lt;/span&gt;&lt;span class="n"&gt;retrieval_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_retrieval_chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document_chain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Let's ask it something!
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;retrieval_chain&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&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 are the main features of LangSmith?&lt;/span&gt;&lt;span class="sh"&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;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧐 Why This is Better Than a Search Engine
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;- No Hallucinations:&lt;/strong&gt; Because we told the AI "Answer ONLY based on context," it won't make things up.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Privacy:&lt;/strong&gt; The data never leaves your "Vector Store" to train the model; it's only sent as a temporary reference during the query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Source Transparency:&lt;/strong&gt; The &lt;code&gt;response&lt;/code&gt; object actually contains a &lt;code&gt;context&lt;/code&gt; key that shows you exactly which snippets of text the AI used to find the answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Day 10 Summary
&lt;/h2&gt;

&lt;p&gt;Today, you built a production-ready AI feature! You learned:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Document Chains:&lt;/strong&gt; How to format multiple text chunks for an LLM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Retrieval Chains:&lt;/strong&gt; How to automate the flow from "Question" to "Answer."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Groundedness:&lt;/strong&gt; How to prevent AI hallucinations using context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your Homework:&lt;/strong&gt; Look at the &lt;code&gt;response["context"]&lt;/code&gt; metadata. Can you see which specific part of your document the AI liked the most?&lt;/p&gt;

&lt;p&gt;See you tomorrow! ☕&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langchain</category>
      <category>rag</category>
      <category>python</category>
    </item>
    <item>
      <title>The Rise of the Machine Identity</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Mon, 04 May 2026 15:54:00 +0000</pubDate>
      <link>https://dev.to/rushanksavant/the-rise-of-the-machine-identity-4de7</link>
      <guid>https://dev.to/rushanksavant/the-rise-of-the-machine-identity-4de7</guid>
      <description>&lt;h2&gt;
  
  
  The Autonomous Paradox
&lt;/h2&gt;

&lt;p&gt;In 2026, we’ve moved past simple chatbots. We are building Production-Grade RAG pipelines and autonomous agents that can plan, execute, and iterate. But as an architect, I’ve noticed a glaring hole in our "Agentic" future: &lt;strong&gt;Identity Sprawl&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We are giving agents non-human identities (NHI) with "Full Admin" permissions just to ensure the RAG works smoothly. We are effectively building a workforce of privileged users that never sleep, never get tired, and—most importantly—never verify their own intent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem: The &lt;code&gt;.env&lt;/code&gt; Security Theater&lt;/strong&gt;&lt;br&gt;
Most "Agentic" workflows today rely on a precarious stack of environment variables. Your agent has your OpenAI key, your Pinecone credentials, and often, write-access to your GitHub or cloud infrastructure.&lt;/p&gt;

&lt;p&gt;If your development environment is compromised—even for a second—via a simple browser injection or a typosquatted library, those keys are gone. In the era of &lt;strong&gt;AI-driven social engineering&lt;/strong&gt;, an attacker doesn’t need to hack your code; they just need to "support" your agent into leaking its own context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why "Human-in-the-Loop" is Failing
&lt;/h2&gt;

&lt;p&gt;We talk about keeping a "Human-in-the-Loop" (HITL) for safety. But if the "Loop" is a web-based dashboard or a browser extension, it’s a battlefield you don't control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Contextual Spoofing:&lt;/strong&gt; An attacker can alter the transaction description in a web UI so a malicious execution looks like a routine "Database Sync."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- The "All Green" Trap:&lt;/strong&gt; AI agents can now simulate perfectly "legitimate" behavior, passing every automated check while exfiltrating data in the background.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building a "Zero-Trust" Agent Architecture
&lt;/h2&gt;

&lt;p&gt;To move from "Experimental" to "Production-Grade," we need to treat Agent Identities with the same rigor we treat Root access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Hardware-Gated Signing:&lt;/strong&gt; No autonomous agent should have the power to move assets or change critical infrastructure without a physical, isolated signature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Short-Lived Tokens:&lt;/strong&gt; Stop using long-lived API keys. Use OAuth flows that require periodic re-authorization via a trusted display.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Independent Interpretation:&lt;/strong&gt; We need "Transaction Interpreters" that decode raw hex and JSON payloads independently of the browser's OS. If you can't read what the agent is actually doing, don't sign it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 2026 Reality&lt;/strong&gt;&lt;br&gt;
The recent infrastructure compromises we’ve seen—from bridge exploits to "ClickFix" social engineering—prove that the "Front Door" (the user interface) is the weakest link.&lt;/p&gt;

&lt;p&gt;I’m currently rebuilding my local agent stack to move away from software-only keys. The goal is a &lt;strong&gt;"Zero-Software" Trust Boundary&lt;/strong&gt;. I’ll be sharing the technical teardown of this setup, including the Python implementation for hardware-gated RAG, in my next post.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Are you trusting your agents with your master keys, or are you building a firewall?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>devsecops</category>
      <category>rag</category>
    </item>
    <item>
      <title>Day 9: RAG — Giving Your AI a Private Library 📚</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Mon, 04 May 2026 15:34:32 +0000</pubDate>
      <link>https://dev.to/rushanksavant/day-9-rag-giving-your-ai-a-private-library-117o</link>
      <guid>https://dev.to/rushanksavant/day-9-rag-giving-your-ai-a-private-library-117o</guid>
      <description>&lt;p&gt;Have you ever asked an AI about something that happened this morning, or about a private document on your laptop, and it hallucinated an answer? That's because LLMs have a "cutoff date."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RAG&lt;/strong&gt; fixes this. Instead of trying to memorize the whole world, the AI "looks up" the relevant information in your documents before it answers. Today, we’ll build the foundation of a RAG pipeline.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ The 5 Steps of RAG
&lt;/h2&gt;

&lt;p&gt;To give an AI a library, we follow a simple assembly line:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Load:&lt;/strong&gt; Pulling data from a PDF, Website, or Text file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Split:&lt;/strong&gt; Breaking long documents into small, bite-sized "chunks."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Embed:&lt;/strong&gt; Converting those text chunks into numbers (vectors) that represent their meaning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Store:&lt;/strong&gt; Saving those numbers in a "Vector Database."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Retrieve:&lt;/strong&gt; Finding the right chunk when a user asks a question.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Step 1: Loading &amp;amp; Splitting
&lt;/h2&gt;

&lt;p&gt;AI can't read a 50-page PDF all at once. We have to "chunk" it so the AI only reads the relevant parts.&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_community.document_loaders&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;WebBaseLoader&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_text_splitters&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Load a webpage
&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;WebBaseLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://docs.smith.langchain.com/user_guide&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Split it into 1000-character chunks
&lt;/span&gt;&lt;span class="n"&gt;text_splitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk_overlap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;splits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text_splitter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Created &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;splits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; chunks of data.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧠 Step 2: The "Brainy" Storage (Vector DB)
&lt;/h2&gt;

&lt;p&gt;We don't search for words; we search for &lt;strong&gt;meaning&lt;/strong&gt;. Using &lt;strong&gt;Embeddings&lt;/strong&gt;, the word "King" will be numerically close to the word "Queen," even if they are spelled differently.&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_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.vectorstores&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Create the "Library" (Vector Store) using your chunks
&lt;/span&gt;&lt;span class="n"&gt;vectorstore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Chroma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;splits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 4. Turn the library into a "Retriever"
&lt;/span&gt;&lt;span class="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 Day 9 Summary
&lt;/h2&gt;

&lt;p&gt;Today, you learned how to bridge the gap between static AI knowledge and your dynamic data. We covered:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- The RAG Concept:&lt;/strong&gt; Why "Search + Generate" is better than just "Generate."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Document Loaders:&lt;/strong&gt; Bringing external data into Python.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Text Splitters:&lt;/strong&gt; Why chunking matters for accuracy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Vector Stores:&lt;/strong&gt; Searching by meaning, not just keywords.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your Homework:&lt;/strong&gt; Find a long article online and try to load it using the &lt;code&gt;WebBaseLoader&lt;/code&gt;. See how many "chunks" it creates when you set the &lt;code&gt;chunk_size&lt;/code&gt; to 500!&lt;/p&gt;

&lt;p&gt;See you tomorrow! ☕&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langchain</category>
      <category>python</category>
      <category>rag</category>
    </item>
    <item>
      <title>Day 8: Building Custom Tools — Teaching Your AI New Skills 🛠️</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Sun, 03 May 2026 19:30:42 +0000</pubDate>
      <link>https://dev.to/rushanksavant/day-8-building-custom-tools-teaching-your-ai-new-skills-284p</link>
      <guid>https://dev.to/rushanksavant/day-8-building-custom-tools-teaching-your-ai-new-skills-284p</guid>
      <description>&lt;p&gt;You’ve seen how agents can search the web, but what if you need your AI to interact with your specific company database, calculate a proprietary risk score, or even control a smart lightbulb in your house?&lt;/p&gt;

&lt;p&gt;For that, you need Custom Tools. Today, we’ll see how a simple Python decorator can bridge the gap between your local code and a LLM.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎨 The Magic of the &lt;code&gt;@tool&lt;/code&gt; Decorator
&lt;/h2&gt;

&lt;p&gt;The easiest way to create a tool in 2026 is using the &lt;code&gt;@tool&lt;/code&gt; decorator. When you wrap a function with this, LangChain automatically analyzes your code to tell the AI:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What the tool is called.&lt;/li&gt;
&lt;li&gt;What it does (based on your docstring).&lt;/li&gt;
&lt;li&gt;What arguments it needs (based on your type hints).&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What are Decorators in python?
&lt;/h2&gt;

&lt;p&gt;In Python, decorators are a powerful design pattern that allows you to modify or enhance the behavior of a function, method, or class without permanently changing its original source code.&lt;/p&gt;

&lt;p&gt;Think of a decorator as a "wrapper" that can execute code before and after the original function runs. Following code will help you understand better:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Before the function.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;func&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;After the function.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapper&lt;/span&gt;

&lt;span class="nd"&gt;@my_decorator&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;say_hello&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;say_hello&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Step-by-Step: Creating a "Secret Multiplier" Tool
&lt;/h2&gt;

&lt;p&gt;Let’s build a tool that performs a calculation the AI couldn't possibly know—using a "secret constant" from our local environment.&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_core.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_secret_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&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;Calculates a business score by multiplying input by a secret company constant.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;secret_constant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;  &lt;span class="c1"&gt;# This could be from a database or API
&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;base_value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;secret_constant&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;The secret business score is &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="c1"&gt;# Let's see what the AI sees!
&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;calculate_secret_score&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&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;calculate_secret_score&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&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;calculate_secret_score&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧠 Why Docstrings and Type Hints Matter
&lt;/h2&gt;

&lt;p&gt;In regular coding, docstrings are for other humans. In LangChain, &lt;strong&gt;docstrings are for the AI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If your docstring is vague (e.g., &lt;code&gt;"Does math"&lt;/code&gt;), the AI won't know when to use the tool. If it’s specific (e.g., &lt;code&gt;"Use this tool when the user asks for a 'business score' or 'proprietary calculation'"&lt;/code&gt;), your agent becomes incredibly reliable.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ Plugging it into the Agent
&lt;/h2&gt;

&lt;p&gt;Once your tool is defined, you just add it to your tool list, exactly like we did yesterday.&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_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langgraph.prebuilt&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_react_agent&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Define your custom skills
&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;calculate_secret_score&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Setup the brain
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&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;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Create the Agent
&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_react_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 4. Test it!
&lt;/span&gt;&lt;span class="n"&gt;response&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="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;human&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 is the secret score for a value of 10?&lt;/span&gt;&lt;span class="sh"&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;response&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&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 Day 8 Summary
&lt;/h2&gt;

&lt;p&gt;Today, you moved from "User" to "Creator." You learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The &lt;code&gt;@tool&lt;/code&gt; Decorator:&lt;/strong&gt; Converting functions to AI skills.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prompt Engineering via Docstrings:&lt;/strong&gt; Writing descriptions so the LLM knows when to call your tool.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integration:&lt;/strong&gt; Adding your custom logic into a ReAct agent loop.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Your Homework:&lt;/strong&gt; Write a custom tool called &lt;code&gt;get_user_status&lt;/code&gt; that takes a &lt;code&gt;username&lt;/code&gt; and returns a fake status (like "Active" or "Away"). Try to get your agent to tell you the status of "Alex."&lt;/p&gt;

&lt;p&gt;See you tomorrow! ☕&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langchain</category>
      <category>python</category>
      <category>agents</category>
    </item>
    <item>
      <title>Day 7: Introducing AI Agents &amp; Tools — Giving Your AI "Hands" 🛠️</title>
      <dc:creator>Rushank Savant</dc:creator>
      <pubDate>Sun, 03 May 2026 06:41:35 +0000</pubDate>
      <link>https://dev.to/rushanksavant/day-7-introducing-ai-agents-tools-giving-your-ai-hands-39d8</link>
      <guid>https://dev.to/rushanksavant/day-7-introducing-ai-agents-tools-giving-your-ai-hands-39d8</guid>
      <description>&lt;p&gt;We’ve spent a week building, where we predefined every single step. But what if you don't know the steps in advance? What if the AI needs to decide whether to search Google, check a database, or use a calculator based on the user's question?&lt;/p&gt;

&lt;p&gt;This is where we move from "Chains" to &lt;strong&gt;Agents&lt;/strong&gt;. If a Chain is a fixed railroad track, an Agent is a &lt;strong&gt;self-driving car&lt;/strong&gt;. It has a destination (your goal) and a set of tools, and it decides the best route to get there.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔 What exactly is an AI Agent?
&lt;/h2&gt;

&lt;p&gt;An Agent is an LLM that uses a "Reasoning Loop" to complete a task. In the official documentation, this is often called the &lt;strong&gt;ReAct&lt;/strong&gt; pattern (Reason + Act). &lt;br&gt;
 Instead of just answering, the Agent follows this cycle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Thought:&lt;/strong&gt; "The user wants the current price of Bitcoin. I don't know that, so I should use a search tool."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Action:&lt;/strong&gt; Calls the &lt;code&gt;Search&lt;/code&gt; tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Observation:&lt;/strong&gt; Reads the search results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Final Response:&lt;/strong&gt; Combines the observation into a helpful answer.&lt;/p&gt;


&lt;h2&gt;
  
  
  🔧 The Power of Tools
&lt;/h2&gt;

&lt;p&gt;Tools are the "hands" of your AI. A tool is essentially a Python function that the LLM knows how to call. LangChain comes with dozens of built-in tools, but you can also create your own!  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common Tools:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tavily/Google Search:&lt;/strong&gt; For real-time information.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wikipedia:&lt;/strong&gt; For general knowledge.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python REPL:&lt;/strong&gt; For executing complex math or data analysis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom APIs:&lt;/strong&gt; To connect to your own company's data.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🏗️ Building Your First Agent (The 2026 Way)
&lt;/h2&gt;

&lt;p&gt;In modern LangChain, we use a specialized "Agent Executor" to manage the loop. Here’s a sneak peek at the setup:&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_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.tools.tavily_search&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TavilySearchResults&lt;/span&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_react_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AgentExecutor&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hub&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Define the Tools
&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="nc"&gt;TavilySearchResults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_results&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="c1"&gt;# 2. Get a "Prompt Template" from the LangChain Hub
# This prompt tells the AI how to use the tools
&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hwchase17/react&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Initialize the Brain (The LLM)
&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&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;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 4. Construct the Agent
&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_react_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 5. Create the Executor (The engine that runs the loop)
&lt;/span&gt;&lt;span class="n"&gt;agent_executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentExecutor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&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="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 6. Run it!
&lt;/span&gt;&lt;span class="n"&gt;agent_executor&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&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 is the current stock price of NVIDIA?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 Day 7 Summary
&lt;/h2&gt;

&lt;p&gt;Today, you learned about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agents:&lt;/strong&gt; AI that can reason and decide its own path.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools:&lt;/strong&gt; How to give LLMs access to the outside world.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The ReAct Loop:&lt;/strong&gt; How AI thinks before it acts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent Executor:&lt;/strong&gt; The runtime that manages the process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your Homework:&lt;/strong&gt; Go to the LangChain Tool Repository and look at the list. Which two tools would you combine to make a "Personal Research Assistant"?&lt;/p&gt;

&lt;p&gt;See you tomorrow! ☕&lt;/p&gt;

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