<?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: Affan Raza</title>
    <description>The latest articles on DEV Community by Affan Raza (@affan_raza_dea).</description>
    <link>https://dev.to/affan_raza_dea</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%2F3200473%2F03227939-4bf7-424e-a685-273ff5f19082.jpg</url>
      <title>DEV Community: Affan Raza</title>
      <link>https://dev.to/affan_raza_dea</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/affan_raza_dea"/>
    <language>en</language>
    <item>
      <title>Voice2Note — Give Your Voice Notes a Memory</title>
      <dc:creator>Affan Raza</dc:creator>
      <pubDate>Sun, 04 Oct 2026 11:15:05 +0000</pubDate>
      <link>https://dev.to/affan_raza_dea/voice2note-give-your-voice-notes-a-memory-2mke</link>
      <guid>https://dev.to/affan_raza_dea/voice2note-give-your-voice-notes-a-memory-2mke</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;Voice2Note&lt;/strong&gt;, a local-first AI application that turns voice recordings into structured, searchable knowledge.&lt;/p&gt;

&lt;p&gt;I built it for a friend who frequently records voice notes to capture ideas, plans, reminders, and thoughts, but often struggles to find or act on that information later.&lt;/p&gt;

&lt;p&gt;The problem isn't recording a voice note.&lt;/p&gt;

&lt;p&gt;The problem is what happens &lt;strong&gt;after&lt;/strong&gt; the recording.&lt;/p&gt;

&lt;p&gt;Important ideas get buried. Tasks get forgotten. Finding something mentioned several days ago becomes difficult.&lt;/p&gt;

&lt;p&gt;Voice2Note turns that unstructured voice data into something useful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Voice Recording
      ↓
Local Speech-to-Text
      ↓
Open-Weight LLM
      ↓
Summary + Tasks + Ideas + Decisions
      ↓
Local Knowledge Base
      ↓
Semantic Search
      ↓
Ask My Notes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of simply transcribing a recording, Voice2Note helps answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What did I say about this before?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎙️ Record voice notes directly from the browser&lt;/li&gt;
&lt;li&gt;📁 Upload existing audio recordings&lt;/li&gt;
&lt;li&gt;📝 Local speech-to-text transcription&lt;/li&gt;
&lt;li&gt;🧠 AI-generated summaries&lt;/li&gt;
&lt;li&gt;✅ Automatic task extraction&lt;/li&gt;
&lt;li&gt;💡 Idea and decision extraction&lt;/li&gt;
&lt;li&gt;🔎 Semantic search across previous notes&lt;/li&gt;
&lt;li&gt;💬 Ask questions about your own voice notes&lt;/li&gt;
&lt;li&gt;📌 Source-backed answers&lt;/li&gt;
&lt;li&gt;🔒 Local-first/private AI architecture&lt;/li&gt;
&lt;li&gt;⚙️ Swappable open-weight AI models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was to build something small enough to actually use, but meaningful enough to solve a real problem for one person.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🌐 &lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://voice2note-one.vercel.app" rel="noopener noreferrer"&gt;https://voice2note-one.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The demo shows the complete workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Record → Transcribe → Understand → Search → Ask&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;💻 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/affanraza84/voice2note" rel="noopener noreferrer"&gt;https://github.com/affanraza84/voice2note&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repository contains the complete application, local AI setup, architecture documentation, evaluation tests, and setup instructions.&lt;/p&gt;

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

&lt;p&gt;Voice2Note is built around &lt;strong&gt;open-source/open-weight AI&lt;/strong&gt;, rather than using a proprietary AI API as the core intelligence layer.&lt;/p&gt;

&lt;p&gt;The architecture consists of several AI components:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Local Speech Recognition
&lt;/h3&gt;

&lt;p&gt;Voice recordings are processed using an open speech-recognition model such as &lt;strong&gt;Whisper/faster-whisper&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Audio
 ↓
Local Speech Model
 ↓
Transcript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the application doesn't need to send a private voice recording to a third-party speech API for its core transcription workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Open-Weight LLM
&lt;/h3&gt;

