<?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: Haider Farooq</title>
    <description>The latest articles on DEV Community by Haider Farooq (@haiderfarooq3).</description>
    <link>https://dev.to/haiderfarooq3</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%2F4088012%2F0ef1892f-3846-4dc5-8a3a-21467e7ba729.jpg</url>
      <title>DEV Community: Haider Farooq</title>
      <link>https://dev.to/haiderfarooq3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/haiderfarooq3"/>
    <language>en</language>
    <item>
      <title>RAG That Actually Works: A Practical Checklist</title>
      <dc:creator>Haider Farooq</dc:creator>
      <pubDate>Fri, 21 Aug 2026 10:12:38 +0000</pubDate>
      <link>https://dev.to/haiderfarooq3/rag-that-actually-works-a-practical-checklist-4mnm</link>
      <guid>https://dev.to/haiderfarooq3/rag-that-actually-works-a-practical-checklist-4mnm</guid>
      <description>&lt;p&gt;Retrieval-augmented generation is the most requested AI feature and the most commonly botched. The failure is almost never the generation step -- it's retrieval quietly returning the wrong context, and the model confidently summarizing garbage. This checklist comes from building research and analysis pipelines where wrong retrieval means wrong business decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chunking: respect the document's own structure
&lt;/h2&gt;

&lt;p&gt;Fixed 512-token windows sliced mid-sentence are the default and the mistake. Chunk on semantic boundaries -- headings, paragraphs, table rows -- and prepend each chunk with its breadcrumb ("Annual Report 2025 &amp;gt; Risk Factors &amp;gt; Currency"). A chunk that can't be understood alone can't be retrieved reliably.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hybrid search beats embeddings alone
&lt;/h2&gt;

&lt;p&gt;Dense vectors miss exact identifiers -- SKUs, names, error codes -- that keyword search catches trivially. Run BM25 and vector search in parallel and fuse results (reciprocal rank fusion is fine). This one change fixes a huge share of "the answer was in the corpus but retrieval missed it" tickets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rerank before you generate
&lt;/h2&gt;

&lt;p&gt;First-stage retrieval optimizes recall; a cross-encoder reranker optimizes precision on the top 30-50 candidates. Feeding the model 6 highly relevant chunks beats feeding it 20 mediocre ones -- better answers &lt;em&gt;and&lt;/em&gt; lower token spend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Metadata filters are half the battle
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Store structured fields (date, source, doc type, customer) alongside every chunk.&lt;/li&gt;
&lt;li&gt;Resolve filters &lt;em&gt;before&lt;/em&gt; semantic search -- "latest pricing" should hard-filter on recency, not hope embeddings notice.&lt;/li&gt;
&lt;li&gt;Let the LLM extract the filter from the question with a typed schema, then apply it in the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Answer honesty: refuse to guess
&lt;/h2&gt;

&lt;p&gt;The system prompt must make abstention a first-class outcome: if the retrieved context doesn't contain the answer, say so and show what &lt;em&gt;was&lt;/em&gt; found. Require citations to chunk IDs and render them in the UI. Users forgive "not found"; they don't forgive confident fabrication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluate retrieval separately from generation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Build a golden set of ~50 real questions with known source passages.&lt;/li&gt;
&lt;li&gt;Measure retrieval hit-rate (is the right chunk in the top-k?) -- this isolates most failures.&lt;/li&gt;
&lt;li&gt;Then grade end-to-end answers for faithfulness and completeness.&lt;/li&gt;
&lt;li&gt;Re-run on every change to chunking, embeddings, or prompts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;RAG is a search-quality problem wearing an AI costume. Treat it with the same rigor as the rest of your production agent stack, and it stops being the feature users quietly distrust.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://haiderfarooq.dev/blog/rag-that-actually-works" rel="noopener noreferrer"&gt;haiderfarooq.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rag</category>
      <category>ai</category>
      <category>llm</category>
      <category>python</category>
    </item>
    <item>
      <title>7 Lessons from Building Agentic AI in Production</title>
      <dc:creator>Haider Farooq</dc:creator>
      <pubDate>Fri, 21 Aug 2026 10:01:55 +0000</pubDate>
      <link>https://dev.to/haiderfarooq3/7-lessons-from-building-agentic-ai-in-production-253d</link>
      <guid>https://dev.to/haiderfarooq3/7-lessons-from-building-agentic-ai-in-production-253d</guid>
      <description>&lt;p&gt;For the past year I've been a core engineer on TryCook.ai, an AI operating system that replaced a $3M/year fulfillment team and powers 348+ founders. That means agents doing real, billable work every day -- not demos. Here are the seven lessons that survived contact with production.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The agent is 20% of the system
