<?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>I Created a Free Firefox Extension to Audit Google Business Profiles and AI Visibility</title>
      <dc:creator>Piyush Kumar Soni</dc:creator>
      <pubDate>Mon, 31 Aug 2026 12:07:44 +0000</pubDate>
      <link>https://dev.to/piyush_kumar_soni/i-created-a-free-firefox-extension-to-audit-google-business-profiles-and-ai-visibility-4199</link>
      <guid>https://dev.to/piyush_kumar_soni/i-created-a-free-firefox-extension-to-audit-google-business-profiles-and-ai-visibility-4199</guid>
      <description>&lt;p&gt;I recently created a Firefox extension called &lt;strong&gt;GBP Audit AI Visibility by Lucky Digitals&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The idea came from something I was doing again and again while working on local SEO.&lt;/p&gt;

&lt;p&gt;Whenever I checked a Google Business Profile, I had to review multiple things manually. Categories, description, reviews, services, profile activity, review responses, and other optimization signals.&lt;/p&gt;

&lt;p&gt;Then another question started becoming more important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is this business visible in AI search too?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is where I got the idea to combine traditional GBP auditing with AI visibility checks in one simple browser extension.&lt;/p&gt;

&lt;p&gt;The extension is completely &lt;strong&gt;free to use for anyone&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can try it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/gbp-audit-ai-visibility/" rel="noopener noreferrer"&gt;https://addons.mozilla.org/en-US/firefox/addon/gbp-audit-ai-visibility/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Created It
&lt;/h2&gt;

&lt;p&gt;I did not want to create another heavy SaaS tool that needs a login, database, dashboard, subscription, and multiple setup steps.&lt;/p&gt;

&lt;p&gt;I wanted something simple.&lt;/p&gt;

&lt;p&gt;Open a business profile.&lt;/p&gt;

&lt;p&gt;Run an audit.&lt;/p&gt;

&lt;p&gt;Check the issues.&lt;/p&gt;

&lt;p&gt;See the score.&lt;/p&gt;

&lt;p&gt;Check AI visibility.&lt;/p&gt;

&lt;p&gt;Export the report.&lt;/p&gt;

&lt;p&gt;Done.&lt;/p&gt;

&lt;p&gt;That was the main goal.&lt;/p&gt;

&lt;p&gt;When I started planning it, I focused on the things I normally check during a GBP audit, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Profile completeness&lt;/li&gt;
&lt;li&gt;Business categories&lt;/li&gt;
&lt;li&gt;Business description&lt;/li&gt;
&lt;li&gt;Reviews&lt;/li&gt;
&lt;li&gt;Review recency&lt;/li&gt;
&lt;li&gt;Review responses&lt;/li&gt;
&lt;li&gt;Services&lt;/li&gt;
&lt;li&gt;Profile activity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I then turned these checks into a scoring system so the user gets a simple health score instead of going through everything manually.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GBP Health Score

82 / 100

Strong review profile
Business description added
Relevant categories found

Needs more recent reviews
Review response rate can be improved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wanted the score to be easy to understand.&lt;/p&gt;

&lt;p&gt;A score alone is not very useful.&lt;/p&gt;

&lt;p&gt;If the tool gives someone a score of 65, I also wanted it to explain why the score is 65 and what they can improve.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Also Added AI Visibility
&lt;/h2&gt;

&lt;p&gt;This was the part I found more interesting.&lt;/p&gt;

&lt;p&gt;Local SEO is changing.&lt;/p&gt;

&lt;p&gt;Businesses are still trying to rank on Google Maps and Google Search, but now people are also asking tools like ChatGPT and Gemini for recommendations.&lt;/p&gt;

&lt;p&gt;Someone might search:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Best dentist near me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Recommended roofing companies in Dallas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Best local SEO agency for Google Business Profile optimization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So I started thinking about how I could include AI visibility inside the same audit.&lt;/p&gt;

&lt;p&gt;The idea was not to replace traditional SEO metrics.&lt;/p&gt;

&lt;p&gt;I just wanted to add another layer.&lt;/p&gt;

&lt;p&gt;The extension checks AI-related visibility signals through external data sources using DataForSEO.&lt;/p&gt;

&lt;p&gt;The flow is basically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business
   ↓
Relevant Search Query
   ↓
AI Visibility Data
   ↓
Business Mention Check
   ↓
Visibility Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives the user a better idea of how the business is performing beyond normal GBP optimization.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Structured It
&lt;/h2&gt;

