PNA-Assistant / knowledge_base.py
Nursing Citizen Development
Fix: Force embedding models to CPU for ZeroGPU compatibility
5ee6662
import os
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer
import marko
class PNAKnowledgeBase:
def __init__(self, guide_path):
self.guide_path = guide_path
# Force CPU for embeddings to avoid ZeroGPU device mismatch
self.encoder = SentenceTransformer('all-MiniLM-L6-v2', device='cpu')
self.chunks = []
self.index = None
if os.path.exists(guide_path):
self._process_guide()
else:
print(f"Warning: Guide not found at {guide_path}")
def _process_guide(self):
with open(self.guide_path, 'r', encoding='utf-8') as f:
content = f.read()
# Simple chunking by paragraph/section
# For nursing docs, we want to keep context together
chunks = content.split('\n\n')
self.chunks = [c.strip() for c in chunks if len(c.strip()) > 50]
# Create FAISS index
embeddings = self.encoder.encode(self.chunks)
dimension = embeddings.shape[1]
self.index = faiss.IndexFlatL2(dimension)
self.index.add(np.array(embeddings).astype('float32'))
print(f"Knowledge Base initialized with {len(self.chunks)} chunks.")
def search(self, query, top_k=3):
if not self.index:
return ""
query_vector = self.encoder.encode([query])
distances, indices = self.index.search(np.array(query_vector).astype('float32'), top_k)
results = [self.chunks[i] for i in indices[0] if i != -1]
return "\n\n---\n\n".join(results)
if __name__ == "__main__":
# Test
kb = PNAKnowledgeBase("Professional nurse advocate A-EQUIP model Guide.md")
print(kb.search("What are the four functions of A-EQUIP?"))