<?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: Sébastien Descloux</title>
    <description>The latest articles on DEV Community by Sébastien Descloux (@sdx_development).</description>
    <link>https://dev.to/sdx_development</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%2F4106878%2Fc3dfd247-539f-47a6-a7ce-100d3e95245b.png</url>
      <title>DEV Community: Sébastien Descloux</title>
      <link>https://dev.to/sdx_development</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sdx_development"/>
    <language>en</language>
    <item>
      <title>EmbeddingGemma 2: Building Local Multimodal RAG with Python</title>
      <dc:creator>Sébastien Descloux</dc:creator>
      <pubDate>Wed, 07 Oct 2026 21:54:23 +0000</pubDate>
      <link>https://dev.to/sdx_development/embeddinggemma-2-building-local-multimodal-rag-with-python-3l4k</link>
      <guid>https://dev.to/sdx_development/embeddinggemma-2-building-local-multimodal-rag-with-python-3l4k</guid>
      <description>&lt;p&gt;What if an AI search application could retrieve information from internal documentation, source code, screenshots, and recordings &lt;strong&gt;without sending those files to an external embedding API&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;On October 6, 2026, Google DeepMind introduced &lt;strong&gt;EmbeddingGemma 2&lt;/strong&gt;, an open-weight multimodal embedding model released under the Apache 2.0 license. It brings text, code, images, video, and audio into a &lt;strong&gt;shared 768-dimensional vector space&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For developers building Retrieval-Augmented Generation (RAG) systems, the most interesting question is architectural: &lt;strong&gt;which parts of retrieval can run directly on the user's device?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why local multimodal retrieval matters
&lt;/h2&gt;

&lt;p&gt;A typical RAG pipeline prepares documents, creates embeddings, retrieves relevant passages, and optionally sends those passages to a generative language model. Depending on its design, the pipeline may transmit content to third-party services.&lt;/p&gt;

&lt;p&gt;Local retrieval offers a different trade-off:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data locality:&lt;/strong&gt; encoding and searching can take place on the device holding the files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline access:&lt;/strong&gt; once the model, runtime, and index are available, retrieval can work without a network connection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure control:&lt;/strong&gt; fewer per-query embedding API calls, but more memory, CPU/GPU, and storage requirements on the device.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This does not make cloud APIs obsolete. For public data or centrally managed services, a remote API can still be the right engineering choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  EmbeddingGemma 2 in numbers
&lt;/h2&gt;

&lt;p&gt;The model uses modular encoders that share a compatible embedding space:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;th&gt;Parameters&lt;/th&gt;
&lt;th&gt;Typical content&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Text and code&lt;/td&gt;
&lt;td&gt;270M&lt;/td&gt;
&lt;td&gt;Documentation, codebases, knowledge bases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text + vision&lt;/td&gt;
&lt;td&gt;440M&lt;/td&gt;
&lt;td&gt;Images, diagrams, video frames&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text + audio&lt;/td&gt;
&lt;td&gt;570M&lt;/td&gt;
&lt;td&gt;Recordings and speech&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full multimodal&lt;/td&gt;
&lt;td&gt;740M&lt;/td&gt;
&lt;td&gt;Text, code, images, video, audio&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The shared representation makes it possible to compare a text query with an image or audio segment without requiring a separate caption or transcript in every workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; EmbeddingGemma 2 is an embedding model, &lt;strong&gt;not a generative LLM&lt;/strong&gt;. It helps find relevant content. If you want a written answer, you need a separate generation step. For fully on-device RAG, that generative model must also run locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compare three RAG architectures
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Remote embedding API
&lt;/h3&gt;

&lt;p&gt;A service provider computes the vectors; the application stores and queries an index locally or on a server. This can simplify deployment, but introduces considerations around network access, data handling, and recurring costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Local text-only RAG
&lt;/h3&gt;

&lt;p&gt;A compact text encoder and retrieval index live on the user's device. This is a practical starting point for notes, internal documentation, and code search. Document parsing, chunking, and access control still matter.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Local multimodal RAG
&lt;/h3&gt;

