Solution published: update src/utils.py
This commit is contained in:
+29
-41
@@ -1,47 +1,35 @@
|
|||||||
import os
|
import os
|
||||||
from pathlib import Path
|
import pathlib
|
||||||
import json
|
from typing import List
|
||||||
import httpx
|
|
||||||
from langchain_ollama import OllamaEmbeddings
|
from langchain_community.document_loaders import TextLoader
|
||||||
from langchain_chroma import Chroma
|
|
||||||
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
||||||
|
from langchain_chroma import Chroma
|
||||||
|
from langchain_ollama import OllamaEmbeddings
|
||||||
|
|
||||||
CHROMA_PATH = Path("./chroma_faq")
|
CHROMA_PATH = pathlib.Path("./chroma_faq")
|
||||||
|
CHROMA_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
# Load FAQ markdown files into ChromaDB
|
|
||||||
def load_faq_to_chroma(md_dir: str = "data"):
|
def load_faq_to_chroma(md_dir: str = "data") -> None:
|
||||||
Path(md_dir).mkdir(parents=True, exist_ok=True)
|
"""Load all .md files from md_dir into a Chroma vector store.
|
||||||
md_files = list(Path(md_dir).glob("*.md"))
|
The store is persisted at CHROMA_PATH.
|
||||||
if not md_files:
|
"""
|
||||||
raise FileNotFoundError(f"No .md files found in {md_dir}")
|
loader = TextLoader
|
||||||
texts = []
|
all_docs = []
|
||||||
for md_file in md_files:
|
for md_file in pathlib.Path(md_dir).glob("*.md"):
|
||||||
text = md_file.read_text(encoding="utf-8")
|
loader_obj = loader(str(md_file))
|
||||||
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
|
docs = loader_obj.load()
|
||||||
texts.extend(splitter.split_text(text))
|
all_docs.extend(docs)
|
||||||
|
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
|
||||||
|
docs = splitter.split_documents(all_docs)
|
||||||
|
embeddings = OllamaEmbeddings(model="nomic-embed-text")
|
||||||
|
Chroma.from_documents(docs, embeddings, persist_directory=str(CHROMA_PATH))
|
||||||
|
|
||||||
|
|
||||||
|
def search_course_docs(query: str, k: int = 3) -> List[str]:
|
||||||
|
"""Return top k document snippets from the persisted Chroma store."""
|
||||||
embeddings = OllamaEmbeddings(model="nomic-embed-text")
|
embeddings = OllamaEmbeddings(model="nomic-embed-text")
|
||||||
chroma = Chroma(persist_directory=str(CHROMA_PATH), embedding_function=embeddings)
|
chroma = Chroma(persist_directory=str(CHROMA_PATH), embedding_function=embeddings)
|
||||||
chroma.add_texts(texts)
|
results = chroma.similarity_search(query, k=k)
|
||||||
chroma.persist()
|
return [doc.page_content for doc in results]
|
||||||
return chroma
|
|
||||||
|
|
||||||
# Search the ChromaDB for relevant documents
|
|
||||||
def search_course_docs(query: str, k: int = 3):
|
|
||||||
chroma = Chroma(persist_directory=str(CHROMA_PATH), embedding_function=OllamaEmbeddings(model="nomic-embed-text"))
|
|
||||||
retriever = chroma.as_retriever(search_kwargs={"k": k})
|
|
||||||
return retriever.get_relevant_documents(query)
|
|
||||||
|
|
||||||
# MCP‑style tool: fetch metadata from a mock HTTP endpoint
|
|
||||||
# In production this would be a real MCP server. Here we use a local JSON file served by http.server.
|
|
||||||
def fetch_course_meta(query: str):
|
|
||||||
url = f"http://localhost:8000/course_meta.json"
|
|
||||||
try:
|
|
||||||
response = httpx.get(url, timeout=5.0)
|
|
||||||
response.raise_for_status()
|
|
||||||
data = response.json()
|
|
||||||
except Exception:
|
|
||||||
# Fallback to local static file if server not running
|
|
||||||
data = json.loads(Path("data/course_meta.json").read_text(encoding="utf-8"))
|
|
||||||
# Simple filtering: return items where query is in title or description
|
|
||||||
results = [item for item in data if query.lower() in item.get("title", "").lower() or query.lower() in item.get("description", "").lower()]
|
|
||||||
return results
|
|
||||||
|
|||||||
Reference in New Issue
Block a user