&lt;p&gt;I kept the setup quite simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Google Search or Google Maps
            ↓
      Firefox Extension
            ↓
      GBP Audit Engine
            ↓
      AI Visibility Check
            ↓
      Cloudflare Worker
            ↓
         DataForSEO
            ↓
     Recommendations
            ↓
       PDF Report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used a Cloudflare Worker because I did not want to expose private API credentials inside the browser extension.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Important Thing I Learned About API Keys
&lt;/h2&gt;

&lt;p&gt;While creating the extension, one thing was very clear.&lt;/p&gt;

&lt;p&gt;API keys should never be placed directly inside browser extension JavaScript.&lt;/p&gt;

&lt;p&gt;For example, this is a bad idea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-secret-api-key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anyone can inspect the extension files and find it.&lt;/p&gt;

&lt;p&gt;So instead, I created a small Cloudflare Worker that works between the extension and the external API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Firefox Extension
       ↓
Cloudflare Worker
       ↓
External API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Worker handles the API request and keeps the private credentials away from the browser.&lt;/p&gt;

&lt;p&gt;It can also help with things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request validation&lt;/li&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Rate limiting&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;Response formatting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a lightweight extension, this setup worked well for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Wanted to Keep It Free and Simple
&lt;/h2&gt;

&lt;p&gt;Another important decision was keeping the tool free to use.&lt;/p&gt;

&lt;p&gt;Anyone can install the extension and use it.&lt;/p&gt;

&lt;p&gt;I did not want users to create an account just to run a basic GBP audit.&lt;/p&gt;

&lt;p&gt;I also did not want to create unnecessary storage.&lt;/p&gt;

&lt;p&gt;The workflow is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open profile
    ↓
Run audit
    ↓
Check results
    ↓
Export report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this type of tool, I did not feel that permanent user data storage was necessary.&lt;/p&gt;

&lt;p&gt;That also helped me avoid unnecessary complexity around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User accounts&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Saved personal data&lt;/li&gt;
&lt;li&gt;Login systems&lt;/li&gt;
&lt;li&gt;Monthly subscriptions&lt;/li&gt;
&lt;li&gt;Extra hosting costs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes a simple tool is better than turning everything into a full SaaS product.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Added PDF Reports Too
&lt;/h2&gt;

&lt;p&gt;I also wanted the audit to be useful for agency work and client reporting.&lt;/p&gt;

&lt;p&gt;So I added PDF report generation.&lt;/p&gt;

&lt;p&gt;The user can run the audit and export the findings into a report.&lt;/p&gt;

&lt;p&gt;A report can include things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Business Information

GBP Health Score

Audit Findings

Review Analysis

AI Visibility

Priority Issues

Recommended Actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful if someone wants to share the audit with a client, business owner, or internal team.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Did Not Want It to Just Find Problems
&lt;/h2&gt;

&lt;p&gt;Another thing I focused on was recommendations.&lt;/p&gt;

&lt;p&gt;Finding an issue is easy.&lt;/p&gt;

&lt;p&gt;Explaining what to do next is more useful.&lt;/p&gt;

&lt;p&gt;For example, instead of only saying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Low review activity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the extension can give a recommendation such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HIGH PRIORITY

Try to increase the frequency of new customer reviews.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MEDIUM PRIORITY

Improve the consistency of review responses.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LOW PRIORITY

Improve the business description.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the audit more actionable.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Visibility Does Not Replace Local SEO
&lt;/h2&gt;

&lt;p&gt;I do not see AI visibility as a replacement for SEO.&lt;/p&gt;

&lt;p&gt;I see it as another layer of search visibility.&lt;/p&gt;

&lt;p&gt;A business still needs strong fundamentals.&lt;/p&gt;

&lt;p&gt;Things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website content&lt;/li&gt;
&lt;li&gt;Google Business Profile&lt;/li&gt;
&lt;li&gt;Reviews&lt;/li&gt;
&lt;li&gt;Local citations&lt;/li&gt;
&lt;li&gt;Brand mentions&lt;/li&gt;
&lt;li&gt;Structured data&lt;/li&gt;
&lt;li&gt;Authority&lt;/li&gt;
&lt;li&gt;Relevant content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;all still matter.&lt;/p&gt;

&lt;p&gt;I currently think about it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Website
   +
Google Business Profile
   +
Reviews
   +
Citations
   +
Brand Mentions
   +
Structured Data
          ↓
     Entity Understanding
          ↓
 Google Search + AI Search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SEO, GEO, AI visibility, local SEO, and entity optimization are becoming more connected.&lt;/p&gt;

&lt;p&gt;That is one reason I wanted to experiment with bringing these areas together in one tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned While Creating It
&lt;/h2&gt;

&lt;p&gt;I learned quite a few things while creating this extension.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep the scoring understandable
&lt;/h3&gt;

&lt;p&gt;If a user gets a score, they should understand how it was calculated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Never expose private APIs
&lt;/h3&gt;

&lt;p&gt;I used a Cloudflare Worker because API credentials should not be stored inside an extension.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep permissions limited
&lt;/h3&gt;

&lt;p&gt;I tried to keep browser permissions focused only on what the extension actually needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do not overbuild
&lt;/h3&gt;

&lt;p&gt;I did not need a huge backend, user database, or login system for the first version.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI visibility needs context
&lt;/h3&gt;

&lt;p&gt;One AI mention does not automatically mean a business has strong AI visibility.&lt;/p&gt;

&lt;p&gt;Location, query intent, entity recognition, relevance, and other factors all matter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start from a real problem
&lt;/h3&gt;

&lt;p&gt;I think this was the biggest lesson.&lt;/p&gt;

&lt;p&gt;I did not start by asking:&lt;/p&gt;

&lt;p&gt;"What SaaS should I build?"&lt;/p&gt;

&lt;p&gt;I started with:&lt;/p&gt;

&lt;p&gt;"What task am I doing repeatedly that I can make easier?"&lt;/p&gt;

&lt;p&gt;That question led to the extension.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Want to Add Next
&lt;/h2&gt;

&lt;p&gt;This is still an early version, and I have more ideas for it.&lt;/p&gt;

&lt;p&gt;Some things I am considering are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better AI visibility scoring&lt;/li&gt;
&lt;li&gt;Competitor comparison&lt;/li&gt;
&lt;li&gt;Entity analysis&lt;/li&gt;
&lt;li&gt;Citation checks&lt;/li&gt;
&lt;li&gt;Schema checks&lt;/li&gt;
&lt;li&gt;AI recommendation tracking&lt;/li&gt;
&lt;li&gt;Historical visibility tracking&lt;/li&gt;
&lt;li&gt;More GBP recommendations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The bigger idea is to bring local SEO and AI search visibility into one simple workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It for Free
&lt;/h2&gt;

&lt;p&gt;The extension is free for anyone to use.&lt;/p&gt;

&lt;p&gt;You can install it here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GBP Audit AI Visibility by Lucky Digitals&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/gbp-audit-ai-visibility/" rel="noopener noreferrer"&gt;https://addons.mozilla.org/en-US/firefox/addon/gbp-audit-ai-visibility/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you work with local SEO, Google Business Profiles, agencies, AI visibility, or GEO, I would genuinely like to know what you think about it.&lt;/p&gt;

&lt;p&gt;Feedback will help me improve the next version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect With Me
&lt;/h2&gt;

&lt;p&gt;I am &lt;strong&gt;Piyush Kumar Soni&lt;/strong&gt;, and I like creating practical tools around AI, LLMs, automation, SEO, and search visibility.&lt;/p&gt;

&lt;p&gt;GitHub&lt;br&gt;
&lt;a href="https://github.com/piyushsoni-ai" rel="noopener noreferrer"&gt;https://github.com/piyushsoni-ai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;LinkedIn&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/piyushkumarsoni/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/piyushkumarsoni/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Medium&lt;br&gt;
&lt;a href="https://medium.com/@piyushkrsoni" rel="noopener noreferrer"&gt;https://medium.com/@piyushkrsoni&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Substack&lt;br&gt;
&lt;a href="https://piyushkumarsoni.substack.com/" rel="noopener noreferrer"&gt;https://piyushkumarsoni.substack.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;About.me&lt;br&gt;
&lt;a href="https://about.me/piyushkumarsoni" rel="noopener noreferrer"&gt;https://about.me/piyushkumarsoni&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Personal Profile&lt;br&gt;
&lt;a href="https://piyushkumarsoni.carrd.co/" rel="noopener noreferrer"&gt;https://piyushkumarsoni.carrd.co/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are building something around AI, RAG, agents, automation, SEO tools, GEO, or AI search visibility, feel free to connect.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>seo</category>
      <category>googlebusinessprofile</category>
    </item>
    <item>
      <title>How LLMs Can Automate Technical SEO Workflows</title>
      <dc:creator>Piyush Kumar Soni</dc:creator>
      <pubDate>Thu, 20 Aug 2026 07:48:08 +0000</pubDate>
      <link>https://dev.to/piyush_kumar_soni/how-llms-can-automate-technical-seo-workflows-4109</link>
      <guid>https://dev.to/piyush_kumar_soni/how-llms-can-automate-technical-seo-workflows-4109</guid>
      <description>&lt;p&gt;Technical SEO has always involved a strange mix of strategy and repetition.&lt;/p&gt;

&lt;p&gt;The strategic side is interesting: understanding how a website is structured, identifying why important pages are not performing, deciding what deserves to be indexed, improving internal linking, and prioritizing fixes that actually affect organic growth.&lt;/p&gt;

&lt;p&gt;The repetitive side is less exciting.&lt;/p&gt;

&lt;p&gt;SEO teams repeatedly review title tags, meta descriptions, canonical URLs, heading structures, status codes, internal links, schema markup, indexability signals, and large spreadsheets of crawl data.&lt;/p&gt;

&lt;p&gt;This is where Large Language Models can become genuinely useful.&lt;/p&gt;

&lt;p&gt;I am &lt;strong&gt;Piyush Kumar Soni, an SEO Expert &amp;amp; AI/LLM Specialist&lt;/strong&gt;, and much of my current work focuses on combining Technical SEO, Generative Engine Optimization (GEO), AI Search, LLM integration, RAG, Entity SEO, Schema Markup, and automation.&lt;/p&gt;

&lt;p&gt;I do not see LLMs as a replacement for technical SEO expertise.&lt;/p&gt;

&lt;p&gt;I see them as a layer that can sit on top of deterministic SEO data and help teams interpret, prioritize, automate, and communicate findings faster.&lt;/p&gt;

&lt;p&gt;This article explains where that approach works well, where it does not, and how I think about building LLM-powered SEO workflows in practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Right Way to Think About LLMs in Technical SEO
&lt;/h2&gt;

&lt;p&gt;A common mistake is asking an LLM to "audit a website" without giving it structured data.&lt;/p&gt;

&lt;p&gt;That usually results in generic recommendations such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;improve page speed&lt;/li&gt;
&lt;li&gt;optimize title tags&lt;/li&gt;
&lt;li&gt;add schema markup&lt;/li&gt;
&lt;li&gt;improve internal linking&lt;/li&gt;
&lt;li&gt;make content helpful&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of those suggestions are necessarily wrong.&lt;/p&gt;

&lt;p&gt;But they are not an audit.&lt;/p&gt;

&lt;p&gt;A real technical SEO workflow should start with actual evidence.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;URL: https://example.com/product-a

Status: 200
Canonical: https://example.com/product-a
Robots: index, follow
Title: Product A | Example
Meta description: "Missing"
H1: Product A
Internal links pointing to page: 2
Structured data: Product
Word count: 430
Crawl depth: 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now an LLM has something useful to work with.&lt;/p&gt;

&lt;p&gt;The architecture should look more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Website
   ↓
Crawler / SEO API
   ↓
Structured SEO Data
   ↓
Rules &amp;amp; Validation
   ↓
LLM
   ↓
Interpretation / Prioritization
   ↓
Report or Workflow Action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM is not replacing the crawler.&lt;/p&gt;

&lt;p&gt;It is interpreting what the crawler found.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Automating SEO Issue Explanations
&lt;/h2&gt;

&lt;p&gt;Most SEO crawlers are very good at identifying problems.&lt;/p&gt;

&lt;p&gt;They can tell you:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;174 pages are missing meta descriptions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The crawler has done its job.&lt;/p&gt;

&lt;p&gt;But somebody still needs to explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;why that matters&lt;/li&gt;
&lt;li&gt;which pages matter most&lt;/li&gt;
&lt;li&gt;whether it deserves immediate attention&lt;/li&gt;
&lt;li&gt;what the recommended action should be&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An LLM can turn structured crawl findings into clear explanations.&lt;/p&gt;

&lt;p&gt;For example, we could provide:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"missing_meta_description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"affected_pages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;174&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"important_commercial_pages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"medium"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM could generate:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;174 pages are missing meta descriptions, including 12 commercially important landing pages. Missing descriptions do not directly prevent indexing, but they reduce control over how these pages may appear in search results. Prioritize high-value landing pages before informational or low-traffic URLs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That saves time without changing the underlying technical diagnosis.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Prioritizing Large SEO Audits
&lt;/h2&gt;

