Smart Answer: KI-Antwort in deiner Website-Suche
Wie du Smart Answer einbindest – das Skript suche.js, die Box im Markup, die öffentliche HTTP-Schnittstelle für serverseitig gerenderte Suchseiten und den Antwortstrom per Server-Sent Events, Gestaltung per CSS-Variablen und die Übergabe an den Chat.
Smart Answer zeigt über oder unter den Treffern deiner Website-Suche eine kurze Antwort auf die Frage des Besuchers – gestreamt, mit Quellen aus deiner Wissensdatenbank und einem Feld für die nächste Frage. Smart Answer ist ein eigener Dienst; er nutzt dieselbe Wissensdatenbank wie dein Chat-Assistent. Eingeschaltet und gestaltet wird er im Konto unter Projekt → Smart Answer für die Website-Suche.
Einbinden mit suche.js
Steht der Chat-Loader schon auf der Seite, genügt eine Zeile:
<script src="https://cdn.reactive.chat/suche.js" async></script>
Ohne Chat-Widget gibst du den Site-Key mit:
<script src="https://cdn.reactive.chat/suche.js" data-site-key="SITE_KEY" async></script>
Das Skript hängt sich an die Suchfelder deiner Seite (welche, legst du im Konto als CSS-Selektor fest), wartet auf das Absenden bzw. eine Tipp-Pause und zeigt die Antwort in einer Box am eingestellten Ort (vor, nach oder in einem Zielelement). Standardmäßig antwortet es nur auf Eingaben, die wie eine Frage aussehen.
Attribute am Skript-Tag:
- data-site-key (optional) – sonst vom Chat-Loader (
data-rc-site-key) übernommen. - data-ws-url (optional) – Chat-Adresse; sonst wie beim Chat abgeleitet.
- data-api (optional) – Basisadresse der Schnittstelle, Vorgabe
https://ws.reactive.chatbzw. deine eigene Domain. - data-locale (optional) – Sprache; sonst
<html lang>, dann Browser.
Das Skript setzt keine Cookies und speichert nur im sessionStorage. Für die CSP braucht es script-src https://cdn.reactive.chat und connect-src https://ws.reactive.chat (Sicherheit und CSP).
Übergabe an den Chat
Stellt der Besucher in der Box eine Folgefrage, wird – je nach Einstellung Folgefrage – das Gespräch im Chat-Widget fortgesetzt (ReactiveChat('continueConversation', id, text) bzw. ReactiveChat('startConversation', text)) oder in derselben Box beantwortet. Ohne Chat-Widget auf der Seite bleibt die Folgefrage immer in der Box.
Gestaltung
Die Box (.rc-ai) bringt ihr eigenes CSS mit und ist gegen Resets deiner Seite geschützt. Anpassen kannst du sie über Variablen mit niedrigster Spezifität:
.rc-ai {
--rc-ai-akzent: #0a7cff;
--rc-ai-hg: var(--karte, #fff);
--rc-ai-text: #1d1d1f;
--rc-ai-rand: #e3e3e8;
--rc-ai-radius: 10px;
--rc-ai-schrift: inherit;
--rc-ai-abstand: 20px;
--rc-ai-schriftgroesse: 16px;
--rc-ai-zeilenhoehe: 1.6;
}
Einzelne Teile änderst du mit .rc-ai .rc-ai__teil { … } im Feld Eigenes CSS im Konto, z. B. .rc-ai .rc-ai__hinweis { display: none; }. Gegen Regeln deiner Seite mit #id oder !important schützt die Schutzschicht nicht.
HTTP-Schnittstelle
Für serverseitig gerenderte Suchseiten oder eigene Oberflächen gibt es eine öffentliche Schnittstelle ohne Anmeldung und ohne Cookies unter https://ws.reactive.chat/api/suche/SITE_KEY.
Gemeinsam:
- CORS nur für Herkünfte aus den Domains deines Projekts (Subdomains eingeschlossen); Aufrufe von deinem Server ohne
Origingehen immer. - Drossel: 60 Anfragen je Minute und Besucheradresse über alle Endpunkte → 429 mit
Retry-AfterundX-RateLimit-*. Rufst du von deinem Server aus auf, zählt deine Serveradresse – für viele Besucher nimm deshalbsuche.jsim Browser oder die eigene Domain mit Proxy-Schlüssel. - Fragen und Antworten werden nicht in Zugriffsprotokolle geschrieben.
GET /api/suche/SITE_KEY?locale=de – Konfiguration, CSS und leere Vorlage der Box (Cache-Control: public, max-age=60):
{"v":1,"aktiv":false}– aus, gesperrt oder unbekannt (404 bei unbekanntem Schlüssel).{"v":1,"aktiv":true,"sprache":"de","konfig":{…},"css":"…","vorlage":"<div class=\"rc-ai\" …>","skript":"https://cdn.reactive.chat/suche.js"}
POST /api/suche/SITE_KEY – fertiges HTML der Box für eine Frage, Rumpf höchstens 4 KB:
curl -s -X POST "https://ws.reactive.chat/api/suche/SITE_KEY" \
-H "Content-Type: application/json" \
-d '{"q":"Wie lange dauert der Versand?","locale":"de"}'
{"v":1,"aktiv":true,"frage":false,"html":""}– die Eingabe ist keine Frage.{"v":1,"aktiv":true,"frage":true,"html":"…","css":"<style id=\"rc-ai-css\">…</style>","skript":"…","einbettung":"…"}– setzeeinbettungin deine Suchseite;suche.jsfüllt die Box dann mit der Antwort.- 400
{"v":1,"error":"bad_request","field":"q"}–qfehlt, ist leer oder länger als 300 Zeichen. - 413
payload_too_large, 405 bei anderer Methode.
POST /api/suche/SITE_KEY/antwort – die Antwort selbst als Server-Sent-Events-Strom, Rumpf höchstens 8 KB:
{"q":"Wie lange dauert der Versand?","locale":"de",
"visitor_id":"v_…",
"ctx":{"url":"https://shop.example/suche","title":"Suche"},
"folge":false,
"vorher":[{"q":"…","a":"…"}]}
- q (String, Pflicht, 1–300 Zeichen)
- locale (String, optional)
- visitor_id (String, optional,
[A-Za-z0-9_-]{1,80}) – die Kennung des Chat-Besuchers, damit die Übergabe an den Chat passt. - ctx (Objekt, optional) –
url,path,referrer,title; Query und Anker werden entfernt. - folge (
true, optional) – Folgefrage; umgeht den Fragefilter. - vorher (Liste, optional) – höchstens 3 frühere Paare (
q≤ 300,a≤ 1500 Zeichen).
Antwort text/event-stream:
event: status
data: {"stufe":"denkt"}
event: text
data: {"text":"Der Versand dauert"}
event: fertig
data: {"text":"Der Versand dauert in der Regel 2–3 Werktage.","quellen":[{"titel":"Versand","url":"https://shop.example/versand"}],"fortsetzung":{"art":"faden","id":"01J…"}}
- status –
{stufe}:denkt,sucht,schreibt,wartet. Das erste Ereignis ist immerdenkt. - text –
{text}: der ganze bisher sichtbare Text (kein Delta), höchstens alle 150 ms. - fertig –
{text, quellen, fortsetzung};fortsetzungist{art:"faden", id}(als Gespräch gespeichert),{art:"neu"}odernull. - fehler –
{code, text?}mitcode:aus,gesperrt,drossel,motor,zeit,einwilligung,ungueltig. Kommtfehlernachtext, lass den Text stehen.
Nach fertig oder fehler endet der Strom. Auch Fehler vor dem Start kommen als Strom mit genau einem fehler (HTTP 404, 429, 400, 413, 503 oder 200). Ohne Text nach 45 Sekunden oder ohne Ende nach 90 Sekunden folgt fehler zeit. Schließt du die Verbindung, bricht die Antwort ab. Ein Proxy auf dem Weg muss den Strom ungepuffert durchreichen.
// Strom im Browser lesen (EventSource kann kein POST)
const r = await fetch('https://ws.reactive.chat/api/suche/SITE_KEY/antwort', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ q: frage, locale: 'de' }), credentials: 'omit'
});
const leser = r.body.getReader(); const dec = new TextDecoder(); let puffer = '';
for (;;) {
const { value, done } = await leser.read(); if (done) break;
puffer += dec.decode(value, { stream: true });
let i; while ((i = puffer.indexOf('\n\n')) >= 0) {
const block = puffer.slice(0, i); puffer = puffer.slice(i + 2);
const ev = /^event: (.*)$/m.exec(block), da = /^data: (.*)$/m.exec(block);
if (ev && da) zeige(ev[1], JSON.parse(da[1]));
}
}
Weiter: Datenschutz-Einbindung
Stand: