Spaces:
Sleeping
Sleeping
File size: 1,987 Bytes
d309047 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | """
FAISS-based RAG pipeline for real-time Q&A over meeting transcript.
Stores sentence embeddings in a session-scoped FAISS index.
On query: embed question, retrieve top-k relevant sentences, pass to Claude.
"""
import faiss
import numpy as np
from typing import Optional
# Per-session FAISS stores: session_id -> { index, sentences, timestamps }
_session_stores: dict = {}
def get_or_create_store(session_id: str, dim: int = 384) -> dict:
if session_id not in _session_stores:
index = faiss.IndexFlatIP(dim) # Inner product = cosine on normalized vecs
_session_stores[session_id] = {
"index": index,
"sentences": [],
"timestamps": [],
}
return _session_stores[session_id]
def add_to_store(session_id: str, sentence: str, embedding: np.ndarray, timestamp: float = 0.0):
"""Add a sentence and its embedding to the session FAISS store."""
store = get_or_create_store(session_id)
vec = embedding.astype("float32").reshape(1, -1)
store["index"].add(vec)
store["sentences"].append(sentence)
store["timestamps"].append(timestamp)
def retrieve(session_id: str, query_embedding: np.ndarray, top_k: int = 5) -> list[str]:
"""
Retrieve top-k most relevant sentences for a query embedding.
Returns list of sentence strings.
"""
store = _session_stores.get(session_id)
if not store or store["index"].ntotal == 0:
return []
k = min(top_k, store["index"].ntotal)
query = query_embedding.astype("float32").reshape(1, -1)
_, indices = store["index"].search(query, k)
results = []
for idx in indices[0]:
if 0 <= idx < len(store["sentences"]):
ts = store["timestamps"][idx]
text = store["sentences"][idx]
results.append(f"[{ts:.0f}s] {text}")
return results
def clear_store(session_id: str):
"""Remove a session's FAISS store (call on meeting end)."""
_session_stores.pop(session_id, None)
|