Support bot that answers from your knowledge base
You'll have a bot that answers customers only from your knowledge base, and when it doesn't know, says "I'm passing this to a colleague" and sends the question to an operator chat.
You need: a fetch_... key with a spend limit (create one, limits), a balance (top up), Python 3.10+. For Telegram — the bot from Telegram bot with AI.
- 1Write the knowledge base
Create
knowledge_base.md: delivery, payment, returns, warranty, opening hours, contacts. Be specific, with numbers. Sample below. - 2Save the code
Copy the code from "Full code" below into
support.py, next to the knowledge base. - 3Try it in the terminalbash
pip install openai export ZUKKO_API_KEY="fetch_..." python support.pyAsk questions covered by the knowledge base and some that aren't. Each returns JSON: the reply,
needs_humanand the reason. - 4Test on 20 real questions
Use real customer questions, awkward ones included. The bot must not invent prices or delivery times. Automated check: LLM as a judge.
1Sample knowledge base
# Delivery
- Within the city by courier: 1–2 days, $5, free over $80.
- Nationwide: 3–7 days, the price is shown at checkout.
- Pickup: 1 Example St., Mon–Fri 10:00–20:00.
# Payment
- Card on the website, bank transfer, cash to the courier.
# Returns
- Within 14 days of delivery if the item hasn't been used.
- Refunds go back to the original payment method within 10 business days.
# Contacts
- Support hours: Mon–Fri 9:00–21:00.2Full code
The model is claude-haiku-5-5 (or deepseek-v4.1-flash): both stick to the JSON schema. Unanswered questions go to unanswered.jsonl — add them to the knowledge base once a week. Changed the knowledge base? Restart the bot.
import asyncio
import json
import logging
import os
from datetime import datetime, timezone
from pathlib import Path
from openai import APIConnectionError, APIStatusError, AsyncOpenAI
log = logging.getLogger("support")
MODEL = os.environ.get("ZUKKO_SUPPORT_MODEL", "claude-haiku-5-5")
COMPANY = "Example Store"
KNOWLEDGE_BASE = Path(os.environ.get("KB_FILE", "knowledge_base.md")).read_text(encoding="utf-8")3Connect to Telegram
- 1Put the files together
support.pyandknowledge_base.mdgo in the folder withbot.pyfrom Telegram bot with AI. - 2Create an operator chat
Create a Telegram group and add the bot to it.
- 3Paste the code into bot.py
It replaces
on_messageand adds an /id command. Inmain(), addapp.add_handler(CommandHandler("id", show_id)).bot.py (add)from support import answer as support_answer ADMIN_CHAT_ID = int(os.environ["ADMIN_CHAT_ID"]) # the chat where operator requests arrive async def show_id(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: """/id command: shows the chat id you need for ADMIN_CHAT_ID.""" await update.message.reply_text(f"chat id: {update.effective_chat.id}") async def on_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: chat_id = update.effective_chat.id if chat_id == ADMIN_CHAT_ID: return # stay silent in the operators' chat - 4Get the chat id
Send
/idin the operators' group. The bot replies with the id (group ids start with a minus). - 5Start
Set
export ADMIN_CHAT_ID="-100..."and start the bot. Questions that need a person arrive in the operator chat; the operator contacts the customer directly.
4If it doesn't work
| What you see | What to do |
|---|---|
FileNotFoundError: knowledge_base.md | Put it next to support.py or set the path in KB_FILE |
| The bot invents a price or a delivery time | Add the fact. If it keeps happening, use a stronger model |
| The bot calls a person for almost everything | Add customers' wording to the knowledge base, check unanswered.jsonl |
| "invalid JSON" in the log | Use claude-haiku-5-5 or deepseek-v4.1-flash |
| Operators get nothing | Send /id in the operators' group and copy the id, minus included, into ADMIN_CHAT_ID. The bot must be in the group |
| 401, 402, 403, 429 | See Telegram bot and API errors |