<?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>Forem: Divyanshu Singh</title>
    <description>The latest articles on Forem by Divyanshu Singh (@divyanshusingh96).</description>
    <link>https://forem.com/divyanshusingh96</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3643823%2F853102e7-4fa5-44b2-bdf4-4ea872b2ccdb.png</url>
      <title>Forem: Divyanshu Singh</title>
      <link>https://forem.com/divyanshusingh96</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/divyanshusingh96"/>
    <language>en</language>
    <item>
      <title>How I built a RAG-powered Anime Recommendation Engine with Python &amp; FastAPI (Open Sourcing the Journey)</title>
      <dc:creator>Divyanshu Singh</dc:creator>
      <pubDate>Wed, 03 Dec 2025 15:45:21 +0000</pubDate>
      <link>https://forem.com/divyanshusingh96/how-i-built-a-rag-powered-anime-recommendation-engine-with-python-fastapi-open-sourcing-the-11mg</link>
      <guid>https://forem.com/divyanshusingh96/how-i-built-a-rag-powered-anime-recommendation-engine-with-python-fastapi-open-sourcing-the-11mg</guid>
      <description>&lt;p&gt;&lt;strong&gt;MyAnimeList recommendations were broken, so I scraped 108 years of history to fix them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Standard anime search engines rely on keyword matching. If you search for &lt;em&gt;"Cyberpunk"&lt;/em&gt;, they look for the tag "Sci-Fi". I wanted to search by &lt;strong&gt;"Vibe"&lt;/strong&gt; (e.g., &lt;em&gt;"Anime that feels like a warm hug"&lt;/em&gt; or &lt;em&gt;"Neon-soaked tragedy"&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;So, I spent the last 2 months building &lt;strong&gt;AiMi&lt;/strong&gt;: A production-grade &lt;strong&gt;Hybrid RAG&lt;/strong&gt; engine.&lt;/p&gt;

&lt;p&gt;Here is the full technical breakdown of how I built it, the architectural challenges I faced (handling 8,000+ embeddings on CPU vs GPU), and the code behind the viral "Anime Receipts" generator.&lt;/p&gt;

&lt;p&gt;

&lt;iframe class="tweet-embed" id="tweet-1994846548740674011-309" src="https://platform.twitter.com/embed/Tweet.html?id=1994846548740674011"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1994846548740674011-309');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1994846548740674011&amp;amp;theme=dark"
  }





&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Data: 108 Years of History (1917-2025)
&lt;/h2&gt;

&lt;p&gt;Garbage in, garbage out. Before building the model, I needed a dataset that didn't exist.&lt;/p&gt;

&lt;p&gt;I aggregated data from &lt;strong&gt;AniDB, and MAL&lt;/strong&gt; to create a unified database of &lt;strong&gt;8,248 anime&lt;/strong&gt;.&lt;br&gt;
The biggest challenge was &lt;strong&gt;Normalization&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ratings:&lt;/strong&gt; AniDB uses floats (0-10), MAL uses integers. I preserved the float precision.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context:&lt;/strong&gt; Raw synopses aren't enough for RAG. I engineered a &lt;code&gt;canonical_embedding_text&lt;/code&gt; field that blends &lt;strong&gt;Themes + Character Archetypes + Emotional Tone&lt;/strong&gt; into a single dense vector block.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🎁 Free Resource:&lt;/strong&gt; I’ve open-sourced a &lt;strong&gt;500-row sample&lt;/strong&gt; of this cleaned dataset on Kaggle for anyone who wants to test their own models:&lt;br&gt;
&lt;a href="https://www.kaggle.com/datasets/divyanshusingh369/aimi-anime-rag-and-receipts-dataset-sample/data" rel="noopener noreferrer"&gt;&lt;strong&gt;Download Sample Dataset&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  2. The Engine: Hybrid RAG Architecture
&lt;/h2&gt;

&lt;p&gt;Most RAG tutorials are "Hello World" toys. I needed this to run in production.&lt;/p&gt;

&lt;p&gt;I settled on a &lt;strong&gt;Hybrid Search&lt;/strong&gt; architecture to balance "Vibe" (Semantic) with "Precision" (Keywords).&lt;/p&gt;
&lt;h3&gt;
  
  
  A. The Embedding Model
&lt;/h3&gt;

&lt;p&gt;I chose &lt;strong&gt;Nomic v1.5&lt;/strong&gt; over OpenAI.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why?&lt;/strong&gt; It outperforms other open-source models like Jina, Stella, and Alibaba-NLP for structured retrieval tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; It runs locally. No API bills.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  B. The "Keyword Boosting" Layer (BM25 Logic)
&lt;/h3&gt;

&lt;p&gt;Vector search is bad at specific nouns. If a user searches for &lt;strong&gt;"Anime about a notebook"&lt;/strong&gt;, vectors might give you "School Life" anime.&lt;br&gt;
I implemented a python-native boosting logic to force specific terms to the top.&lt;/p&gt;

