// Products · Ollie

The chatbot
that only knows
your site.

Ollie answers from your own pages and refuses everything else. When it can't help, it fetches a human — or books the call at 3am when nobody's watching.

Talk to us about Ollie It's running on this page — bottom right.
~80KB
gzipped, in a shadow root so no CSS leaks either way
~8ms
to embed a question — locally, at no per-query cost
0.50
similarity floor before it will answer at all
0
polling. Everything is a socket push

// How it answers

Retrieval is local and free. The model only does the writing.

Most of the pipeline never leaves your server. An LLM is used for exactly one job — phrasing an answer from passages that were already found — under a prompt that forbids inventing prices, timelines or capabilities.

  1. Question

    Visitor types

    Pre-chat form captures name and email once, then never asks again.

  2. Embed

    ~8ms, in-process

    bge-base-en-v1.5 runs locally via Transformers.js. No embeddings API, no key, no per-query cost.

  3. Search

    pgvector, HNSW

    Cosine similarity across every page and post on the site.

  4. Weight

    Section bias

    Service and product pages carry a small multiplier; legal pages a penalty.

  5. Answer

    LLM, one job

    Phrases the answer from retrieved passages only — with source links and page images.

Why the weighting exists

This site has 87 blog posts against 6 service pages, so raw ranking let blog volume bury the commercial ones — “what services do you offer?” used to return Terms & Conditions. Service, home and product pages now carry a small multiplier, legal pages a penalty. The nudge is deliberately small: it flips near-ties without overriding a genuinely better blog match, so cost questions still land on the cost guides.

// Staying on topic

Two guards, because
neither is enough alone.

A grounded bot fails in one specific way: it improvises from a weak match. Ollie is built so that “what is the capital of France?” never reaches the model, and anything that slips past the gate gets declined by the prompt.

Similarity of the best passage, measured on live traffic
0.42
Where off-topic questions land
0.45
Below this, a passage is never read
0.50
The best passage must clear this to answer
0.57–0.86
Where genuine questions land

Score gates

Two thresholds, set from measured traffic. Passages below 0.45 are never read. The single best passage must clear 0.50 before Ollie will attempt an answer at all.

Genuine questions score 0.57–0.86. Off-topic ones fall to 0.42 or match nothing.

The system prompt

A question can be off-domain and still graze a passage. For general knowledge, coding help, other companies, maths or jokes, Ollie declines and offers a human — even when it knows the answer.

“Tell me a joke” brushes the Owlse mocking docs at 0.53. The gate lets it through; the prompt turns it down.

// When it can't answer

Two exits, so a dead end is never one of them.

Live handover only works when someone is watching. Booking works at 3am.

Hand to a human

The visitor asks for a person, or Ollie decides it can't help. The chat moves to waiting_human, the team is alerted, and whoever replies first claims it.

A conversation closes itself after 10 minutes without a message — counting messages, not connections, so a widget left open in a background tab doesn't keep a stale chat alive. The transcript then emails both the visitor and the team, exactly once.

Book the call

When nobody is online, Ollie offers a scheduled call instead of an apology — using the Calendly link you already publish.

It's a single config line, and clearing it removes the option entirely. No second integration to maintain, no separate booking flow for someone to abandon.

// The dashboard

Where the conversations land.

A widget on its own is a toy. The value is in what your team sees afterwards.

A shared inbox

Every conversation in one place, live. Nothing polls — the inbox, the transcript and the widget are all driven by socket pushes. Reply to a bot-handled chat and you claim it automatically, which aborts the bot mid-sentence. Two voices at once is worse than one truncated.

Who you're talking to

Name, email and previous chats from the same address. Country, city and their local time. Browser, OS and device — bots labelled. The page they were on and where they came from. Geolocation prefers Cloudflare's own header, so the visitor's IP never leaves your infrastructure.

A content roadmap, written by prospects

Every answer records how well it matched. Read backwards, that's a list of things your site fails to explain. The Unanswered view groups repeated questions, sorts by frequency, and separates “no match at all” from “answered shakily”. A question with no match, asked five times, is a page you haven't written yet.

Alerts that reach a closed laptop

Web Push, delivered by the browser's own service — so a handover request arrives with the dashboard closed and the machine asleep. Three triggers, toggled per device, so a phone can be urgent-only while a desktop gets everything. Repeat messages collapse into one notification.

// Installing

One script tag.

The widget renders inside a shadow root, so your CSS can't leak in and its styles can't touch your site. A conversation survives page navigation — on a multi-page site it rejoins rather than starting over.

There's no third thing to deploy. The widget is a build artifact the API serves itself.

<script
  src="https://chat.loudowls.com/widget.js"
  data-api="https://chat.loudowls.com"
  data-greeting="Got an app idea? Ask me anything"
  defer
></script>
Attribute Default Notes
data-api script origin API base URL
data-greeting Teaser bubble shown before the chat is opened
data-accent #5fa052 Override the brand colour
data-position right left or right
data-auto-open off Milliseconds before auto-opening, once per tab

// Want one on your site?

Try Ollie here first.
Then let's talk.

Ask it something about LoudOwls in the corner of this page. Then ask it something it shouldn't know, and watch it decline.

Start a conversation
WhatsApp
Email
Call