&lt;p&gt;A technical audit can easily produce thousands of individual findings.&lt;/p&gt;

&lt;p&gt;The challenge is rarely:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can we find SEO issues?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The harder question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which issues should we fix first?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is one of the most useful applications for LLMs.&lt;/p&gt;

&lt;p&gt;Instead of asking the model to invent priorities, give it structured context.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"orphan_page"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pages_affected"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;84&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"page_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"organic_traffic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"high"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"conversion_value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"high"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"crawl_depth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare that with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"long_title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pages_affected"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"page_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"blog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"organic_traffic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"low"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"conversion_value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"low"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A good workflow should prioritize the orphaned commercial pages before spending time shortening low-value blog titles.&lt;/p&gt;

&lt;p&gt;The LLM can help group findings into categories such as:&lt;/p&gt;

&lt;h3&gt;
  
  
  Critical
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;important URLs blocked from indexing&lt;/li&gt;
&lt;li&gt;broken canonical implementation&lt;/li&gt;
&lt;li&gt;widespread server errors&lt;/li&gt;
&lt;li&gt;accidental noindex directives&lt;/li&gt;
&lt;li&gt;redirect chains affecting important pages&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  High
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;orphaned commercial pages&lt;/li&gt;
&lt;li&gt;broken internal links&lt;/li&gt;
&lt;li&gt;duplicate pages competing for the same intent&lt;/li&gt;
&lt;li&gt;important pages buried deep in site architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Medium
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;missing metadata&lt;/li&gt;
&lt;li&gt;weak heading structures&lt;/li&gt;
&lt;li&gt;underlinked informational content&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Low
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;minor formatting inconsistencies&lt;/li&gt;
&lt;li&gt;cosmetic metadata opportunities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model should not make these decisions blindly.&lt;/p&gt;

&lt;p&gt;It should be given business and SEO context.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Metadata Analysis at Scale
&lt;/h2&gt;

&lt;p&gt;Title tags and meta descriptions are simple until you have 50,000 URLs.&lt;/p&gt;

&lt;p&gt;At that point, manual review becomes expensive.&lt;/p&gt;

&lt;p&gt;An LLM-powered workflow can help classify metadata into categories such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;missing&lt;/li&gt;
&lt;li&gt;duplicated&lt;/li&gt;
&lt;li&gt;generic&lt;/li&gt;
&lt;li&gt;mismatched with page intent&lt;/li&gt;
&lt;li&gt;overly repetitive&lt;/li&gt;
&lt;li&gt;weakly differentiated&lt;/li&gt;
&lt;li&gt;potentially templated incorrectly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Imagine sending this data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;URL: /services/technical-seo
Title: SEO Services
H1: Technical SEO Services
Primary topic: Technical SEO
Page type: Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A model can identify that the title is technically present but poorly aligned with the page's actual topic.&lt;/p&gt;

&lt;p&gt;That is different from a simple character-count rule.&lt;/p&gt;

&lt;p&gt;A deterministic rule can say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Title exists.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An LLM can say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The title is too generic compared with the page's H1 and topic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is where the combination becomes powerful.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Internal Linking Recommendations
&lt;/h2&gt;

&lt;p&gt;Internal linking is another strong use case.&lt;/p&gt;

&lt;p&gt;Traditional tools can show which pages have very few incoming internal links.&lt;/p&gt;

&lt;p&gt;An LLM can help determine &lt;strong&gt;where relevant links could come from&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Suppose we have a target page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Target:
Technical SEO Audit Services

Topic:
Technical SEO, site audits, crawlability, indexation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And possible source pages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Complete Guide to Technical SEO
2. How to Fix Crawl Errors
3. Social Media Marketing Tips
4. Schema Markup Guide
5. Local SEO Checklist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM can rank relevant internal-link opportunities based on semantic similarity.&lt;/p&gt;

&lt;p&gt;It can also suggest natural anchor text such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;technical SEO audit&lt;/li&gt;
&lt;li&gt;professional SEO audit&lt;/li&gt;
&lt;li&gt;identifying technical SEO issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, human review still matters.&lt;/p&gt;

&lt;p&gt;But the discovery process becomes much faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Schema Markup Generation
&lt;/h2&gt;

&lt;p&gt;Schema markup is a natural area for automation because the output is structured.&lt;/p&gt;

