| """
|
| chatbot.py — standalone RAG chain helpers for 9jaLingo FAQ chatbot.
|
| """
|
|
|
| from __future__ import annotations
|
|
|
| import os
|
| from operator import itemgetter
|
|
|
| from langchain_core.output_parsers import StrOutputParser
|
| from langchain_core.prompts import ChatPromptTemplate
|
| from langchain_core.runnables import RunnableParallel
|
| from langchain_ollama import ChatOllama
|
|
|
| from src.ingest import get_or_build_vectorstore
|
|
|
|
|
| LLM_MODEL = os.getenv("LLM_MODEL", "hf.co/LiquidAI/LFM2-1.2B-RAG-GGUF:Q5_K_M")
|
|
|
| SYSTEM_PROMPT = """You are a friendly and knowledgeable support assistant for 9jaLingo,
|
| a voice AI platform for African language speech products.
|
|
|
| Answer the user's question using ONLY the context provided below.
|
| If the context does not contain enough information to answer, say so politely
|
| and suggest the user visit https://www.9jalingo.org or contact support.
|
|
|
| Context:
|
| {context}
|
| """
|
|
|
|
|
| def _format_docs(docs) -> str:
|
| return "\n\n".join(doc.page_content for doc in docs)
|
|
|
|
|
| def build_rag_chain(k: int = 4):
|
| vectorstore = get_or_build_vectorstore()
|
| retriever = vectorstore.as_retriever(search_kwargs={"k": k})
|
|
|
| llm = ChatOllama(model=LLM_MODEL, temperature=0.2)
|
| prompt = ChatPromptTemplate.from_messages(
|
| [
|
| ("system", SYSTEM_PROMPT),
|
| ("human", "{question}"),
|
| ]
|
| )
|
|
|
| setup = RunnableParallel(
|
| context=itemgetter("question") | retriever | _format_docs,
|
| question=itemgetter("question"),
|
| )
|
|
|
| return setup | prompt | llm | StrOutputParser()
|
|
|
|
|
| def stream_rag_chain(question: str, k: int = 4):
|
| chain = build_rag_chain(k=k)
|
| yield from chain.stream({"question": question}) |