&lt;p&gt;The transcript is passed to a locally running open-weight language model.&lt;/p&gt;

&lt;p&gt;The model extracts structured information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;summaries&lt;/li&gt;
&lt;li&gt;tasks&lt;/li&gt;
&lt;li&gt;ideas&lt;/li&gt;
&lt;li&gt;decisions&lt;/li&gt;
&lt;li&gt;people&lt;/li&gt;
&lt;li&gt;topics&lt;/li&gt;
&lt;li&gt;important dates&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 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;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Discussed the college project and deployment plan."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tasks"&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;"Finish the landing page"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Deploy the backend"&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="nl"&gt;"ideas"&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;"Add semantic search to the project"&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;h3&gt;
  
  
  3. Local Knowledge Base
&lt;/h3&gt;

&lt;p&gt;The transcripts are chunked and converted into embeddings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Transcript
    ↓
Chunking
    ↓
Embeddings
    ↓
Vector Store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows Voice2Note to understand semantic relationships instead of relying only on keyword matching.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Retrieval-Augmented Generation
&lt;/h3&gt;

&lt;p&gt;When the user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What did I say about my project?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Voice2Note retrieves relevant sections from previous voice notes and provides them as context to the local LLM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question
   ↓
Embedding
   ↓
Semantic Retrieval
   ↓
Relevant Voice Notes
   ↓
Local LLM
   ↓
Grounded Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response also points back to the source note so the user can verify where the information came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;This is the most important part of Voice2Note.&lt;/p&gt;

&lt;p&gt;Voice recordings can contain extremely personal information.&lt;/p&gt;

&lt;p&gt;A voice note might contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;personal plans&lt;/li&gt;
&lt;li&gt;private conversations&lt;/li&gt;
&lt;li&gt;project ideas&lt;/li&gt;
&lt;li&gt;financial information&lt;/li&gt;
&lt;li&gt;family information&lt;/li&gt;
&lt;li&gt;unfinished thoughts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn't want the fundamental value of the application to depend on sending that information to a proprietary AI provider.&lt;/p&gt;

&lt;p&gt;With an open/local AI architecture, Voice2Note can keep the core AI pipeline under the user's control:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microphone
    ↓
Local Speech Model
    ↓
Local LLM
    ↓
Local Embeddings
    ↓
Local Knowledge Base
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Open AI made several things possible.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Privacy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The application can process sensitive voice data locally instead of requiring a cloud AI API for its core intelligence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model freedom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The application isn't permanently tied to one model provider. The AI provider is abstracted so compatible models can be swapped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because the AI pipeline is under our control, we can customize transcription, extraction, retrieval, prompting, and model behavior around the actual user's workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lower recurring cost&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the required models are available locally, the core inference pipeline doesn't require paying a per-request proprietary AI API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transparency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I can understand and control the components responsible for processing the user's data instead of treating the AI layer as a black box.&lt;/p&gt;

&lt;p&gt;There are trade-offs, of course.&lt;/p&gt;

&lt;p&gt;Local AI can require more hardware, model setup can be more complicated, and some closed models may provide better performance for particular tasks.&lt;/p&gt;

&lt;p&gt;But for this application, &lt;strong&gt;control and privacy are more important than simply choosing the strongest available API&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's where open innovation made the most sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;The biggest lesson from building Voice2Note was that &lt;strong&gt;AI doesn't have to mean building another chatbot&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The interesting part was designing the pipeline around a real person's workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw Voice
   ↓
Information
   ↓
Structure
   ↓
Memory
   ↓
Action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI is valuable because it transforms something the user already does—recording voice notes—into something much more useful.&lt;/p&gt;

&lt;p&gt;I also learned how different AI components can work together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;speech recognition&lt;/li&gt;
&lt;li&gt;structured LLM extraction&lt;/li&gt;
&lt;li&gt;embeddings&lt;/li&gt;
&lt;li&gt;vector search&lt;/li&gt;
&lt;li&gt;RAG&lt;/li&gt;
&lt;li&gt;local inference&lt;/li&gt;
&lt;li&gt;source attribution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;rather than treating a single LLM call as the entire application.&lt;/p&gt;

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