&lt;/h2&gt;

&lt;p&gt;The LLM call is the easy part. The other 80% is queues, retries, idempotency keys, state machines, audit logs, and rollback paths. If you architect the agent as a stateless function inside a boring, observable pipeline, failures become recoverable. If the agent &lt;em&gt;is&lt;/em&gt; the pipeline, every hallucination is an outage.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Constrain outputs structurally, not rhetorically
&lt;/h2&gt;

&lt;p&gt;Prompts that beg the model to "only respond with valid JSON" fail at scale. Schema-enforced outputs (tool calling, JSON mode, grammar constraints) fail approximately never. Every agent boundary in our stack is a typed contract -- if the model can't fill the schema, that's a retry, not a parse error downstream.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Design for the 2% failure case first
&lt;/h2&gt;

&lt;p&gt;An agent that's 98% autonomous still fails dozens of times a day at volume. The difference between a product and a liability is what happens on failure: does the task land in a human review queue with full context, or does it silently vanish? Build the escalation path before you build the happy path.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Small models for routing, big models for judgment
&lt;/h2&gt;

&lt;p&gt;Most agent steps are classification, extraction, or formatting -- cheap-model work. Reserve frontier models for the few steps that need actual judgment. This is the core of cost engineering for LLM products, and it routinely cuts spend 5-10x with no quality loss.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Memory is a database problem, not a prompt problem
&lt;/h2&gt;

&lt;p&gt;Long-running agents need durable state: what they did, what they learned, what the customer prefers. Stuffing history into the context window doesn't scale and isn't queryable. Model agent memory as normal rows -- events, facts, preferences -- and retrieve selectively. Retrieval discipline is the same skill as building RAG that works.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Evals are your regression tests
&lt;/h2&gt;

&lt;p&gt;Every prompt change ships against a fixed eval set of real (anonymized) cases with graded outputs. Without evals, prompt engineering is vibes; with them, it's engineering. Start with 30 cases and a pass/fail rubric -- you can grow sophistication later, but you can't retrofit confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Humans are a feature, not a fallback
&lt;/h2&gt;

&lt;p&gt;The systems that win don't remove humans -- they move humans up the stack. In a well-designed agentic system, one operator supervises the throughput that used to take a team, intervening only on flagged exceptions. Frame it that way and adoption stops being a fight.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Agents don't replace engineering discipline. They punish the lack of it, at machine speed.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://haiderfarooq.dev/blog/lessons-agentic-ai-production" rel="noopener noreferrer"&gt;haiderfarooq.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Get Cited by AI Search Engines: A Practical GEO Checklist</title>
      <dc:creator>Haider Farooq</dc:creator>
      <pubDate>Fri, 21 Aug 2026 09:59:59 +0000</pubDate>
      <link>https://dev.to/haiderfarooq3/how-to-get-cited-by-ai-search-engines-a-practical-geo-checklist-4ae7</link>
      <guid>https://dev.to/haiderfarooq3/how-to-get-cited-by-ai-search-engines-a-practical-geo-checklist-4ae7</guid>
      <description>&lt;p&gt;Search is splitting in two. Classic Google still matters, but a growing share of discovery now happens inside ChatGPT, Perplexity, Claude, and Google's AI Overviews. Those engines don't rank ten blue links — they synthesize an answer and cite a handful of sources. Getting cited is the new ranking. The practice of engineering for it is called &lt;strong&gt;Generative Engine Optimization (GEO)&lt;/strong&gt;, and this post documents the exact setup running on my site.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Let the AI crawlers in
&lt;/h2&gt;

&lt;p&gt;Every AI engine has its own crawler, and many sites block them by accident with a blanket rule. Your &lt;code&gt;robots.txt&lt;/code&gt; should explicitly allow the bots you want: &lt;code&gt;GPTBot&lt;/code&gt; and &lt;code&gt;OAI-SearchBot&lt;/code&gt; (OpenAI), &lt;code&gt;PerplexityBot&lt;/code&gt;, &lt;code&gt;ClaudeBot&lt;/code&gt; and &lt;code&gt;anthropic-ai&lt;/code&gt; (Anthropic), &lt;code&gt;Google-Extended&lt;/code&gt; (Gemini training), &lt;code&gt;Applebot-Extended&lt;/code&gt; (Apple Intelligence), and &lt;code&gt;CCBot&lt;/code&gt; (Common Crawl, which feeds many models).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;Agent&lt;/span&gt;: &lt;span class="n"&gt;GPTBot&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;Agent&lt;/span&gt;: &lt;span class="n"&gt;OAI&lt;/span&gt;-&lt;span class="n"&gt;SearchBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;Agent&lt;/span&gt;: &lt;span class="n"&gt;PerplexityBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;User&lt;/span&gt;-&lt;span class="n"&gt;Agent&lt;/span&gt;: &lt;span class="n"&gt;ClaudeBot&lt;/span&gt;
&lt;span class="n"&gt;Allow&lt;/span&gt;: /

