<?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: Piyush Kumar Soni</title>
    <description>The latest articles on DEV Community by Piyush Kumar Soni (@piyush_kumar_soni).</description>
    <link>https://dev.to/piyush_kumar_soni</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3969512%2F2bc3320a-f115-4a77-af9f-260948bf9c16.png</url>
      <title>DEV Community: Piyush Kumar Soni</title>
      <link>https://dev.to/piyush_kumar_soni</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/piyush_kumar_soni"/>
    <language>en</language>
    <item>
      <title>RAG for Beginners: Build a Document Q&amp;A System with LangChain (Full Code)</title>
      <dc:creator>Piyush Kumar Soni</dc:creator>
      <pubDate>Sun, 19 Jul 2026 08:11:29 +0000</pubDate>
      <link>https://dev.to/piyush_kumar_soni/rag-for-beginners-build-a-document-qa-system-with-langchain-full-code-5772</link>
      <guid>https://dev.to/piyush_kumar_soni/rag-for-beginners-build-a-document-qa-system-with-langchain-full-code-5772</guid>
      <description>&lt;h1&gt;
  
  
  RAG for Beginners: Build a Document Q&amp;amp;A System with LangChain (Full Code)
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;code&gt;#ai&lt;/code&gt; &lt;code&gt;#langchain&lt;/code&gt; &lt;code&gt;#python&lt;/code&gt; &lt;code&gt;#tutorial&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;LLMs don't know your private documents. ChatGPT can write you an essay about quantum computing, but it has zero idea what's in your company's internal wiki, your client reports, or that PDF you saved last Tuesday — unless you paste it in yourself, every single time.&lt;/p&gt;

&lt;p&gt;RAG (Retrieval-Augmented Generation) fixes this. This post walks through the concept and a full working code example you can run today.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Documents  →  Split into chunks  →  Convert to embeddings  →  Stored in a vector database
                                                                              ↓
User's Question  →  Convert to embedding  →  Find closest matching chunks  →  Send question + chunks to LLM  →  Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two steps, really: &lt;strong&gt;retrieval&lt;/strong&gt; (find the relevant pieces of your data) and &lt;strong&gt;generation&lt;/strong&gt; (let the LLM answer using those pieces instead of guessing from training data alone).&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langchain langchain-community langchain-openai faiss-cpu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll also need an &lt;code&gt;OPENAI_API_KEY&lt;/code&gt; environment variable set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-key-here"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full Working Example — Text Document
&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_community.document_loaders&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TextLoader&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.text_splitter&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RecursiveCharacterTextSplitter&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;FAISS&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;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;,&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.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RetrievalQA&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Load your document
&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;TextLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client_seo_report.txt&lt;/span&gt;&lt;span class="sh"&gt;"&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;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 into chunks — LLMs work better with focused chunks than walls of text
&lt;/span&gt;&lt;span class="n"&gt;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;500&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;50&lt;/span&gt;  &lt;span class="c1"&gt;# overlap prevents cutting a key sentence in half
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;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;documents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Convert chunks into embeddings and store them in a local vector index
&lt;/span&gt;&lt;span class="n"&gt;embeddings&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="n"&gt;vector_store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FAISS&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;chunks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 4. Wire up retrieval + generation
&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-mini&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;qa_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RetrievalQA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_chain_type&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="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="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;vector_store&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;span class="n"&gt;search_kwargs&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;k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;  &lt;span class="c1"&gt;# top 4 matching chunks
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 5. Ask a question about YOUR document
&lt;/span&gt;&lt;span class="n"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qa_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;What was the biggest traffic change this month?&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;answer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result&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;p&gt;That's a complete, runnable RAG pipeline in about 20 lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Swapping in a PDF Instead of Plain Text
&lt;/h2&gt;

&lt;p&gt;Most real documents aren't &lt;code&gt;.txt&lt;/code&gt; files. Swapping the loader is the only change needed:&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;PyPDFLoader&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;PyPDFLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client_seo_report.pdf&lt;/span&gt;&lt;span class="sh"&gt;"&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;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;# everything else in the pipeline stays exactly the same
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LangChain has loaders for most formats you'll actually run into — &lt;code&gt;Docx2txtLoader&lt;/code&gt; for Word docs, &lt;code&gt;CSVLoader&lt;/code&gt; for spreadsheets, &lt;code&gt;WebBaseLoader&lt;/code&gt; for scraping a URL directly. Same downstream pipeline every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why &lt;code&gt;chunk_size&lt;/code&gt; and &lt;code&gt;chunk_overlap&lt;/code&gt; Matter More Than They Look Like They Should
&lt;/h2&gt;