&lt;p&gt;Voice2Note started with a simple observation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;My friend already had the information. They just couldn't easily find or use it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So instead of building another place to create more information, I built a tool that helps turn the information they already create into something searchable, structured, and actionable.&lt;/p&gt;

&lt;p&gt;That's what &lt;strong&gt;Build for a Friend&lt;/strong&gt; meant to me.&lt;/p&gt;

&lt;p&gt;Not building the biggest AI application.&lt;/p&gt;

&lt;p&gt;Building something that &lt;strong&gt;one real person would actually want to keep using.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>DevDocs Intelligence: A Gemini Agent for Version-Aware Next.js Documentation</title>
      <dc:creator>Affan Raza</dc:creator>
      <pubDate>Sat, 03 Oct 2026 14:39:46 +0000</pubDate>
      <link>https://dev.to/affan_raza_dea/devdocs-intelligence-a-gemini-agent-for-version-aware-nextjs-documentation-fm7</link>
      <guid>https://dev.to/affan_raza_dea/devdocs-intelligence-a-gemini-agent-for-version-aware-nextjs-documentation-fm7</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvm5rhwd00pkfu0h20r4l.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvm5rhwd00pkfu0h20r4l.png" alt=" " width="799" height="453"&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbscejfcrcocjtrd2n1y3.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbscejfcrcocjtrd2n1y3.png" alt=" " width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  DevDocs Intelligence: A Gemini Agent for Version-Aware Next.js Documentation
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A developer documentation intelligence agent powered by Gemini, Sanity Knowledge Base, and Sanity Context MCP.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;DevDocs Intelligence&lt;/strong&gt;, a Gemini-powered agent designed to answer complex, version-aware questions about Next.js documentation.&lt;/p&gt;

&lt;p&gt;The core idea is simple: developer documentation shouldn't always be treated as a flat collection of text.&lt;/p&gt;

&lt;p&gt;A question such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Explain the major routing changes between Next.js 15 and Next.js 16, including params, Route Handlers, and the transition from &lt;code&gt;middleware.ts&lt;/code&gt; to &lt;code&gt;proxy.ts&lt;/code&gt;.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;can require information from multiple documentation types and versions.&lt;/p&gt;

&lt;p&gt;So instead of storing everything as unstructured text, I modeled the knowledge as &lt;strong&gt;structured, interconnected content in Sanity&lt;/strong&gt; and exposed it to the agent through &lt;strong&gt;Sanity Context MCP&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The resulting 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;User Question
      ↓
Next.js Frontend
      ↓
Application API
      ↓
Gemini Agent
      ↓
Sanity Context MCP
      ↓
Sanity Knowledge Base
      ↓
Structured Sanity Content
      ↓
Grounded Answer + Sources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;Framework documentation changes quickly.&lt;/p&gt;

&lt;p&gt;A developer asking a version-specific question may need to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what changed between versions&lt;/li&gt;
&lt;li&gt;whether an API behavior changed&lt;/li&gt;
&lt;li&gt;whether a feature was deprecated&lt;/li&gt;
&lt;li&gt;how to migrate&lt;/li&gt;
&lt;li&gt;which APIs or features are affected&lt;/li&gt;
&lt;li&gt;how different pieces of documentation relate to each other&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple keyword search can find matching text, but it doesn't necessarily preserve these relationships.&lt;/p&gt;

&lt;p&gt;For DevDocs Intelligence, I wanted to explore a different approach:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model the documentation itself as structured knowledge and let an AI agent retrieve that knowledge through Sanity Context MCP.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Structured Content Model
&lt;/h2&gt;

&lt;p&gt;I created four custom Sanity document types:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Content Type&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;General Next.js concepts, guides, and feature documentation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Reference&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;APIs, parameters, examples, limitations, and related documentation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Migration Guide&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Version-to-version changes, breaking changes, migration steps, and affected APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Release Note&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Version-specific changes, breaking changes, deprecations, and affected features&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These documents aren't isolated.&lt;/p&gt;

