From 62dc69374a430fc686906916bcf746ae73317368 Mon Sep 17 00:00:00 2001 From: Philipp Mock Date: Tue, 3 Feb 2026 11:44:11 +0100 Subject: [PATCH] added logging of RAG chunks for debugging --- local_rag.py | 39 ++++++++++++++++++++++++--------------- server.py | 24 ++++++++++++++++++++++-- templates/chat.html | 9 +++++++++ 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/local_rag.py b/local_rag.py index 70ded93..403b040 100644 --- a/local_rag.py +++ b/local_rag.py @@ -134,18 +134,26 @@ class LocalRAG: return doc_list def query(self, question, k=4): - """Query the RAG system""" + """Query the RAG system. Returns dict with 'answer' and 'retrieved' (list of chunks with content, source, page).""" if self.vectorstore is None: - return "Error: No documents loaded. Please add documents first." - - print(f"\nSearching for relevant documents...") + return { + "answer": "Error: No documents loaded. Please add documents first.", + "retrieved": [], + } + docs = self.vectorstore.similarity_search(question, k=k) - print(f"Found {len(docs)} relevant documents") - + retrieved = [ + { + "content": doc.page_content, + "source": doc.metadata.get("source", ""), + "page": doc.metadata.get("page"), + } + for doc in docs + ] + # Combine context from documents context = "\n\n".join([doc.page_content for doc in docs]) - - # Create prompt + prompt = f"""Use the following context to answer the question. If you don't know the answer, say that you don't know instead of making up an answer. @@ -155,12 +163,11 @@ Context: Question: {question} Answer:""" - - print("Generating answer with Ollama...") + response = self.llm.invoke(prompt) - answer = response.content if hasattr(response, 'content') else str(response) - - return answer + answer = response.content if hasattr(response, "content") else str(response) + + return {"answer": answer, "retrieved": retrieved} def main(): @@ -184,9 +191,11 @@ def main(): # Query question = "What do the documents say about modality for perceived message perception?" - answer = rag.query(question) + result = rag.query(question) print(f"\nQuestion: {question}") - print(f"Answer: {answer}") + print(f"Answer: {result['answer']}") + if result.get("retrieved"): + print(f"Retrieved {len(result['retrieved'])} chunks") # print("\nSetup complete! Uncomment the code above to add documents and query.") diff --git a/server.py b/server.py index 48c7839..54e71a8 100644 --- a/server.py +++ b/server.py @@ -22,9 +22,16 @@ class ChatRequest(BaseModel): message: str +class RetrievedChunk(BaseModel): + content: str + source: str + page: int | None + + class ChatResponse(BaseModel): answer: str error: str | None = None + retrieved: list[RetrievedChunk] | None = None @app.get("/", response_class=HTMLResponse) @@ -42,8 +49,21 @@ def chat(request: ChatRequest): if not request.message or not request.message.strip(): return ChatResponse(answer="", error="Message cannot be empty") try: - answer = rag.query(request.message.strip()) - return ChatResponse(answer=answer) + result = rag.query(request.message.strip()) + answer = result["answer"] + retrieved = result.get("retrieved", []) + + # Server-side console trace: log retrieved chunks before LLM answer + if retrieved: + print(f"\n[RAG] Retrieved {len(retrieved)} chunk(s) for query: {request.message[:80]!r}") + for i, chunk in enumerate(retrieved): + content = chunk.get("content", "") + preview = (content[:1000] + "...") if len(content) > 1000 else content + print(f" [{i + 1}] source={chunk.get('source', '')} page={chunk.get('page')} | {preview!r}") + else: + print(f"\n[RAG] Retrieved 0 chunks for query: {request.message[:80]!r}") + + return ChatResponse(answer=answer, retrieved=retrieved) except Exception as e: return ChatResponse(answer="", error=str(e)) diff --git a/templates/chat.html b/templates/chat.html index 5588efa..fa414cb 100644 --- a/templates/chat.html +++ b/templates/chat.html @@ -186,6 +186,15 @@ }); const data = await res.json(); setLoading(false); + if (data.retrieved && data.retrieved.length > 0) { + console.groupCollapsed('[RAG] Retrieved ' + data.retrieved.length + ' chunk(s)'); + data.retrieved.forEach(function(chunk, i) { + console.group('Chunk ' + (i + 1) + ' | ' + (chunk.source || '') + (chunk.page != null ? ' p.' + chunk.page : '')); + console.log(chunk.content); + console.groupEnd(); + }); + console.groupEnd(); + } if (data.error) { appendMessage('assistant', data.error, true); } else {