&lt;p&gt;Additional encoders make screenshots, diagrams, sound, and video searchable within a common representation. This can improve retrieval when essential information is not purely textual, at the cost of more processing and memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  A minimal Python example
&lt;/h2&gt;

&lt;p&gt;Google documents EmbeddingGemma 2 with &lt;code&gt;sentence-transformers&lt;/code&gt; &lt;strong&gt;6.1.0 or newer&lt;/strong&gt;. Install the dependencies in your Python environment:&lt;br&gt;
&lt;/p&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; &lt;span class="nt"&gt;-U&lt;/span&gt; &lt;span class="s2"&gt;"sentence-transformers[image,audio,video]"&lt;/span&gt; transformers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a text-only prototype, omit the encoders you do not need:&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;sentence_transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&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;SentenceTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;google/embeddinggemma-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;config_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;vision_config&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;audio_config&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;documents&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;The application enforces document access permissions.&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;The meeting notes describe a local retrieval architecture.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;question&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Where can I find information about offline search?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;document_vectors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&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="n"&gt;prompt_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Document&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;normalize_embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;query_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;prompt_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SearchQuery&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;normalize_embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_vector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document_vectors&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;best_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&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="nf"&gt;argmax&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;documents&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;best_match&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns a &lt;strong&gt;retrieved passage&lt;/strong&gt;, not an AI-generated answer. The first run requires downloading model weights. Subsequent encoding can work offline when all necessary resources have been cached.&lt;/p&gt;

&lt;p&gt;A production search system should also store stable document identifiers and source locations, handle updates incrementally, and enforce document-level permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cross-modal search with images and audio
&lt;/h2&gt;

&lt;p&gt;With the full model, media can be embedded by passing a dictionary keyed by modality:&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="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SentenceTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;google/embeddinggemma-2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;image_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image&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;architecture.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;audio_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;audio&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;meeting.wav&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;query_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;discussion about application architecture&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;prompt_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SearchQuery&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Image:&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_vector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_vector&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Audio:&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_vector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;audio_vector&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The sample files must exist and be compatible with the runtime. For longer recordings, &lt;strong&gt;index meaningful segments with timestamps&lt;/strong&gt;: a vector for an entire video cannot reliably locate a particular moment. PDFs with diagrams may require image-based retrieval alongside extracted text and, for scanned pages, OCR.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory and vector storage
&lt;/h2&gt;

&lt;p&gt;EmbeddingGemma 2 supports &lt;strong&gt;Matryoshka Representation Learning&lt;/strong&gt;, so embeddings can be shortened from 768 dimensions to 512, 256, or 128. For example, one million raw &lt;code&gt;float32&lt;/code&gt; vectors require approximately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;3.07 GB&lt;/strong&gt; at 768 dimensions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1.02 GB&lt;/strong&gt; at 256 dimensions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These figures exclude metadata and index overhead. Queries and indexed content need matching dimensions, and smaller vectors should be evaluated for retrieval quality on your actual dataset.&lt;/p&gt;

&lt;p&gt;Google has also published memory figures for optimized configurations on specific devices. Those are &lt;strong&gt;not universal memory guarantees&lt;/strong&gt; for a Python application or every browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does on-device retrieval guarantee privacy?
&lt;/h2&gt;

&lt;p&gt;Not automatically. A privacy-oriented deployment also needs to answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do model downloads, analytics, logs, or synchronization transmit sensitive data?&lt;/li&gt;
&lt;li&gt;How are files, embeddings, and metadata protected at rest?&lt;/li&gt;
&lt;li&gt;Does retrieval enforce user permissions before displaying results?&lt;/li&gt;
&lt;li&gt;Is retrieved content treated as untrusted input to prevent prompt injection?&lt;/li&gt;
&lt;li&gt;Does the final LLM run on-device or receive selected documents through an API?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Local embeddings reduce certain data transfers; they do not replace a complete security design.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to evaluate it reproducibly
&lt;/h2&gt;

