01What you’ll have running#
cob-rag-engine is a self-hosted knowledge engine. Each business you serve (a customer, called a tenant in the API) gets private knowledge bases: its documents go in, and cited answers come out through a website chat widget, your own app, or an AI agent. You run one Docker Compose stack: the engine API, a background worker, a mailer, a scheduler, a web scraper, the dashboard, and the datastores (PostgreSQL, Valkey (a Redis-compatible store), Qdrant and the embedding container). This guide takes you from the code you cloned or unzipped to a first customer with a working widget, then covers day-to-day running and what to do when something breaks.
Windows and macOS are for trying cob-rag-engine on your own computer, which is what this guide does. A live server runs Linux: see the requirements and install it with one command from the deploy guide.
| Service | Address | What it is |
|---|---|---|
| Dashboard | http://127.0.0.1:8090 | Where you and your customers sign in. Port variable RAG_DASHBOARD_HOST_PORT. |
| Engine API | http://127.0.0.1:8000 | The REST API. Interactive docs at /docs while RAG_ENV=dev. Port variable RAG_APP_HOST_PORT. |
| Web scraper | http://127.0.0.1:8001 | Crawls a customer’s website for the dashboard’s Crawler page. Port variable RAG_SCRAPER_HOST_PORT. |
| Embeddings (TEI) | 127.0.0.1:8081 | The embedding model container (profile tei, on by default). |
| Langfuse | http://127.0.0.1:3002 | Optional: traces of every question (profile observability). |
| Whisper | 127.0.0.1:9010 | Optional: audio transcription (profile transcription). Port variable RAG_WHISPER_HOST_PORT. |
| Datastores | 5433 6380 6333/6334 | PostgreSQL, Valkey and Qdrant. You never need to open these. |
127.0.0.1 only (RAG_BIND_ADDR), so only your own machine can reach the stack. The three web ports are configurable through RAG_APP_HOST_PORT, RAG_SCRAPER_HOST_PORT and RAG_DASHBOARD_HOST_PORT; step 4 shows how the wizard changes them for you. The other ports are fixed in docker-compose.yml.Start hereYour setup#
The setup wizard asks different questions depending on your computer and your answers, and the steps after it change with them. Say how you will answer and this guide shows only what applies: the right commands for your system, where your sign-in link will arrive, and what to do about a missing AI key. Your choices stay in this browser and in the page address; nothing is sent anywhere.
JavaScript is off, so every variant is shown and each one is labelled with the setup it applies to.
02Before you start#
2.1Software#
- Docker with Compose v2: Docker Desktop on Windows or macOS, Docker Engine on Linux. You need the
docker composecommand (two words), not the olddocker-compose. - Python 3.10 or newer, only for the setup wizard. The wizard uses the standard library, so there is nothing to
pip installand no virtualenv to create. - git, only if you keep your copy under version control.
- make is optional.
make setupis only a shortcut forpython scripts/setup.py.
Check what you have:
docker --version
docker compose version
python --version
git --versionpython is not found, install Python 3.10 or newer (on Windows tick “Add python.exe to PATH” in the installer). On macOS and Linux the command is often python3; make setup uses python when it works and python3 otherwise, so it needs no change; without make use the python3 scripts/setup.py form.2.2Your machine#
- Memory: 4 GB of RAM or more for Docker. The default stack measured 2.1 GB on CPU with 270,000 chunks indexed. Turning on the local re-ranker on CPU adds about 2.3 GB.
- Disk: the repository does not state a figure. The first start builds three images and downloads several more plus an embedding model, so keep several GB free. Ten GB is a comfortable margin; that number is a rule of thumb, not something we measured.
- An NVIDIA GPU is optional. It only makes the local models faster (the embedding model and a local re-ranker), not better. Hosted APIs and LLM re-ranking run at the provider either way. To see whether Docker can use your GPU, run this (it is the same check the wizard suggests; it downloads a small image the first time):
docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smiIf it prints a table with your GPU, Docker can use it. If it fails, answer “no” to the GPU question later; everything works on the CPU.
You chose no GPU, so skip this check: everything local runs on the CPU. If you get one later, re-run the wizard and answer yes.
2.3An AI model key#
Answers are written by a language model, so you need one provider key: OpenRouter (one key, hundreds of models), OpenAI, Anthropic (Claude), Google Gemini, or a local Ollama with no key at all. You can skip this during setup: uploading and searching work without a key, and only answering needs one. The key is stored in your local .env file and nowhere else.
You said you will add one, so have the key ready before step 4: the wizard asks for it (hidden as you type).
You chose to skip it for now. Do step 4 without a key and add it afterwards; Ask in the playground shows how.
03Get the code#
Clone the repository (or unzip a release zip) and move into its folder. Every command in the rest of this guide runs from this folder.
cd cob-rag-engine04Configure with the setup wizard#
The wizard asks a few questions, generates every secret, and writes one file: .env in the repository root. Keys you type are hidden and never printed back.
4.1Run it#
python scripts/setup.py
# or, if make is installed: make setuppython scripts/setup.pypython3 scripts/setup.py
# or: make setupIt opens with “How much do you want to set up?” Choose Quick, the default (or run it with --quick to skip that menu).Choose Full (or run it with --full to skip that menu). Press Enter to accept the answer in [brackets] at any prompt.
4.2Quick or full#
- Quick (the default, recommended): the GPU question once, then your e-mail, the AI model, how to send e-mail, and the re-ranker. Start here.
- Full: also asks about the environment (development or production), where embeddings run, where uploaded files are stored, the web addresses and host ports, the network bind address, and the optional services (audio transcription, Langfuse) and the answer-quality evaluation add-on. Choose it with
--full;--quickforces quick mode.
4.3What each answer means#
- GPU
- “Do you have an NVIDIA GPU that Docker can use?” It is asked once, first, and yes / no / not sure (not sure is treated as no and prints the check from step 2). The answer decides three things: whether the start command includes the GPU overlay, whether the bundled embedding container (TEI) uses its CUDA image, and where a local re-ranker runs.
--gpu yesor--gpu noanswers it up front. - Super-admin e-mail
- The account you sign in to the dashboard with, for example
admin@yourcompany.in. It gets a link to set its password. It must be a real address: names that never receive mail (.local,.test,.example,.localhost,.invalid) are accepted only when the environment is development (RAG_ENV=dev) and refused in production, and the wizard asks again. Press Enter to skip; you then sign in with the admin API key instead (step 6). - AI model
- Pick a provider, the model that writes answers, and a fast model; the wizard suggests both per provider (answers / fast: OpenRouter
openai/gpt-oss-120b/openai/gpt-6-luna, OpenAIgpt-6.1-sol/gpt-4.1-mini, Anthropicclaude-sonnet-5-5/claude-haiku-4-5, Geminigemini-3.8-flash/gemini-3.5-flash-lite, Ollamallama3.1/llama3.2). The fast model is a small, quick model from the same provider that rewrites the search question before it is searched (RAG_LLM_FAST_MODEL); Use a small non-thinking model here: it labels every message and suggests follow-ups; a thinking model makes replies slow. Budget option. On OpenRouter the wizard shows two fast models as a numbered choice and defaults to the first:openai/gpt-6-luna(recommended, 98.9% accurate, about ₹13.6 per 1,000 messages) andgoogle/gemma-4-26b-a4b-it(64% cheaper, about ₹4.9 per 1,000, 97.7% accurate); the numbers come from the fast-model benchmark. Thinking is one setting for every model:RAG_LLM_THINKINGfor answers andRAG_LLM_FAST_THINKING(default off) for the fast model, each off, minimal, low, medium, high or provider-default, and per knowledge base under Model & keys. Off is fastest and cheapest; turn it on only for hard questions. A model that cannot stop thinking (gpt-oss, Gemini 3 Flash) runs at its lowest setting, and every answer says what it ran at. A model per language: on OpenRouter the wizard also asks whether Hindi and Hinglish replies should use their own model (default yes,google/gemma-4-31b-it, written toRAG_LLM_LANGUAGE_MODELS). The assistant notices the language of each message, so Hindi (Devanagari) and Hinglish (Hindi in English letters) are answered by Gemma 4 31B, which had the best Hindi tone and the fastest first word in the answer benchmark, while English keeps the main model (openai/gpt-oss-120bby default, at thinking low). The chosen model answers at its lowest thinking setting, wherever the assistant answers (the plain query, widget and conversation endpoints included). Change it per knowledge base under Model & keys → Model per language (the language switch can follow the engine, name a model per language, or be off); the engine page shows the engine's setting. Routing only applies on the engine's own provider: a knowledge base with a key for another company keeps its model unless you name models for it. The engine skips the rewrite altogether for greetings and questions of three words or fewer. Then paste the key, which is hidden. For Ollama it asks for the address,http://host.docker.internal:11434by default, because from inside Docker your machine ishost.docker.internal. Choose “Skip for now” to add the key later asRAG_LLM_API_KEYin.env. - E-mail sending
- E-mail carries sign-up codes, password resets and invitations. Skip is fine on your own machine: in development the codes and links go to the logs (step 7 shows where). Gmail or Google Workspace needs an app password (2-step verification on, then create one). Another SMTP server asks for host (for example
smtp.zoho.in), port, connection security, login and a sender such asShree Labs <no-reply@shree-labs.in>. - Re-ranker
- A second pass that re-reads the top search results and reorders them. Off is the safe start. In the project’s benchmarks the local model helped on question-and-answer data (the chatbot case) and hurt on other kinds of search; re-ranking through your LLM has not been measured yet. The options follow your GPU answer. With a GPU: off, local on the GPU (about 0.4 s a question), or through your LLM. Without one: off, through your LLM (small cost per question), or local on the CPU (free but about 10 s a question and 2.3 GB of RAM). You can change it per knowledge base later in the dashboard (Knowledge base, then Retrieval).
- Embeddings
- Quick mode does not ask. It uses the bundled TEI container with the model
BAAI/bge-base-en-v1.5, on your GPU if you said yes and on the CPU otherwise. Full mode lets you choose: TEI on CPU, TEI on GPU (offered only if you said yes), inside the engine (BGE-M3), or a hosted API (OpenAI, Cohere, Voyage, Mistral, Gemini or Jina). Changing the embedding model for a knowledge base that already has documents needs a re-embed.
4.4Answers for your setup#
The wizard’s questions in the order it asks them, with the answer that matches what you picked in Your setup. Press Enter to take any default.
- Environment. “Is this a development machine or a live deployment?” Choose Development. A live deployment needs SMTP (production refuses the log provider) and public https addresses. The deploy guide covers the server, HTTPS and updates.
- GPU. “Do you have an NVIDIA GPU that Docker can use?” Choose No. (Not sure is treated as no.)
- GPU. “Do you have an NVIDIA GPU that Docker can use?” Choose Yes.
- Super admin. “Your e-mail”: type the address you will sign in with, for example
admin@yourcompany.in. - Super admin. “Your e-mail”: press Enter to leave it empty. The summary says “skipped (sign in with the admin API key)”.
- AI model. “Which AI provider will write the answers?” Pick one, accept or change the suggested model, then paste your key (it is hidden as you type).
- AI model. “Which AI provider will write the answers?” Choose the last option, “Skip for now (answers will not work until you add a key)”.
- E-mail sending. “How should the engine send e-mail?” Choose “Skip for now (in development, codes and links go to the mailer log)”, the default.
- E-mail sending. Choose “Gmail or Google Workspace”. It asks for your Gmail address, an app password (16 characters, hidden; spaces are removed) and the sender shown on e-mails. Create the app password first at myaccount.google.com/apppasswords; 2-step verification must be on.
- E-mail sending. Choose “Another SMTP server”. It asks for the server (for example
smtp.zoho.in), the port, the connection security (STARTTLS for 587, SSL/TLS for 465), the login and password, and a sender such asShree Labs <no-reply@shree-labs.in>. - Re-ranker. “Turn on re-ranking?” Choose Off, the default.
- Re-ranker. “Turn on re-ranking?” Choose “Local on your GPU”.
- Re-ranker. “Turn on re-ranking?” Choose “Local on your CPU (free but slow: ~10 s a question, 2.3 GB RAM)”.
- Re-ranker. “Turn on re-ranking?” Choose “Via your LLM key”.
- Embeddings. Not asked in quick mode. You get the bundled TEI container on the CPU.You get the bundled TEI container on the GPU.Because you are on Windows with a GPU, the wizard uses the engine’s own embedding model on the GPU, not TEI.
- Embeddings. “Where should embeddings be computed?” Choose “Bundled container (TEI) on the CPU”.
- Embeddings. “Where should embeddings be computed?” Choose “Bundled container (TEI) on your GPU”.
- Embeddings. “Where should embeddings be computed?” Choose “Inside the engine” (BGE-M3, on your GPU if you have one).
- Embeddings. “Where should embeddings be computed?” Choose “A hosted API”, then pick the service (OpenAI, Cohere, Voyage, Mistral, Gemini or Jina), accept or change the model and its vector size, and paste that service’s key.
- Storage. “Where should uploaded files live?” Choose “On this server”.
- Storage. “Where should uploaded files live?” Choose “S3-compatible storage”. It asks for the endpoint address, bucket, region (R2 needs
auto), address style, the access and secret keys, and whether to create the bucket automatically. - Web addresses and network. Press Enter through the three host ports, the public address (leave it empty for local use), the three addresses and the bind address (
127.0.0.1). - Web addresses and network. Type new numbers for the host ports that clash; the wizard moves the matching addresses and allowed origins. Leave the public address empty for local use and keep the bind address
127.0.0.1. - Optional services. Answer yn to audio transcription and yn to Langfuse. Then Install answer-quality evaluation? (default no): it adds RAGAS and LangChain, about 150 MB, and only the RAGAS scores described under Day-to-day need it.
4.5Without the questions#
For scripts, CI or a repeat install, every question can be answered on the command line. --yes accepts every default and asks nothing, --set KEY=VALUE sets any value (repeat it as often as you like), and --dry-run shows what would change, with secrets masked, and writes nothing.
The same answers as one command for your setup. The placeholders (paste-your-key and so on) are yours to replace:
Other examples:
python scripts/setup.py --quick --yes --set "RAG_SUPERADMIN_EMAIL=admin@yourcompany.in"
python scripts/setup.py --quick --yes --gpu yes
python scripts/setup.py --dry-run--yes cannot ask for your LLM key. Add RAG_LLM_API_KEY to .env afterwards, or run the wizard once without --yes. On macOS and Linux write python3 for python.
4.6Running it again later#
Re-running is safe. The wizard copies your old file to .env.backup-<timestamp> first, keeps every value you already have and every key it does not know, and only changes what you answer (it asks “Already set. Keep current?” for things like your key). At the end it prints a summary, a “Worth a look” list of things to double-check, and the exact start command for your choices.
RAG_ENCRYPTION_KEY from .env. Without it, the LLM keys stored by your customers are unreadable. See backing it up. Never commit .env or paste it into a chat.05Start the stack#
5.1Run the command the wizard printed#
The wizard ends with the exact command for your choices. You said no GPU, so it is the plain one.You said yes to the GPU, so it includes the GPU overlay. make up runs the same command.make up-gpu runs the same command.
docker compose up -d --builddocker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d --buildCOMPOSE_PROFILES in .env, so the command does not change. Whisper (audio transcription) listens on 127.0.0.1:9010. Langfuse shows its traces at http://127.0.0.1:3002.5.2The first start takes a while#
The first run builds the engine, scraper and dashboard images and pulls the datastore images, then downloads the embedding model. The compose file gives the embedding container a 120 second grace period before it even checks its health, then 30 checks ten seconds apart, because the model download is the slow part. Models are kept in a Docker volume, so later starts are quick. You can watch it with docker compose logs -f tei. There is no embedding container to wait for here: the engine loads its own embedding model (BGE-M3), which is downloaded too. Embeddings come from the hosted API you chose, so there is no embedding model to download. The local re-ranker model downloads as well.
5.3Wait until it is healthy#
docker compose psRun it again every minute or so until the app service says healthy. When it does, the engine’s health URL answers in your browser. The engine runs its database migrations by itself as it starts, so there is nothing to migrate by hand. If something stays unhealthy or keeps restarting, jump to reading the logs.
5.4Embedding model#
The default is BAAI/bge-m3 (1024-d, multilingual including Hindi and Hinglish), served by the bundled TEI container, roughly 2.3 GB of weights in memory on CPU (an estimate, not measured). A fresh install needs nothing.
An existing install keeps the model in its own .env (RAG_EMBEDDING_MODEL, RAG_EMBEDDING_DIMENSIONS, RAG_TEI_MODEL_ID), so upgrading the engine changes nothing. To switch, set those to BAAI/bge-m3, 1024 and BAAI/bge-m3 and restart: the daily drift check queues one re-embed migration per knowledge base (GET /api/v1/migrations). Start each with POST /api/v1/migrations/{id}/approve, or all of them with POST /api/v1/admin/migrations/approve-all. It builds the new index beside the old one and swaps once verified, so answers keep working; POST .../rollback undoes it.
python -m callobuzz_rag.retrieval.reindex --dense is not the way to switch models: it re-embeds with the same model.06First login#
You gave a super-admin e-mail, so you sign in with it once you have set a password. The engine creates the account on its first start and issues a link to set the password.
You skipped the super-admin e-mail, so there is no password account: you sign in to the dashboard with the admin API key.
6.1Get your set-password link#
You skipped e-mail sending, so the engine prints a one-time link in the app’s log instead of sending it:
docker compose logs app | grep -A4 "ONE-TIME SET-PASSWORD"docker compose logs app | Select-String -Context 0,4 "ONE-TIME SET-PASSWORD"docker compose logs app | grep -A4 "ONE-TIME SET-PASSWORD"You set up SMTP, so the link is e-mailed to the address you gave and nothing is printed in the log. Check that inbox once the app is healthy.
No e-mail yet? Issue a new link and print it on screen right now:
docker compose exec app python -m callobuzz_rag.accounts.bootstrap --resend --print-linkThe output shows the account, a link and a code. Open the link, which is valid for 24 hours, and choose a password: 10 to 128 characters, not one of the 10,000 most common, and not containing the name part of your e-mail. Until you set it, every start of the app issues a fresh code and voids the old one, so if you get several, use the newest.
The page says “That code has expired or was used up” when the link is older than 24 hours, a newer link replaced it, or it was tried 5 times. Issue a fresh one and use only that newest link, in a new tab:
docker compose exec app python -m callobuzz_rag.accounts.bootstrap --resend --print-linkIt runs inside the app container, so you need nothing installed. If you still cannot get in, sign in with the admin key (step 6.3).
6.2Open the dashboard#
Go to http://127.0.0.1:8090 and sign in with your e-mail and the new password.the admin key from the next step.
localhost resolves to the IPv6 address ::1 first, and the connection resets in a way that looks exactly like the service being down.6.3Sign in with the admin keyThe admin key as a fallback#
On the sign-in page click Use an API key instead and paste the admin key, which is RAG_ADMIN_API_KEY in .env. This prints only that one line:
If you lose the password you can still click Use an API key instead on the sign-in page and paste the admin key, which is RAG_ADMIN_API_KEY in .env. This prints only that one line:
grep RAG_ADMIN_API_KEY .envSelect-String RAG_ADMIN_API_KEY .envgrep RAG_ADMIN_API_KEY .envTo add an e-mail login later, re-run the wizard with an e-mail, recreate the app, and issue a link:
python scripts/setup.py --quick --yes --gpu no --set "RAG_SUPERADMIN_EMAIL=admin@yourcompany.in"docker compose up -d appdocker compose exec app python -m callobuzz_rag.accounts.bootstrap --resend --print-link
07Try the whole flow#
This walks one customer from sign-up to a working chat bubble. The example is Shree Labs, a pathology lab in Pune. You play two roles: the operator (you, signed in as the super admin) and the customer’s owner. Use a private browser window for the customer so the two sessions do not collide.
7.1Choose how customers join#
The Customers page shows the current sign-up mode; you change it under Sign-up & branding. There are three:
- Approval required (the default): a new workspace waits as pending until you activate it.
- Open: the workspace is active the moment the customer verifies their e-mail.
- Closed: sign-up is refused with your “contact us” text.
You can also skip sign-up: Customers, then Add customer creates an active workspace by hand, and you then invite its owner. That path works even with no e-mail set up, because an invitation sent by the operator shows the accept link on screen.
RAG_ENV=dev) instead of being sent: read them with docker compose logs mailer.With SMTP set up, sign-up codes, activation e-mails, invitations and password resets are sent by e-mail. Operator invitations also show the accept link on screen.7.2Create a customer#
- In the private window open
http://127.0.0.1:8090/signup. Enter the business name (Shree Labs), your name, an e-mail that is not the super admin’s (for exampleowner@shree-labs.in) and a password. - The dashboard asks for a 6-digit code. It works for 10 minutes and 5 tries. It arrives by e-mail at the address you entered (check spam).You have no SMTP, so it is in the mailer’s log:
docker compose logs mailer | grep -A12 "DEV EMAIL"docker compose logs mailer | Select-String -Context 0,12 "DEV EMAIL"docker compose logs mailer | grep -A12 "DEV EMAIL"Each message is printed in full after the words DEV EMAIL; take the code from the newest one. Enter it, and the workspace is created with you as its owner.
7.3Activate it#
In approval mode the customer now sees “We’ll activate your workspace soon”. As operator, open Customers, the Pending tab, and choose Activate. Pick a plan and, if you like, add a private note such as “Paid ₹3,000 via UPI on 29 Sep”. The owner gets a “You’re in” e-mail (in the mailer log, as you have no SMTPby e-mail). Activation is not billing: collect payment however you like, then activate.
7.4Create a knowledge base#
As the customer’s owner open Knowledge bases, then New knowledge base, and name it Shree Labs FAQ. A knowledge base has its own documents, model settings, search index and API key. The key is shown once at creation.
7.5Upload something#
Open Add content and drag in a file, for example the lab’s test menu with prices in ₹ and fasting instructions. You watch each file go through queued, parsing, chunking, embedding and done. PDF, Word, PowerPoint, Excel, CSV, HTML, Markdown, plain text, PNG and JPEG are accepted, and audio (mp3, wav, m4a, ogg) when the transcription service is on. You can also crawl a website from Crawler (you review the pages before they go in) or import records from JSON or CSV. See upload size limits before you try a large file. If a file looks like one you already have (the same content, not merely a page from the same site with the same menu and footer), it waits as a possible duplicate and you choose: Replace the old one (it becomes a new version), Keep both, or Skip (don’t add), which drops the upload and adds nothing.
7.6Set up the assistant#
Open the knowledge base, then Assistant, then Guided setup (or press Set up the assistant now right after creating it). Pick a business type, or paste your website and let the engine read it. Confirm what it found (name, phone, WhatsApp, e-mail, hours), then answer the twelve questions, mostly multiple choice. You get a draft in which every item says which answer or page created it, and 15 to 25 automatic checks run against it; a question your documents could not answer is listed as a gap, with a link to add a document or an exact answer. When you are happy, an owner presses Publish. Without an AI model the website step is skipped and the draft is written from the template.
7.7Ask in the playground#
Open Playground, pick the knowledge base, and ask something the document answers, such as “Do I need to fast before a lipid profile?” You get an answer with the passages it used. An owner can also give one knowledge base its own model and key.
Then talk to the assistant the way a visitor would. Say “hi” and it answers at once from its persona, with no model call. Ask a question the document answers and you get an answer with sources. Ask something the documents do not hold, such as a price that is not listed, and it says so honestly, shows no sources and offers a way to reach the business. Ask something unrelated, such as who won a cricket match, and it politely steers back to what it can help with. Prices, dates, times, numbers and names in an answer are checked against the documents sentence by sentence, so one that is not there never reaches the screen.
.env and set RAG_LLM_API_KEY to your key (the default provider is OpenRouter; for another provider also set RAG_LLM_PROVIDER and RAG_LLM_MODEL, or re-run the wizard and pick it). Then recreate the services so they read it:docker compose up -d7.8Add the website widget#
- Open Website widget and choose New widget key. Name it, and list the sites allowed to use it, one address each (for example
https://shree-labs.in; plainhttp://is accepted only for localhost and 127.0.0.1). Set the messages per minute for each visitor and per day, and the title, greeting, colour and corner. - Copy the embed snippet and paste it into the website before the closing
</body>tag:
<script src="http://127.0.0.1:8000/widget.js" data-key="pk_..." async></script>Optional attributes are data-open="true" (open the chat on load), data-position="left" and data-color="#0f766e". The pk_ key is meant to be visible in page source: it can only chat with its one knowledge base, only from the sites you listed, and only within the limits you set. The chat panel always shows a small “cob-rag-engine by Callobuzz” link; no setting hides it.
To see it before touching a real site, choose Preview and style on the key. That shows the real widget on a sample website, at phone or desktop width, served from the dashboard at /widget-demo.html. For a live site, set RAG_PUBLIC_URL to your engine’s public HTTPS address so the snippet points there.
The widget answers with the same model as the playground, so it needs the AI model key you skipped (see the playground step) before visitors get answers.
7.9Invite a teammate#
In the customer’s dashboard open Team and choose Invite teammate. They can be an Owner or a Member. The invitation link is valid for 7 days and works once. With no SMTP the invitation e-mail is in the mailer’s log.The invitation is sent by e-mail. Members can use the playground, view everything, upload content and edit prompts and retrieval settings. Owners can also create or delete knowledge bases, manage API and widget keys, set the model key, and manage the team.
7.10Plans and limits#
Open Plans as operator. A fresh install has one plan, Standard, with no limits. A plan can cap four things, each optional: knowledge bases, questions per month, active documents and website widget keys. Move a customer between plans from Customers, then Change plan. Customers see their own usage against the caps under Plan & usage, and you see metered usage per customer under Usage. What the models really cost you is under Costs: the provider’s own figure for every answer, by customer, knowledge base, model and source, with a CSV export. A price the engine cannot find reads “price unknown”, never ₹0.00, and the header shows this month’s spend (and your OpenRouter balance when that is your provider). Payments are not built in: the usage meter is what you bill from.
7.11Set up the assistant#
Every knowledge base already has an assistant, switched on. This is how its owner makes it theirs. Changes go into a draft; visitors see nothing until you publish.
- Open the knowledge base, then the Assistant tab. Choose Start from a template (for Shree Labs, Clinic or lab front desk) and keep your business name and contacts.
- Under Identity fill in the name, what the business does and the business card: opening hours, phone, WhatsApp, e-mail and address. The assistant quotes these exactly, and visitors can ask about them after you publish. Save the draft.
- Open Preview and ask three questions the way a visitor would: one the documents answer, one in Hinglish (for example “Lipid profile ka rate kya hai?”) and one it should not answer. Owners see how each answer was made: the passages, the search confidence against its minimum, the facts that were checked and removed, and the instructions sent to the model. Preview questions count as real questions.
- Choose Publish (owners only; members can edit the draft). Under Versions you can view any earlier version and restore it as a new live version.
- Open the website where the widget is installed and ask the same three questions. If the widget is not installed yet, see Add the website widget.
To get plain grounded answers with no greetings, topic limits, lead forms or hand-off, owners can switch the assistant off on the overview; the old Prompt settings then drive the answers again. Answers show as formatted text: lists, tables, links and source chips.
7.12Leads, handoff and the daily digest#
This is what happens after the assistant has done its job: a visitor wants to be contacted, or needs a person. Everything below is set in the knowledge base’s Assistant tab and saved into the draft, so visitors see it only after you publish.
- Open Leads. Keep the mobile number required, add the notification e-mail addresses, and choose when the form is offered (a buying question, no answer found, a person asked for, out of hours). Leads are stored encrypted, so the engine needs
RAG_ENCRYPTION_KEY; without it the assistant publishes with leads switched off. - Under Qualifying leads choose Add a rule: for example Qualified when why they left their details is equal to asked about buying, and a second rule marking Partly qualified when the name is given. A lead that matches neither is marked unqualified; with no rules nothing is marked and nothing changes. A qualified lead’s thank-you shows a Book now button when the business card has a booking page. The inbox on the Leads page filters by it.
- Tick Daily digest under Notify if you would rather not get a mail for every unqualified lead. Those leads then arrive in one mail a day, listing yesterday’s leads, sent at
RAG_LEAD_DIGEST_HOUR(9 by default) in the business time zone from the business card. An empty day sends nothing. Qualified and partly qualified leads are still mailed at once. - Under Talk to a person choose the ways to reach the business (WhatsApp, call, e-mail, a call-back request) and the office hours. When a visitor needs a person the assistant offers them; you see who was offered one on the Handoffs tab of the Leads page, and can mark each one handled.
- Under Conversation add a proactive greeting, for example the page
/tests/**, a delay of 10 seconds and the message “Need help choosing a test?”. In a page address*stays inside one part and**goes across/. It shows once per visit, never over an open chat, and the visitor can choose “Don’t show again”. - Under Guidance rules, press Improve next to a rule you wrote in a hurry. It suggests a clearer wording and names the rules it may clash with; nothing changes until you press Use this wording, and you still save the draft yourself. It uses the knowledge base’s own model, so it needs one set up.
08Connect an AI agent (MCP)#
cob-rag-mcp is a companion MCP server and command-line tool that plugs a knowledge base into Claude, Cursor, VS Code, n8n or any MCP client. It is only a client: it talks to the engine you just started, and nothing is sent anywhere else. You need Node.js 22 or newer.
8.1What it needs#
The engine address (http://127.0.0.1:8000 here) and a key. Use a key of the knowledge base itself (it starts with ck_), which lets the agent see that one knowledge base and nothing else. Give every agent its own named key with the lowest permission it needs: read searches, asks and lists; write also adds and changes content; full also deletes and manages keys. Revoking one key cuts that agent off and touches nothing else. The server asks the engine who the key is and offers only the tools that key may use. Destructive tools stay hidden unless you set COB_RAG_ALLOW_DESTRUCTIVE=true, and deleting a knowledge base or a document always needs the item’s exact name (confirm_name).
The easy way: open the dashboard’s Agents (MCP) page, choose your client under Connect an agent, leave the permission on Read and press Create key and show config. It makes a key named “Agent – <client>” and shows the exact config for that client with the key already in it. The key is shown once, so copy the config before you leave the page.
8.2Claude Code#
claude mcp add cob-rag \
-e COB_RAG_URL=http://127.0.0.1:8000 \
-e COB_RAG_API_KEY=ck_your_corpus_key \
-- npx -y cob-rag-mcp startclaude mcp add cob-rag -e COB_RAG_URL=http://127.0.0.1:8000 -e COB_RAG_API_KEY=ck_your_corpus_key -- npx -y cob-rag-mcp startclaude mcp add cob-rag \
-e COB_RAG_URL=http://127.0.0.1:8000 \
-e COB_RAG_API_KEY=ck_your_corpus_key \
-- npx -y cob-rag-mcp start8.3Claude Desktop and everything else#
For Claude Desktop, add this to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\) and restart it:
{
"mcpServers": {
"cob-rag": {
"command": "npx",
"args": ["-y", "cob-rag-mcp", "start"],
"env": {
"COB_RAG_URL": "http://127.0.0.1:8000",
"COB_RAG_API_KEY": "ck_your_corpus_key"
}
}
}
}Cursor, VS Code, n8n, the streamable HTTP mode and the cob-rag-engine command-line tool are covered in the cob-rag-mcp README and on its website; the package is on npm. The dashboard’s Agents (MCP) page links there too.
8.4Install before npm publish#
Until the package is published on npm, npx -y cob-rag-mcp start does not work. Install it from a checkout instead (Node.js 22 or newer and pnpm):
git clone https://github.com/callobuzz/cob-rag-mcp.git
cd cob-rag-mcp
pnpm install && pnpm build && npm linknpm link puts the cob-rag-mcp command on your PATH. Then use it wherever a config above says npx -y cob-rag-mcp start: the command is cob-rag-mcp and the arguments are start. For Claude Code:
claude mcp add cob-rag \
-e COB_RAG_URL=http://127.0.0.1:8000 \
-e COB_RAG_API_KEY=ck_your_corpus_key \
-- cob-rag-mcp startThe environment variables are the same either way: COB_RAG_URL, COB_RAG_API_KEY and, for a customer (tk_) key, COB_RAG_CORPUS_ID, the knowledge base the tools default to. The dashboard’s Connect an agent shows these local-install commands until the package is on npm.
09Day-to-day#
Run these from the repository folder. Each has a make shortcut where one exists.
Leads that visitors leave in the website widget appear under Leads in the dashboard. A lead is new until someone follows up, then contacted, and ends as won, lost or spam. Owners can export the list as a CSV and delete a lead; members can update status, assignee and notes. A visitor can withdraw consent from the link shown after they submit, which deletes their details. Put your own purpose, contact and privacy policy link in the consent notice (Assistant, Leads): the defaults are a starting point, not legal advice. Set RAG_PUBLIC_URL so withdrawal links use your public address.
When a visitor asks for a person, the widget offers the ways to reach you (WhatsApp, a call, e-mail, a booking link or a call-back request), chosen by the office hours on your business card. A tap is recorded as a handoff: it appears in the Handoffs tab beside Leads, with a short summary and the chat, and is e-mailed to you (and sent to your knowledge base’s webhook as handoff.requested). Open one and press Mark handled when you have followed up; members can do this too. WhatsApp links open a chat on the visitor’s phone with their question already typed; nothing is sent until they press send. There is no live takeover: the assistant keeps answering.
Every week, open Review in the dashboard (or GET /assistant/review) and fix what visitors could not get answered with one click. Before a big change, run your golden set as an experiment and compare it with the last run. Quick checks, your own criteria and comparisons need nothing extra. Scoring answers with the RAGAS metrics (faithfulness, answer relevancy, context precision and recall) and the operator’s traffic evaluations and optimisation runs need the optional evaluation add-on, which brings LangChain: set RAG_INSTALL_EVAL=true in .env and run docker compose build (the wizard asks), or pip install 'cob-rag-engine[eval]' for a native install. Without it the Quality page says so and keeps everything else working.
Stuck on a screen? Press the COB button at the bottom right of the dashboard, or Ctrl+/ (⌘+/ on a Mac). COB is the engine’s own assistant: it answers from this engine’s help pages in English, Hindi or Hinglish, shows which pages it used, and opens the right screen for you. The panel can be resized, takes the whole screen on a phone, and keeps your chats private for 30 days (delete any time). A COB answer counts toward your workspace’s monthly questions; once they are used up it shows matching help pages instead of writing an answer.
Prefer to read? Open Docs in the dashboard menu. It holds the guides, the help page of every screen and the API reference, with search (press /), a contents list on each page and examples that already show your engine’s address. The small ? beside a screen’s title opens that screen’s page, and Ask COB about this page hands the page to COB. You see the pages for your role; the server and operations pages are for the platform operator.
9.1See what is running and read logs#
docker compose ps
docker compose logs -f --tail=100 app
# every service at once:
docker compose logs -f --tail=100The services are app, worker, mailer, celery-beat, scraper, dashboard, postgres, valkey, qdrant and tei. make ps and make logs are the shortcuts. Your setup also runs whisper. Langfuse adds langfuse and langfuse-postgres. You do not use TEI, so there is no tei service.
With no SMTP the mailer’s log is where every sign-up code, activation e-mail, invitation and password reset lands, so this is the log you will read most:
docker compose logs -f --tail=100 mailerWith SMTP, docker compose logs mailer shows delivery errors when an e-mail does not arrive.
9.2Restart one service#
docker compose restart appA restart does not re-read .env. After you edit .env, run the start command again (docker compose up -d); Compose recreates only the services whose settings changed. Keep the GPU overlay in the command: without it Compose recreates the services with no GPU. For the dashboard alone: docker compose up -d dashboard.
9.3Stop and start again without losing data#
docker compose downThis stops and removes the containers but keeps every named volume: the database, vectors, uploaded files and model cache. make down does the same. Start again with the same command you used the first time (docker compose up -d; add --build only after an update). The containers also come back on their own when Docker starts, because they are set to restart unless stopped.
9.4Update to a new version#
- Read
CHANGELOG.mdin the repository for the release you are moving to. It lists upgrade notes. - Fetch the new code:
git pull. - Re-run the wizard so new settings are added and your values are kept (see running it again later).
- Rebuild and restart:
git pull
python scripts/setup.py
docker compose up -d --buildDatabase migrations run automatically: the app’s entrypoint runs alembic upgrade head before it starts serving, and stops with “ERROR: Alembic migration failed!” in docker compose logs app if one fails. On macOS and Linux write python3 for python, and add the GPU overlay to the last command if you use one.
If your install already holds documents and you are updating to the release with named keys, the fast model and page-furniture stripping, run two one-off commands afterwards. Neither re-embeds anything, and each only changes data when you add --apply:
docker compose exec app python -m callobuzz_rag.retrieval.reindex --payload-hash --apply
docker compose exec app python -m callobuzz_rag.retrieval.reindex --rehash-blocks --apply--payload-hash gives chunks stored earlier the fingerprint that lets search show a passage held by several documents once. --rehash-blocks counts the page furniture (menus, footers, cookie notices) already stored, so new pages of the same site are stripped of it. Keys issued before this release keep working: each became its owner’s “Default key” with full permission. The wizard also carries the old RAG_WIDGET_TRUST_PROXY_HEADERS to RAG_TRUST_PROXY_HEADERS and suggests a fast model when you pick a provider. Behind a proxy of your own, also set RAG_TRUSTED_PROXY_HOPS to the number of proxies in front of the engine (see the deploy guide).
If your documents are in Hindi or another Indic language (Devanagari, Bengali, Tamil, Telugu, Gujarati, Kannada, Malayalam, Gurmukhi, Odia), also rebuild the keyword vectors once, because earlier versions indexed those words in fragments. It re-embeds nothing:
docker compose exec app python -m callobuzz_rag.retrieval.reindex --applycob-rag, and an install from before that rename starts with new, empty volumes. Always read the changelog first.10Set up billing in 5 minutes#
Billing is optional and quiet until you price a plan. With no price on a plan, nothing is charged and nobody is paused, so you can ignore this section and your customers are limited by their plan only. Everything below is done in the dashboard under Billing (you need the super-admin sign-in). Amounts are whole paise or cents behind the scenes, so totals never drift.
10.1Pick a recipe#
Open Billing, then Pricing, choose a plan and press Edit pricing. The three common set-ups:
- Subscription, own key free. Set the Subscription fee (for example ₹999 a month), leave Usage on your AI key on Included, set Usage on their own AI key to Free, and keep the plan’s question limits unlimited. Choose Postpaid with a credit limit at least as large as the fee, so a customer is never paused for the fee itself. Customers who bring their own AI key pay you only the fee.
- Pay per question. Choose Prepaid, set A price per question (for example ₹2), and set the Alerts (20, 5 and 0 percent by default). A customer tops up, each answer takes its price from the balance, and answers pause politely at zero.
- Real AI cost plus a markup. Choose AI cost plus a markup and enter the markup percentage (25 means 25 percent on top). Each answer is charged what the AI really cost you, converted to rupees at the fixed rate
RAG_USD_INR_RATE. The rate is written on the charge, so a charge can always be explained later, even after you change the rate. A call with no known price is charged ₹0 and flagged “price unknown” on the statement. Customers never see the markup.
Press Save pricing. Every save is a new version with a history, and it applies to the next answer. For one customer who deserves a different deal, open their Billing tab, turn on Custom for just the fields you want to change, and press Save terms. Your own workspace and the Internal plan are never billed.
10.2Top-ups, refunds and add-ons#
Payments are recorded by hand for now. When a customer pays you (or asks through Request top-up on their Plan & billing page, which e-mails you), open their Billing tab and press Add a transaction:
- Top-up adds money to the balance. A large amount must be typed a second time to confirm it.
- Refund takes money back out. It is limited to what the customer actually paid and still has, and needs a private note.
- Adjustment corrects a mistake, up or down, with a private note. Nothing in the transaction list is ever edited or deleted; every correction is a new line.
Add-ons are extras you sell: credit packs (money plus an optional bonus), extra limits (more knowledge bases, documents or widget keys) and extra questions for the month. Create them under Billing, Add-ons, then press Apply an add-on on the customer’s tab and say how it was paid: outside the engine, free, or taken from their balance. Pressing a button twice never applies it twice.
10.3What visitors see when a balance runs out#
A prepaid customer pauses when what they can still spend reaches zero (less their grace amount); a postpaid one when they owe their credit limit. The owner is e-mailed at each alert level and again when answers pause, and so are you. Visitors never see the word billing: the assistant still greets them and answers the fixed topics, and any other question gets the knowledge base’s message when answers are paused with its contact card, so nobody is lost. The pause costs you nothing, because no AI model is called. Adding money lifts it within a minute. Pause override on a customer lets you force a pause or never pause.
10.4Statements, the P&L and provider balances#
Every customer gets a statement for each calendar month: opening balance, subscription, usage by knowledge base, model and source, top-ups and the closing balance, which always adds up to the transactions to the last paisa. Customers open it themselves (View, CSV, Download PDF); it never shows your markup or AI cost. Billing, P&L compares what each customer was billed and paid with what your AI key cost you (an estimate), month by month, with the margin. On Costs, Provider balances shows what OpenRouter, OpenAI, Anthropic and any manual provider have left so you know when to top up your own keys. Every night the engine checks that each balance equals its transactions and that every answer was charged once; Books check shows the result and Check now runs it on demand.
10.5What is not built yet#
11Businesses: the simple dashboard and website learning#
A business owner such as a clinic in Pune should never have to learn what a knowledge base or an embedding is. This section covers what you set up as the person who runs the platform, what the owner then sees, and what to check when their website is not read the way they expect.
11.1Choose what businesses see#
Each plan decides how much of the dashboard a business gets. Open Plans, edit a plan and use What businesses on this plan see. The default shows everything, so existing plans do not change until you switch something off. A plain business plan usually turns off Advanced settings: its owners then see only Home, Conversations & Leads, Knowledge, Assistant, Plan & billing, Team and Help. A part you hide is missing from the menu, and the engine refuses its settings for that business’s owners and members, so a bookmark does not get around it. API keys, your own workspace and the admin sign-in are never limited by these switches, and documents, leads, conversations and usage are always available.
The same editor sets Website learning: whether businesses on the plan may let their assistant read their website, and Pages we read from their website. When a website has more pages than the limit, the important ones (home page, menu, prices, services, contact) are read first and the rest show as “Beyond your plan’s page limit”.
11.2What the business owner does#
- Sign up and sign in. The first time, four short steps open by themselves.
- Step 1, your website. The owner types
shreedental.in, names the assistant (for example “Shree Dental Assistant”), chooses its picture, and presses Continue. The knowledge base, the assistant, the website code and the reading of the website are all set up in one go. - Step 2, brochures and price lists. Optional. The owner drops in the files customers ask about, such as a price list or a menu, and sees how many the assistant has read. Skip this step leaves it for later.
- Step 3, add it to your website. The owner copies the code, or presses Send to my developer. A light turns green with Connected the moment the assistant loads on the website.
- Step 4, try your assistant. The owner chats with it, with suggested questions taken from their own pages. Until the pages are read, the assistant tells visitors politely that it is still learning and shows how to reach the team.
Afterwards the owner works in Knowledge (what was learned and why a page was skipped, plus their own articles and answers) and Assistant (name, picture, tone, languages). The assistant carries the business’s own name and picture; the visitor sees the business, not your product. COB, the built-in helper, is always called COB.
11.3Keeping the website knowledge fresh#
A learned page is checked on a schedule the owner picks (every day by default). A page is read again only when it has changed, so frequent checks cost nothing extra. Three things make it faster than the schedule:
- The update link. In Knowledge, Update instantly when you publish makes a link the website can call when it publishes a page. Developers on WordPress or any other system can call it from a plugin or a hook. The link is shown once.
- The widget. The widget on the website notices when a page’s text changed and asks the engine to check that page. It sends only a short code, never the text and never anything a visitor typed.
- Removed pages. A page that is gone from the website is forgotten after two checks an hour apart. A temporary outage changes nothing.
11.4The light never turns green#
</body>, publish the website, then open the live page once. After 15 minutes the setup stops checking and the owner can finish later from Home.11.5www and the plain address do not match#
www.shreedental.in but the owner typed shreedental.in (or the other way round).11.6Google Sites#
11.7robots.txt blocks the bot#
robots.txt or page settings ask programs not to read it. The engine obeys them.11.8A website that needs a browser#
12Answer speed and fair use#
Two things keep a shared engine fair and affordable. Answer speed decides how each plan’s questions are answered: which AI model, how deeply it searches and who goes first when the engine is busy. Fair use sets how much one business may use and what happens when it passes a limit or its balance runs out. Both are per plan, with an override for a single business, and every default is only a starting point. You need the super-admin sign-in.
12.1Choose a pipeline profile for each plan#
Open Engine, then Pipeline profiles. Three are built in and editable: Economy (the Free profile: the free model on this server, short answers, low priority), Standard (the default: nothing changes until you edit it) and Premium (re-ranking with a model, high priority). Clone one, or press New profile. Every field you leave empty follows the engine, and the help beside it says what that is now. Then open Plans, edit a plan and pick its profile under Answer speed. To give one business a different profile, open Customers, choose the business and open Answer speed & limits.
12.2Set the limits#
- Open Plans, edit a plan and scroll to Fair use.
- Fill only the limits you want: questions a minute, an hour and a day, answers at once, website pages and reads, files, storage, AI spend (in dollars) and questions to COB. Empty means no limit.
- Under What happens, choose what the engine does when the balance runs out and when a limit is passed. The defaults keep answering on the free, slower profile and pause politely only far past a limit.
- For one business, open its Answer speed & limits tab and choose Follow plan, Own limit or No limit for each limit.
The seeded Free plan starts at 30 questions an hour, 300 a day and 50 website reads a day. Edit it to suit your product.
12.3What happens past a limit or an empty balance#
- Near a limit (80% by default): nothing changes. The owner sees a notice and gets an e-mail, and so do you.
- Past a limit: answers continue on the free profile, slower, until the limit resets. With Hard stop they pause at once; with Only tell me nothing slows down.
- Far past a limit (150% by default): visitors see the business’s own pause message and contact options.
- Balance runs out: answers continue on the free profile at no charge, or pause, or carry on as usual, as the plan says.
- The AI spend ceiling stops at the ceiling exactly. Answers move to the free local model when it is ready, and pause when it is not.
A visitor never sees an error and the website widget never mentions a plan, a limit or a balance. Your own workspace, the Internal plan and the admin sign-in are never limited.
12.4Turn on the free local model#
Slowing down for free needs a model that costs you nothing: a small open model that runs on this server’s CPU. It needs about 6 GB of free memory.
- Run
python scripts/setup.py --fulland answer yes to free answers on this server (or setRAG_LOCAL_LLM_ENABLED=trueand addlocal-llmtoCOMPOSE_PROFILES). - Run
docker compose up -d. The first start downloads the model. - Open Engine. The Free local model card says “Downloading the model”, then “Ready”. Press Try it to hear how fast it answers.
Until it says Ready, a business that would be slowed down is paused politely instead, never shown an error. Safety rails and Answers right now on the same page set an engine-wide AI spend ceiling and show what is being answered.
12.5What owners see#
An owner sees a banner in your product’s name when a limit is near, passed or reached, a Fair use card on Plan & billing with a meter for each limit, and a tile on Home. AI usage is shown only as a share, never as an amount of money. A member reads the same words. COB can explain all of it: ask “Why have my answers become slow?”.
13Trust and value#
The engine is built so a visitor is never stuck or misled and an owner is never surprised, and so a business can see what its assistant is worth. Every default is the safe, customer-friendly one. You change the switches under Sign-up & branding (the trust engine settings); owners change only what is their own choice.
13.1A person, always#
A visitor who asks for a person (“talk to a person”, “insaan se baat karni hai”) gets the business’s contact options on the first ask, in every state: balance empty, website still being learned, monthly limit reached, fair-use limits, busy engine. Asking is free and is not counted as a question. Every chat header has a Talk to a person button; you decide whether an owner may hide it (Let businesses hide the Talk to a person button, off by default). The assistant also offers a person after an unanswered question (the owner can change this from 1 to 5, or never) and never gives the same reply twice in a row.
13.2Nobody repeats themselves#
A chat that is offered a person gets a short reference such as SD-4F7K. The WhatsApp message opens with it and the visitor’s last few questions, the call option shows it, and the owner’s e-mail, the leads export and the data sent to the business’s own systems carry it. Owners find a chat by typing the reference on the Handoffs tab of Leads. Phone numbers and e-mail addresses are hidden in the summary unless the visitor left their details.
13.3No surprises#
The plan page shows the next renewal with its exact amount and a projection of the month; owners are e-mailed before each renewal (7 days by default). A price rise is announced at least 30 days ahead (7 to 90, your choice), is scheduled in Billing, and applies to each business only from its next period. Owners set a monthly spending cap, up to a maximum you choose; at the cap the assistant switches to a slower model or pauses, and a visitor who asks for a person is never refused. Businesses write a support request from Get help, you answer it in the Support inbox, and you can show how fast you usually reply. The Price list page makes a white-label list of your plans to print or share by a link you can turn off.
13.4The value report#
Every month the owner gets an estimated value in rupees, always shown with its formula and always “based on your settings”: qualified leads, requests to talk to a person and staff time saved, each times a number the owner sets. It is on Home, in a full report with a print page and in an e-mail on the 1st. You can switch it off for everyone or copy your support address on every e-mail.
13.5Honest about being an AI#
Every chat shows an AI assistant badge next to the assistant’s name and starts with a line saying so, in the visitor’s language. By default you require both, so no owner can switch them off (Always show the AI badge and first line). Let businesses word the first line lets an owner use their own wording as long as it still says AI; anything else shows the standard line. Turn the first switch off only if your businesses must be free to hide it.
13.6How fresh an answer is#
The assistant knows when each source last changed and says so: the source chips show “Updated 3 Oct”, and a visitor can ask when something was updated. The date is the day the text of the page or file last changed, in the business’s time zone, so a page that is read again with no change keeps its date. The owner sees the same date in the Changed column of Knowledge. Home also suggests adding brochures and price lists while an assistant has no files and has read only a few pages, and the first-run steps ask for them as step 2.
14WhatsApp#
WhatsApp is one more place where a business’s assistant answers. A customer writes to the business’s own WhatsApp Business number and the same assistant that answers on the website replies, from the same knowledge, behind the same gates (a request for a person, the monthly limit, the balance, fair use). Each platform operator registers their own Meta app: the engine ships with none, and until you switch it on (RAG_WHATSAPP_ENABLED) nothing about it appears in the dashboard.
14.1Your Meta app#
In Meta for Developers create a Business app with the WhatsApp product and note its App ID and App Secret. Verify your business (Business Verification). To let businesses sign in with Facebook (Embedded Signup version 4), become a Tech Provider and pass App Review for whatsapp_business_management and whatsapp_business_messaging; Meta lets a new provider onboard about 10 numbers a week at first and raises it to 200 a week later. Before that, connect numbers by hand. The full steps, the webhook address and the settings are in the deployment guide, section Connect WhatsApp (Meta app).
14.2Connecting a number#
A workspace owner opens WhatsApp in the menu and chooses Connect with Meta: Facebook’s window opens, the owner picks the business and the number, and the engine registers it (with a PIN it derives from the number, so a retry always uses the same one), subscribes your app to its messages and stores the token encrypted. A number that is also in the WhatsApp Business app is already registered and is left alone. Or you connect it for them: Customers, the customer, Knowledge bases, Connect WhatsApp for this business, then paste the phone number ID, the WhatsApp Business Account ID and a permanent token. To have the engine register the number, also type a six-digit two-step PIN; leave it empty if you already registered the number in Meta’s dashboard. A number belongs to one knowledge base at a time. Disconnecting keeps the chats, and it stops Meta’s message subscription only when no other connected number uses the same WhatsApp Business Account. Connecting a different number to the same knowledge base starts its chats fresh: earlier STOP and opt-in choices do not carry over.
14.3Plans and Meta’s fees#
Tick WhatsApp included on each plan that should have it: the menu item and the routes then appear for those businesses only, and the operator’s own view is unaffected. Meta charges for some messages. A business that connects its own WhatsApp Business account pays Meta directly. For a number on your account, choose per plan whether the fees are passed on or included, and under Sign-up & branding enter your rate per category (service, utility, marketing, authentication) in paise or cents. Every rate starts at zero and the engine states no prices: use Meta’s current price list for your country. A fee is charged once per message and shows as WhatsApp on the business’s statement.
14.4What owners see#
The WhatsApp page lists the chats (names partly hidden), shows unread ones and lets the owner or a member reply inside WhatsApp’s 24-hour window. A reply makes the assistant stay quiet in that chat for the hours the owner sets (12 by default); a reply from the WhatsApp Business app on the same number does the same when coexistence is on. A customer who writes STOP is never messaged first again, and the one optional follow-up (an approved template, off by default) is never sent to them. The assistant can send brochures, price lists and menus, but only from the PDFs, JPGs and PNGs the owner ticks, up to 20.
15Tear down and reset#
15.1down versus down -v#
docker compose down stops the stack and keeps your data. docker compose down -v also deletes the volumes.
docker compose down -v permanently deletes the database, vector store, uploaded files, Valkey data and model cache: every customer, knowledge base, document and account on this install. There is no undo. Use it only when you want to start from nothing. (make clean runs the same down -v and also removes Python cache folders.)docker compose down -v15.2Remove the images too#
The images take disk space. This stops the stack, deletes the volumes and removes the images Compose used (Docker skips any image another project still uses):
docker compose down -v --rmi all15.3Start completely fresh#
- Delete the data:
docker compose down -v. - Move the old settings aside. The wizard keeps the values it finds, so to get brand-new secrets the file has to be gone:
mv .env .env.oldRename-Item .env .env.oldmv .env .env.oldThen run the wizard again (step 4) and start the stack (step 5).
.env. PostgreSQL only reads its password when its volume is first created, so new secrets with the old volume leave the app unable to sign in to the database. To reset the data but keep your settings, leave .env in place.16Troubleshooting#
Each item reads symptom, why it happens, fix. The ones that match your setup come first. Start with docker compose ps and docker compose logs <service>; they answer most questions.
16.1Port already in use#
docker compose up fails with a message like “port is already allocated” or “address already in use”.netstat -ano | findstr :8000netstat -ano | findstr :8000lsof -i :8000--full (it asks for the host ports and updates the matching addresses and allowed origins), or pass one directly:python scripts/setup.py --quick --yes --gpu no --set "RAG_APP_HOST_PORT=8100"docker-compose.yml; stop whatever uses them instead.16.2Docker Desktop is not running#
docker command fails with “Cannot connect to the Docker daemon” or, on Windows, a pipe error such as “The system cannot find the file specified”.sudo systemctl start docker. Check with docker info, then run the start command again.16.3Containers are unhealthy or restarting#
docker compose ps shows unhealthy, Restarting or Exited for a service.docker compose logs --tail=100 appapp with the service name. Causes the wizard itself warns about: RAG_SMTP_HOST set but RAG_SMTP_FROM empty (the engine will not start); RAG_ENV=prod with RAG_EMAIL_PROVIDER=log (refused); RAG_EMBEDDING_PROVIDER=tei without tei in COMPOSE_PROFILES (ingestion fails). A line such as “set RAG_DB_PASSWORD in .env” means a required secret is empty: re-run the wizard. A failed migration shows “ERROR: Alembic migration failed!” in the app log. After fixing .env run docker compose up -d.16.4The first start is very slow#
docker compose ps shows tei as starting for minutes, and the app does not become healthy.BAAI/bge-base-en-v1.5) on first start, and the images are being built. This is normal.docker compose logs -f tei. The compose file allows TEI 120 seconds before the first health check and then 30 checks ten seconds apart. The download is cached in a Docker volume, so the next start is fast. If you chose a local re-ranker or in-engine embeddings, those models download too.16.5The GPU is not used#
Cuda, or Compose refuses to start a service with “could not select device driver nvidia”.python scripts/setup.py --gpu no) and use the plain start command. If it works, answer yes and use the GPU start command. On Windows, quick mode picks the engine’s own embeddings for you, which use your GPU without TEI. For TEI on Linux with a specific card you can set RAG_TEI_IMAGE to the tag for its generation: turing-1.9, 86-1.9 (Ampere), 89-1.9 (Ada), hopper-1.9, 120-1.9 (Blackwell) or the portable cuda-1.9, all under ghcr.io/huggingface/text-embeddings-inference. The local re-ranker alone needs about 2.3 GB of GPU memory.16.6localhost does not work on Windows#
http://localhost:8090 resets or never loads, but the containers are healthy.localhost resolves to the IPv6 address ::1 first, and Docker Desktop resets that connection. It looks exactly like the service being down.http://127.0.0.1:8090 (and 127.0.0.1 in every address you put in .env).16.7The dashboard cannot reach the engine#
RAG_DASHBOARD_ENGINE_URL and RAG_DASHBOARD_SCRAPER_URL (where the browser reaches them), and RAG_CORS_ORIGINS (which must list the dashboard’s own origin; the scraper has SCRAPER_CORS_ORIGINS). They break when you change a port, open the dashboard from another address, or put the stack behind a domain. The dashboard’s Content-Security-Policy only allows calls to the two configured addresses.python scripts/setup.py --full and set the “Web addresses” (it merges the dashboard’s origin into both CORS lists), and recreate the services with docker compose up -d. For a live deployment use your public https addresses and follow the deploy guide.16.8There is no set-password link#
RAG_SUPERADMIN_EMAIL is set (otherwise the log says “No RAG_SUPERADMIN_EMAIL; skipping”), and the account needs RAG_SESSION_SECRET, which the wizard generates. With SMTP the link is e-mailed, not printed. Old log lines may also have rotated away.--set "RAG_SUPERADMIN_EMAIL=admin@yourcompany.in"), then restart the app with docker compose up -d app. To issue a new link and print it on screen right now:docker compose exec app python -m callobuzz_rag.accounts.bootstrap --resend --print-link--resend issues a fresh code anyway.16.9Sign-up codes do not arrive#
RAG_ENV=dev) every message is written to the mailer’s log instead.The mail server may be refusing the message. Gmail needs an app password, not your normal password, and the message may have landed in spam. In production (RAG_ENV=prod) with no SMTP, e-mail is disabled and sign-up is unavailable.docker compose logs mailer | grep -A12 "DEV EMAIL"docker compose logs mailer | Select-String -Context 0,12 "DEV EMAIL"docker compose logs mailer | grep -A12 "DEV EMAIL"docker compose logs mailer) for errors, and use With SMTP set up you would check the same log for errors, and you could use Email (SMTP) in the operator dashboard to check the configuration and send yourself a test. Temporary failures are retried after 15, 30, 60, 120 and 240 seconds, and a message whose code would already have expired is dropped (codes last 10 minutes), so ask for a new code.16.10“Too many attempts” or a sign-in lockout#
docker compose ps redis.16.11“Workspace not active”#
workspace_not_active.16.12A plan limit message#
16.13An upload is refused as too large#
upload_too_large), or it is accepted and the job later fails with “The document holds N tokens of text; the limit is M” (code document_too_large).RAG_MAX_UPLOAD_BYTES (50 MB by default). And the text inside it, counted after the engine has read the file, may be at most RAG_MAX_DOCUMENT_TOKENS (500,000 tokens by default), so a large scan with little text is fine and a small file with a great deal of text may not be. A plan can set lower limits for one customer, and the dashboard shows the limits that apply to you when you add content.POST /api/v1/ingest/records), which takes up to 1,000 records per request and up to 200,000 characters of text in each. To allow more, raise the two settings in .env and restart, or raise the customer’s plan limits.16.14Answers are slow#
RAG_LLM_MODEL, or per knowledge base in the dashboard). Set a small, quick fast model from the same provider (RAG_LLM_FAST_MODEL): with none, a thinking model rewrites every search question itself, at RAG_LLM_FAST_THINKING (off, or the model’s lowest setting). If your model thinks before it answers, switch Thinking off (RAG_LLM_THINKING=off, or per knowledge base under Model & keys in the dashboard): off is fastest and cheapest, high is more careful. The older RAG_LLM_REASONING_EFFORT still works (none means off). Turn the re-ranker off, or use it on a GPU or through your LLM (the Standard and Premium presets already leave it off on a machine without a GPU unless you switch it on for the whole engine): re-run the wizard and answer the re-ranker question, or change it under the knowledge base’s Retrieval settings.16.15Answers fail: no AI model key#
RAG_LLM_API_KEY in .env (the default provider is OpenRouter; for another provider also set RAG_LLM_PROVIDER and RAG_LLM_MODEL, or re-run the wizard and pick one), then recreate the services:docker compose up -d16.16I forgot the admin password#
RAG_ADMIN_API_KEY in .env). Or issue a new set-password link with the bootstrap --resend --print-link command from the “no set-password link” item. Finishing a reset also clears any sign-in lockout.16.17Where is the admin API key?#
RAG_ADMIN_API_KEY in the .env file in the repository root. Print just that line with the command under First login, the admin key. Send it in an X-API-Key header. Keep it private: it can do everything on the engine.16.18Back up RAG_ENCRYPTION_KEY#
.env.RAG_ENCRYPTION_KEY encrypts the LLM keys your customers store in their knowledge bases. Without it those stored keys cannot be read, and every customer would have to paste theirs again. It is generated once and never printed..env.backup-* files and your .env hold all your secrets, so store them as carefully as the key. The engine can rotate the key, and python -m callobuzz_rag.core.reencrypt rewrites stored tokens under the new primary key; see the README’s Operations section.16.19A file fails: no readable text#
no_text_found). Nothing is added to the knowledge base.RAG_OCR_ENGINE to rapidocr (the default) or tesseract in .env and restart, then upload it again. For Hindi or another Indian language see 12.20. Otherwise export the text and upload that, or import it as records. A file you were replacing stays exactly as it was.16.20A scanned Hindi document comes out garbled or empty#
rapidocr) reads Devanagari unreliably: on our test page it recovered about half of the text, while paddleocr recovered 99%. The engine logs a warning at start-up when RAG_OCR_LANGS names an Indian language and RAG_OCR_ENGINE is rapidocr.RAG_OCR_LANGS=hi,en and RAG_OCR_ENGINE=paddleocr in .env (the first non-English language picks the model; it reads the English words too). PaddleOCR is an optional extra: build the image with docker compose build --build-arg INSTALL_OCR_PADDLE=true, or run pip install -e ".[ocr-paddle]" when you run natively. Restart, then upload the file again. Prefer Tesseract? Set RAG_OCR_ENGINE=tesseract; the image already has the Hindi data (tesseract-ocr-hin), and other languages need their own tesseract-ocr-<code> package added to the Dockerfile. Codes: en, hi, mr, ne, sa, ta, te, kn (paddleocr and rapidocr), plus bn, gu, ml, pa, or, as, ur (tesseract only).17Where to get help#
- A bug or a question: write to callobuzz@gmail.com.
- A security problem: do not post it in public. Write to callobuzz@gmail.com with “security” in the subject.
- Everything else about the engine: the
README.mdin the repository covers configuration, the API, plans, accounts and operations. - The API reference:
http://127.0.0.1:8000/docson your own install (hidden whenRAG_ENV=prod), ordocs/openapi.jsonin the repository. - Agents and the command line: cob-rag-mcp.
- Questions before you buy, or help with a first set-up: callobuzz@gmail.com.