added logging of RAG chunks for debugging

This commit is contained in:
Philipp Mock 2026-02-03 11:44:11 +01:00
parent 205e348be0
commit 62dc69374a
3 changed files with 55 additions and 17 deletions

View File

@ -134,18 +134,26 @@ class LocalRAG:
return doc_list return doc_list
def query(self, question, k=4): 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: if self.vectorstore is None:
return "Error: No documents loaded. Please add documents first." return {
"answer": "Error: No documents loaded. Please add documents first.",
"retrieved": [],
}
print(f"\nSearching for relevant documents...")
docs = self.vectorstore.similarity_search(question, k=k) 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 # Combine context from documents
context = "\n\n".join([doc.page_content for doc in docs]) context = "\n\n".join([doc.page_content for doc in docs])
# Create prompt
prompt = f"""Use the following context to answer the question. 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. If you don't know the answer, say that you don't know instead of making up an answer.
@ -156,11 +164,10 @@ Question: {question}
Answer:""" Answer:"""
print("Generating answer with Ollama...")
response = self.llm.invoke(prompt) response = self.llm.invoke(prompt)
answer = response.content if hasattr(response, 'content') else str(response) answer = response.content if hasattr(response, "content") else str(response)
return answer return {"answer": answer, "retrieved": retrieved}
def main(): def main():
@ -184,9 +191,11 @@ def main():
# Query # Query
question = "What do the documents say about modality for perceived message perception?" 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"\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.") # print("\nSetup complete! Uncomment the code above to add documents and query.")

View File

@ -22,9 +22,16 @@ class ChatRequest(BaseModel):
message: str message: str
class RetrievedChunk(BaseModel):
content: str
source: str
page: int | None
class ChatResponse(BaseModel): class ChatResponse(BaseModel):
answer: str answer: str
error: str | None = None error: str | None = None
retrieved: list[RetrievedChunk] | None = None
@app.get("/", response_class=HTMLResponse) @app.get("/", response_class=HTMLResponse)
@ -42,8 +49,21 @@ def chat(request: ChatRequest):
if not request.message or not request.message.strip(): if not request.message or not request.message.strip():
return ChatResponse(answer="", error="Message cannot be empty") return ChatResponse(answer="", error="Message cannot be empty")
try: try:
answer = rag.query(request.message.strip()) result = rag.query(request.message.strip())
return ChatResponse(answer=answer) 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: except Exception as e:
return ChatResponse(answer="", error=str(e)) return ChatResponse(answer="", error=str(e))

View File

@ -186,6 +186,15 @@
}); });
const data = await res.json(); const data = await res.json();
setLoading(false); 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) { if (data.error) {
appendMessage('assistant', data.error, true); appendMessage('assistant', data.error, true);
} else { } else {