跪拜 Guibai
← All articles
AI Programming · Frontend · Full-Stack

Adding AI Q&A to a Docusaurus Knowledge Base with RAG and SSE Streaming

By _lucas ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

This walkthrough surfaces the exact Nginx, streaming, and chunking pitfalls that turn a weekend RAG project into a multi-week debugging session. The concrete fixes—disabling proxy buffering, using `@microsoft/fetch-event-source` for POST-based SSE, and parsing Markdown via AST instead of regex—are directly portable to any developer adding AI search to a documentation site.

Summary

A Docusaurus-based knowledge site replaces its plain-text Algolia search with a conversational AI Q&A feature. The implementation is a full-stack RAG pipeline: Markdown documents are parsed into an AST, chunked by heading structure, and embedded into a ChromaDB vector store using Alibaba's text-embedding-3 model. A lightweight Hono backend handles queries by retrieving relevant chunks, assembling a strict anti-hallucination prompt, and streaming DeepSeek's response back to the frontend.

The streaming architecture uses Server-Sent Events (SSE) with a critical Nginx configuration detail: `proxy_buffering` must be disabled, or the stream freezes. The frontend uses the `@microsoft/fetch-event-source` library instead of the native `EventSource` to support POST requests and custom headers, avoiding compatibility issues with WeChat's built-in browser. An incremental ingestion strategy, driven by Git diffs in GitHub Actions, ensures only changed documents are re-embedded.

A basic evaluation loop is also in place: a golden dataset of question-answer pairs is used to score model responses via LLM-as-a-judge, and all Q&A logs are stored for manual sampling. The project identifies recall failure as the root cause of most incorrect answers, pointing toward future upgrades like hybrid search and re-ranking.

Takeaways
Parsing Markdown with `unified` and `remark-parse` into an AST prevents false heading matches inside code blocks, which regex-based chunking would miss.
Chunking only to H2/H3 level keeps each piece a complete semantic unit; finer cuts fragment the context and hurt retrieval quality.
ChromaDB's `upsert` method supports incremental ingestion natively, and its HNSW index is self-maintaining with no manual rebuilds required.
Nginx's default `proxy_buffering` will freeze SSE streams; setting it to `off` is mandatory for real-time token-by-token display.
The native browser `EventSource` API only supports GET requests and cannot send custom headers, making `@microsoft/fetch-event-source` necessary for POST-based SSE with auth tokens.
An `onAbort` handler that cancels the upstream reader prevents wasted token consumption when a user closes the browser tab mid-stream.
90% of RAG answer failures are recall problems—the correct chunk was never retrieved—not generation problems, so tuning chunking and embedding strategies should come before prompt engineering.
Conclusions

Treating a personal knowledge base as an AI Agent training ground is a pragmatic on-ramp: the single-user, low-QPS constraints eliminate distributed-systems complexity and let a developer focus purely on the RAG data flow.

The choice of Hono over Express for a 12-15kb framework that runs across Node.js, Bun, and Deno signals a growing preference for Web Standard API-native tooling in the JavaScript ecosystem, even for small projects.

Using LLM-as-a-judge with a hand-labeled golden dataset is a low-effort evaluation strategy that catches regressions without building a full observability stack, but its reliability depends entirely on the quality of the scoring prompt.

The project's explicit admission that it's 'Naive RAG' and that pure vector search misses specific proper nouns is a useful counterpoint to overhyped RAG demos—hybrid BM25+vector search is framed as the necessary next step, not an optional enhancement.

Concepts & terms
RAG (Retrieval-Augmented Generation)
A technique that retrieves relevant documents from a knowledge base and feeds them into a language model's prompt, grounding the model's response in provided facts to reduce hallucination.
SSE (Server-Sent Events)
A standard allowing a server to push real-time updates to a browser over a single HTTP connection. Unlike WebSockets, SSE is unidirectional (server to client) and uses the `text/event-stream` content type.
ChromaDB
An open-source vector database built on SQLite that stores embeddings and their metadata. It uses an HNSW index for fast similarity search and supports add, upsert, update, and delete operations without manual index rebuilds.
HNSW (Hierarchical Navigable Small World)
A graph-based algorithm for approximate nearest neighbor search in high-dimensional vector spaces. It is self-maintaining in ChromaDB, meaning new vectors can be inserted incrementally without rebuilding the entire index.
Hybrid Search
A retrieval strategy that combines dense vector similarity search with sparse keyword-based search (like BM25) to catch both semantic matches and exact term matches, addressing the weakness of pure vector search on rare proper nouns.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