&lt;p&gt;This trips up almost everyone the first time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chunk size too large&lt;/strong&gt; → retrieval pulls back a lot of irrelevant surrounding text along with the useful part, and the LLM's answer gets muddier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chunk size too small&lt;/strong&gt; → you lose context; a chunk might not contain enough surrounding information to be useful on its own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No overlap&lt;/strong&gt; → you can accidentally split a sentence's meaning exactly at the point where the important information was.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's no universal "correct" number — 500 characters with 50 overlap is a reasonable starting point for report-style text, but experiment for your actual documents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes (Beyond Chunking)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Expecting perfect retrieval on the first try.&lt;/strong&gt; Sometimes the "closest match" by embedding similarity isn't actually the most relevant chunk for the question. This is normal — tuning retrieval quality is where most of the real engineering effort goes, well past this example.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not filtering by metadata.&lt;/strong&gt; If you're indexing documents from multiple clients or time periods, tag your chunks with metadata (&lt;code&gt;client_name&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt;) so you can filter the search instead of searching everything every time:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;vector_store&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;span class="n"&gt;search_kwargs&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;k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;filter&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;client_name&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;acme_corp&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Using the wrong &lt;code&gt;k&lt;/code&gt; value.&lt;/strong&gt; Too few retrieved chunks (&lt;code&gt;k=1&lt;/code&gt; or &lt;code&gt;2&lt;/code&gt;) and the LLM might not have enough context. Too many (&lt;code&gt;k=10+&lt;/code&gt;) and you're paying for tokens the model doesn't need and diluting the relevant signal. &lt;code&gt;k=3&lt;/code&gt; to &lt;code&gt;k=5&lt;/code&gt; is a reasonable starting range.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where This Goes Next
&lt;/h2&gt;

&lt;p&gt;Once this basic pattern works, natural next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Try a production-grade vector store (&lt;strong&gt;Pinecone&lt;/strong&gt;, &lt;strong&gt;Chroma&lt;/strong&gt;, or &lt;strong&gt;Weaviate&lt;/strong&gt;) instead of local FAISS once you need this to scale or persist across sessions&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;metadata filtering&lt;/strong&gt; as shown above once you're indexing more than one source&lt;/li&gt;
&lt;li&gt;Experiment with &lt;strong&gt;hybrid search&lt;/strong&gt; (combining keyword search with embedding similarity) — pure embedding search sometimes misses exact-match terms like product names or codes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm covering &lt;strong&gt;agents&lt;/strong&gt; next — giving an LLM the ability to actually take actions instead of just answering questions. RAG is the foundation a lot of that builds on, so if this made sense, you're already most of the way there.&lt;/p&gt;

&lt;p&gt;If you build this and hit a snag, drop a comment — happy to help debug.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Piyush Kumar Soni, an AI Developer and LLM Integration Expert with 15+ years running digital agency operations. I write about practical AI tools for SEO and digital marketing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://www.linkedin.com/in/piyushkumarsoni/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · 💻 &lt;a href="https://github.com/piyushsoni-ai" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · 📰 &lt;a href="https://piyushkumarsoni.substack.com/" rel="noopener noreferrer"&gt;Substack&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langchain</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Build Your First LLM Tool: A Beginner's Guide to LangChain</title>
      <dc:creator>Piyush Kumar Soni</dc:creator>
      <pubDate>Sat, 18 Jul 2026 07:14:17 +0000</pubDate>
      <link>https://dev.to/piyush_kumar_soni/build-your-first-llm-tool-a-beginners-guide-to-langchain-38f8</link>
      <guid>https://dev.to/piyush_kumar_soni/build-your-first-llm-tool-a-beginners-guide-to-langchain-38f8</guid>
      <description>&lt;h1&gt;
  
  
  Build Your First LLM Tool: A Beginner’s Guide to LangChain
&lt;/h1&gt;

&lt;p&gt;Building an LLM application can sound complicated, but your first working tool may require fewer than 15 lines of Python.&lt;/p&gt;

