KI-Schlüssel (BYOK)
Lalabase folgt dem Bring-your-own-Key-Prinzip: Die KI-Features laufen über deinen eigenen Provider-Schlüssel. So fließen keine Daten über fremde Sammelkonten, und du behältst die volle Kontrolle und Abrechnung.
Schlüssel hinterlegen
Trage den Schlüssel deines Providers als Umgebungsvariable ein:
OPENAI_API_KEY=sk-...
Ohne hinterlegten Schlüssel bleiben die KI-Features deaktiviert — der Rest von Lalabase funktioniert uneingeschränkt weiter.
Was an den Provider geht
KI-Funktionen senden nur den jeweils nötigen Kontext an den Provider — etwa den Text eines Tickets, das zusammengefasst werden soll. Es werden keine vollständigen Datenbank-Inhalte übertragen.
Mit einem eigenen Schlüssel bleibt die Vertragsbeziehung zwischen dir und deinem KI-Provider. Lalabase ist nur das Werkzeug dazwischen.
EU-Anbieter (DSGVO)
Neben OpenAI und Anthropic lassen sich EU-Anbieter mit Datenverarbeitung in der EU anbinden — über den Provider OpenAI-kompatibel im Admin-Backend. Beim Anlegen eines neuen Credentials füllt ein EU-Preset Endpunkt-URL und Modell direkt vor:
- Mistral (Frankreich)
- IONOS AI Model Hub (Deutschland)
- OVHcloud AI Endpoints (EU)
Die Presets füllen bewusst nur das Chat-Modell vor. Für Embeddings sind
768- und 1024-dimensionale EU-Modelle (z. B. mistral-embed, nomic, bge-m3)
inzwischen konfigurierbar — das geschieht aber pro Organisation über die Konsole und
nicht über ein Preset, weil ein Wechsel auf bestehendem Bestand einen vollständigen
Neu-Index auslöst. Details im Abschnitt „Embedding-Dimension wählen" weiter unten.
Mit einem EU-Anbieter und eigenem Schlüssel bleiben Vertragsbeziehung und Datenverarbeitung vollständig in der EU.
Google Gemini über Vertex AI (EU)
Google Gemini lässt sich DSGVO-konform ausschließlich über Vertex AI mit einer EU-Region anbinden — nicht über Google AI Studio (der einfache API-Key-Weg landet auf einem globalen Endpunkt ohne garantierte EU-Datenresidenz). Deshalb ist dieser Weg bewusst als Betreiber-Einrichtung gebaut: Du hinterlegst ihn einmal systemweit im Admin-Backend, danach steht „Google (Gemini)" allen Organisationen zur Verfügung — niemand muss selbst ein Google-Cloud-Konto anfassen.
Wichtig vorab: Vertex nutzt keinen API-Key, sondern einen Service-Account mit
JSON-Schlüssel. Nur so lässt sich der regionale EU-Endpunkt erzwingen. Ersetze in den
folgenden Befehlen DEIN_PROJEKT durch deine GCP-Projekt-ID.
Schritt 1 — Vertex AI API aktivieren
Lege ein GCP-Projekt an und aktiviere die Vertex AI API. In der Cloud Console
heißt dieser Eintrag inzwischen teils „Agent Platform API" — der Dienstname darunter
ist unverändert aiplatform.googleapis.com, und genau der ist gemeint. Am schnellsten
per Cloud Shell:
gcloud services enable aiplatform.googleapis.com --project=DEIN_PROJEKT
Ein Rechnungskonto muss mit dem Projekt verknüpft sein.
Schritt 2 — Service-Account mit Rolle anlegen
Erstelle ein Dienstkonto und weise ihm die Rolle Vertex AI User
(roles/aiplatform.user) zu — so eng wie möglich, kein „Owner":
gcloud iam service-accounts create lalabase-vertex --project=DEIN_PROJEKT
gcloud projects add-iam-policy-binding DEIN_PROJEKT \
--member="serviceAccount:lalabase-vertex@DEIN_PROJEKT.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
Schritt 3 — JSON-Schlüssel erzeugen
Dienstkonto → Schlüssel → Schlüssel hinzufügen → JSON. Die Datei wird einmalig heruntergeladen (nicht erneut abrufbar) — wie ein Passwort behandeln.
Neue Google-Cloud-Organisationen erzwingen per Voreinstellung die Richtlinie
iam.disableServiceAccountKeyCreation und blockieren den Schlüssel-Download.
Zum Aufheben braucht es die Rolle Organisationsrichtlinienadministrator
(roles/orgpolicy.policyAdmin) — „Owner" und „Organization Administrator"
reichen dafür nicht. Nach dem Zuweisen die Richtlinie fürs Projekt zurücksetzen:
gcloud org-policies reset iam.disableServiceAccountKeyCreation --project=DEIN_PROJEKT
Schritt 4 — Region und Modell wählen
Die Modell-Verfügbarkeit unterscheidet sich je EU-Region und ändert sich laufend —
prüfe sie, bevor du live gehst. Enumeriere die Modelle in deiner Region direkt
(Statuscode 200 = verfügbar, 404 = nicht):
TOKEN=$(gcloud auth print-access-token); PROJECT=DEIN_PROJEKT; LOC=europe-west3
for MODEL in gemini-2.5-flash gemini-2.5-pro gemini-embedding-001; do
CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
"https://${LOC}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${LOC}/publishers/google/models/${MODEL}:generateContent" \
-d '{"contents":[{"role":"user","parts":[{"text":"ping"}]}]}')
echo "${MODEL} -> ${CODE}"
done
Bewährte Kombination (Stand 2026-07): europe-west3 (Frankfurt) + gemini-2.5-flash
für den Chat. Ältere Modelle wie gemini-2.0-flash sind zurückgezogen; die neuesten
Generationen (3.x) liefert Google in der EU aktuell nur über den Multi-Region-Endpunkt,
den Lalabase aus Residenz-Gründen bewusst nicht anspricht.
Schritt 5 — Im Admin-Backend hinterlegen
Neues AI-Credential, Provider „Google (Gemini)":
- Service-Account-JSON: den kompletten Schlüssel einfügen (wird verschlüsselt gespeichert; kein API-Key).
- GCP-Projekt-ID: die ID deines Projekts.
- Vertex-AI-Region: die geprüfte EU-Region, z. B.
europe-west3.globalwird abgelehnt, weil es die EU-Datenresidenz aushebeln würde. - Modell: das in Schritt 4 als verfügbar bestätigte Modell, z. B.
gemini-2.5-flash.
Anschließend die Credential als Standard setzen (Stern-Button — sie bedient dann alle Organisationen, die den Provider ohne eigene Schlüssel nutzen) und die Organisation auf den Provider „Google" umstellen.
Schritt 6 — Prüfen
Sende eine Chat-Nachricht. Schlägt sie fehl, nennt das Server-Log die Ursache
(grep "ChatResponseJob: provider" log/production.log):
| Log-Zeile | Ursache | Lösung |
|---|---|---|
provider unauthorized: … HTTP 403 |
Rolle fehlt am Dienstkonto | roles/aiplatform.user zuweisen (Schritt 2) |
provider unauthorized: google token mint failed |
Service-Account-JSON beschädigt | JSON neu einfügen (private_key mit intakten Zeilenumbrüchen) |
provider error: … HTTP 404 |
Modell in der Region nicht verfügbar | Region/Modell nach Schritt 4 korrigieren |
Welche Modelle in welcher EU-Region tatsächlich erreichbar sind, zeigt die Karte
„Modell-Verfügbarkeit (Vertex AI)" auf der Credential-Seite im Admin-Backend: Ein
Klick prüft kostenlos per countTokens alle Kombinationen aus Region und Modell — die
Verfügbarkeit unterscheidet sich je EU-Region und ändert sich laufend.
Gemini ist auch für Embeddings ein EU-tauglicher Weg: Sein Embedding-Modell liefert per Kürzung (Matryoshka) sauber 1536 Dimensionen. Seit der Multidim-Unterstützung ist es nicht mehr der einzige — 768- und 1024-dimensionale EU-Modelle anderer Anbieter lassen sich ebenfalls konfigurieren (siehe unten). Ein Wechsel des Embedding-Raums auf einem bestehenden Bestand erfordert in jedem Fall einen vollständigen Neu-Index der Organisation.
Der Vertex-Zugang wird einmal vom Betreiber der Instanz hinterlegt. Endnutzer wählen ihn nicht selbst aus und benötigen kein Google-Cloud-Konto.
Embeddings
Für die semantische Suche und den KI-Assistenten erzeugt Lalabase Embeddings, die in der
vector-Spalte von PostgreSQL gespeichert werden. Auch diese laufen über deinen Schlüssel.
Embedding-Dimension wählen
Ein Embedding-Raum ist das Tripel aus Provider, Modell und Dimension. Unterstützt
werden 768, 1024, 1536 und 3072 Dimensionen — damit sind EU-Modelle wie
mistral-embed (1024), nomic (768) und bge-m3 (1024) nutzbar, ebenso die großen
Modelle text-embedding-3-large (3072) und gemini-embedding-001 (3072).
3072 setzt pgvector 0.7+ voraus. Der Suchindex nutzt für diese Größe einen
halfvec-Cast, weil pgvector reguläre Vektor-Indexe nur bis 2000 Dimensionen zulässt.
Der gespeicherte Vektor bleibt voll präzise; halbiert wird nur die Genauigkeit im
Index, was die Trefferreihenfolge praktisch nicht verändert. Läuft die Extension unter
0.7, lässt sich das Schema gar nicht erst einspielen — und sollte eine Organisation
dennoch auf 3072 stehen, schlägt die Suche mit einem Fehler fehl statt langsam zu
werden: die Abfrage nutzt denselben halfvec-Cast wie der Index, und den Typ gibt es
dort nicht.
Für diese Konfiguration gibt es bewusst keine Oberfläche: Sie greift sofort und ohne Zwischenstufe, deshalb gehört sie in die Konsole und in die Hand des Betreibers. Eine Organisation ohne Konfiguration bleibt unverändert bei 1536.
Lalabase trennt Konfiguration (wohin neue Embeddings geschrieben werden) von Bedienung (welcher Raum die Suche beantwortet). Eine Umkonfiguration allein verschiebt die Bedienung nicht: Der bisherige Raum antwortet weiter, während der neue im Hintergrund aufgebaut wird. Erst das Umschalten (embeddings:flip) wechselt die Bedienung — in einem einzigen Schritt.
Ablauf für einen Wechsel, am Beispiel Mistral mit 1024 Dimensionen:
# 0. Ausgangslage prüfen — muss grün sein
bin/rails "embeddings:check_alignment[ORG_ID]"
# 1. Umkonfigurieren (Rails-Konsole)
# org.update!(embedding_provider: 'openai_compatible',
# embedding_api_base: 'https://api.mistral.ai/v1',
# embedding_access_token: '…',
# embedding_model: 'mistral-embed',
# embedding_dims: 1024)
# → die Suche läuft unverändert weiter, im BISHERIGEN Raum
# 2. Ziel-Raum im Hintergrund aufbauen (kein Umschalten).
# Idempotent und wiederanlaufbar; läuft durchs KI-Kontingent.
bin/rails "embeddings:build_target[ORG_ID]"
# 3. Fortschritt prüfen — zeigt aktiven Raum, Ziel-Raum und die Restlücke
bin/rails "embeddings:status[ORG_ID]"
# 4. Umschalten. Verweigert, solange der Ziel-Raum unvollständig ist.
bin/rails "embeddings:flip[ORG_ID]"
# 5. Gegenprüfen — muss grün sein
bin/rails "embeddings:check_alignment[ORG_ID]"
Nach dem Umschalten werden die Vektoren des alten Raums aus dem Suchindex genommen
(im Hintergrund), bleiben aber als Rückweg liegen. Im check_alignment erscheinen sie
als stale — das ist der Normalzustand und kein Befund.
Zurückrollen, falls die Qualität des neuen Modells nicht überzeugt:
# SPACE_ID aus `embeddings:status`. Reaktiviert den alten Raum, holt die
# Änderungen seit dem Wechsel nach und schaltet zurück.
bin/rails "embeddings:rollback[ORG_ID,SPACE_ID]"
Der Rückweg funktioniert auch mit eigenen Zugangsdaten: Zu jedem gehaltenen Raum sind Endpunkt und Token gespeichert, sie müssen also nicht neu eingegeben werden — auch dann nicht, wenn die Organisations-Konfiguration inzwischen auf einen anderen Endpunkt zeigt.
KI muss aktiv sein: Ist die KI für die Organisation deaktiviert, bricht der Aufbau ab. Erst aktivieren, dann aufbauen.
Neue Inhalte während des Aufbaus: Sie werden bereits mit der Ziel-Konfiguration eingebettet und sind deshalb erst nach dem Umschalten auffindbar. Ein kurzes Frische-Fenster für die jüngsten Inhalte, keine Lücke im Bestand.
Anders als Dokumente und Notizen werden Code-Symbole bei jedem Voll-Index gelöscht und neu angelegt. Die aufbewahrten Vektoren des alten Raums verlieren damit ihren Bezug: Für Code ist ein Rückweg nach dem nächsten Push faktisch ein vollständiger Neu-Index. Für alle anderen Inhalte bleibt er billig.
KI-Pakete: derselbe Mechanismus, vom Kunden ausgelöst
Alles oben beschreibt den Weg über die Konsole. Daneben gibt es kuratierte KI-Pakete — vom Betreiber im Adminbereich gepflegte Bündel aus einem Embedding-Anbieter und einer Staffel von Chat-Stufen, jeweils mit einer Rechtsraum-Einordnung. Wählt eine Organisation ein Paket, entscheidet dessen Embedding-Slot über ihren Vektorraum — nicht mehr die Organisations-Konfiguration.
Wichtig für den Betrieb: Bewegt ein Paketwechsel den Vektorraum, läuft genau die
gestaffelte Umstellung von oben ab — Zielraum aufbauen, alte Bedienung beibehalten,
automatisch umschalten, sobald der neue Raum vollständig ist. Der Unterschied ist nur, wer
sie auslöst: Das macht seit KI-Pakete P4 die Organisation selbst, über einen
Konsequenzen-Dialog, ohne Konsole und ohne dein Zutun. Ein Watcher übernimmt das
Umschalten; embeddings:flip von Hand ist dafür nicht nötig.
Anbieter, Modell oder Dimension im Embedding-Slot eines Pakets zu bearbeiten, verschiebt den Vektorraum jeder Organisation, die auf diesem Paket sitzt. Jede von ihnen baut daraufhin ihren gesamten Korpus neu auf — und weil Reindexe seit P4a das Monatskontingent belasten, ist das eine Kostenentscheidung für fremde Konten, nicht bloß eine Konfigurationsänderung. Willst du ein anderes Embedding-Modell anbieten, lege ein neues Paket an und ziehe das alte zurück, statt das bestehende umzubauen.
Ein zurückgezogenes Paket (active: false) verschwindet aus dem Katalog, läuft für
Organisationen darauf aber unverändert weiter. Sie sehen ihre Karte weiterhin, können die
Leistungsstufe darin jedoch nicht mehr wechseln — der Weg hinaus ist ein anderes Paket oder
„Eigene Konfiguration". Wer ein Paket zurückzieht, sollte deshalb einen Nachfolger
veröffentlicht haben.
Wer wann gewechselt hat, wird in zwei Formen festgehalten: Die Organisation trägt
Zeitpunkt und Person der letzten Wahl in eigenen Spalten, und jede Wahl schreibt zusätzlich
eine Activity mit beiden Rechtsraum-Einordnungen (vorher/nachher) und der Angabe, ob dabei
ein Neuaufbau der Suche angestoßen wurde. Diese Einträge lösen bewusst keine
Benachrichtigungen aus.
Dasselbe gilt seit dem KI-Bereichs-Umbau für den Ein- und Ausschalter: Jedes Aktivieren und
jedes Deaktivieren schreibt eine eigene Activity (ai_activated / ai_deactivated) mit
Zeitpunkt und Person. Auch hier halten die Spalten der Organisation nur die letzte
Aktivierung — wer die Kette braucht, findet sie ausschließlich in diesen Einträgen.
Die Historie hat seit dem KI-Bereichs-Umbau eine Oberfläche: Im Bereich KI der Organisationsverwaltung listet die Seite Protokoll alle vier Verben in zeitlicher Reihenfolge auf, mit Zeitpunkt, Person und, wo das Paket den Rechtsraum bewegt hat, beiden Einordnungen. Sie ist Administratoren der Organisation vorbehalten und rein lesend.
Der Konsolenweg bleibt daneben nützlich, wenn du über Organisationen hinweg oder nach Rohwerten aus dem Payload suchst:
Activity.where(organisation_id: ORG_ID,
action: %w[ai_activated ai_deactivated ai_package_selected ai_tier_selected])
.order(:created_at)
.pluck(:created_at, :action, :actor_id, :parameters)
Zwei Einschränkungen, damit Seite und Abfrage nicht mehr versprechen, als sie halten. Erstens schreibt das Formular „Eigene Konfiguration" bislang nichts mit: Ein Wechsel des Anbieters oder des hinterlegten Tokens taucht im Verlauf nicht auf, obwohl er den Auftragsverarbeiter ändert. Zweitens ist das Schreiben der Schalter-Einträge bewusst fehlertolerant: Scheitert es, wird die Aktivierung trotzdem ausgeführt und der Fehlschlag nur ins Log geschrieben, denn der Schalter darf an einer Protokollzeile nicht scheitern. Die Paketwahl verhält sich umgekehrt und committet ohne ihren Eintrag gar nicht erst.