&lt;p&gt;They contain explicit references to related documentation, APIs, migrations, and release notes.&lt;/p&gt;

&lt;p&gt;The current corpus contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;30 structured documents&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4 custom content types&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;128 cross-document relationships&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives the retrieval layer more context than simply searching a collection of independent text chunks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Sanity?
&lt;/h2&gt;

&lt;p&gt;Sanity is the structured content foundation of the project.&lt;/p&gt;

&lt;p&gt;Instead of treating a documentation page as one large piece of text, I can represent different types of knowledge using different schemas and connect them through references.&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;Migration Guide
      │
      ├──→ API Reference
      │
      ├──→ Documentation
      │
      └──→ Release Note
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This becomes particularly useful for version-aware questions where the answer may span multiple sources.&lt;/p&gt;

&lt;p&gt;Sanity's structured content model therefore becomes part of the agent's reasoning context rather than simply acting as a place to store documents.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sanity Knowledge Base
&lt;/h2&gt;

&lt;p&gt;The structured Sanity corpus is connected to a &lt;strong&gt;Sanity Knowledge Base&lt;/strong&gt; designed specifically for answering complex Next.js documentation questions.&lt;/p&gt;

&lt;p&gt;The Knowledge Base contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;30 source documents&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;18 Knowledge Base entries&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100% source span coverage&lt;/strong&gt; in the successful build&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to make the structured documentation available as navigable contextual knowledge for the agent.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Sanity Context MCP Fits In
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MCP (Model Context Protocol)&lt;/strong&gt; provides the interface between the Gemini agent and Sanity's contextual knowledge.&lt;/p&gt;

&lt;p&gt;The agent does not directly contain the documentation.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gemini Agent
     │
     │ MCP tool calls
     ▼
Sanity Context MCP
     │
     ▼
Knowledge Base
     │
     ▼
Structured Sanity Content
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During testing, the agent used Sanity Context MCP operations including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;initial_context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;knowledge_base_search&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;knowledge_base_read&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows the agent to retrieve relevant information when it needs additional context instead of placing the entire documentation corpus into the model prompt.&lt;/p&gt;




&lt;h2&gt;
  
  
  How the Agent Works
&lt;/h2&gt;

&lt;p&gt;When a developer submits a question:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The user asks a question
&lt;/h3&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Explain the major routing changes between Next.js 15 and Next.js 16, including params, Route Handlers, and the transition from middleware.ts to proxy.ts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. The Next.js frontend sends the request
&lt;/h3&gt;

&lt;p&gt;The frontend communicates with the application's chat API.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The backend initializes the agent
&lt;/h3&gt;

&lt;p&gt;The backend handles the request, validates the input, and connects the agent to the configured Sanity Context MCP endpoint.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Gemini determines what context is needed
&lt;/h3&gt;

&lt;p&gt;Gemini acts as the reasoning and generation layer.&lt;/p&gt;

&lt;p&gt;It can use the MCP-exposed tools to retrieve relevant contextual information.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Sanity Context retrieves the knowledge
&lt;/h3&gt;

&lt;p&gt;The MCP layer accesses the Sanity Knowledge Base and retrieves relevant structured content.&lt;/p&gt;

&lt;p&gt;The retrieved information can span multiple document types.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Gemini synthesizes the answer
&lt;/h3&gt;

&lt;p&gt;Gemini uses the retrieved content to produce a coherent, grounded response.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. The response is streamed to the frontend
&lt;/h3&gt;

&lt;p&gt;The backend streams the response progressively to the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Sources are displayed
&lt;/h3&gt;