&lt;span class="n"&gt;Sitemap&lt;/span&gt;: &lt;span class="n"&gt;https&lt;/span&gt;://&lt;span class="n"&gt;haiderfarooq&lt;/span&gt;.&lt;span class="n"&gt;dev&lt;/span&gt;/&lt;span class="n"&gt;sitemap&lt;/span&gt;.&lt;span class="n"&gt;xml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Ship an llms.txt
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; is an emerging convention: a plain-markdown file at your site root that gives language models a compressed, structured summary of who you are and what your pages contain. Think of it as a sitemap for meaning rather than URLs. Keep it under a few hundred lines, lead with a one-sentence identity statement, and list your key pages with one-line summaries each. A fuller &lt;code&gt;llms-full.txt&lt;/code&gt; can carry the long version.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Build an entity graph with JSON-LD
&lt;/h2&gt;

&lt;p&gt;AI engines resolve &lt;em&gt;entities&lt;/em&gt;, not keywords. Schema.org JSON-LD is how you declare them unambiguously. The minimum viable graph for a personal site: a &lt;code&gt;Person&lt;/code&gt; node with &lt;code&gt;@id&lt;/code&gt;, &lt;code&gt;sameAs&lt;/code&gt; links to GitHub/LinkedIn/X, &lt;code&gt;knowsAbout&lt;/code&gt;, and &lt;code&gt;hasOccupation&lt;/code&gt;; a &lt;code&gt;WebSite&lt;/code&gt; node; and &lt;code&gt;CreativeWork&lt;/code&gt; or &lt;code&gt;Article&lt;/code&gt; nodes for project pages. Crucially, use stable &lt;code&gt;@id&lt;/code&gt; URIs and reference them across pages so crawlers can stitch the graph together.&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;"@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;"Person"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@id"&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://haiderfarooq.dev/#person"&lt;/span&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;"Haider Farooq"&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;"AI Engineer &amp;amp; Data Scientist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sameAs"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="s2"&gt;"https://github.com/haiderfarooq3"&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://www.linkedin.com/in/haiderfarooqdev/"&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;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;h2&gt;
  
  
  4. Write outcome-first copy
&lt;/h2&gt;

&lt;p&gt;LLMs extract and repeat concrete numbers. "$12.1M in client revenue", "141 districts", "5,500+ patients" — figures like these survive summarization; adjectives don't. Put at least one hard number in the first 150 words of every page. Write bios in third person ("Haider Farooq is an AI engineer…") because that's the frame AI answers use when citing you.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Freshness and internal linking still matter
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Update pages on a real cadence — stale &lt;code&gt;lastmod&lt;/code&gt; dates in your sitemap depress recrawl priority.&lt;/li&gt;
&lt;li&gt;Interlink related pages with descriptive anchor text; AI crawlers follow links to build context just like Googlebot does.&lt;/li&gt;
&lt;li&gt;Use IndexNow to ping Bing (which feeds ChatGPT search and Copilot) the moment content changes.&lt;/li&gt;
&lt;li&gt;Keep canonical URLs consistent — one host, one protocol, no trailing-slash ambiguity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The checklist
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;robots.txt&lt;/code&gt; allows GPTBot, OAI-SearchBot, PerplexityBot, ClaudeBot, Google-Extended, CCBot&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;llms.txt&lt;/code&gt; + &lt;code&gt;llms-full.txt&lt;/code&gt; at site root&lt;/li&gt;
&lt;li&gt;JSON-LD Person/WebSite/Article graph with stable &lt;code&gt;@id&lt;/code&gt; URIs&lt;/li&gt;
&lt;li&gt;One concrete metric in the first 150 words of every page&lt;/li&gt;
&lt;li&gt;Sitemap with honest &lt;code&gt;lastmod&lt;/code&gt; dates, submitted to Google Search Console and Bing&lt;/li&gt;
&lt;li&gt;IndexNow key installed and pinged on every deploy&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of this replaces good content — it makes good content legible to machines.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://haiderfarooq.dev/blog/geo-visibility-ai-search" rel="noopener noreferrer"&gt;haiderfarooq.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>ai</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
