The problem
The company's operational knowledge lived in Jira and Confluence. Answering a routine "how does this flow work" question meant interrupting an engineer who happened to remember the right ticket, and the existing search tool returned documents rather than answers.
What I built
A production retrieval-augmented generation service over the Jira/Confluence corpus: LangChain + LangGraph over Pinecone with dual knowledge bases, migrated off ChromaDB once the corpus outgrew it. It indexes 30–60K Jira issues across an enumeration reaching 40 projects, and answers with numbered source citations.
The citations are generated by construction: the answer is assembled from retrieved chunks that carry their own source identity, so a citation cannot reference a document that was never retrieved. Hallucinated references are prevented structurally instead of being detected afterwards.
How it works
Serving is async Flask with Celery workers and CI deployment. Conversation state uses Redis-cached rolling summarisation so long threads stay inside the context budget; a database-backed feedback loop and latency analytics record what users actually accepted, and the retrieval configuration is tuned against that record.
Evidence
The system was validated by blind pairwise evaluation over 283 real questions against the incumbent tool: preferred 240–30–13 by an LLM judge and 246–34–3 by a human domain expert, with the two judges agreeing 91.5% of the time.
One measurement is worth reporting because it went the other way. An early corpus count of ~178K "tickets" was wrong — raw JQL had been interpolated into a URL without percent-encoding, and the pagination bug inflated the row count roughly 50×. The real figure is 30–60K distinct issues. I corrected the number rather than keeping the impressive one.
What I owned
I designed and built this system end to end: the retrieval pipeline and the ChromaDB → Pinecone migration, the by-construction citation layer, the async Flask + Celery serving path with its Redis-cached rolling summarisation, and the blind pairwise evaluation harness that decided whether it was allowed to replace the incumbent tool.
Stack
LangChain · LangGraph · Pinecone (migrated from ChromaDB) · Flask (async) · Celery · Redis · Python