&lt;p&gt;A useful evaluation can compare remote embeddings, local text retrieval, and local multimodal retrieval using &lt;strong&gt;the same authorized corpus, questions, and target hardware&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prepare representative documents and media, plus 30–50 questions with expected retrieval results.&lt;/li&gt;
&lt;li&gt;Measure &lt;strong&gt;recall@k&lt;/strong&gt;, source relevance, indexing time, retrieval latency, peak memory, and storage.&lt;/li&gt;
&lt;li&gt;Repeat with 768-dimensional and 256-dimensional vectors to measure the quality/storage trade-off.&lt;/li&gt;
&lt;li&gt;Add a generative LLM only if the user experience truly needs written answers, and test cases where the system should abstain.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is a &lt;strong&gt;proposed evaluation method&lt;/strong&gt;, not a report of independent benchmarks or a description of a deployed product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;EmbeddingGemma 2 provides an intriguing building block for multimodal search over sensitive, heterogeneous content on local devices. It does not remove the need for good segmentation, source metadata, evaluation, permissions, or a separate generative model.&lt;/p&gt;

&lt;p&gt;The key engineering decision is &lt;strong&gt;where each stage of the retrieval pipeline should run&lt;/strong&gt;, given the application's performance, privacy, and usability constraints.&lt;/p&gt;

&lt;p&gt;For a more detailed discussion of the architecture, examples, and practical limitations, see the original English article on &lt;strong&gt;&lt;a href="https://sdx-development.com/en/news/applied-ai/multimodal-rag-that-stays-on-your-device" rel="noopener noreferrer"&gt;SDX Development&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Official references
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.googleblog.com/embeddinggemma-2-the-developer-guide/" rel="noopener noreferrer"&gt;Google Developers Blog — EmbeddingGemma 2: The Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.googleblog.com/google-ai-edge-with-embeddinggemma-2/" rel="noopener noreferrer"&gt;Google AI Edge — EmbeddingGemma 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Discussion:&lt;/strong&gt; Which stage would you move on-device first: embeddings, retrieval, or generation?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>rag</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>EmDash 1.0 vs WordPress: When Should You Consider This Astro CMS?</title>
      <dc:creator>Sébastien Descloux</dc:creator>
      <pubDate>Wed, 30 Sep 2026 22:00:00 +0000</pubDate>
      <link>https://dev.to/sdx_development/emdash-10-vs-wordpress-when-should-you-consider-this-astro-cms-2780</link>
      <guid>https://dev.to/sdx_development/emdash-10-vs-wordpress-when-should-you-consider-this-astro-cms-2780</guid>
      <description>&lt;p&gt;Cloudflare recently released &lt;strong&gt;EmDash 1.0&lt;/strong&gt;, an open-source CMS built around &lt;strong&gt;Astro and TypeScript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It comes with an admin interface, structured content, media management, localization, APIs, a CLI, a plugin system, and even an integrated MCP server.&lt;/p&gt;

&lt;p&gt;That sounds promising.&lt;/p&gt;

&lt;p&gt;But the interesting question is not whether EmDash is a new “WordPress killer”.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;For which projects does an Astro-based CMS like EmDash actually make more sense than WordPress?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And if you already have a WordPress website, what does migrating to EmDash really involve?&lt;/p&gt;




&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;EmDash 1.0 looks particularly interesting for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;custom Astro websites&lt;/li&gt;
&lt;li&gt;TypeScript-heavy projects&lt;/li&gt;
&lt;li&gt;structured-content platforms&lt;/li&gt;
&lt;li&gt;multilingual sites&lt;/li&gt;
&lt;li&gt;projects where developers want full control over the frontend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WordPress still has a major advantage when a project depends on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a large plugin ecosystem&lt;/li&gt;
&lt;li&gt;WooCommerce&lt;/li&gt;
&lt;li&gt;page builders&lt;/li&gt;
&lt;li&gt;LMS or membership plugins&lt;/li&gt;
&lt;li&gt;mature third-party integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest mistake would be to treat a WordPress → EmDash migration as a simple content import.&lt;/p&gt;

&lt;p&gt;In many cases, it is closer to a &lt;strong&gt;technical rebuild&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is EmDash?
&lt;/h2&gt;

&lt;p&gt;EmDash adds CMS capabilities to an Astro project.&lt;/p&gt;

