Lucas AI aufbauen: Ein Portfolio in ein Produkt verwandeln

Passwort vergessen

23. April 20264 min gelesen

Lucas AI aufbauen: Ein Portfolio in ein Produkt verwandeln

Systemdesign für Lucas AI: geschichtete Prompts, lexikalische Wiederherstellung, Sitzungspeicher, Token-Budgets und ein Vorflug-Klassifikator auf einer begrenzten Portfolio-Chat-Oberfläche.

ProduktKIArchitekturFrontend

Diese Website ist ein Portfolio, aber die Lucas AI-Oberfläche ist bewusst wie ein kleines Produkt aufgebaut: eine dedizierte /{locale}/ai-Erfahrung, vorhersehbare Ausgaben und Antworten, die in erster Person aus strukturiertem Kontext bleiben – nicht ein generischer Assistent mit web-skaligen Ambitionen.

Dieser Beitrag ist ein technischer Deep Dive in die Funktionsweise dieses Systems: was bei jeder Anfrage zusammengesetzt wird, warum es auf diese Weise geschichtet ist und welche Einschränkungen bewusst gewählt wurden.

Das Problem

Statische Portfolios beantworten einmalige Fragen gut, aber versagen bei Tiefe. Folgefragen („Wie haben Sie das Projekt geplant?“, „Welche Technologie haben Sie verwendet?“) verschwinden entweder in PDFs oder erfordern einen menschlichen Eingriff.

Naive Chat-Integrationen verbessern das Interaktionsmodell, aber schaffen neue Probleme: unbegrenzter Kontext, erfundene Arbeitgeber, stiller Umfangswandel und jede Frage wird gegen das größte Modell verrechnet, das Sie aufgebaut haben. Ein Portfolio benötigt keinen Open-World-Chatbot; es benötigt eine enge Schnittstelle mit einer überprüfbaren Faktenbasis.

Lucas AI befindet sich in dieser Lücke: begrenzte UX, begrenztes Wissen, explizite Grenzen darüber, was „Lucas“ behaupten kann.

Systemdesign-Übersicht

Von Ende zu Ende ist ein Senden immer noch ein POST /api/chat mit JSON (message, locale, optionales sessionSummary / recentTurns). Die Route besitzt Richtlinien und Ausgaben; der Browser besitzt die Transkript-UI und clientseitige Persistenz (sessionStorage).

Schichten in der Ausführungsreihenfolge:

  1. Eingabevalidierung – leere Nachrichten werden abgelehnt; Benutzerttext hart begrenzt auf 2000 Zeichen, um Missbrauch und Prompt-Injektionsoberfläche zu begrenzen.
  2. Vorflug-Klassifikator (optional) – ein kleiner Groq-Chat-Abschluss (llama-3.1-8b-instant standardmäßig), nicht-streaming, max_tokens: 5, temperature: 0, Einzelwort-Entscheidung: OFF_TOPIC vs fortfahren. Wenn OFF_TOPIC, gibt die API mock SSE mit einer lokalisierten Ablehnung zurück, damit der Client-Pfad einem normalen Stream entspricht. Bei Klassifikatorfehler oder -timeout fällt der Handler offen und führt das Hauptmodell aus – billige Tore sollten legitimen Verkehr nicht blockieren. Hosts können CHAT_SKIP_CLASSIFIER setzen, um diesen Aufruf beim Lasttest oder wenn die Reduzierung von Anbieteranrufen die Ersparnis wert ist, ganz zu überspringen.
  3. Prompt-ZusammenstellungbuildChatPrompt komponiert die System-Nachricht; das Hauptmodell erhält System + aktuelle Benutzernachricht (kein mehr Nachrichten-Chat-Transkript über Kabel).
  4. Hauptabschluss – Streaming POST …/v1/chat/completions (Standard llama-3.3-70b-versatile auf Groq, Überschreibung GROQ_MODEL), Antwort als SSE an den Client proxied. max_tokens begrenzt via CHAT_MAX_TOKENS (256–8192, Standard 2048) bindet UX an Wirtschaftlichkeitsrechnung.
  5. Client-Kontinuität – die UI hält Nachrichten und eine rollierende Sitzungszusammenfassung in sessionStorage; jede Anfrage kann eine getrimmte Zusammenfassung und einen Ausschnitt aus aktuellen Runden anhängen, damit der Server die Kontinuität ohne serverseitige Speicherung des Chats erhält.

