Context-Aware Support Chatbot with RAG
Building a retrieval-augmented AI assistant that answers strictly from a company's real documentation instead of hallucinating, and streams responses fast enough to feel like a real conversation.
< 800ms
First-token latency
~40%
Support tickets deflected
Seconds
Lead routing time
Source-cited
Answer grounding
Problem
A generic LLM chatbot gave confident but incorrect answers about product-specific behavior, and the support team didn't trust it enough to deploy. It needed to answer only from the company's own docs, tickets, and FAQs — and cite where each answer came from.
Challenges
- Keeping answers grounded in real documentation instead of model hallucination
- Serving streamed responses with low first-token latency over a persistent connection
- Controlling inference and embedding cost as document volume and traffic grew
- Routing qualified leads to a human in real time without adding conversational latency
Architecture
Incoming documents are chunked, embedded, and stored in a vector index. On each user message, the backend retrieves the top-k relevant chunks, assembles a grounded prompt, and streams the model's response token-by-token to the client over a WebSocket connection rather than a REST round-trip, cutting perceived latency significantly. A lightweight classifier runs in parallel to score buying intent and pushes qualified conversations to Slack instantly.
Document ingested → chunked and embedded → stored in vector index
User message received over WebSocket connection
Top-k relevant chunks retrieved and assembled into a grounded prompt
Response streamed token-by-token back to the client via Claude AI
Parallel lead-scoring pass flags high-intent conversations to Slack
Database Design
Conversation history and document metadata live in Postgres, while vector embeddings are stored in a dedicated vector index optimized for approximate nearest-neighbor search. Embeddings are versioned so documentation updates can be re-indexed without downtime, with the previous version serving traffic until the new index is warm.
Scalability
Embedding generation is cached and deduplicated so re-ingesting an unchanged document costs nothing. Rate limiting and request batching keep inference spend predictable under bursty traffic, and the retrieval layer is decoupled from the generation layer so either can scale independently.
Outcome
Deflected a significant portion of first-line support questions from the human queue while maintaining answer accuracy the support team was willing to trust in production — with qualified leads now reaching sales in seconds instead of hours.
Tech Stack
Have a similar problem you're trying to architect your way through?