&lt;p&gt;Instead of starting with a traditional CMS and building the frontend inside it, the architecture is closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Astro
  ↓
Your frontend
  ↓
EmDash CMS
  ↓
Structured content / database / media
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Astro remains the foundation of the application.&lt;/p&gt;

&lt;p&gt;EmDash provides the editorial layer.&lt;/p&gt;

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

&lt;p&gt;With WordPress, the CMS is usually both the runtime and the content platform.&lt;/p&gt;

&lt;p&gt;With EmDash, your Astro project stays at the center of the architecture.&lt;/p&gt;

&lt;p&gt;For teams already working with TypeScript, this can result in a much more consistent stack.&lt;/p&gt;




&lt;h2&gt;
  
  
  A TypeScript-first CMS architecture
&lt;/h2&gt;

&lt;p&gt;One of the most attractive aspects of EmDash is that developers can stay inside a modern JavaScript/TypeScript ecosystem.&lt;/p&gt;

&lt;p&gt;A project can combine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Astro for routing and rendering&lt;/li&gt;
&lt;li&gt;TypeScript for application logic&lt;/li&gt;
&lt;li&gt;EmDash for content management&lt;/li&gt;
&lt;li&gt;SQL-based storage&lt;/li&gt;
&lt;li&gt;local or S3-compatible media storage&lt;/li&gt;
&lt;li&gt;APIs and CLI tools for automation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is very different from maintaining a WordPress installation containing PHP templates, JavaScript, multiple plugins and several layers of custom code.&lt;/p&gt;

&lt;p&gt;But “different” does not automatically mean “better”.&lt;/p&gt;

&lt;p&gt;It depends heavily on the project.&lt;/p&gt;




&lt;h1&gt;
  
  
  EmDash vs WordPress by use case
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. A custom marketing website
&lt;/h2&gt;

&lt;p&gt;This is probably one of the most interesting use cases for EmDash.&lt;/p&gt;

&lt;p&gt;Imagine a company website with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a custom design&lt;/li&gt;
&lt;li&gt;20–50 pages&lt;/li&gt;
&lt;li&gt;a blog&lt;/li&gt;
&lt;li&gt;case studies&lt;/li&gt;
&lt;li&gt;team profiles&lt;/li&gt;
&lt;li&gt;a few forms&lt;/li&gt;
&lt;li&gt;multilingual content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With WordPress, this could involve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a custom theme&lt;/li&gt;
&lt;li&gt;Advanced Custom Fields or similar tooling&lt;/li&gt;
&lt;li&gt;SEO plugins&lt;/li&gt;
&lt;li&gt;form plugins&lt;/li&gt;
&lt;li&gt;multilingual plugins&lt;/li&gt;
&lt;li&gt;performance plugins&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Astro + EmDash, much of the frontend can simply be implemented as components while EmDash manages editable content.&lt;/p&gt;

&lt;p&gt;For a development team already comfortable with Astro, this can be a very clean architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. A multilingual blog
&lt;/h2&gt;

&lt;p&gt;EmDash also has an interesting approach to localization.&lt;/p&gt;

&lt;p&gt;Translations can be managed as separate content variants with their own slugs and publication states.&lt;/p&gt;

&lt;p&gt;This is useful when, for example, the English version of an article is published while the French translation is still a draft.&lt;/p&gt;

&lt;p&gt;For a new multilingual project, that model is attractive.&lt;/p&gt;

&lt;p&gt;Migrating an existing WordPress multilingual site, however, is more complicated.&lt;/p&gt;

&lt;p&gt;A WordPress export does not automatically reproduce every relationship created by tools such as WPML or Polylang.&lt;/p&gt;

&lt;p&gt;That means multilingual migrations need to be tested carefully.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. A highly customized application
&lt;/h2&gt;

&lt;p&gt;This is where EmDash becomes especially interesting.&lt;/p&gt;