&lt;p&gt;For example, if we know:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Piyush Kumar Soni"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jobTitle"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SEO Expert &amp;amp; AI/LLM Specialist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/piyush"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"worksFor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example Company"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;an LLM can help generate a Person schema template.&lt;/p&gt;

&lt;p&gt;But I would never stop there.&lt;/p&gt;

&lt;p&gt;The workflow should validate the JSON-LD after generation.&lt;/p&gt;

&lt;p&gt;The architecture should be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Entity Data
   ↓
LLM Schema Generation
   ↓
JSON Validation
   ↓
Schema Rules
   ↓
Final Output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not blindly publish generated structured data.&lt;/p&gt;

&lt;p&gt;LLMs can produce valid-looking JSON that contains inaccurate relationships or unsupported properties.&lt;/p&gt;

&lt;p&gt;Schema automation should therefore combine:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLM generation + deterministic validation + human review.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Entity Extraction for SEO and AI Search
&lt;/h2&gt;

&lt;p&gt;Entity SEO becomes particularly interesting as search systems increasingly use semantic relationships rather than isolated keywords.&lt;/p&gt;

&lt;p&gt;An LLM can extract entities from content such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;people&lt;/li&gt;
&lt;li&gt;organizations&lt;/li&gt;
&lt;li&gt;products&lt;/li&gt;
&lt;li&gt;locations&lt;/li&gt;
&lt;li&gt;technologies&lt;/li&gt;
&lt;li&gt;services&lt;/li&gt;
&lt;li&gt;concepts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, from a professional profile it could identify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Person:
Piyush Kumar Soni

Organization:
Lucky Digitals

Expertise:
Technical SEO
Generative Engine Optimization
AI Search
Large Language Models
RAG
Schema Markup
SEO Automation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can help teams examine whether their content consistently communicates important relationships.&lt;/p&gt;

&lt;p&gt;That is useful for traditional search, knowledge graph clarity, and AI-driven retrieval systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. GEO and AI Search Auditing
&lt;/h2&gt;

&lt;p&gt;Generative Engine Optimization is still an evolving area.&lt;/p&gt;

&lt;p&gt;I would be careful about anyone claiming there is a simple checklist that guarantees citations in ChatGPT, Gemini, Perplexity, or other AI systems.&lt;/p&gt;

&lt;p&gt;There isn't.&lt;/p&gt;

&lt;p&gt;However, we can audit factors that make information easier to interpret and retrieve.&lt;/p&gt;

&lt;p&gt;An LLM-assisted GEO audit might examine whether:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the author is clearly identified&lt;/li&gt;
&lt;li&gt;the organization is clearly identified&lt;/li&gt;
&lt;li&gt;expertise is explicit&lt;/li&gt;
&lt;li&gt;important entities are connected consistently&lt;/li&gt;
&lt;li&gt;claims are supported&lt;/li&gt;
&lt;li&gt;sources are cited&lt;/li&gt;
&lt;li&gt;pages answer specific questions directly&lt;/li&gt;
&lt;li&gt;structured data supports visible content&lt;/li&gt;
&lt;li&gt;topics are covered with enough depth&lt;/li&gt;
&lt;li&gt;terminology is consistent across pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Person → worksFor → Organization

Person → knowsAbout → Technical SEO

Person → knowsAbout → AI Search

Article → author → Person
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These relationships can help create a clearer entity footprint.&lt;/p&gt;

&lt;p&gt;The point is not to "trick an LLM."&lt;/p&gt;

&lt;p&gt;The point is to make information less ambiguous.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. SEO Reporting Automation
&lt;/h2&gt;

&lt;p&gt;SEO reporting consumes a surprising amount of agency time.&lt;/p&gt;

&lt;p&gt;Data might come from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Search Console&lt;/li&gt;
&lt;li&gt;Google Analytics&lt;/li&gt;
&lt;li&gt;Ahrefs&lt;/li&gt;
&lt;li&gt;Semrush&lt;/li&gt;
&lt;li&gt;crawlers&lt;/li&gt;
&lt;li&gt;rank trackers&lt;/li&gt;
&lt;li&gt;spreadsheets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The challenge is combining these sources into a useful narrative.&lt;/p&gt;

&lt;p&gt;An LLM can summarize structured metrics.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"organic_clicks_change"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+18%"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"impressions_change"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+24%"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"average_position_change"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-1.8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"technical_errors_fixed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"new_top_10_keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model could generate:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Organic search performance improved during the period, with clicks increasing 18% and impressions rising 24%. Average ranking position improved by 1.8 positions, while 34 technical issues were resolved. Twelve additional keywords entered the top 10.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This type of automation is especially useful because the numbers come from deterministic sources.&lt;/p&gt;

