ALL CASE STUDIES

AI Infra

RAG Knowledge Assistant for Ops

A production RAG chatbot over RCAs, ADRs and onboarding docs — ~45% faster resolution.

01

The answer existed. Nobody could find it.

Post-incident reviews get written, filed, and never read again. The next engineer to hit the same failure searches the wiki with different words, finds nothing, and rediscovers the cause from first principles at 2am. The knowledge is not missing — it is unreachable, because search matches words and incidents are remembered as symptoms.

02

Symptoms are the query, causes are the content

People search with what they see: 'connection reset after deploy'. The document that answers it is titled 'PeerAuthentication STRICT rollout'. Keyword search cannot bridge that; embeddings can, because the symptom and the cause are semantically close even with no shared vocabulary. That gap is the entire reason this works better than the wiki's own search.

03

Retrieval quality is a data problem

Most RAG disappointment is bad chunking blamed on the model. RCAs have structure — symptom, timeline, root cause, remediation — and chunking on those boundaries with the document title carried into each chunk's metadata changes the results far more than swapping models does.

# measure before tuning
for q, expected_doc in golden_set:
    hits = store.search(q, limit=5)
    recall_at_5.append(expected_doc in [h.id for h in hits])
print(sum(recall_at_5) / len(recall_at_5))

Thirty real questions with known-correct documents. Without this number you are tuning on vibes, and every change feels like an improvement.

04

Cite, or it is worse than the wiki

For operational knowledge a confident wrong answer is actively dangerous — someone will run the command. Every response carries the source document and its date, and the model is instructed to refuse rather than infer when retrieval comes back weak. Refusal is a feature here, not a limitation.

05

What goes wrong

Stale content is the big one: a runbook from three reorganisations ago answers confidently and sends someone to a service that no longer exists, so age has to be surfaced in the answer and heavily weighted in ranking. Access control is the other — an index built across all documentation will happily surface HR content to an engineer unless the filter is applied at retrieval, not after generation. And embedding drift: re-embedding with a new model without reindexing everything gives you a silently broken index that still returns results.

curl -s localhost:6333/collections/runbooks | jq '.result | {points_count, config: .config.params.vectors}'

Pin and record the embedding model alongside the collection. A mismatch between query-time and index-time models degrades silently — no error, just quietly worse answers.

Tools, and why these ones

  • Qdrant

    DOCS ↗

    Vector database with payload filtering, so retrieval can be constrained by team, source or recency alongside similarity.

    Why: Filtering at retrieval is what makes access control and freshness weighting possible at all.

  • Qwen (open-weight LLM)

    DOCS ↗

    Open-weight model served on internal infrastructure.

    Why: RCAs contain hostnames, customer names and architecture. Self-hosting means none of that leaves the perimeter to answer a question.

What it took

The institutional knowledge that resolves an incident is usually written down somewhere nobody can find at 2am. Indexed RCAs, architecture decision records and onboarding material into a Qdrant vector store, served through an open-weight LLM, and made it answer in the terms engineers actually search in. Average resolution time dropped by roughly 45% — not because the answers were new, but because they were finally reachable.

  • Qdrant
  • Qwen LLM
  • RAG
  • Python
  • Kubernetes

Outcome

-45%
resolution time
production
status

Next case study

Onboarding Assistant over Company Docs