&lt;p&gt;Consider a website containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;custom content types&lt;/li&gt;
&lt;li&gt;business APIs&lt;/li&gt;
&lt;li&gt;application-specific forms&lt;/li&gt;
&lt;li&gt;structured relationships&lt;/li&gt;
&lt;li&gt;automation&lt;/li&gt;
&lt;li&gt;custom dashboards&lt;/li&gt;
&lt;li&gt;third-party services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At some point, a heavily customized WordPress project starts behaving more like a web application than a traditional CMS.&lt;/p&gt;

&lt;p&gt;In that situation, using Astro and TypeScript directly can be attractive.&lt;/p&gt;

&lt;p&gt;Instead of forcing application logic into WordPress hooks and plugin conventions, developers can build the application using the same tools they would use for any other TypeScript project.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. A WordPress site with 20+ plugins
&lt;/h2&gt;

&lt;p&gt;This is almost the opposite scenario.&lt;/p&gt;

&lt;p&gt;Suppose a WordPress site relies on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WooCommerce&lt;/li&gt;
&lt;li&gt;Elementor&lt;/li&gt;
&lt;li&gt;an SEO suite&lt;/li&gt;
&lt;li&gt;advanced forms&lt;/li&gt;
&lt;li&gt;memberships&lt;/li&gt;
&lt;li&gt;analytics plugins&lt;/li&gt;
&lt;li&gt;newsletter integrations&lt;/li&gt;
&lt;li&gt;custom payment gateways&lt;/li&gt;
&lt;li&gt;several business-specific plugins&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Moving that site to EmDash is not simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Export WordPress
→
Import EmDash
→
Done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every important dependency needs to be reviewed.&lt;/p&gt;

&lt;p&gt;For each plugin, you have to decide whether the feature will be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;replaced by an EmDash feature&lt;/li&gt;
&lt;li&gt;replaced by another service&lt;/li&gt;
&lt;li&gt;implemented through an EmDash plugin&lt;/li&gt;
&lt;li&gt;rebuilt in TypeScript&lt;/li&gt;
&lt;li&gt;removed completely&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is why plugin inventory is one of the most important parts of migration planning.&lt;/p&gt;




&lt;h1&gt;
  
  
  What actually migrates from WordPress?
&lt;/h1&gt;

&lt;p&gt;EmDash includes tooling for WordPress migration.&lt;/p&gt;

&lt;p&gt;Content can be imported using WordPress export data, and EmDash also provides tooling designed to extract additional data from an existing WordPress installation.&lt;/p&gt;

&lt;p&gt;Typical migration candidates include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;posts&lt;/li&gt;
&lt;li&gt;pages&lt;/li&gt;
&lt;li&gt;custom post types&lt;/li&gt;
&lt;li&gt;taxonomies&lt;/li&gt;
&lt;li&gt;authors&lt;/li&gt;
&lt;li&gt;media references&lt;/li&gt;
&lt;li&gt;some metadata&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But importing content is only one part of the project.&lt;/p&gt;




&lt;h1&gt;
  
  
  Your WordPress theme does not migrate
&lt;/h1&gt;

&lt;p&gt;A PHP WordPress theme cannot simply be installed inside EmDash.&lt;/p&gt;

&lt;p&gt;The frontend must be rebuilt with Astro.&lt;/p&gt;

&lt;p&gt;For example, a WordPress template 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;single.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;might become an Astro route similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/pages/posts/[slug].astro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The visual design can obviously be recreated.&lt;/p&gt;

&lt;p&gt;The implementation is what changes.&lt;/p&gt;

&lt;p&gt;In many projects, this is actually an opportunity.&lt;/p&gt;

&lt;p&gt;A migration can be used to remove years of accumulated technical debt instead of reproducing an old WordPress architecture exactly.&lt;/p&gt;




&lt;h1&gt;
  
  
  WordPress plugins do not magically become EmDash plugins
&lt;/h1&gt;

&lt;p&gt;This is another critical point.&lt;/p&gt;

&lt;p&gt;Existing WordPress plugins are not directly compatible with EmDash.&lt;/p&gt;

&lt;p&gt;Their functionality needs to be analyzed and, where necessary, ported or rebuilt.&lt;/p&gt;

