Systems Library / Operations & Admin / How to Build an AI-Powered Internal FAQ Bot
Operations & Admin communication

How to Build an AI-Powered Internal FAQ Bot

Answer common employee questions instantly with an AI-powered internal bot.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

HR and IT answer the same questions every week. Where is the expense policy? How do I reset my password? I built an ai internal faq bot that answers employee questions instantly by pulling from your existing documentation. It handles the repetitive questions so your team can focus on real problems.

The bot gets smarter as you add more documentation.

What You Need Before Starting

Step 1: Build the Knowledge Index

import chromadb
from pathlib import Path

def build_faq_index(docs_directory):
    client = chromadb.Client()
    collection = client.create_collection("internal_faq")

    for filepath in Path(docs_directory).rglob("*.md"):
        content = filepath.read_text(encoding="utf-8")
        chunks = [content[i:i+500] for i in range(0, len(content), 400)]

        for idx, chunk in enumerate(chunks):
            collection.add(
                documents=[chunk],
                metadatas=[{"source": filepath.name, "section": idx}],
                ids=[f"{filepath.stem}_{idx}"]
            )

    return collection

Step 2: Search and Answer

import anthropic

ai_client = anthropic.Anthropic()

def answer_faq(question, collection):
    results = collection.query(query_texts=[question], n_results=3)
    context = "\n\n".join(results["documents"][0])
    sources = list(set(m["source"] for m in results["metadatas"][0]))

    message = ai_client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=500,
        system="You are an internal company assistant. Answer from the provided context only. If the answer is not in the context, say so. Be concise and specific.",
        messages=[{"role": "user", "content": f"Context:\n{context}\n\nQuestion: {question}"}]
    )

    return {"answer": message.content[0].text, "sources": sources}

Step 3: Deploy as a Slack Bot

from slack_bolt import App

app = App(token="xoxb-your-bot-token")
collection = build_faq_index("/path/to/docs")

@app.event("app_mention")
def handle_mention(event, say):
    question = event["text"].split(">", 1)[-1].strip()
    if not question:
        say("Ask me a question and I will check our docs for the answer.")
        return

    result = answer_faq(question, collection)
    response = f"{result['answer']}\n\n_Sources: {', '.join(result['sources'])}_"
    say(response)

@app.event("message")
def handle_dm(event, say):
    if event.get("channel_type") == "im":
        result = answer_faq(event["text"], collection)
        say(f"{result['answer']}\n\n_Sources: {', '.join(result['sources'])}_")

Step 4: Track Unanswered Questions

import sqlite3
from datetime import datetime

def init_faq_tracking(db_path="faq_tracking.db"):
    conn = sqlite3.connect(db_path)
    conn.execute("""
        CREATE TABLE IF NOT EXISTS faq_queries (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            question TEXT,
            answered INTEGER,
            confidence TEXT,
            asked_at TEXT
        )
    """)
    conn.commit()
    return conn

def log_query(conn, question, was_answered):
    conn.execute(
        "INSERT INTO faq_queries (question, answered, asked_at) VALUES (?,?,?)",
        (question, int(was_answered), datetime.now().isoformat())
    )
    conn.commit()

def get_unanswered(conn, limit=20):
    return conn.execute(
        "SELECT question, COUNT(*) as freq FROM faq_queries WHERE answered=0 GROUP BY question ORDER BY freq DESC LIMIT ?",
        (limit,)
    ).fetchall()

Step 5: Refresh the Index

def refresh_index(docs_directory):
    global collection
    client = chromadb.Client()
    try:
        client.delete_collection("internal_faq")
    except Exception:
        pass
    collection = build_faq_index(docs_directory)
    print(f"Index refreshed from {docs_directory}")

# Schedule weekly refresh
# 0 6 * * 1 python3 /path/to/refresh_faq.py

What to Build Next

Review the unanswered questions weekly. Each unanswered question is a documentation gap. Write a doc for the top 5 most-asked unanswered questions each week, and the bot handles more over time.

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems