modified: blueprints/chat.py
modified: services/rag_service.py
This commit is contained in:
@@ -63,6 +63,36 @@ def ping_llm():
|
|||||||
return jsonify({"status": "error", "error": str(e), "url": url, "model": model, "embed_model": embed_model}), 502
|
return jsonify({"status": "error", "error": str(e), "url": url, "model": model, "embed_model": embed_model}), 502
|
||||||
|
|
||||||
|
|
||||||
|
@chat_bp.route("/debug-rag", methods=["GET"])
|
||||||
|
@login_required
|
||||||
|
def debug_rag():
|
||||||
|
"""Diagnose RAG: show collection size, run a test query, return raw distances."""
|
||||||
|
query = request.args.get("q", "test")
|
||||||
|
source_id = request.args.get("source_id", type=int)
|
||||||
|
source_type = request.args.get("source_type", "doc")
|
||||||
|
try:
|
||||||
|
collection = rag_service._get_collection()
|
||||||
|
total_chunks = collection.count()
|
||||||
|
source_ids = [source_id] if source_id else None
|
||||||
|
raw = collection.query(
|
||||||
|
query_texts=[query],
|
||||||
|
n_results=min(5, max(1, total_chunks)),
|
||||||
|
where=rag_service._build_where(current_user.id, source_ids, source_type if source_id else None),
|
||||||
|
include=["documents", "distances", "ids"],
|
||||||
|
)
|
||||||
|
hits = [
|
||||||
|
{"id": i, "distance": round(d, 4), "preview": t[:120]}
|
||||||
|
for i, d, t in zip(
|
||||||
|
(raw.get("ids") or [[]])[0],
|
||||||
|
(raw.get("distances") or [[]])[0],
|
||||||
|
(raw.get("documents") or [[]])[0],
|
||||||
|
)
|
||||||
|
]
|
||||||
|
return jsonify({"total_chunks": total_chunks, "query": query, "hits": hits})
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
# ── Main chat ────────────────────────────────────────────────────────────────
|
# ── Main chat ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@chat_bp.route("/sessions/<int:session_id>/ask", methods=["POST"])
|
@chat_bp.route("/sessions/<int:session_id>/ask", methods=["POST"])
|
||||||
@@ -108,6 +138,8 @@ def ask(session_id):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.warning(f"RAG lookup failed, continuing without context: {e}")
|
current_app.logger.warning(f"RAG lookup failed, continuing without context: {e}")
|
||||||
|
|
||||||
|
current_app.logger.info(f"RAG: found {len(chunks)} chunks for session {session_id}")
|
||||||
|
|
||||||
# Build history (last 10 messages for context window)
|
# Build history (last 10 messages for context window)
|
||||||
history = [
|
history = [
|
||||||
{"role": m.role, "content": m.content}
|
{"role": m.role, "content": m.content}
|
||||||
|
|||||||
@@ -190,6 +190,16 @@ def _fetch_neighbor_docs(chunk_id: str, collection) -> list[tuple[str, str]]:
|
|||||||
return neighbors
|
return neighbors
|
||||||
|
|
||||||
|
|
||||||
|
def _build_where(user_id: int, source_ids=None, source_type=None) -> dict:
|
||||||
|
"""Build a ChromaDB where-filter for user/source scoping."""
|
||||||
|
conditions = [{"user_id": {"$eq": str(user_id)}}]
|
||||||
|
if source_ids is not None and len(source_ids) > 0:
|
||||||
|
conditions.append({"source_id": {"$in": [str(sid) for sid in source_ids]}})
|
||||||
|
if source_type:
|
||||||
|
conditions.append({"source_type": {"$eq": source_type}})
|
||||||
|
return {"$and": conditions} if len(conditions) > 1 else conditions[0]
|
||||||
|
|
||||||
|
|
||||||
def similarity_search(
|
def similarity_search(
|
||||||
query: str,
|
query: str,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
@@ -199,13 +209,7 @@ def similarity_search(
|
|||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
"""Multi-query search with neighbor expansion and reading-order sorting."""
|
"""Multi-query search with neighbor expansion and reading-order sorting."""
|
||||||
collection = _get_collection()
|
collection = _get_collection()
|
||||||
|
where = _build_where(user_id, source_ids, source_type)
|
||||||
conditions = [{"user_id": {"$eq": str(user_id)}}]
|
|
||||||
if source_ids is not None and len(source_ids) > 0:
|
|
||||||
conditions.append({"source_id": {"$in": [str(sid) for sid in source_ids]}})
|
|
||||||
if source_type:
|
|
||||||
conditions.append({"source_type": {"$eq": source_type}})
|
|
||||||
where = {"$and": conditions} if len(conditions) > 1 else conditions[0]
|
|
||||||
|
|
||||||
# Generate multiple queries for broader recall
|
# Generate multiple queries for broader recall
|
||||||
queries = _expand_query(query)
|
queries = _expand_query(query)
|
||||||
@@ -228,7 +232,7 @@ def similarity_search(
|
|||||||
dists = (results.get("distances") or [[]])[0]
|
dists = (results.get("distances") or [[]])[0]
|
||||||
ids = (results.get("ids") or [[]])[0]
|
ids = (results.get("ids") or [[]])[0]
|
||||||
for doc, dist, doc_id in zip(docs, dists, ids):
|
for doc, dist, doc_id in zip(docs, dists, ids):
|
||||||
if doc_id not in seen_ids and dist < 0.65:
|
if doc_id not in seen_ids and dist < 0.80:
|
||||||
seen_ids.add(doc_id)
|
seen_ids.add(doc_id)
|
||||||
ranked.append((dist, doc_id, doc))
|
ranked.append((dist, doc_id, doc))
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
Reference in New Issue
Block a user