&lt;p&gt;For a custom WordPress plugin, developers may need to review things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hooks&lt;/li&gt;
&lt;li&gt;REST endpoints&lt;/li&gt;
&lt;li&gt;custom database tables&lt;/li&gt;
&lt;li&gt;cron jobs&lt;/li&gt;
&lt;li&gt;admin screens&lt;/li&gt;
&lt;li&gt;shortcodes&lt;/li&gt;
&lt;li&gt;blocks&lt;/li&gt;
&lt;li&gt;external integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some plugins may no longer be required at all.&lt;/p&gt;

&lt;p&gt;A caching plugin designed around a traditional PHP WordPress runtime, for example, might have no equivalent purpose in a completely different architecture.&lt;/p&gt;

&lt;p&gt;The useful question is therefore not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do we migrate every plugin?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What functionality does each plugin provide, and do we still need it?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  What about plugins in EmDash?
&lt;/h1&gt;

&lt;p&gt;EmDash 1.0 also introduces its own plugin architecture.&lt;/p&gt;

&lt;p&gt;One interesting part of the model is the ability to run some plugins inside isolated environments with explicit permissions.&lt;/p&gt;

&lt;p&gt;That creates a different security model from the traditional WordPress approach where plugins frequently execute inside the same PHP runtime as the application.&lt;/p&gt;

&lt;p&gt;EmDash also supports native plugins for features that require deeper integration.&lt;/p&gt;

&lt;p&gt;The architecture is promising.&lt;/p&gt;

&lt;p&gt;The ecosystem, however, is still extremely young compared with WordPress.&lt;/p&gt;

&lt;p&gt;And that matters.&lt;/p&gt;




&lt;h1&gt;
  
  
  Ecosystem maturity is still WordPress' biggest advantage
&lt;/h1&gt;

&lt;p&gt;WordPress has been around for more than two decades.&lt;/p&gt;

&lt;p&gt;Its ecosystem includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tens of thousands of plugins&lt;/li&gt;
&lt;li&gt;thousands of themes&lt;/li&gt;
&lt;li&gt;hosting providers&lt;/li&gt;
&lt;li&gt;agencies&lt;/li&gt;
&lt;li&gt;freelancers&lt;/li&gt;
&lt;li&gt;integrations&lt;/li&gt;
&lt;li&gt;documentation&lt;/li&gt;
&lt;li&gt;tutorials&lt;/li&gt;
&lt;li&gt;existing solutions for almost every common website requirement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;EmDash 1.0 cannot reproduce that overnight.&lt;/p&gt;

&lt;p&gt;So if your project depends heavily on ready-made functionality, WordPress still offers something extremely valuable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;maturity.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On the other hand, if you were going to build most of the functionality yourself anyway, the difference becomes much smaller.&lt;/p&gt;




&lt;h1&gt;
  
  
  A WordPress → EmDash migration is often a rebuild
&lt;/h1&gt;

&lt;p&gt;For a professional project, I would approach the migration in roughly this order.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Audit the existing WordPress site
&lt;/h3&gt;

&lt;p&gt;Identify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;content types&lt;/li&gt;
&lt;li&gt;taxonomies&lt;/li&gt;
&lt;li&gt;plugins&lt;/li&gt;
&lt;li&gt;custom fields&lt;/li&gt;
&lt;li&gt;shortcodes&lt;/li&gt;
&lt;li&gt;theme customizations&lt;/li&gt;
&lt;li&gt;forms&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;redirects&lt;/li&gt;
&lt;li&gt;SEO metadata&lt;/li&gt;
&lt;li&gt;multilingual content&lt;/li&gt;
&lt;li&gt;scheduled jobs&lt;/li&gt;
&lt;li&gt;business integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Classify every dependency
&lt;/h3&gt;

&lt;p&gt;Decide whether each feature should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;imported&lt;/li&gt;
&lt;li&gt;replaced&lt;/li&gt;
&lt;li&gt;rebuilt&lt;/li&gt;
&lt;li&gt;connected to an external service&lt;/li&gt;
&lt;li&gt;removed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Import a small content sample
&lt;/h3&gt;

&lt;p&gt;Don't migrate thousands of posts immediately.&lt;/p&gt;

&lt;p&gt;Start with representative examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Rebuild the frontend in Astro
&lt;/h3&gt;

&lt;p&gt;Create routes, layouts and components based&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>astro</category>
      <category>wordpress</category>
      <category>typescript</category>
    </item>
    <item>
      <title>I Built a RAG AI Assistant That Runs in the Browser with WebGPU</title>
      <dc:creator>Sébastien Descloux</dc:creator>
      <pubDate>Sun, 27 Sep 2026 19:28:01 +0000</pubDate>
      <link>https://dev.to/sdx_development/i-built-a-rag-ai-assistant-that-runs-in-the-browser-with-webgpu-2m4n</link>
      <guid>https://dev.to/sdx_development/i-built-a-rag-ai-assistant-that-runs-in-the-browser-with-webgpu-2m4n</guid>
      <description>&lt;p&gt;A website may already contain the answers visitors need.&lt;/p&gt;

&lt;p&gt;The real problem is often finding them.&lt;/p&gt;

&lt;p&gt;So I built and deployed a first version of a &lt;strong&gt;RAG AI assistant&lt;/strong&gt; for my own website, with one particular constraint:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The response model runs directly in the visitor's browser using WebGPU.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This was not meant to be another chatbot connected to an API.&lt;/p&gt;

&lt;p&gt;I wanted to explore what happens when retrieval, local inference, source-based answers, conversation context, and a CMS are designed as one complete workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the architecture works
&lt;/h2&gt;

&lt;p&gt;The system splits the work between the website server and the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The CMS prepares the knowledge base
&lt;/h3&gt;

&lt;p&gt;Selected website content is split into passages and indexed.&lt;/p&gt;

&lt;p&gt;The CMS also lets me manage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which documents are available to the assistant&lt;/li&gt;
&lt;li&gt;model profiles&lt;/li&gt;
&lt;li&gt;search parameters&lt;/li&gt;
&lt;li&gt;assistant instructions&lt;/li&gt;
&lt;li&gt;activation and validation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. The browser understands the question
&lt;/h3&gt;

&lt;p&gt;The browser can use recent conversation context to reformulate follow-up questions.&lt;/p&gt;

&lt;p&gt;An embedding model then converts the query into a vector.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The server performs vector search
&lt;/h3&gt;

&lt;p&gt;The vector is sent to the website API.&lt;/p&gt;

&lt;p&gt;The server searches the document index and returns the most relevant passages together with their sources.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. WebGPU generates the answer locally
&lt;/h3&gt;

&lt;p&gt;The response model runs on the visitor's GPU.&lt;/p&gt;

&lt;p&gt;It receives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the question&lt;/li&gt;
&lt;li&gt;recent conversation context&lt;/li&gt;
&lt;li&gt;retrieved passages&lt;/li&gt;
&lt;li&gt;CMS instructions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first result is not displayed immediately.&lt;/p&gt;

&lt;p&gt;A second pass checks the draft against the retrieved sources, and the system can perform one corrective search if necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. The visitor gets an answer with sources
&lt;/h3&gt;

&lt;p&gt;The final response contains links back to the original website content.&lt;/p&gt;

&lt;p&gt;If the available information is not sufficient, the assistant is expected to say so instead of inventing an answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why run the model in the browser?
&lt;/h2&gt;

&lt;p&gt;The main experiment was to avoid calling a hosted generation API for every message.&lt;/p&gt;

&lt;p&gt;This changes several things.&lt;/p&gt;

&lt;h3&gt;
  
  
  No per-response generation API call
&lt;/h3&gt;

&lt;p&gt;Once the models are loaded, generation happens on the visitor's device.&lt;/p&gt;

&lt;p&gt;That does not make the system free — hosting, downloads, development and maintenance still have costs — but there is no token bill for every generated response in this workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  More control over conversation data
&lt;/h3&gt;

&lt;p&gt;The conversation is not sent to an external generation API to produce the answer.&lt;/p&gt;

&lt;p&gt;Optional conversation memory is also stored locally in the browser.&lt;/p&gt;

&lt;p&gt;The server is still involved in document retrieval, so this is not a fully offline system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local memory
&lt;/h2&gt;

&lt;p&gt;I also added optional semantic memory using IndexedDB.&lt;/p&gt;

&lt;p&gt;It can keep previous exchanges locally for a limited period and retrieve an older, related question when useful.&lt;/p&gt;

&lt;p&gt;An important design decision was to keep three concepts separate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;documents&lt;/strong&gt; are the factual source&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;recent conversation&lt;/strong&gt; maintains context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;local memory&lt;/strong&gt; helps recover previous intent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An old AI-generated answer never becomes a new factual source.&lt;/p&gt;

&lt;h2&gt;
  
  
  The limitations are just as important
&lt;/h2&gt;

&lt;p&gt;Running AI models in the browser comes with real constraints.&lt;/p&gt;

&lt;p&gt;The current response model requires roughly &lt;strong&gt;2 GB of downloads&lt;/strong&gt;, plus about &lt;strong&gt;279 MB&lt;/strong&gt; for the embedding model.&lt;/p&gt;

&lt;p&gt;Browser support is another factor.&lt;/p&gt;

&lt;p&gt;Having &lt;code&gt;navigator.gpu&lt;/code&gt; available does not automatically mean that every model and inference engine will work correctly on that device.&lt;/p&gt;

&lt;p&gt;Drivers, GPU capabilities, memory limits and browser implementation all matter.&lt;/p&gt;

&lt;p&gt;Latency is also very different from a fast cloud API.&lt;/p&gt;

&lt;p&gt;With the models already cached, one documented test produced a reviewed answer in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;36.11 seconds&lt;/strong&gt; on a Samsung Galaxy S25 Ultra&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;13.06 seconds&lt;/strong&gt; on a desktop with an NVIDIA Ampere GPU&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are measurements from my own test devices, not performance guarantees.&lt;/p&gt;

&lt;p&gt;More complex mobile requests can take over a minute.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I still find this architecture interesting
&lt;/h2&gt;

&lt;p&gt;The goal is not to replace every search box with an AI assistant.&lt;/p&gt;

&lt;p&gt;The interesting use cases are situations where users have a real question and the website already has reliable information that can answer it.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;product catalogs&lt;/li&gt;
&lt;li&gt;technical documentation&lt;/li&gt;
&lt;li&gt;training websites&lt;/li&gt;
&lt;li&gt;tourism or accommodation&lt;/li&gt;
&lt;li&gt;business software&lt;/li&gt;
&lt;li&gt;real-estate search&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A user can express a need naturally, while structured data and RAG keep the response connected to information that can actually be verified.&lt;/p&gt;

&lt;p&gt;The model is only one part of the solution.&lt;/p&gt;

&lt;p&gt;The real value comes from combining:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;data + retrieval + business rules + UX + performance + validation&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned from this first version
&lt;/h2&gt;

&lt;p&gt;Building this project reinforced something I increasingly see in applied AI work:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A better model does not automatically create a better product.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The difficult parts are often around the model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;preparing reliable knowledge&lt;/li&gt;
&lt;li&gt;keeping retrieval consistent&lt;/li&gt;
&lt;li&gt;managing context&lt;/li&gt;
&lt;li&gt;handling model downloads and caching&lt;/li&gt;
&lt;li&gt;keeping the interface responsive&lt;/li&gt;
&lt;li&gt;validating answers&lt;/li&gt;
&lt;li&gt;testing on real devices&lt;/li&gt;
&lt;li&gt;deciding when the system should simply say "I don't know"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This first version is now running in production on my own website, and I am continuing to test lighter models, additional browsers, GPUs and possible business applications.&lt;/p&gt;




&lt;p&gt;I wrote a more complete article with the architecture, limitations, benchmarks and potential use cases:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://sdx-development.com/en/news/applied-ai/rag-webgpu-ai-assistant-first-version" rel="noopener noreferrer"&gt;RAG and WebGPU: When Your Website Becomes an AI Assistant&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is also a deeper technical case study covering the complete RAG pipeline, CMS integration, embeddings, local memory and model choices.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>webgpu</category>
      <category>rag</category>
    </item>
  </channel>
</rss>
