Download src/math/knowledge_indexer.py from False45/math-api: direct link, hf CLI and curl.
- Browser
- Download file 2.95 kB
-
https://huggingface.co/spaces/False45/math-api/resolve/main/src/math/knowledge_indexer.py
- Command line
-
hf download hf://spaces/False45/math-api/src/math/knowledge_indexer.py
-
curl -L -o knowledge_indexer.py https://huggingface.co/spaces/False45/math-api/resolve/main/src/math/knowledge_indexer.py
2.95 kB
| """ | |
| Knowledge Base Indexing Pipeline — Markdown loading, preprocessing, and chunking for Qdrant. | |
| """ | |
| import os | |
| import glob | |
| import logging | |
| from typing import List | |
| from langchain_core.documents import Document | |
| from backend.src.services.qdrant_service import QdrantService | |
| from backend.src.config import settings | |
| logger = logging.getLogger("math_assistant.indexer") | |
| class KnowledgeIndexer: | |
| """Parses local markdown files and indexes them into the Qdrant vector store.""" | |
| def __init__(self, kb_dir: str = "knowledge-base"): | |
| self.kb_dir = kb_dir | |
| self.qdrant = QdrantService() | |
| def parse_frontmatter(self, text: str) -> tuple[dict, str]: | |
| """Extract metadata from markdown frontmatter.""" | |
| metadata = {} | |
| content = text | |
| if text.startswith("---\n"): | |
| parts = text.split("---\n", 2) | |
| if len(parts) == 3: | |
| frontmatter = parts[1] | |
| content = parts[2] | |
| for line in frontmatter.strip().split('\n'): | |
| if ':' in line: | |
| key, val = line.split(':', 1) | |
| metadata[key.strip()] = val.strip() | |
| return metadata, content.strip() | |
| def load_markdown_files(self) -> List[Document]: | |
| """Load all markdown files from the knowledge base directory.""" | |
| documents = [] | |
| search_pattern = os.path.join(self.kb_dir, "**", "*.md") | |
| filepaths = glob.glob(search_pattern, recursive=True) | |
| logger.info(f"Found {len(filepaths)} markdown files in {self.kb_dir}") | |
| for filepath in filepaths: | |
| try: | |
| with open(filepath, 'r', encoding='utf-8') as f: | |
| text = f.read() | |
| metadata, content = self.parse_frontmatter(text) | |
| metadata["source_file"] = filepath | |
| doc = Document(page_content=content, metadata=metadata) | |
| documents.append(doc) | |
| except Exception as e: | |
| logger.error(f"Failed to process {filepath}: {e}") | |
| return documents | |
| def index_all(self): | |
| """Load all files, split, and index into Qdrant.""" | |
| logger.info("Starting Knowledge Base indexing...") | |
| docs = self.load_markdown_files() | |
| if not docs: | |
| logger.warning("No documents found to index.") | |
| return | |
| from langchain.text_splitter import RecursiveCharacterTextSplitter | |
| splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100) | |
| chunks = splitter.split_documents(docs) | |
| logger.info(f"Created {len(chunks)} chunks. Pushing to Qdrant...") | |
| self.qdrant.add_documents(chunks) | |
| logger.info(f"Indexing complete. Total vectors: {self.qdrant.get_document_count()}") | |
| if __name__ == "__main__": | |
| indexer = KnowledgeIndexer() | |
| indexer.index_all() | |