&lt;p&gt;In this tutorial, we’ll build a simple AI explainer using LangChain and an OpenAI model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use LangChain Instead of Calling the OpenAI API Directly?
&lt;/h2&gt;

&lt;p&gt;Calling an AI model directly is perfectly reasonable for a small script. You send a prompt, receive a response, and display it.&lt;/p&gt;

&lt;p&gt;The complexity begins when your application needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reusable prompt templates&lt;/li&gt;
&lt;li&gt;Structured output&lt;/li&gt;
&lt;li&gt;Multiple model providers&lt;/li&gt;
&lt;li&gt;Documents or external data&lt;/li&gt;
&lt;li&gt;Conversation history&lt;/li&gt;
&lt;li&gt;Tools and agents&lt;/li&gt;
&lt;li&gt;Logging and debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LangChain provides a standard interface for composing these pieces. It also makes switching between supported providers easier because your application does not need to be completely rewritten around each provider’s API. (&lt;a href="https://docs.langchain.com/oss/python/langchain/models" rel="noopener noreferrer"&gt;Docs by LangChain&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Think of the raw API as an engine. LangChain gives you reusable parts for building the rest of the vehicle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install the Required Packages
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langchain langchain-openai python-dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OPENAI_API_KEY=your_api_key_here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Never commit this file or expose your API key in a public repository. OpenAI recommends storing API keys securely rather than placing them directly inside source code. (&lt;a href="https://platform.openai.com/docs/guides/production-best-practices/infrastructure%3B.eps" rel="noopener noreferrer"&gt;OpenAI Platform&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a Basic LangChain Chain
&lt;/h2&gt;

&lt;p&gt;Create a file named &lt;code&gt;app.py&lt;/code&gt;:&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;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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&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="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&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;Explain {topic} to a beginner using one example.&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&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-5-nano&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&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;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;StrOutputParser&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;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;topic&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;vector databases&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;p&gt;Run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The chain has three simple steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Insert the topic into the prompt.&lt;/li&gt;
&lt;li&gt;Send the formatted prompt to the model.&lt;/li&gt;
&lt;li&gt;Convert the model response into a normal Python string.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;code&gt;|&lt;/code&gt; operator connects each component into a readable pipeline. The current LangChain OpenAI integration is provided through the separate &lt;code&gt;langchain-openai&lt;/code&gt; package and its &lt;code&gt;ChatOpenAI&lt;/code&gt; class. (&lt;a href="https://docs.langchain.com/oss/python/integrations/chat/openai" rel="noopener noreferrer"&gt;Docs by LangChain&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Should You Go Next?
&lt;/h2&gt;

&lt;p&gt;Once this basic chain works, explore two important areas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RAG, or Retrieval-Augmented Generation&lt;/strong&gt;, lets your application retrieve information from PDFs, webpages, databases, or company documents before generating an answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agents&lt;/strong&gt; allow a model to decide when to call tools such as search functions, APIs, calculators, or custom Python functions. LangChain currently provides configurable agent-building functionality for connecting models with tools and application logic. (&lt;a href="https://docs.langchain.com/oss/python/langchain/overview" rel="noopener noreferrer"&gt;Docs by LangChain&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;You can also turn your script into a web interface using Gradio and publish it through Hugging Face Spaces.&lt;/p&gt;

&lt;p&gt;Here are two live examples from my own AI-tool experiments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://huggingface.co/spaces/piyushsoni-ai/seo-meta-generator" rel="noopener noreferrer"&gt;SEO Meta Tag Generator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://huggingface.co/spaces/piyushsoni-ai/ai-business-name-generator" rel="noopener noreferrer"&gt;AI Business Name Generator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start with one prompt and one model. Get that working first. Then add memory, retrieval, tools, and agents only when your application genuinely needs them.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;About the author:&lt;/strong&gt; Piyush Kumar Soni is an AI Developer, LLM Expert and Digital Growth Specialist building practical AI tools, automation systems and LLM-powered workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suggested Dev.to tags:&lt;/strong&gt; &lt;code&gt;ai&lt;/code&gt;, &lt;code&gt;langchain&lt;/code&gt;, &lt;code&gt;python&lt;/code&gt;, &lt;code&gt;beginners&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This article follows the Dev.to and topical-authority direction in your SERP plan, including the focus on LangChain development, Python-based AI tools and Hugging Face demos.  Your supplied profile list confirms the two live Hugging Face Space URLs used above. &lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
