[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fvAvZ18sn9RkGTpPUk5xuszOQ2zMIf5XlNeqyQrR8XI4":3},{"id":4,"slug":5,"title":6,"projectType":7,"client":8,"tools":9,"year":10,"summary":11,"problem":12,"approach":13,"outcome":14,"previewUrl":15,"repoUrl":15,"thumbnailUrl":16,"images":17,"sortOrder":18,"active":19,"next":20},6,"rag-knowledge-assistant","AI-Powered Knowledge Assistant","AI \u002F ML","Personal project","React, TypeScript, Zustand, Pinecone, embeddings, semantic search, LLM APIs","2025","A retrieval-augmented chat assistant over 1,200+ technical documents, with streamed answers, source citations, and a relevance-feedback loop.","A large body of technical documentation is only useful if you can find the one paragraph you need. Keyword search misses anything phrased differently, and asking a general model straight out produces confident answers that are not grounded in the actual documents.","I built the ingestion side first: chunk the corpus, embed it, and index it in Pinecone so retrieval runs on semantic similarity rather than keyword overlap. The answer path retrieves the relevant chunks, grounds the model on them, and returns citations alongside the response so a reader can check the source. The front end is React and TypeScript with Zustand for state and streaming responses over SSE — which means treating loading, partial, error, and empty states as first-class, since a streamed answer can fail halfway through. A relevance-feedback loop captures which retrievals were actually useful, and the whole thing sits behind a REST API so it can be embedded in other applications.","Retrieval over the 1,200+ document corpus returns in under 400ms, and prompt engineering evaluated against a fixed question set cut hallucinated answers by roughly a third against the ungrounded baseline.","","\u002Fimg\u002Fprojects\u002Fcover-rag-assistant.svg","[]",2,true,{"slug":21,"title":22},"java-ee-to-spring-boot-migration","Java EE to Spring Boot Migration"]