The conclusion first
I built a RAG MVP for Chinese-language health-education questions. It chunks team-reviewed articles, retrieves passages with pgvector, and lets a model organize a response from that context. It has been developed and tested locally, but not deployed or used by production users. The hardest question was not whether the model could answer. It was whether the system could stop when it lacked a sound basis.
pgvector finds similar content. The application decides whether to proceed to answer generation. A vector index is neither a safety control nor a guarantee that the model will use only facts from the knowledge base.
flowchart LR
D[Reviewed health-education articles] --> C[Section-aware chunks + sources]
C --> V[Embeddings + PostgreSQL/pgvector]
Q[User question] --> G[Consent, quota, cost budget]
G --> R[Vector retrieval; rewrite follow-up if needed]
V --> R
R --> E{Retrieval score sufficient?}
E -- No --> N[Fixed refusal; no answer model call]
E -- Yes --> A[Generate from retrieved passages]
A --> O[Check citations and output rules]
Retrieve first, then decide whether to generate
Articles are chunked by heading, with the title and source preserved on each chunk. PostgreSQL and pgvector return candidate passages for a question. The index helps retrieval; a separate score gate decides whether the answer model is called. These are different responsibilities. pgvector documentation
Below the gate, application code returns a fixed response rather than sending the question to the answer-generation model. That does not mean the entire turn made no model calls: query embedding still uses an embedding model, and a contextual follow-up might use a rewriting model. “No generated answer” is the accurate claim.
A stricter threshold is not automatically safer. Real questions rarely match article headings; a high threshold rejects useful conversational questions, while a low one can pass unrelated passages into the model. I used answerable, off-topic, and conversational follow-up questions to tune three paths: refuse, answer with lower confidence, or answer with stronger evidence. A retrieval score measures similarity, not medical correctness.
Multi-turn questions and answer checks
A follow-up such as “What should I do about that?” can retrieve the wrong topic when searched alone. When the original question scores poorly and there is conversation context, the MVP rewrites it as a standalone query and retrieves again. Always prefixing the previous turn is simpler, but can drag a genuine topic change back toward the old topic.
After generation, source markers must match passages retrieved for that turn. This can reject invented references; it cannot prove that every sentence is entailed by its cited passage. Regression questions still need to test the substance of answers, abstention, and adversarial inputs. Passing a small local test suite is not proof of zero hallucinations or prompt-injection resistance. OWASP RAG Security Cheat Sheet, Microsoft RAG evaluation guide
Consent, visitor quotas, and daily cost limits are enforced by server-side code before the answer model, not delegated to a prompt. The shared vector index contains reviewed articles only. Personal conversations and health information belong behind per-user authorization, not in a shared knowledge index just to give the assistant “memory.”
What this MVP establishes
The local work shows that the pipeline can run end to end and that a test set can exercise retrieval, refusal, follow-up handling, and citation rules. It does not establish production reliability, user acceptance, or medical and legal compliance. Those require deployment checks, ongoing monitoring, and specialist review.
My takeaway: a useful RAG system should explain why those passages were retrieved, when it must stop, and which source supports the answer. That lesson travels to other knowledge-base applications without presenting an MVP as a launched product.