Zum Hauptinhalt springen
KI

Context Engineering – dein Frontmatter ist der Anfang

Context Engineering praktisch: wie strukturierte Frontmatter-Metadaten aus Astro Content Collections zur präzisen, budgetierten Kontextquelle für ein LLM werden – mit TypeScript-Beispielen statt naiver Volltextsuche.

Alain Ritter 6
Context Engineering – dein Frontmatter ist der Anfang
Titelbild: KI-generiert

Context Engineering ist die Disziplin, das Kontextfenster eines LLM zur Laufzeit so zu befüllen, dass das Modell genau die Informationen vor sich hat, die es für eine gute Antwort braucht – nicht mehr und nicht weniger. Klingt abstrakt? Ist es nicht. Die Markdown-Dateien, aus denen dieser Blog besteht, sind bereits ein Lehrstück dafür. Genau daran entlang wird dieser Post konkret.

Prompt endet, wo der Kontext beginnt

Prompt Engineering optimiert eine Nachricht: Formulierung, Ton, ein gutes Beispiel. Das trägt für abgegrenzte Aufgaben. Sobald ein System aber über externe Wissensquellen, Verlauf und Tools hinweg zuverlässig sein soll, verschiebt sich die Frage von „Wie formuliere ich?“ zu „Was muss im Kontextfenster stehen, damit die Frage überhaupt gut beantwortbar ist?“ – und in welcher Form, welcher Reihenfolge, welchem Budget.

Dein Frontmatter ist schon Context Engineering

Der Blog nutzt Astro Content Collections. Das Schema in content.config.ts ist nichts anderes als ein Kontext-Vertrag: es zwingt jeden Post in eine strukturierte, typsichere Form.

// src/content.config.ts (Auszug)
const blogCollection = defineCollection({
  loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }),
  schema: z.object({
    title: z.string(),
    lang: z.enum(['de', 'en', 'fr']).default('de'),
    translationKey: z.string().optional(),
    description: z.string().optional(),
    tags: z.array(z.string()).default([]),
    publishDate: z.coerce.date(),
    draft: z.boolean().default(false),
  }),
});

Und der Frontmatter dieses Beitrags – das ist bereits kuratierter, komprimierter Kontext:

---
title: 'Context Engineering – dein Frontmatter ist der Anfang'
description: 'Context Engineering praktisch: wie strukturierte …'
lang: 'de'
translationKey: 'context-engineering'
tags: ['tutorial', 'Context Engineering', 'prompting', 'KI', 'LLM']
---

title, description, tags fassen einen 900-Wörter-Artikel in ~30 Token zusammen. translationKey verknüpft Sprachvarianten. lang erlaubt Filterung. Das ist kein Zufall – das ist genau das Rohmaterial, das ein LLM-Feature braucht.

Strukturierte Metadaten schlagen Volltext

Angenommen, du willst ein „Ähnliche Beiträge“-Feature oder einen Chat über deinen Blog bauen. Der naive Reflex: alle MDX-Bodies embedden und per Vektorsuche reinkippen. Rechnen wir das gegen:

AnsatzKontext pro Post15 Posts
Voller Markdown-Body~1.200 Token~18.000 Tok
Nur Frontmatter (Titel+Desc)~30 Token~450 Tok

Faktor 40. Und die 450 Token sind nicht nur billiger, sondern präziser: kein Boilerplate, kein Rauschen, keine Verdünnung. Für „welche Posts passen zu X?“ braucht das Modell keinen Fließtext – es braucht die kuratierte Essenz, die im Frontmatter längst steht.

Kontext im Code assemblieren

So sieht eine budgetierte Kontext-Assemblierung direkt auf den Content Collections aus – ohne Vektor-DB, nur mit dem, was der Frontmatter hergibt:

import { getCollection } from 'astro:content';

// Grobe, aber brauchbare Heuristik: ~4 Zeichen pro Token.
const estimateTokens = (s: string) => Math.ceil(s.length / 4);

export async function buildBlogContext(query: string, budget = 1500) {
  const posts = await getCollection('blog', ({ data }) => !data.draft && data.lang === 'de');

  // 1. Ranken nach Tag-Overlap – simpel, transparent, ohne Embeddings.
  const terms = new Set(query.toLowerCase().split(/\W+/).filter(Boolean));
  const ranked = posts
    .map((post) => ({
      post,
      score: post.data.tags.filter((t) => terms.has(t.toLowerCase())).length,
    }))
    .filter((r) => r.score > 0)
    .sort((a, b) => b.score - a.score);

  // 2. Kontext NUR aus Frontmatter bauen – und das Token-Budget einhalten.
  const lines: string[] = [];
  let used = 0;
  for (const { post } of ranked) {
    const line = `- ${post.data.title} [${post.data.tags.join(', ')}]: ${post.data.description ?? ''}`;
    const tokens = estimateTokens(line);
    if (used + tokens > budget) break; // harte Grenze statt „mal sehen“
    lines.push(line);
    used += tokens;
  }
  return lines.join('\n');
}