&lt;p&gt;The frontend shows the Sanity sources used to ground the response.&lt;/p&gt;




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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         ┌──────────────────┐
                         │       User       │
                         └────────┬─────────┘
                                  │
                                  ▼
                         ┌──────────────────┐
                         │ Next.js Frontend │
                         │  TypeScript/UI   │
                         └────────┬─────────┘
                                  │
                                  ▼
                         ┌──────────────────┐
                         │ Application API  │
                         │ Agent Orchestration
                         └────────┬─────────┘
                                  │
                                  ▼
                         ┌──────────────────┐
                         │   Gemini Agent   │
                         │ Reasoning +      │
                         │ Generation       │
                         └────────┬─────────┘
                                  │
                             MCP Tool Calls
                                  │
                                  ▼
                         ┌──────────────────┐
                         │ Sanity Context  │
                         │       MCP       │
                         └────────┬─────────┘
                                  │
                                  ▼
                         ┌──────────────────┐
                         │ Sanity Knowledge │
                         │      Base       │
                         └────────┬─────────┘
                                  │
                                  ▼
                   ┌────────────────────────────┐
                   │ Structured Sanity Content │
                   │                            │
                   │ Documentation              │
                   │ API References             │
                   │ Migration Guides           │
                   │ Release Notes              │
                   └────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  A Real Example
&lt;/h2&gt;

&lt;p&gt;One of the main queries I use to demonstrate the system is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Explain the major routing changes between Next.js 15 and Next.js 16, including params, Route Handlers, and the transition from middleware.ts to proxy.ts.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is useful because the answer requires more than retrieving one isolated paragraph.&lt;/p&gt;

&lt;p&gt;The agent can retrieve information across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;API Reference&lt;/li&gt;
&lt;li&gt;Migration Guide&lt;/li&gt;
&lt;li&gt;Release Note&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resulting response is grounded in Sanity sources and displayed alongside the answer in the application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Other Example Queries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Next.js 15 caching
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the default dynamic &lt;code&gt;staleTime&lt;/code&gt; in Next.js 15 and how did it change from previous versions?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Route Handlers
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;How did Route Handler caching behavior change in Next.js 15?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Version migration
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;What are the major changes developers should know when migrating from Next.js 14 to Next.js 15?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These queries test whether the agent can connect version-specific information rather than simply return a matching keyword.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Gemini-powered documentation agent&lt;/li&gt;
&lt;li&gt;Sanity structured content&lt;/li&gt;
&lt;li&gt;Sanity Knowledge Base&lt;/li&gt;
&lt;li&gt;Sanity Context MCP integration&lt;/li&gt;
&lt;li&gt;Four domain-specific content types&lt;/li&gt;
&lt;li&gt;Cross-document relationships&lt;/li&gt;
&lt;li&gt;Version-aware retrieval&lt;/li&gt;
&lt;li&gt;Grounded responses&lt;/li&gt;
&lt;li&gt;Sanity source display&lt;/li&gt;
&lt;li&gt;Progressive response streaming&lt;/li&gt;
&lt;li&gt;Server-side secret management&lt;/li&gt;
&lt;li&gt;Error handling and validation&lt;/li&gt;
&lt;li&gt;Production deployment on Vercel&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Next.js&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Gemini&lt;/li&gt;
&lt;li&gt;AI SDK&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Content &amp;amp; Retrieval
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sanity&lt;/li&gt;
&lt;li&gt;Sanity Knowledge Base&lt;/li&gt;
&lt;li&gt;Sanity Context MCP&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deployment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Vercel&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Technical Implementation
&lt;/h2&gt;

&lt;p&gt;The application is divided into a few major layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frontend/
    ↓
Next.js application
    ↓
Chat API
    ↓
Agent layer
    ↓
Gemini + MCP
    ↓
Sanity Context
    ↓
Knowledge Base
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend keeps sensitive credentials server-side, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GEMINI_API_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SANITY_API_READ_TOKEN&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SANITY_CONTEXT_MCP_URL&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not exposed as public frontend environment variables.&lt;/p&gt;




&lt;h2&gt;
  
  
  Streaming
&lt;/h2&gt;

&lt;p&gt;The application supports progressive responses rather than waiting for the entire answer to finish.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gemini
   ↓