&lt;p&gt;The LLM is simply making them easier to understand.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Turning SEO Data Into Developer Tasks
&lt;/h2&gt;

&lt;p&gt;SEO recommendations often fail at implementation.&lt;/p&gt;

&lt;p&gt;An SEO says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fix canonicalization.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The developer asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Where? How? Which URLs? What is the expected behavior?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An LLM can translate SEO findings into more actionable tickets.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Canonical issue found.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the workflow could generate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Issue:
Category pages are self-canonicalizing correctly, but paginated URLs point to page 1.

Affected templates:
category-pagination.php

Expected behavior:
Each indexable paginated URL should use an appropriate self-referencing canonical unless the SEO strategy specifies otherwise.

Example:
Current:
/category/page/3 → canonical /category/

Expected:
/category/page/3 → canonical /category/page/3/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is significantly more useful to development teams.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Building SEO Content Briefs
&lt;/h2&gt;

&lt;p&gt;Content workflows are another obvious application.&lt;/p&gt;

&lt;p&gt;SEO tools can provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;target keywords&lt;/li&gt;
&lt;li&gt;related queries&lt;/li&gt;
&lt;li&gt;competing pages&lt;/li&gt;
&lt;li&gt;search intent&lt;/li&gt;
&lt;li&gt;entities&lt;/li&gt;
&lt;li&gt;subtopics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An LLM can combine those inputs into a structured brief.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Primary topic:
AI-powered SEO audits

Related topics:
Technical SEO
Python
LLMs
SEO automation
Schema
Internal linking
RAG

Intent:
Informational / technical
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the model can create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;proposed title&lt;/li&gt;
&lt;li&gt;search intent summary&lt;/li&gt;
&lt;li&gt;recommended sections&lt;/li&gt;
&lt;li&gt;questions to answer&lt;/li&gt;
&lt;li&gt;entities to cover&lt;/li&gt;
&lt;li&gt;supporting examples&lt;/li&gt;
&lt;li&gt;internal-link suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the brief should be based on collected data.&lt;/p&gt;

&lt;p&gt;Otherwise we are back to generic AI-generated content.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. RAG for Internal SEO Knowledge
&lt;/h2&gt;

&lt;p&gt;One of the more advanced applications is combining technical SEO automation with Retrieval-Augmented Generation.&lt;/p&gt;

&lt;p&gt;Imagine an SEO agency has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;internal SOPs&lt;/li&gt;
&lt;li&gt;audit templates&lt;/li&gt;
&lt;li&gt;client documentation&lt;/li&gt;
&lt;li&gt;past recommendations&lt;/li&gt;
&lt;li&gt;development standards&lt;/li&gt;
&lt;li&gt;schema guidelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of relying only on the model's general knowledge, the system can retrieve relevant internal documentation before generating recommendations.&lt;/p&gt;

&lt;p&gt;The workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Technical SEO Finding
         ↓
Search Internal Knowledge Base
         ↓
Retrieve Relevant SOP
         ↓
LLM
         ↓
Context-Aware Recommendation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows recommendations to follow the organization's actual processes.&lt;/p&gt;

&lt;p&gt;For example, an agency may have a specific canonicalization policy.&lt;/p&gt;

&lt;p&gt;RAG can retrieve that policy before producing the recommendation.&lt;/p&gt;

&lt;p&gt;That is much more useful than asking a generic model what to do.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. AI Agents for SEO Workflows
&lt;/h2&gt;

&lt;p&gt;Once individual automations are working reliably, they can be connected into agent-style workflows.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Crawl Agent
     ↓
Technical Analysis Agent
     ↓
Entity Analysis Agent
     ↓
Internal Linking Agent
     ↓
Report Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I would still keep critical SEO checks deterministic.&lt;/p&gt;

&lt;p&gt;The agents should orchestrate tasks, not invent facts.&lt;/p&gt;

&lt;p&gt;A safer architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SEO Tools / APIs
      ↓
Verified Data
      ↓
AI Agents
      ↓
Analysis &amp;amp; Recommendations
      ↓
Human Approval
      ↓
Implementation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That human approval layer matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  What LLMs Should NOT Automate Blindly
&lt;/h2&gt;

&lt;p&gt;Automation is useful until it creates more problems than it solves.&lt;/p&gt;