&lt;p&gt;Here is the actual search logic from my pipeline:&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="c1"&gt;# Inside robust_rag_pipeline.py
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# 1. Vector Search (Nomic)
&lt;/span&gt;    &lt;span class="n"&gt;query_emb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_emb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Keyword Boosting (Safety Net)
&lt;/span&gt;    &lt;span class="c1"&gt;# Extract rare nouns (&amp;gt;4 chars) like "Pancreas" or "Notebook"
&lt;/span&gt;    &lt;span class="n"&gt;query_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;anime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;anime_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;anime&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Synopsis&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;anime&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;# Check for exact matches
&lt;/span&gt;        &lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;query_words&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;anime_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Boost score by 5% per match (Max 15%)
&lt;/span&gt;        &lt;span class="n"&gt;boost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;final_score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;boost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.9999&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Solving the "Hardware-Aware" Problem
&lt;/h2&gt;

&lt;p&gt;I wanted this to run on a &lt;strong&gt;MacBook Air&lt;/strong&gt; (CPU) and a &lt;strong&gt;Gaming Rig&lt;/strong&gt; (NVIDIA GPU) without changing code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;On GPU:&lt;/strong&gt; The system loads a local LLM (&lt;strong&gt;Qwen-2.5-1.5B&lt;/strong&gt;) to enable &lt;strong&gt;HyDE&lt;/strong&gt; (Hypothetical Document Embeddings). It "translates" queries like &lt;em&gt;"No fanservice"&lt;/em&gt; into &lt;em&gt;"Wholesome, family friendly"&lt;/em&gt; before searching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On CPU:&lt;/strong&gt; It gracefully degrades to "Lightweight Mode" (Nomic + Boosting only) to prevent timeouts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This "Self-Healing" initialization was critical for deployment:&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="c1"&gt;# Hardware-Aware Initialization
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cuda&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;⚡ GPU Detected: Enabling HyDE (Generative Intent).&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;llm_pipeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_qwen_model&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;⚠️ CPU Detected: Skipping LLM to prevent timeouts.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;llm_pipeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. The Viral Feature: Generating Receipts with Playwright
&lt;/h2&gt;

&lt;p&gt;Data is boring if you can't share it. I wanted users to be able to visualize their watch history as &lt;strong&gt;"Store Receipts."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I used &lt;strong&gt;Playwright&lt;/strong&gt; (headless browser) to render HTML templates into High-DPI images.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftloydna54hyala9ksmg5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftloydna54hyala9ksmg5.png" alt="Tamako Market Front Receipt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvb1xn8qwidi3ppgreqfn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvb1xn8qwidi3ppgreqfn.png" alt="Tamako Market Back Receipt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Challenge:&lt;/strong&gt; Performance. Generating 100 receipts sequentially took forever.&lt;br&gt;
&lt;strong&gt;The Solution:&lt;/strong&gt; &lt;code&gt;asyncio.gather&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="c1"&gt;# Batch Processing Receipts
&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;convert_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;receipts&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;async_playwright&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chromium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;# Create multiple contexts for parallelism
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;receipt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;receipts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
             &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;render_receipt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="c1"&gt;# Execute all renders in parallel
&lt;/span&gt;        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reduced generation time from &lt;strong&gt;40 seconds to 3 seconds&lt;/strong&gt; for a batch.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Build it Yourself (Source Code)
&lt;/h2&gt;

&lt;p&gt;I believe in &lt;strong&gt;Source-Available&lt;/strong&gt; software. You shouldn't have to spend 2 months scraping and refactoring like I did.&lt;/p&gt;

&lt;p&gt;I have packaged the &lt;strong&gt;Entire Ecosystem&lt;/strong&gt; into a "Business-in-a-Box" for developers who want to launch their own Anime SaaS or learn advanced RAG patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  📦 What's in the box?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The 8k RAG Dataset&lt;/strong&gt; (Parquet).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Recommendation Engine&lt;/strong&gt; (FastAPI + Streamlit Source Code).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Receipt Generator&lt;/strong&gt; (Playwright + Async Logic).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Asset Library&lt;/strong&gt; (2.3GB of Posters/Logos).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can clone this, white-label it, and launch your own version today.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 Launch Special (Limited Time)
&lt;/h3&gt;

&lt;p&gt;To celebrate the launch, I'm offering a &lt;strong&gt;10% Discount&lt;/strong&gt; on the Ultimate Tier.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code:&lt;/strong&gt; &lt;code&gt;AIMILAUNCH&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Note:&lt;/strong&gt; I will be raising the prices by $50 after the first 50 sales. Lock it in now.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;💎 &lt;a href="https://divyanshu369.gumroad.com/l/aimi-anime-ecosystem/AIMILAUNCH" rel="noopener noreferrer"&gt;Get the Ultimate Ecosystem (Tier 3)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(If you just want the raw data, Tier 1 is available for $49 &lt;a href="https://divyanshu369.gumroad.com/l/anime-rag-dataset" rel="noopener noreferrer"&gt;here&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Let me know if you have any questions about the &lt;strong&gt;Nomic vs. OpenAI&lt;/strong&gt; benchmarks or the &lt;strong&gt;HyDE implementation&lt;/strong&gt; in the comments!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go make something impossible.&lt;/strong&gt; 🚀&lt;/p&gt;

</description>
      <category>python</category>
      <category>showdev</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