Agent Backend
   ↓
Streaming/SSE
   ↓
Next.js Frontend
   ↓
Progressive UI Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the interaction feel more like an active agent session rather than a request that remains blocked until the complete response is generated.&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing &amp;amp; Validation
&lt;/h2&gt;

&lt;p&gt;I tested the complete workflow with real questions against the hosted Sanity Context MCP endpoint.&lt;/p&gt;

&lt;p&gt;The validation covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sanity Context MCP tool invocation&lt;/li&gt;
&lt;li&gt;Knowledge Base retrieval&lt;/li&gt;
&lt;li&gt;Multi-document retrieval&lt;/li&gt;
&lt;li&gt;Grounded Sanity sources&lt;/li&gt;
&lt;li&gt;Streaming responses&lt;/li&gt;
&lt;li&gt;Empty/malformed request handling&lt;/li&gt;
&lt;li&gt;Server-side secret handling&lt;/li&gt;
&lt;li&gt;TypeScript validation&lt;/li&gt;
&lt;li&gt;Production build&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent was tested with both focused documentation questions and higher-value cross-document questions involving version changes and related APIs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sanity Project Details
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sanity Project ID:&lt;/strong&gt; &lt;code&gt;0ovd9f2s&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dataset:&lt;/strong&gt; &lt;code&gt;production&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content Types:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;documentation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;apiReference&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;migrationGuide&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;releaseNote&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Structured Documents:&lt;/strong&gt; 30&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-document Relationships:&lt;/strong&gt; 128&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Knowledge Base Entries:&lt;/strong&gt; 18&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;One of the biggest takeaways from this project was that &lt;strong&gt;the structure of the knowledge matters as much as the model used to reason over it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A documentation agent becomes much more useful when the underlying information contains explicit relationships between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;versions&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;migrations&lt;/li&gt;
&lt;li&gt;release changes&lt;/li&gt;
&lt;li&gt;documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sanity made it possible to model those relationships explicitly and expose the resulting knowledge to an agent through Context MCP.&lt;/p&gt;

&lt;p&gt;This also changed how I think about RAG systems: retrieval doesn't always have to mean searching a flat collection of chunks. The underlying content model can itself provide useful context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Future Improvements
&lt;/h2&gt;

&lt;p&gt;Some areas I would explore next:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expand the corpus beyond Next.js&lt;/li&gt;
&lt;li&gt;Add more framework versions&lt;/li&gt;
&lt;li&gt;Add evaluation datasets for retrieval quality&lt;/li&gt;
&lt;li&gt;Measure grounded-answer accuracy systematically&lt;/li&gt;
&lt;li&gt;Add richer source-level explanations&lt;/li&gt;
&lt;li&gt;Explore more complex multi-hop documentation queries&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Built for the Sanity Challenge
&lt;/h2&gt;

&lt;p&gt;This project was built for the &lt;strong&gt;Sanity Challenge 2026 — Path One: Ship an agent that queries real content&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The core implementation focuses on using:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structured Sanity Content → Knowledge Base → Sanity Context MCP → Gemini Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;rather than treating Sanity as only a storage layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://devdocs-intelligence.vercel.app" rel="noopener noreferrer"&gt;https://devdocs-intelligence.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Code:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/affanraza84/devdocs-intelligence" rel="noopener noreferrer"&gt;https://github.com/affanraza84/devdocs-intelligence&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Note
&lt;/h2&gt;

&lt;p&gt;DevDocs Intelligence is an exploration of what happens when developer documentation is treated as &lt;strong&gt;structured, connected knowledge&lt;/strong&gt; instead of just a collection of searchable pages.&lt;/p&gt;

&lt;p&gt;The goal is not simply to make an LLM answer documentation questions, but to give the agent a structured knowledge layer it can actually reason over.&lt;/p&gt;




&lt;h1&gt;
  
  
  sanitychallenge
&lt;/h1&gt;

</description>
      <category>sanitychallenge</category>
      <category>ai</category>
      <category>agents</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