Kontextstrategie

Das Design vermeidet „immer alles senden“. Die Einbindung des vollständigen strukturierten Profils bei jeder Anfrage skaliert schlecht: Token-Kosten wachsen mit dem Korpus, irrelevante Fragen zahlen für irrelevante Fakten und Sie nähern sich den Anbietergrenzen, wenn das Profil wächst.

Stattdessen:

  • systemPrompt (corePromptText.ts) – stabile Regeln: erste Person, Transparenz („nicht live tippen“), Grundgesetz, Dauer-Math-Regeln, Lokalisierungsverhalten. Minimal und fix gehalten, damit Prefix-Caching (wo der Anbieter den Eröffnungstext dupliziert) eine Chance hat zu helfen.
  • Dynamische CONTEXT-Fragmente – nach dem gemeinsamen Präfix angehängt, klar abgegrenzt (--- CONTEXT (kanonisch / FAQ) ---, Sitzungspeicher, abgerufene Exzerpte) und geschlossen mit --- Ende CONTEXT-Fragmente --- plus einer Besucher-Lokalisierung: …-Zeile, damit das Modell in der Seitensprache antwortet.

Selektive Wiederherstellung (kein Einbettungs-RAG)

„RAG“ impliziert oft Einbettungen und eine Vektordatenbank. Diese Implementierung verwendet diese nicht. Die Wiederherstellung ist lexikalisch: Tokenisierung der Benutzernachricht in eine Wortmenge, Bewertung jedes Chunks durch Schlüsselworttreffer + Substring-Überlappung im Chunk-Text, Hinzufügen von intentionbasierten Boosts (z. B. Recruiter-Publikumstags, portfolio_meta-Boosting von portfolio_*-Domänen), Sortierung, dann Auswahl der obersten Chunks unter harten Kappen.

Token-Optimierung

Naive Implementierungen wiederholen entweder volle Historie oder binden volle Korpora ein. Beide verursachen Kosten- und Latenzexplosionen.

Konkrete Strategien im Code:

  • estimateTokens – Charakterlängen / 4 Heuristik; keine Tokenizer-Abhängigkeit; gut genug für Budgetierung, nicht für abrechnungsgenaue Buchhaltung.
  • Sitzungsblock-DeckelmaxSessionBlockTokens: rollierende Zusammenfassung + formatierte aktuelle Runden werden iterativ getrimmt (Slice auf 85 % bis unter die Kappe).
  • Aktuelle Runden – nur die letzten maxRecentTurnPairs Paare (Standard 3), jede Nachricht auf maxCharsPerTurn (Standard 700) begrenzt. Der Client sendet bis zu acht vorherige Nachrichten; der Server erzwingt das strengere Budget.
  • Sitzungszusammenfassung – Client erstellt eine rollierende Protokollzeile pro Runde (Benutzer-Snippet + Assistent-Snippet), clientseitig begrenzt (~2500 Zeichen), dann Server sanitizeSessionSummary (maxSessionSummaryChars, Standard 900). Keine serverseitige LLM-Zusammenfassung – vorhersehbare Kosten, aber laut, wenn Benutzer Wände von Text einfügen (durch Klemmen gemildert).

Fazit

Lucas AI sollte als eine Produktschnittstelle mit einer Spezifikation gelesen werden: das lucasPersonalContext-Objekt und abgeleitete Chunks sind der Vertrag, das System ist Gesetz, Token-Budgets sind Schutzgeländer, und der Klassifikator plus Off-Topic-Stream-Pfad definieren was das Produkt nicht sein wird.

Wenn Sie etwas Ähnliches aufbauen, liegt der Hebel nicht im größten allgemeinen Modell – es geht darum, was bei jeder Runde in den Prompt eingeht und es zu messen. Ein Portfolio benötigt keinen unendlichen Kontext; es benötigt ehrliche, begrenzte Antworten – und eine Architektur, die einfach genug ist, um dies zu erreichen.