⚡ You're viewing a live demo of ChimerAI. Data resets daily at midnight UTC.Get the CLI →

Prompt Templates

ChimerAI Prompt Templates let you store, manage, and apply system prompts from the database — without changing code. Admins create templates in the dashboard; the chat route loads them automatically at runtime.


Installation

chimerai add prompt-management

Scaffolds:

  • app/dashboard/prompts/page.tsx — CRUD UI (create, edit, delete, set default)
  • app/api/prompts/route.ts — GET / POST
  • app/api/prompts/[id]/route.ts — GET / PUT / DELETE
  • app/api/prompts/[id]/set-default — POST (marks one prompt as default per category)
  • components/chat/prompt-selector.tsx — dropdown for the chat UI
  • PromptTemplate model added to Prisma schema

Database Model

model PromptTemplate {
  id          String   @id @default(cuid())
  name        String
  category    String   // "system" | "rag" | "widget" | "user"
  description String?
  content     String   @db.Text
  isDefault   Boolean  @default(false)
  isActive    Boolean  @default(true)
  language    String   @default("en")
  tags        String[]
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}

Categories

CategoryZweckAutomatisch aktiv
systemChat-Verhalten, Persona, Tonalität✅ ja — Default-Prompt wird immer geladen
ragKontext-Framing für Dokumentantworten❌ nein — manuelle Integration (siehe unten)
widgetSystem-Prompt für eingebettetes Chat-Widget❌ nein — optional per promptId
userVorgeschlagene User-Prompts / Starter-Fragen❌ nein — rein informativ / UI

Wie Prompts im Chat verwendet werden

Automatisch — Default-Prompt

Die Stream-Route (/api/v1/chat/stream) lädt bei jedem Request automatisch den aktiven Default-Prompt der Kategorie system:

Request ohne promptId
  → Stream-Route sucht: category='system', isDefault=true, isActive=true
  → Findet einen → wird als System-Message vor alle anderen Messages prepended
  → Kein Default gefunden → kein System-Prompt (normales Verhalten)

Das bedeutet: du erstellst einen Prompt in /dashboard/prompts, setzt ihn als Default — ab sofort gilt er für alle Chat-Konversationen, ohne Code-Änderung.

Explizit — per promptId

Der Client kann eine promptId im Request-Body mitschicken um einen bestimmten Prompt zu erzwingen:

// useChat hook — sendMessage
await fetch('/api/v1/chat/stream', {
  method: 'POST',
  body: JSON.stringify({
    messages,
    model,
    promptId: 'clxyz123...',   // lädt diesen Prompt statt dem Default
  }),
});

Die Stream-Route priorisiert promptId über den Default:

if (promptId) {
  // lädt genau diesen Prompt
} else {
  // lädt Default (category='system', isDefault=true)
}

PromptSelector-Komponente

chimerai add prompt-management liefert einen fertigen Dropdown mit dem der User im Chat selbst einen Prompt wählen kann:

import { PromptSelector } from '@/components/chat/prompt-selector';

// Im Chat-Header oder Sidebar:
const [promptId, setPromptId] = useState<string | null>(null);

<PromptSelector
  value={promptId}
  onChange={setPromptId}
  category="system"          // filtert auf System-Prompts
  placeholder="No system prompt"
/>

Die gewählte promptId dann beim Senden mitgeben:

sendMessage(userInput, { promptId });

Prompts im RAG

Die Kategorie rag ist für Dokument-Kontext-Templates gedacht ("Beantworte die Frage nur anhand der folgenden Dokumente: ..."). Die RAG-Route lädt sie nicht automatisch — das erfordert eine manuelle Anpassung:

// app/api/v1/rag/query/route.ts — eigene Erweiterung
const ragTemplate = await prisma.promptTemplate.findFirst({
  where: { category: 'rag', isDefault: true, isActive: true },
});

const systemPrompt = ragTemplate
  ? ragTemplate.content
  : 'Answer based on the provided context only.';

// systemPrompt dann als System-Message in den LLM-Call einbauen

Ein typisches RAG-Template:

Du bist ein hilfreicher Assistent. Beantworte die folgende Frage ausschließlich
auf Basis der bereitgestellten Dokumente. Wenn die Antwort nicht in den
Dokumenten enthalten ist, antworte mit "Diese Information liegt mir nicht vor."

Dokumente:
{{context}}

Frage: {{question}}

{{context}} und {{question}} sind Platzhalter — die RAG-Route muss sie vor dem LLM-Aufruf ersetzen.


API Endpoints

MethodPathBeschreibung
GET/api/promptsAlle aktiven Templates
GET/api/prompts?category=systemGefiltert nach Kategorie
POST/api/promptsNeues Template erstellen
GET/api/prompts/:idEinzelnes Template
PUT/api/prompts/:idTemplate aktualisieren
DELETE/api/prompts/:idTemplate löschen
POST/api/prompts/:id/set-defaultAls Default markieren

Access Control

Prompt-Verwaltung hinter Admin-Rolle absichern:

// app/dashboard/prompts/page.tsx
const session = await getServerSession(authOptions);
if (session?.user?.role !== 'admin') redirect('/');

Typische Workflows

System-Prompt für alle Chats setzen:

  1. /dashboard/prompts → Neuer Prompt → Kategorie: system
  2. "Als Default setzen" klicken
  3. Fertig — gilt ab sofort für alle neuen Konversationen

Verschiedene Prompts pro Use-Case (z.B. Support vs. Coding):

  1. Mehrere system-Prompts erstellen (nur einer kann Default sein)
  2. PromptSelector in die Chat-UI einbauen
  3. User wählt den passenden Prompt pro Konversation

Mehrsprachige Apps:

  1. Gleicher Prompt-Name, unterschiedliche language-Werte (de, en, fr)
  2. In der Stream-Route auf Accept-Language Header filtern:
    const lang = request.headers.get('accept-language')?.slice(0, 2) ?? 'en';
    const tmpl = await prisma.promptTemplate.findFirst({
      where: { category: 'system', isDefault: true, isActive: true, language: lang },
    });
    
ChimerAI Docs · Back to Demo