&lt;p&gt;I would not allow an LLM to automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;redirect large numbers of URLs&lt;/li&gt;
&lt;li&gt;change canonical tags sitewide&lt;/li&gt;
&lt;li&gt;add noindex directives&lt;/li&gt;
&lt;li&gt;delete content&lt;/li&gt;
&lt;li&gt;rewrite important commercial pages&lt;/li&gt;
&lt;li&gt;change robots.txt&lt;/li&gt;
&lt;li&gt;modify structured data at scale&lt;/li&gt;
&lt;li&gt;change internal linking across thousands of pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without validation and approval.&lt;/p&gt;

&lt;p&gt;These decisions can have significant SEO consequences.&lt;/p&gt;

&lt;p&gt;AI should accelerate the workflow.&lt;/p&gt;

&lt;p&gt;It should not remove accountability.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Practical LLM + SEO Stack
&lt;/h2&gt;

&lt;p&gt;A simple stack might include:&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Collection
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Screaming Frog&lt;/li&gt;
&lt;li&gt;Sitebulb&lt;/li&gt;
&lt;li&gt;custom Python crawler&lt;/li&gt;
&lt;li&gt;Google Search Console API&lt;/li&gt;
&lt;li&gt;Google Analytics API&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Processing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Pandas&lt;/li&gt;
&lt;li&gt;SQL&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  LLM Layer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI API&lt;/li&gt;
&lt;li&gt;other LLM APIs&lt;/li&gt;
&lt;li&gt;LangChain where orchestration is useful&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  RAG
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;embeddings&lt;/li&gt;
&lt;li&gt;vector database&lt;/li&gt;
&lt;li&gt;internal SEO documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Output
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Google Sheets&lt;/li&gt;
&lt;li&gt;CSV&lt;/li&gt;
&lt;li&gt;dashboards&lt;/li&gt;
&lt;li&gt;client reports&lt;/li&gt;
&lt;li&gt;project-management tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You do not need all of these at once.&lt;/p&gt;

&lt;p&gt;Start with one repetitive task.&lt;/p&gt;

&lt;p&gt;Automate it well.&lt;/p&gt;

&lt;p&gt;Then expand.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Opportunity: SEO + AI
&lt;/h2&gt;

&lt;p&gt;The most interesting part of this shift is not that AI can write title tags faster.&lt;/p&gt;

&lt;p&gt;That is useful, but small.&lt;/p&gt;

&lt;p&gt;The bigger opportunity is building systems that connect:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical SEO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entity SEO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generative Engine Optimization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI Search&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structured Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLM Integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RAG&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SEO professionals already work with large amounts of structured and unstructured information.&lt;/p&gt;

&lt;p&gt;LLMs are very good at working with that type of information when they are given the right context.&lt;/p&gt;

&lt;p&gt;That makes SEO a natural environment for practical AI automation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;LLMs can automate a significant portion of technical SEO workflows, but the strongest systems do not ask the model to do everything.&lt;/p&gt;

&lt;p&gt;Use crawlers and APIs to collect facts.&lt;/p&gt;

&lt;p&gt;Use code and rules to validate those facts.&lt;/p&gt;

&lt;p&gt;Use LLMs to interpret, classify, prioritize, summarize, and communicate.&lt;/p&gt;

&lt;p&gt;Use SEO professionals to make the final strategic decisions.&lt;/p&gt;

&lt;p&gt;That combination is much more reliable than trying to build a completely autonomous "AI SEO expert."&lt;/p&gt;

&lt;p&gt;The future of technical SEO is unlikely to be humans versus AI.&lt;/p&gt;

&lt;p&gt;It looks much more like:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SEO expertise + reliable data + automation + LLM intelligence.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And that is exactly where some of the most interesting SEO engineering work is happening right now.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;About the Author&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Piyush Kumar Soni&lt;/strong&gt; is an &lt;strong&gt;SEO Expert &amp;amp; AI/LLM Specialist&lt;/strong&gt; with 15+ years of experience across SEO, web development and digital marketing. He works on Technical SEO, GEO, AI Search, LLM integration, SEO automation, Entity SEO, Schema Markup, RAG and AI agents.&lt;/p&gt;

&lt;p&gt;Learn more: &lt;a href="https://piyushsoni-ai.github.io/" rel="noopener noreferrer"&gt;Piyush Kumar Soni&lt;/a&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>aiseo</category>
      <category>automation</category>
      <category>technicalseo</category>
    </item>
    <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>
