Technisches Design für einen KI-Kontaktchat in einer Astro-Website
Inhaltsverzeichnis
- Gesamtstruktur
- Den Endpoint-Vertrag klein halten
- Validierung und Modellaufruf auf dem Server steuern
- Website-Informationen als expliziten Kontext pflegen
- Im Prompt Regeln schreiben
- Kontaktwege trennen
- Locale-URLs bewahren
- Origin-Prüfung und Rate Limit
- Markdown-Links per Allow-List rendern
- Local, Preview und Produktion testen
- Betriebsmetriken
- Abgegrenzter Umfang
- Zusammenfassung
Einen KI-Chat auf eine Website zu setzen, ist einfach. Entscheidend ist der Betrieb: Was darf die KI beantworten, wohin soll sie Besucher führen, welche URLs dürfen erscheinen und wie bleiben API-Kosten kontrollierbar?
Acecore hat einen KI-Kontaktchat in eine statische Astro + Cloudflare Pages Website integriert. Die Hauptimplementierung steht im PR für Kontakt-KI und CMS-begrenzten Übersetzungsfluss. Das sichere Rendering von Markdown-Links wurde anschließend in einem weiteren PR verbessert. Die Details dazu sind in Markdown-Links in KI-Chat-Antworten sicher rendern separat beschrieben.
Dieser Artikel beschreibt das Design als wiederverwendbares Muster für andere statische Websites. Auch außerhalb von Astro gilt: Client-Widget, API-Grenze, Prompt und Renderer sollten getrennte Verantwortlichkeiten haben.
Gesamtstruktur
| Schicht | Verantwortung |
|---|---|
| Chat widget | UI, Eingabe, aktueller locale, minimaler Verlauf, Markdown-Rendering |
/api/ai-contact | Validierung, Origin-Prüfung, Rate Limit, Prompt, OpenAI-Aufruf |
| OpenAI Responses API | Antwort aus öffentlichem Kontext und Gesprächszustand erzeugen |
Der Browser sollte OpenAI nicht direkt aufrufen. Ein serverseitiger Endpoint verhindert Schlüssel-Leaks, erlaubt Anpassungen von Prompt und Kontext und bündelt Limits sowie Fehlerbehandlung.
Bei Astro + Cloudflare Pages kann die Grenze eine Pages Function unter /api/ai-contact sein. In Next.js wäre es ein Route Handler, in Hono oder Express eine normale API-Route.
Den Endpoint-Vertrag klein halten
type ContactAiRequest = {
message: string
locale: 'ja' | 'en' | 'zh-cn' | 'es' | 'pt' | 'fr' | 'ko' | 'de' | 'ru'
history?: Array<{
role: 'user' | 'assistant'
content: string
}>
}
type ContactAiResponse = {
answer: string
}
Name, E-Mail, Telefonnummer, Firma und detaillierte Formularfelder müssen nicht durch den Chat laufen. Der Chat hilft bei der Wahl von Service und Kontaktweg, er sammelt keine personenbezogenen Daten.
Auch der Verlauf wird auf wenige aktuelle Nachrichten und eine maximale Länge begrenzt. Das reduziert Prompt-Größe und Kosten.
Validierung und Modellaufruf auf dem Server steuern
export async function onRequestPost({ request, env }: PagesFunction<Env>) {
assertSameOrigin(request)
assertRateLimit(request)
const body = await request.json()
const message = validateMessage(body.message)
const locale = validateLocale(body.locale)
const history = trimHistory(body.history)
const prompt = buildContactPrompt({
locale,
message,
history,
siteContext: buildPublicSiteContext(locale),
})
const answer = await callOpenAIResponsesApi({
apiKey: env.OPENAI_API_KEY,
model: env.OPENAI_MODEL,
prompt,
})
return Response.json({ answer })
}
Wichtig ist, Eingaben vor dem KI-Aufruf zu verkleinern und zu validieren. Lange Texte, unbegrenzter Verlauf und fremde wiederholte Aufrufe destabilisieren den Betrieb.
OPENAI_MODEL sollte eine Umgebungsvariable sein, OPENAI_API_KEY bleibt ausschließlich serverseitig. Für Auslieferung und CSP siehe Cloudflare Pages Sicherheit.
Website-Informationen als expliziten Kontext pflegen
Für eine Website dieser Größe ist eine Vektordatenbank nicht der erste Schritt. Strukturierter Kontext aus öffentlichen Seiten ist oft ausreichend.
Dazu gehören Unternehmens- und Service-Übersichten, Zielgruppen, Beispielanfragen, URLs, FAQ, Regeln für Formular/LINE/E-Mail/Telefon, nicht zu behauptende Bereiche wie Preise oder Verträge, und interne URLs pro locale.
function buildPublicSiteContext(locale: Locale) {
return {
services: [
{
name: 'Web production',
summary: 'Corporate sites, recruiting sites, and landing pages',
url: localizePath('/services/web-production/', locale),
},
{
name: 'Business systems',
summary: 'Reservation, inventory, and customer management systems',
url: localizePath('/services/business-system/', locale),
},
],
contact: {
form: localizePath('/contact/', locale),
line: 'https://lin.ee/...',
emailPolicy:
'Show email only when the form cannot be used or follow-up is needed',
phonePolicy: 'Show phone only for urgent confirmation',
},
}
}
Das Modell soll nicht aus allgemeinem Wissen antworten, sondern aus dem, was diese Website sagen darf. Bei Wachstum kann diese Schicht zu Pagefind, CMS JSON, D1, Vectorize oder anderer Suche erweitert werden.
Im Prompt Regeln schreiben
You are the contact guidance AI for this website.
Answer only from public site information.
Rules:
- Do not make firm statements about pricing, contracts, schedules, or guarantees
- Send formal consultations and estimates to the contact form
- Also suggest LINE for short questions and school-related inquiries
- Show email and phone only when the user asks for direct contact
- Use URLs that match the current locale
- If unsure, do not guess; guide the user to the form
Ein typischer Fehler ist eine zu hilfsbereite KI, die zu viel zusichert. Preise, Termine und Garantien sollten allgemein erklärt und dann ans Formular verwiesen werden.
Kontaktwege trennen
| Weg | Rolle |
|---|---|
| FAQ | Häufige Fragen direkt auf der Seite klären |
| KI-Chat | Services, Kontaktwege und verwandte Seiten sortieren |
| LINE | Kurze Fragen, Schul-Themen und leichte Rückfragen |
| Formular | Angebote, Produktion, Partnerschaften und Recruiting |
| Direktkontakt | Ergänzungen nach Formular oder dringende Bestätigung |
Die KI verbindet Inhalte wie die Service-Übersicht mit konkreten Wegen auf der Kontaktseite. Das Muster passt zu B2B-Websites, Agenturen, Schulen und SaaS-Support.
Locale-URLs bewahren
Bei mehrsprachigen Websites reicht die richtige Antwortsprache nicht. Auch URLs müssen zum locale passen.
function localizePath(path: string, locale: Locale) {
if (locale === 'ja') return path
return `/${locale}${path}`
}
Serverseitige URL-Erzeugung ist stabiler als nur eine Prompt-Anweisung. Der Übersetzungsbetrieb wird in Mehrsprachige Blogs mit Sveltia CMS betreiben beschrieben.
Origin-Prüfung und Rate Limit
function assertSameOrigin(request: Request) {
const origin = request.headers.get('Origin')
if (!origin) return
const requestUrl = new URL(request.url)
const originUrl = new URL(origin)
if (originUrl.host !== requestUrl.host) {
throw new Response('Forbidden', { status: 403 })
}
}
IP-basiertes Rate Limiting ist eine erste Bremse. In Cloudflare können CF-Connecting-IP, X-Forwarded-For oder CF-Ray genutzt werden. Bei höherem Traffic sind Cloudflare WAF, Turnstile, KV, D1 oder Durable Objects stabiler. Den CMS-Betrieb für Content-Updates beschreibt der Sveltia CMS Einrichtungsleitfaden; Bot-Schutz für Formulare und Kommentare ist eine eigene Ebene.
Markdown-Links per Allow-List rendern
Erlauben Sie nur Absätze, Listen, Fettdruck, Inline-Code und Markdown-Links. Linkziele werden auf interne Pfade, aktuellen Origin, https://acecore.net, offizielle LINE-URLs und notwendige mailto: oder tel: beschränkt.
function sanitizeHref(rawHref: string, currentOrigin: string) {
const href = rawHref.trim()
if (href.startsWith('/')) return href
if (href.startsWith(`${currentOrigin}/`)) return href
if (href.startsWith('https://acecore.net/')) return href
if (href.startsWith('https://lin.ee/')) return href
if (href === 'mailto:[email protected]') return href
if (href === 'tel:05088902788') return href
return null
}
trim() ist wichtig, weil KI-Ausgaben wie [Services]( /services/ ) vorkommen können. Ein kleiner, strenger Renderer ist leichter zu pflegen als vollständiges Markdown.
Local, Preview und Produktion testen
Astro dev oder preview entspricht nicht vollständig Cloudflare Pages Functions. Ohne OPENAI_API_KEY sollten lokal Fallback und Fehleranzeige geprüft werden.
In Preview oder Produktion prüfen Sie POST auf /api/ai-contact, OPENAI_API_KEY und OPENAI_MODEL, Ablehnung fremder Origins, Eingabelimits, Antworten im richtigen locale, lokalisierte URLs, keine Zusagen zu Angebot oder Vertrag, keine Standardanzeige von E-Mail und Telefon, sowie Markdown-Links nur bei erlaubter URL.
Testen Sie außerdem lange Eingaben, unerwartete Fragen, englische Seiten, Direktkontakt-Wünsche und Preisfragen.
Betriebsmetriken
Beobachten Sie API-Fehlerquote, Rate-Limit-Treffer, durchschnittliche Nachrichten pro Anfrage, Übergänge zu Formular und LINE, Weiterleitungen zum Formular bei fehlender Antwort und Nutzung pro locale.
Wenn Gesprächsinhalte gespeichert werden, müssen Datenschutzregeln zuerst feststehen. Ein sicherer Start ist, nur Ereignisse und Fehler ohne Nachrichtentext zu speichern.
Abgegrenzter Umfang
Dieser Artikel behandelt nur das technische Design des KI-Chats. Die Strecke, die den Beratungsgegenstand von der Service-Seite ins Formular übergibt, ist ebenfalls implementiert und in Technisches Design zur Kontextübergabe vom Service-CTA zum Kontaktformular beschrieben.
- KI-Chat: Unsicherheit im Gespräch ordnen und sicher führen
- Service-CTA: Den gelesenen Service-Kontext ins Formular übergeben
Getrennt bleiben beide Artikel lesbarer und lassen sich später besser verlinken.
Zusammenfassung
Bei einem KI-Kontaktchat für eine statische Website sollten API-Grenze und Antwortkontrolle vor der UI gestaltet werden.
Die wichtigsten Entscheidungen: OpenAI über Cloudflare Pages Function aufrufen, Eingabe und Verlauf klein halten, Kontext und locale-URLs serverseitig bauen, Grenzen im Prompt formulieren, Formular/LINE/Direktkontakt trennen, Origin-Prüfung und Rate Limit einbauen, Markdown-Links nach trim() per Allow-List rendern.
Statische Websites können sinnvolle KI-Kontaktchats haben. Entscheidend ist nicht, die KI sichtbar zu machen, sondern Besucher sicher zur nächsten Aktion zu führen.
Referenzarchitektur
Widget
Das Astro-Chat-UI sendet nur Frage, aktuellen locale und minimalen Verlauf.
Function
Die Cloudflare Pages Function validiert Eingaben, prüft Origin, begrenzt Anfragen und baut den Prompt.
Model
Die OpenAI Responses API erhält öffentlichen Website-Kontext und Gesprächszustand.
Renderer
Der Client rendert nur erlaubtes Markdown und führt zu internen Links oder freigegebenen Kontaktwegen.
Alles vermischt
- Die KI-API wird direkt aus dem Browser aufgerufen
- Website-Kontext, API-Schlüssel, UI und Link-Rendering sind gekoppelt
- Die KI kann Preise, Verträge oder Termine zu bestimmt formulieren
- Markdown und URLs können direkt als HTML gerendert werden
Getrennte Verantwortlichkeiten
- API-Schlüssel und Modellaufrufe bleiben serverseitig
- Öffentliche Website-Informationen werden als expliziter Kontext gepflegt
- Der Prompt steuert Antwortumfang und Kontaktwege
- Markdown und URLs werden über Allow-Lists gerendert
- Erledigt: Den Chat als Orientierungshilfe definieren, nicht als vollständigen Formularersatz
- Erledigt: Eine serverseitige API-Grenze schaffen und den API-Schlüssel nicht im Browser ausgeben
- Erledigt: Antworten auf öffentliche Website-Informationen beschränken
- Erledigt: Festlegen, was die KI nicht behaupten darf, etwa Preise, Verträge, Fristen und Garantien
- Erledigt: Rollen von Formular, LINE, E-Mail und Telefon definieren
- Erledigt: URLs nach locale erzeugen, damit mehrsprachige Navigation intakt bleibt
- Erledigt: Origin-Prüfung, Längenlimits, Verlaufslimits und Rate Limiting einbauen
- Erledigt: Markdown-Link-URLs vor der Allow-List-Prüfung trimmen
Braucht man RAG oder eine Vektordatenbank für einen KI-Kontaktchat?
Wird der OpenAI API-Schlüssel im Browser sichtbar?
Darf die KI beliebige Links ausgeben?
Kommentare
Gui
CEO von Acecore. Steuert Geschäftssysteme, Web, Datenbanken und Infrastruktur, Qualität und KI-Einsatz von der Analyse geschäftlicher Probleme über Design und Einführung bis zur Verbesserung nach dem Launch. Baut auf praktischer C#/.NET-Kompetenz auf und berücksichtigt zugleich PHP/JavaScript, SQL Server/PostgreSQL/MySQL und Linux/Windows Server, um Anforderungen, Technologieauswahl, Qualitätsstandards und GitHub-basierte Entwicklungsabläufe als kohärenten Prozess zu gestalten. Integriert generative KI in Entwicklungs-, Prüfungs- und Informationsorganisationsprozesse, als praktische Grundlage, damit kleine Teams schneller und verlässlicher liefern können.
Möchten Sie mehr über unsere Dienste erfahren?
Wir bieten umfassende Unterstützung, einschließlich Systementwicklung, Webdesign, Grafikdesign und IT-Bildung.
Verwandte Artikel
Eine Astro + Cloudflare Website Schritt für Schritt erweitern 7. Juni 2026 um 19:00
Astro-Blogkommentare nur mit Cloudflare umsetzen 7. Juni 2026 um 18:00