07. FAQ Bot

Chapter 7 of 18 · 20 min

An FAQ bot answers common questions by retrieving relevant knowledge and generating natural responses. The architecture is retrieval-augmented generation: find the relevant information, then have the model synthesize an answer.

Start by structuring your knowledge base:

import json
from pathlib import Path

def build_knowledge_base(knowledge_files):
    """Convert documents into a searchable knowledge base."""
    documents = []
    
    for file_path in knowledge_files:
        path = Path(file_path)
        if path.suffix == '.md':
            content = path.read_text()
            documents.append({
                'source': str(path),
                'type': 'markdown',
                'content': content
            })
        elif path.suffix == '.txt':
            content = path.read_text()
            documents.append({
                'source': str(path),
                'type': 'text',
                'content': content
            })
        elif path.suffix == '.json':
            data = json.loads(path.read_text())
            for item in data:
                documents.append({
                    'source': str(path),
                    'type': 'qa_pair',
                    'question': item.get('question', ''),
                    'answer': item.get('answer', '')
                })
    
    return documents

def chunk_documents(documents, chunk_size=500):
    """Split documents into manageable chunks."""
    chunks = []
    
    for doc in documents:
        content = doc['content']
        if 'question' in doc:
            # Q&A pairs stay together
            chunks.append({
                'content': f"Q: {doc['question']}\nA: {doc['answer']}",
                'source': doc['source']
            })
        else:
            # Split longer documents
            words = content.split()
            for i in range(0, len(words), chunk_size):
                chunk_text = ' '.join(words[i:i+chunk_size])
                chunks.append({
                    'content': chunk_text,
                    'source': doc['source']
                })
    
    return chunks

The simple retrieval approach for a FAQ bot uses keyword matching:

import re

def find_relevant_chunks(query, chunks, max_chunks=3):
    """Find chunks relevant to user query."""
    query_words = set(re.findall(r'\w+', query.lower()))
    scored_chunks = []
    
    for chunk in chunks:
        chunk_words = set(re.findall(r'\w+', chunk['content'].lower()))
        overlap = len(query_words & chunk_words)
        if overlap > 0:
            scored_chunks.append((overlap, chunk))
    
    scored_chunks.sort(reverse=True)
    return [chunk for _, chunk in scored_chunks[:max_chunks]]

More advanced retrieval uses embeddings, but for FAQ bots with hundreds of documents, keyword matching with TF-IDF scoring often suffices and avoids the complexity of embedding model management.

The answer generation combines the user question with retrieved context:

FAQ_PROMPT = """Answer the user's question based only on the provided context. 
If the context does not contain the answer, say "I don't have information about that in my knowledge base."

CONTEXT:
{context}

USER QUESTION: {question}

Provide a helpful, accurate answer:
"""

def answer_faq(question, chunks):
    """Generate FAQ answer using retrieved context."""
    relevant = find_relevant_chunks(question, chunks)
    
    if not relevant:
        return {
            'answer': "I don't have information about that in my knowledge base.",
            'sources': []
        }
    
    context = "\n---\n".join(chunk['content'] for chunk in relevant)
    sources = [chunk['source'] for chunk in relevant]
    
    prompt = FAQ_PROMPT.format(question=question, context=context)
    
    response = chat(model='llama3.2:3b', messages=[
        {'role': 'user', 'content': prompt}
    ])
    
    return {
        'answer': response['message']['content'],
        'sources': sources
    }
EXERCISE

Compile your top twenty FAQ topics into a structured knowledge base file. Deploy the FAQ bot and test with real user questions.