Die entscheidenden Zeilen sind nicht das Ranking, sondern if (used + tokens > budget) break. Context Engineering ist zur Hälfte ein Weglassen.

Übersetzungen deduplizieren

Jeder Post existiert dreimal (de/en/fr) – gleicher Inhalt, gleicher translationKey. Ungefiltert würdest du demselben Modell dieselbe Information dreifach servieren: dreifache Kosten, null Mehrwert. Der Frontmatter löst auch das:

function dedupeByTranslation<T extends { data: { translationKey?: string }; id: string }>(posts: T[]): T[] {
  const seen = new Set<string>();
  return posts.filter((p) => {
    const key = p.data.translationKey ?? p.id;
    if (seen.has(key)) return false;
    seen.add(key);
    return true;
  });
}

Struktur schlägt Fließtext: Delimiter & Reihenfolge

Ist der Kontext beisammen, entscheidet die Verpackung. Modelle trennen Instruktion und Daten deutlich zuverlässiger, wenn beides klar ausgezeichnet ist – das mindert nebenbei das Risiko von Prompt Injection aus abgerufenem Inhalt:

const prompt = `
<instructions>
Beantworte die Frage AUSSCHLIESSLICH anhand von <context>.
Fehlt die Information dort, sage das ausdrücklich – rate nicht.
</instructions>

<context>
${await buildBlogContext(userQuery)}
</context>

<question>
${userQuery}
</question>
`;

Zwei Prinzipien stecken darin:

  • Delimiter (<context>, <question>) grenzen Datenblöcke sauber ab.
  • Positionierung: Instruktionen früh, die konkrete Frage spät. Modelle beachten Anfang und Ende zuverlässiger als die Mitte – der „Lost in the middle“-Effekt ist messbar, also platziere Kritisches an den Rändern.

Token-Budget statt „alles rein“

Warum überhaupt budgetieren, wo Fenster doch riesig sind? Weil mehr Kontext drei Dinge gleichzeitig verschlechtert:

  • Kosten & Latenz wachsen linear mit jedem Token.
  • Verdünnung – je mehr Irrelevantes, desto schwerer gewichtet das Modell das Wesentliche.
  • Recall-Abfall – ab einem gewissen Füllstand sinkt die Trefferquote auf Fakten in der Mitte des Kontexts spürbar.

Ein hartes Budget wie oben (budget = 1500) ist deshalb kein Sparzwang, sondern ein Qualitätsmerkmal.

Für Agenten: Kontext dynamisch nachladen

Bei mehrstufigen Agenten sammeln sich Tool-Ergebnisse und Zwischenschritte an. Statt alles vorab zu laden, gibt man dem Modell ein Tool, das gezielt nur den Body eines konkret gewählten Posts nachlädt – Frontmatter zuerst, Volltext nur bei Bedarf:

// Tool-Definition: erst über Frontmatter entscheiden, dann gezielt laden.
const getPostBody = {
  name: 'get_post_body',
  description: 'Lädt den Volltext eines Blog-Posts anhand seiner id nach.',
  input_schema: {
    type: 'object',
    properties: { id: { type: 'string' } },
    required: ['id'],
  },
};

So bleibt das Fenster schlank: Das Modell sieht zunächst nur die kompakte Frontmatter-Übersicht und holt den teuren Volltext ausschließlich für den einen Post, den es wirklich braucht (Just-in-time-Retrieval). Ergänzend halten Scratchpads Zwischenergebnisse außerhalb des Fensters, Sub-Agenten kapseln Teilaufgaben mit eigenem, frischem Kontext.

Häufige Fehler

  1. Zu viel Kontext – „sicherheitshalber alles rein“ verschlechtert Qualität, Kosten und Latenz auf einmal.
  2. Übersetzungen nicht dedupliziert – dieselbe Info in de/en/fr dreifach im Fenster.
  3. Instruktion und Daten vermischt – ohne Delimiter droht Prompt Injection und das Modell verwechselt Anweisung mit Inhalt.
  4. Volltext, wo Metadaten reichen – der Frontmatter ist oft die bessere, billigere Quelle.
  5. Position ignoriert – Kritisches in der Mitte eines langen Kontexts vergraben.

Fazit

Context Engineering ist der Schritt vom „richtig fragen“ zum „richtig informieren“. Und der Anfang liegt näher, als man denkt: Wer seine Inhalte sauber strukturiert – typisiertes Schema, aussagekräftige description, präzise tags, stabile translationKeys –, hat die halbe Arbeit schon getan. Der Frontmatter, den du ohnehin pflegst, ist die kompakteste Kontextquelle, die du besitzt. Der Rest ist Assemblierung: ranken, deduplizieren, budgetieren, strukturieren.

Verwandt: die Fallstudie zum LLM-Wiki nach Karpathy zeigt dasselbe Prinzip im Großen – strukturierte, akkumulierte Notizen statt naiver Vektorsuche.

[Top]

Veröffentlicht am 26. Juli 2026 von Alain Ritter