• Tech Support ⤴
  • Projects
  • Services
    • AI Development
    • UI/UX Design
    • Web Development
    • Technology Support
    • Mobile App Development
    • Banking ATM Interfaces
    • Process Automation
    • Security Auditing
    • Local AI Servers
  • odoo ERP
get in touchStart with Eva
logo
Tech Support ⤴
Projects
Services
AI DevelopmentUI/UX DesignWeb DevelopmentTechnology SupportMobile App DevelopmentBanking ATM InterfacesProcess AutomationSecurity AuditingLocal AI Servers
odoo ERP
get in touchStart with Eva
Loading…
logo

Transforming businesses through AI-powered digital innovation and creative excellence.

Quick Links

BlogAinexProjectsContact us

Contact Us

pinDubai Digital Park, A5, DTEC - Silicon Oasisemail[email protected]phone+971 55 7538087
© 2026 aratech. All rights reserved.
Privacy PolicyTerms of ServiceCookie Policy
Startseite / Blog / Vibe-Coding eines Backends 2026: Wie Directus und die nikola66-Fähigkeit natürliche Sprache in Produktions-Schemata umwandeln

Vibe-Coding eines Backends 2026: Wie Directus und die nikola66-Fähigkeit natürliche Sprache in Produktions-Schemata umwandeln

Stellen Sie sich vor, Sie könnten ein ganzes Backend - inklusive Sammlungen, Beziehungen und Daten - mit einem einzigen Prompt erstellen.

3. Mai 2026 - 25 Min. Lesezeit

Wichtigste Punkte

ExpandCollapse
  • - Die Directus-Fähigkeit ist ein universeller, sammlungsunabhängiger GraphQL-Client, mit dem KI-Agenten jede Directus-Schema erstellen und verwalten können, ohne hartcodierte Modelle zu benötigen
  • - Vibe-Coding eines Backends bedeutet, das gesamte Datenmodell in natürlicher Sprache zu beschreiben und dann den Agenten alles in einem Durchgang scaffolden zu lassen – Sammlungen, Felder, Beziehungen und sogar Seed-Daten
  • - Produktionsmuster umfassen alles-in-einem-Aufruf-Felddefinitionen, Admin-Token-Anforderungen und das zweistufige Blog-Beitrag-Erstellmuster (erst Eltern- dann Übersetzungsdatensätze)
Vibe-Coding a Backend in 2026: How Directus and the nikola66 Skill Turn Natural Language Into Production Schemas

Here is the translation of the blog post from English to German:

Table of Contents

  • Einleitung: Das Backend ist jetzt ein Gespräch
  • Was ist dieser "Directus-Skill" eigentlich
  • Voraussetzungen: Was Sie benötigen, bevor Sie beginnen
  • Installation des Skills in Hermes Agent
  • Anatomie einer einzelnen Prompt-Backend-Spezifikation
  • Beispiel 1: Blog-Backend (Multilingual-Ready)
    • Was dies tut
    • Das generierte Code (Was unter der Haube läuft)
  • Beispiel 2: E-Commerce-Backend in einem Prompt
  • Beispiel 3: Einfaches CRM (Kontakte + Unternehmen + Interaktionen)
  • Wie es eigentlich funktioniert: Der Skills geheime Sauce
    • Schritt 1 - Agent parse Ihr Prompt
    • Schritt 2 - Skill generiert korrekte Payloads
    • Schritt 3 - Admin-API-Aufrufe in Reihenfolge
    • Schritt 4 - Beispiel-Daten + Überprüfung
  • Produktionsbewährte Muster, die wir entdeckt haben
    • 1. Schema und Meta sind obligatorisch
    • 2. Verwenden Sie get_expanded() für Beziehungen
    • 3. IDs sind Strings in GraphQL, Ganzzahlen in REST
    • 4. Junction-Tabelle-Schreibvorgänge gehen über die Junction-Sammlung
    • 5. Übersetzungs-Sammlungen benötigen einen zweistufigen Einfügevorgang
    • 6. Der POST-Trunkierungsfehler und die PATCH-Fix
    • 7. Überprüfen Sie Schreibzugriff vor der Veröffentlichung
  • Fehlerbehandlung: Was schiefgeht und wie Sie es beheben
  • Erweiterte Muster: Filter, Beziehungen und Enum-Felder
    • Filtern mit Operatoren
    • Mehrstufige Beziehungs-Erweiterung
    • JSON-Felder für flexible Daten
  • Die Admin-API: Wenn Sie das Schema programmatisch ändern müssen
  • Alles zusammen: Ihre erste Vibe-Code-Sitzung
  • Was dies ermöglicht: Schnelles Prototyping im großen Maßstab

Einleitung: Das Backend ist jetzt ein Gespräch

!Vibe-coding workflow diagram: natural language prompt to Directus schema to production API

Hier ist ein frustrierendes Muster, das die meisten Entwickler kennen:

  1. Sie haben eine brillante App-Idee
  2. Sie beginnen mit dem Aufbau der Datenbank - users, posts, orders
  3. Sie bauen die API-Ebene - REST-Endpunkte, GraphQL-Resolver
  4. Sie verbinden Authentifizierung, Berechtigungen, Validierung
  5. Drei Tage später kommen Sie endlich zum eigentlichen Feature, das Sie bauen wollten

Diese Reibung ist real. Und im Jahr 2026 ist sie tot.

Was, wenn Sie Schritte 2 bis 4 ganz überspringen könnten? Was, wenn Sie Ihr gesamtes Backend in einfacher Sprache beschreiben, Enter drücken und ein produktionsbereites Schema, API und Admin-Panel erhalten könnten?

Das bedeutet Vibe-Coding eines Backends. Und mit Directus - dem Open-Source-Headless-CMS, das Ihre Datenbank in eine Instant-API verwandelt - und dem nikola66-Directus-Skill (einem universellen GraphQL-Client für KI-Agenten) ist es jetzt möglich, eine gesamte Datenlage in einem Schritt aufzubauen.

Dies ist kein Spielzeug-Demo. Dies ist ein echter Workflow, den wir bei Ainex verwenden, um Projekt-Backends in Minuten und nicht in Tagen aufzubauen. In diesem Guide erfahren Sie:

  • Was der Directus-Skill eigentlich unter der Haube macht
  • Wie Sie ihn installieren und mit Ihrem Directus-Instanz verbinden
  • Die Anatomie einer einzelnen Prompt-Backend-Spezifikation
  • Schritt-für-Schritt-Beispiele: Aufbau eines Blogs, eines E-Commerce-Stores und eines CRMs
  • Produktionsmuster, Fehlerbehandlung und Gotchas, die wir bereits im Feld getroffen haben
  • Wie Sie überprüfen, ob Ihr neu aufgebauter Backend-Server live und abfragbar ist

Lassen Sie uns loslegen.


Was ist dieser "Directus-Skill" eigentlich?

Der Skill bei nikola66/directus-skill ist ein Python-Client, der Directus' GraphQL- und REST-APIs direkt anspricht. Er ist für KI-Agenten wie Hermes konzipiert, aber Sie können ihn auch als eigenständige Bibliothek verwenden.

Schlüsselmerkmale, die Vibe-Coding möglich machen:

  • Sammlungs-agnostisch: Es kümmert sich nicht darum, ob Sie mit Blog_Posts oder Ecom_Products arbeiten. Die gleichen Methoden funktionieren auf jeder Sammlung.
  • Vollständige CRUD-Oberfläche: get, insert, update, delete, count und sogar create_collection und create_field für Schema-Operationen (nur Admin).
  • Intelligente Beziehungs-Erweiterung: Verwenden Sie die Punktnotation wie author.name oder order_items.product.title und der Skill baut die korrekte verschachtelte GraphQL-Auswahlmenge.
  • Filteroperatoren: Alle Directus-Filter werden unterstützt - _eq, _contains, _in, _gt, _null usw.
  • Fehlerbehandlung: Löst DirectusError mit strukturierten Details aus, damit Sie genau wissen, warum etwas fehlgeschlagen ist.

Wenn Sie diesen Skill in einen KI-Agenten laden, geben Sie diesem Agenten die Fähigkeit, ein ganzes Datenbankschema durch Konversation zu bootstrappen.


Voraussetzungen: Was Sie benötigen, bevor Sie beginnen

Bevor Sie ein Backend vibe-codieren können, benötigen Sie drei Dinge:

  1. Eine Directus-Instanz - entweder selbst gehostet oder Directus Cloud. Wir laufen bei https://hub.aratech.ae.
  2. Ein API-Token mit entsprechenden Berechtigungen. Für Schema-Erstellung benötigen Sie ein Admin-Token. Erhalten Sie es von Directus → Settings → API-Tokens → Erstellen (Admin-Bereich, alle Berechtigungen).
  3. Python 3.9+ mit dem Skill installiert:
# Option A: Installieren aus PyPI (wenn veröffentlicht)
pip install directus-skill

## Option B: Klonen und direkt verwenden (aktuell)
git clone https://github.com/nikola66/directus-skill.git
## Kopieren Sie das Paket in Ihr Projekt oder fügen Sie es zu sys.path hinzu

Stand April 2026 ist der Skill aktiv gepflegt und gegen eine Directus-10+-Instanz mit vollständigem CRUD, Filteroperatoren und Sammlungsverwaltung validiert.


Installation des Skills in Hermes Agent

Wenn Sie Hermes Agent (unser Multi-Agenten-Orchestrierungsplattform) ausführen, ist das Hinzufügen des Skills ein einzelner Befehl:

hermes skills install directus

Oder um die upstream-GitHub-Version direkt hinzuzufügen:

npx skills add nikola66/directus-skill

Sobald installiert, wird der directus-Skill automatisch geladen, wenn Sie nach Directus-Operationen fragen. Sie müssen nichts manuell importieren - der Agent kümmert sich darum.

Setzen Sie Ihre Umgebungsvariablen (wir halten diese in ~/.bashrc oder der Gateway-Sitzung):

export DIRECTUS_URL="https://hub.aratech.ae"
export DIRECTUS_API_TOKEN="user_token_here"          # CRUD-Operationen
export DIRECTUS_ADMIN_TOKEN="admin_token_here"      # Schema-Verwaltung

Hinweis: Im Hermes-Gateway werden diese automatisch aus der Gateway-Konfiguration injiziert. Wenn Sie eigenständige Skripte ausführen, setzen Sie sie selbst.


Anatomie einer einzelnen Prompt-Backend-Spezifikation

Die Magie passiert, wenn Sie Ihr gesamtes Datenmodell in einem natürlichen Sprachprompt beschreiben. Hier ist das Muster:

Bauen Sie mir ein [TYPE]-Backend mit Directus. Erstellen Sie diese Sammlungen:

1. [Sammlungsname] - [Zweck]
   - Feldname (Typ), Feld2 (Typ), ...
   - Beziehungen: [Beziehungsdetails]

2. [Sammlungsname] - ...
   ...

Nachdem alle Sammlungen erstellt wurden:
- Überprüfen Sie durch Aufruf von get_collections() und Ausgeben der Liste
- Legen Sie [N] Beispiel-Datensätze für jede Sammlung an
- Ausgeben des vollständigen Python-Skripts

Der Agent interpretiert dies, übersetzt es in Directus-Admin-API-Aufrufe (POST /collections mit vollständiger Felddefinition), führt es aus und gibt ein funktionierendes Schema zurück.

Der Skill erledigt die harte Arbeit:

  1. Baut die korrekte Payload-Struktur für Directus' eigenwillige schema- und meta-Anforderungen
  2. Ruft create_collection() pro Sammlung mit der vollständigen Feldliste auf
  3. Legt optional Beispiel-Daten über CRUD-Operationen an
  4. Überprüft den Erfolg mit get_collections()

Alles in einer Ausführung, ohne manuelle Intervention.


Beispiel 1: Blog-Backend (Multilingual-Ready)

Lassen Sie uns mit einem Klassiker beginnen - einem Blog, der 5 Sprachen unterstützt. Hier ist der vollständige Prompt, den Sie dem Agenten geben würden:

Bauen Sie mir ein multilinguales Blog-Backend mit Directus. Erstellen Sie diese Sammlungen:

1. Blog_Authors - Autor-Profile
   - Name (String), Slug (String, eindeutig), Bio (Text), Avatar (Datei), Social_Twitter (String, nullable)
   - Status: Entwurf/Veröffentlicht
   - Felder: ID, Erstellt am, Aktualisiert am

2. Blog_Categories - Hierarchische Taxonomie
   - Name (String), Slug (String, eindeutig), Beschreibung (Text), Eltern-Kategorie (Viele-zu-Eins → Blog_Categories, nullable)
   - Icon (String, Icon-Name), Farbe (String, Hex)
   - Felder: ID, Sortierreihenfolge

3. Blog_Tags - Flache Tags
   - Name (String), Slug (String, eindeutig), Farbe (String, Hex)
   - Felder: ID

4. Blog_Posts - Eltern-Records (Metadaten nur, pro unserem Schema-Design)
   - Status (Entwurf/Veröffentlicht), Veröffentlicht am (Datum, nullable)
   - Autor (Viele-zu-Eins → Blog_Authors), Kategorie (Viele-zu-Eins → Blog_Categories)
   - Hervorgehobenes Bild (Datei), Lesezeit in Minuten (Ganzzahl)
   - Ist hervorgehoben (Boolean), Ist Säule (Boolean)
   - Felder: ID, Erstellt am, Aktualisiert am

5. Blog_Posts_Translations - pro-Sprach-Inhalt (Kind-Records)
   - Blog_Posts_ID (FK-Ganzzahl → Blog_Posts), Sprachcode (String: en/ar/de/es/fr)
   - Titel (String), Slug (String), Inhalt (Markdown-Text)
   - Exzerpt (Text, max. 200 Zeichen), Schlüssel-Merkmale (JSON-Array, 3-5 Elemente)
   - Meta-Titel (String, ≤60), Meta-Beschreibung (String, ≤160)
   - Hervorgehobenes Bild-Alt (String)
   - CTA-Überschrift (String), CTA-Schaltflächen-Text (String), CTA-Schaltflächen-URL (String)
   - Schema-Markup (JSON - Article schema.org)
   - Felder: ID

6. Blog_Posts_Tags - Junction für Viele-zu-Viele-Beziehungen Post ↔ Tag
   - Blog_Posts_ID (FK → Blog_Posts), Blog_Tags_ID (FK → Blog_Tags)
   - Felder: ID

Wichtig:
- Verwenden Sie create_collection() für alle 6 Sammlungen
- Jedes Feld muss schema: {} und meta: {} in der Payload enthalten
- Definieren Sie alle Felder im Voraus (keine inkrementellen Feldhinzufügungen)
- Nachdem alle Sammlungen erstellt wurden, legen Sie 2 Beispiel-Blog-Beiträge an:
  * Beitrag 1: "Einführung in die KI-Sicherheit" - Autor=1, Kategorie=33 (KI & LLMs), veröffentlicht
  * Beitrag 2: "Verständnis von SOC 2-Konformität" - Autor=1, Kategorie=37 (Konformität), Entwurf
  * Für jeden Beitrag erstellen Sie eine EN-Übersetzung (überspringen Sie AR/DE/ES/FR für jetzt)
- Drucken Sie die Überprüfung: Listen Sie alle Sammlungen und ihre Datensatzanzahlen auf

Wenn Sie diesen Prompt durch einen Agenten mit dem Directus-Skill ausführen:

  1. Erstellt 6 Sammlungen mit vollständiger Felddefinition in korrekter Reihenfolge (Eltern vor Kindern, keine zirkulären Abhängigkeiten)
  2. Fügt korrekte Beziehungen hinzu - Viele-zu-Eins von Posts → Autoren/Kategorie, Viele-zu-Viele über Junction-Tabelle
  3. Respektiert Ihr tatsächliches Schema-Design - Übersetzungs-Records sind separate Kind-Sammlung, verknüpft mit blog_posts_id
  4. Legt echte Daten an - Zwei Beispiel-Beiträge mit erforderlichen Feldern
  5. Überprüft - Gibt aus, was erstellt wurde

Was dies tut

Wenn Sie diesen Prompt durch einen Agenten mit dem Directus-Skill ausführen:

  1. Erstellt 6 Sammlungen mit vollständiger Felddefinition in korrekter Reihenfolge (Eltern vor Kindern, keine zirkulären Abhängigkeiten)
  2. Fügt korrekte Beziehungen hinzu - Viele-zu-Eins von Posts → Autoren/Kategorie, Viele-zu-Viele über Junction-Tabelle
  3. Respektiert Ihr tatsächliches Schema-Design - Übersetzungs-Records sind separate Kind-Sammlung, verknüpft mit blog_posts_id
  4. Legt echte Daten an - Zwei Beispiel-Beiträge mit erforderlichen Feldern
  5. Überprüft - Gibt aus, was erstellt wurde

Das generierte Code (Was unter der Haube läuft)

Der Agent produziert etwas wie dieses Python-Skript:

from directus.client import DirectusClient
import os

client = DirectusClient(
    url=os.getenv('DIRECTUS_URL'),
    token=os.getenv('DIRECTUS_ADMIN_TOKEN')  # Admin-Token für Schema-Operationen
)

## 1. Blog_Authors
client.create_collection('Blog_Authors', fields=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'field': 'name', 'type': 'string', 'schema': {}, 'meta': {'interface': 'input'}},
    {'field': 'slug', 'type': 'string', 'schema': {'is_unique': True}, 'meta': {'interface': 'input'}},
    {'field': 'bio', 'type': 'text', 'schema': {}, 'meta': {'interface': 'textarea'}},
    {'field': 'avatar', 'type': 'file', 'schema': {}, 'meta': {'interface': 'file', 'options': {'accepted_files': 'image/*'}}},
    {'field': 'social_twitter', 'type': 'string', 'schema': {}, 'meta': {'interface': 'input'}},
    {'field': 'status', 'type': 'string', 'schema': {}, 'meta': {'interface': 'select', 'options': {'choices': ['draft', 'published']}}},
    {'field': 'created_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}},
    {'field': 'updated_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}}
])

## 2. Blog_Categories
client.create_collection('Blog_Categories', fields=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'field': 'name', 'type': 'string', 'schema': {}, 'meta': {'interface': 'input'}},
    {'field': 'slug', 'type': 'string', 'schema': {'is_unique': True}, 'meta': {'interface': 'input'}},
    {'field': 'description', 'type': 'text', 'schema': {}, 'meta': {'interface': 'textarea'}},
    {'field': 'parent_category', 'type': 'integer', 'schema': {}, 'meta': {'interface': 'relation', 'options': {'related_collection': 'Blog_Categories'}}},
    {'field': 'icon', 'type': 'string', 'schema': {}, 'meta': {'interface': 'input'}},
    {'field': 'color', 'type': 'string', 'schema': {}, 'meta': {'interface': 'color'}},
    {'field': 'sort_order', 'type': 'integer', 'schema': {}, 'meta': {'interface': 'numeric'}},
    {'field': 'created_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}},
    {'field': 'updated_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}}
])

## 3. Blog_Tags
client.create_collection('Blog_Tags', fields=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'field': 'name', 'type': 'string', 'schema': {}, 'meta': {'interface': 'input'}},
    {'field': 'slug', 'type': 'string', 'schema': {'is_unique': True}, 'meta': {'interface': 'input'}},
    {'field': 'color', 'type': 'string', 'schema': {}, 'meta': {'interface': 'color'}},
    {'field': 'created_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}}
])

## 4. Blog_Posts - Eltern-Records (Metadaten nur, pro unserem Schema-Design)
client.create_collection('Blog_Posts', fields=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'field': 'status', 'type': 'string', 'schema': {}, 'meta': {'interface': 'select', 'options': {'choices': ['draft', 'published']}}},
    {'field': 'published_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': False}},
    {'field': 'author', 'type': 'integer', 'schema': {}, 'meta': {'interface': 'relation', 'options': {'related_collection': 'Blog_Authors'}}},
    {'field': 'category', 'type': 'integer', 'schema': {}, 'meta': {'interface': 'relation', 'options': {'related_collection': 'Blog_Categories'}}},
    {'field': 'featured_image', 'type': 'file', 'schema': {}, 'meta': {'interface': 'file', 'options': {'accepted_files': 'image/*'}}},
    {'field': 'reading_time_minutes', 'type': 'integer', 'schema': {}, 'meta': {'interface': 'numeric'}},
    {'field': 'is_featured', 'type': 'boolean', 'schema': {}, 'meta': {'interface': 'boolean'}},
    {'field': 'is_pillar', 'type': 'boolean', 'schema': {}, 'meta': {'interface': 'boolean'}},
    {'field': 'created_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}},
    {'field': 'updated_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}}
])

## 5. Blog_Posts_Translations - pro-Sprach-Inhalt (Kind-Records)
client.create_collection('Blog_Posts_Translations', fields=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'field': 'blog_posts_id', 'type': 'integer', 'schema': {}, 'meta': {'interface': 'relation', 'options': {'related_collection': 'Blog_Posts'}}},
    {'field': 'languages_code', 'type': 'string', 'schema': {}, 'meta': {'interface': 'select', 'options': {'choices': ['en', 'ar', 'de', 'es', 'fr']}}},
    {'field': 'title', 'type': 'string', 'schema': {'is_required': True}, 'meta': {'interface': 'input'}},
    {'field': 'slug', 'type': 'string', 'schema': {'is_required': True, 'is_unique': True}, 'meta': {'interface': 'input'}},
    {'field': 'content', 'type': 'text', 'schema': {}, 'meta': {'interface': 'markdown'}},
    {'field': 'excerpt', 'type': 'text', 'schema': {}, 'meta': {'interface': 'textarea'}},
    {'field': 'key_takeaways', 'type': 'json', 'schema': {}, 'meta': {'interface': 'list'}},
    {'field': 'meta_title', 'type': 'string', 'schema': {}, 'meta': {'interface': 'input'}},
    {'field': 'meta_description', 'type': 'text', 'schema': {}, 'meta': {'interface': 'textarea'}},
    {'field': 'featured_image_alt', 'type': 'text', 'schema': {}, 'meta': {'interface': 'textarea'}},
    {'field': 'cta_headline', 'type': 'string', 'schema': {}, 'meta': {'interface': 'input'}},
    {'field': 'cta_button_text', 'type': 'string', 'schema': {}, 'meta': {'interface': 'input'}},
    {'field': 'cta_button_url', 'type': 'string', 'schema': {}, 'meta': {'interface': 'input'}},
    {'field': 'schema_markup', 'type': 'json', 'schema': {}, 'meta': {'interface': 'json'}},
    {'field': 'created_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}},
    {'field': 'updated_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}}
])

## 6. Blog_Posts_Tags - Junction-Tabelle
client.create_collection('Blog_Posts_Tags', fields=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'field': 'blog_posts_id', 'type': 'integer', 'schema': {}, 'meta': {'interface': 'relation', 'options': {'related_collection': 'Blog_Posts'}}},
    {'field': 'blog_tags_id', 'type': 'integer', 'schema': {}, 'meta': {'interface': 'relation', 'options': {'related_collection': 'Blog_Tags'}}},
    {'field': 'created_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}}
])

## Legen Sie Beispiel-Daten an
## 1. Erstellen Sie einen Autor (wenn nicht vorhanden)
author = client.insert({'name': 'Alex Chen', 'slug': 'alex-chen', 'bio': 'Sicherheitsingenieur bei Ainex.', 'status': 'published'}, collection='Blog_Authors')
author_id = author['id']

## 2. Erstellen Sie eine Kategorie
category = client.insert({'name': 'KI & LLMs', 'slug': 'ki-llms', 'description': 'Artikel über KI-Sicherheit und LLMs.', 'sort_order': 1}, collection='Blog_Categories')
category_id = category['id']

## 3. Erstellen Sie den Eltern-Blog-Beitrag-Record
post = client.insert({
    'status': 'published',
    'author': author_id,
    'category': category_id,
    'reading_time_minutes': 8,
    'is_featured': False,
    'published_at': '2026-05-03T10:00:00.000Z'
}, collection='Blog_Posts')
post_id = post['id']

## 4. Erstellen Sie die englische Übersetzung
client.insert({
    'blog_posts_id': post_id,
    'languages_code': 'en',
    'title': 'Einführung in die KI-Sicherheit',
    'slug': 'einfuehrung-in-die-ki-sicherheit',
    'content': '# KI-Sicherheitsgrundlagen\n\nDies ist ein Beispielartikel über die Sicherheit von KI-Systemen...\n\n## Schlüsselrisiken\n\n- Prompt-Injektion\n- Datenleakage\n- Modellvergiftung\n\n## Best Practices\n\nImmer Eingaben validieren, Modellausführung sandboxen und Anomalien überwachen.',
    'excerpt': 'Ein Anfänger-freundlicher Leitfaden zur Verständnis und Minderung von KI-Systemrisiken.',
    'key_takeaways': ['KI-Systeme sind anfällig für Prompt-Injektionsangriffe', 'Immer Eingaben validieren und Modellausführung sandboxen', 'Anomalien überwachen'],
    'meta_title': 'Einführung in die KI-Sicherheit - Ainex-Leitfaden',
    'meta_description': 'Erfahren Sie die Grundlagen der KI-Sicherheit, gemeinsame Bedrohungen und Best Practices für den Schutz Ihrer LLM-Anwendungen.',
    'featured_image_alt': 'Abstrakte Visualisierung von neuronalen Netzwerksicherheit',
    'cta_headline': 'Bereit, Ihre KI zu sichern?',
    'cta_button_text': 'Loslegen',
    'cta_button_url': '/loslegen',
    'schema_markup': {
        '@context': 'https://schema.org',
        '@type': 'Article',
        'headline': 'Einführung in die KI-Sicherheit',
        'author': {'@type': 'Person', 'name': 'Alex Chen'},
        'datePublished': '2026-05-03T10:00:00.000Z',
        'description': 'Ein Anfänger-freundlicher Leitfaden zur Verständnis und Minderung von KI-Systemrisiken.'
    }
}, collection='Blog_Posts_Translations')

print(f"✅ Blog-Backend erstellt! Beitrag-ID: {post_id}")

Dieses Skript wird vom Agenten generiert und ausgeführt. Sie erhalten ein vollständiges, abfragbares Schema und angelegte Daten sofort.


Beispiel 2: E-Commerce-Backend in einem Prompt

Lassen Sie uns größer denken. Hier ist, wie Sie ein vollständiges E-Commerce-Datenmodell aufbauen würden:

Bauen Sie ein Produktions-E-Commerce-Backend mit Directus. Erstellen Sie diese Sammlungen:

1. **Produkte** - Katalogartikel
   - Titel, Slug (eindeutig), Beschreibung (Text), Status (Entwurf/Verfügbar/Ausverkauft)
   - Preis_Cents (Ganzzahl), Vergleichspreis_Cents (Ganzzahl, nullable), Kosten_Cents (Ganzzahl)
   - SKU (eindeutig), Barcode (nullable), Gewicht_Gramm (Ganzzahl)
   - Lagerbestand, Niedriger_Bestand_Schwelle (Standard 10)
   - Hervorgehobenes Bild (Datei), Bilder (Viele-zu-Viele über Junction)
   - Kategorie (Viele-zu-Eins → Kategorien), Tags (Viele-zu-Viele → Tags über Junction)
   - Veröffentlicht am

2. **Kategorien** - Hierarchische Taxonomie
   - Name, Slug (eindeutig), Beschreibung, Eltern-Kategorie (nullable Viele-zu-Eins self)
   - Bild (Datei), Sortierreihenfolge

3. **Tags** - Produkt-Tags
   - Name, Slug (eindeutig), Farbe (Hex)

4. **Kunden** - Konten
   - E-Mail (eindeutig), Vorname, Nachname, Telefon
   - Standard-Versandadresse (JSON), Standard-Rechnungsadresse (JSON)
   - Gesamtausgaben_Cents, Bestellanzahl, Letzte_Bestellung_am (nullable)
   - Status (aktiv/blockiert), Notizen

5. **Bestellungen** - Transaktionen
   - Bestellnummer (eindeutig), Status (ausstehend/verarbeitet/versendet/liefert/cancelled)
   - Kunde (Viele-zu-Eins → Kunden)
   - Gesamtpreis_Cents, Steuer_Cents, Versandkosten_Cents, Gesamtbetrag_Cents, Rabatt_Cents
   - Versandadresse, Rechnungsadresse (JSON)
   - Zahlungsstatus (bezahlt/rückerstattet/fehlgeschlagen), Zahlungsmethode (stripe/paypal/manual)
   - Zahlungsabsichts-ID (nullable), Tracking-Nummer (nullable)
   - Notizen, Storniert am (nullable)

6. **Bestellpositionen** - Zeilenartikel (Junction-Tabelle Bestellungen ↔ Produkte)
   - Bestellung (Viele-zu-Eins → Bestellungen), Produkt (Viele-zu-Eins → Produkte)
   - Menge, Einzelpreis_Cents, Gesamtpreis_Cents
   - Variantenname (String, nullable)

7. **Inventar-Anpassungen** - Prüfungprotokoll
   - Produkt (Viele-zu-Eins → Produkte), Grund (nachbestellen/verkaufen/rückgabe/prüfen/anpassen)
   - Mengenänderung, vorherige Menge, neue Menge
   - Referenz-ID (nullable - verknüpft mit Bestellung/anpassen), Notizen

8. **Sammlungen** - Curated-Gruppierungen
   - Name, Slug (eindeutig), Handle (API-freundlicher String)
   - Typ (manual/automatisch), Regeln (JSON für automatische Regeln)
   - Sortierreihenfolge, Veröffentlicht (Boolean)

9. **Rabatte** - Promo-Codes
   - Code (eindeutig, nullable für automatisch), Typ (Prozentsatz/fest)
   - Wert (Ganzzahl - Prozentsatz oder Cents), Maximalverwendungen, Verwendungsanzahl
   - Gültig ab, Gültig bis (nullable)
   - Gilt für (alle/kategorien/produkte), anwendbare Produkt-IDs (JSON-Array)
   - Mindestbestellwert_Cents (nullable), Ausschluss von Verkaufsartikeln (Boolean)

Einschränkungen:
- Verwenden Sie create_collection() für alle 9 Sammlungen + explizite Junction-Tabellen (Produkte_Bilder wenn erforderlich)
- Jedes Feld: enthalten Sie schema: {} und meta: {} im Voraus
- Verwenden Sie richtige Directus-Feldtypen: Ganzzahl, String, Text, Boolean, Datum, JSON, Datei, Pivot
- Fügen Sie eindeutige Indizes auf Slug, SKU, Bestellnummer hinzu
- Legen Sie 3 Beispiel-Produkte mit Beispiel-Bildern an (verwenden Sie Datei-IDs wenn verfügbar), verknüpfen Sie mit Kategorie
- Überprüfen: Aufruf von get_collections() und Ausgeben der Datensatzanzahlen
- Ausgeben des vollständigen Python-Skripts

Das Ausführen dieses Prompts durch einen Agenten produziert ein ~300-zeiliges Skript, das Ihr gesamtes E-Commerce-Datenmodell in einem Schritt aufbaut. Von Null auf "Hier ist Ihr Admin-Panel" bevor Ihr Kaffee kalt wird.


Beispiel 3: Einfaches CRM (Kontakte + Unternehmen + Interaktionen)

Benötigen Sie etwas Leichtgewichtiges? Hier ist ein CRM:

Bauen Sie ein CRM-Backend mit Directus:

1. Unternehmen
   - Name, Domäne (eindeutig), Branche, Größe (1-10/11-50/51-200/200+)
   - Website, Telefon, Adresse (JSON), Jahresumsatz_Cents (nullable)
   - Besitzer (Viele-zu-Eins → Benutzer), Status (Lead/Kunde/Interessent/Abgelehnt)
   - Letzter Kontakt am, Notizen (Text)

2. Kontakte
   - Vorname, Nachname, E-Mail (eindeutig), Telefon, Job-Titel
   - Unternehmen (Viele-zu-Eins → Unternehmen), Besitzer (Viele-zu-Eins → Benutzer)
   - Status (aktiv/inaktiv/Lead), bevorzugte Kontaktmethode (E-Mail/Telefon/LinkedIn)
   - LinkedIn-URL, Notizen

3. Interaktionen
   - Kontakt (Viele-zu-Eins → Kontakte), Typ (Anruf/E-Mail/Treffen/Notiz)
   - Richtung (eingehend/ausgehend), Dauer in Minuten (Ganzzahl)
   - Zusammenfassung (Text), nächste Schritte (Text), Fälligkeitsdatum (nullable)
   - Verwandte Geschäftschance (Viele-zu-Eins → Geschäftschancen nullable)

4. Geschäftschancen
   - Titel, Wert_Cents, Phase (Vorschlag/Verhandlung/abgeschlossen/verloren)
   - Wahrscheinlichkeit (0-100), Abschlussdatum (erwartet)
   - Kontakt (Viele-zu-Eins → Kontakte), Besitzer (Viele-zu-Eins → Benutzer)
   - Notizen

Einschränkungen:
- Verwenden Sie create_collection() für alle 4
- Alle Standardfelder: ID, Erstellt am, Aktualisiert am werden automatisch hinzugefügt
- Beziehungen werden korrekt eingerichtet (Fremdschlüssel sind Ganzzahlen)
- Legen Sie 2 Unternehmen, 4 Kontakte, 3 Interaktionen, 1 Geschäftschance an

Wiederum - ein Prompt, eine Ausführung.


Wie es eigentlich funktioniert: Der Skills geheime Sauce

Lassen Sie uns entmystifizieren, was passiert, wenn Sie den Agenten bitten, "ein Backend zu bauen":

Schritt 1 - Agent parse Ihr Prompt

Der Agent verwendet seine Argumentation, um zu extrahieren:

  • Sammlungsnamen und ihren Zweck
  • Feldnamen, -typen und -einschränkungen
  • Beziehungsrichtungen (Viele-zu-Eins, Viele-zu-Viele)
  • Anforderungen an Beispiel-Daten
  • Überprüfungsschritte

Er muss kein Schema-Definitionssprache sehen - er liest einfach Ihre einfache Sprache und baut die Struktur.

Schritt 2 - Skill generiert korrekte Payloads

Dies ist der Teil, in dem der Skill glänzt. Directus' POST /collections-Endpunkt ist berüchtigt picky:

Ohne schema: {} und meta: {} pro Feld? → 403 Forbidden (auch mit einem gültigen Admin-Token). Falscher Feldtypname? → Die Sammlung erscheint nicht. Fehlende Beziehungs-Meta-Optionen? → Beziehungen funktionieren nicht.

Der Skill kennt den Directus-API-Vertrag und generiert produktionskorrekte Payloads automatisch. Hier ist, wie eine korrekte Felddefinition aussieht:

{
    'field': 'price_cents',
    'type': 'integer',
    'schema': {'is_required': True},      # ← immer enthalten
    'meta': {'interface': 'numeric'}      # ← immer enthalten
}

Schritt 3 - Admin-API-Aufrufe in Reihenfolge

Sammlungen werden in Abhängigkeitsreihenfolge erstellt (Eltern vor Kindern, keine zirkulären Abhängigkeiten). Für jede:

  1. POST /collections erstellt die Sammlung mit vollständiger Feldliste
  2. Skill überprüft mit GET /collections/{name}, dass sie existiert
  3. Wenn sie bereits existiert, wird sie gelöscht und neu erstellt (idempotenter Modus)

Für Junction-Tabellen (Viele-zu-Viele) wird der pivot-Typ oder explizite Fremdschlüssel-Felder mit meta.interface: 'relation' verwendet.

Schritt 4 - Beispiel-Daten + Überprüfung

Nachdem alle Sammlungen existieren, führt der Agent aus:

  • Fügt Beispiel-Datensätze mit Standard-CRUD (insert()) hinzu
  • Fragt zurück mit get() oder get_expanded() zur Bestätigung
  • Gibt eine Zusammenfassung auf Ihrem Terminal aus

Produktionsbewährte Muster, die wir entdeckt haben

Wir haben diesen Workflow gegen https://hub.aratech.ae mit unserem vollständigen Blog-Schema getestet. Hier sind die Lektionen:

1. Schema und Meta sind obligatorisch

Dies kann nicht genug betont werden. Directus 10+ gibt 403 zurück, wenn eines davon fehlt, aber die Fehlermeldung ist irreführend ("Sie haben keine Berechtigung") wenn das eigentliche Problem die Payload-Struktur ist.

Überprüfen Sie immer:

  • Sammlungspayload hat schema: {} und meta: {} auf oberster Ebene
  • Jedes einzelne Feld hat sowohl schema als auch meta
  • Feldtypwerte sind gültige Directus-Typen (integer, nicht int; string, nicht varchar)

2. Verwenden Sie get_expanded() für Beziehungen

Directus GraphQL erfordert verschachtelte Auswahlmengen für Beziehungs-Felder. Wenn Sie versuchen:

{ Blog_Posts_Translations { id blog_posts_id } }

Sie erhalten einen 400-Fehler: Field "blog_posts_id" of type "Blog_Posts" must have a selection of subfields.

Der Skills get_expanded()-Methode mit Punktnotation handhabt dies automatisch:

client.get_expanded(
    fields=['id', 'title', 'blog_posts_id.id', 'blog_posts_id.status'],
    collection='Blog_Posts_Translations',
    limit=50
)
## Gibt Dictionaries zurück: blog_posts_id = {'id': '5', 'status': 'published'}

3. IDs sind Strings in GraphQL, Ganzzahlen in REST

GraphQL gibt alle id-Felder als Strings zurück. Aber Fremdschlüssel-Felder (wie blog_posts_id) sind Ganzzahlen, wenn sie als Filter oder Einfügewerte verwendet werden.

Wenn Sie einen Beitrag erstellen und post_id = "42" zurückbekommen, müssen Sie umwandeln:

client.insert({
    'blog_posts_id': int(post_id),  # NICHT post_id
    'languages_code': 'en',
    ...
}, collection='Blog_Posts_Translations')

Andernfalls erhalten Sie einen 400-GraphQL-Validierungsfehler.

4. Junction-Tabelle-Schreibvorgänge gehen über die Junction-Sammlung

Directus stellt Viele-zu-Viele-Beziehungen als schreibgeschützte virtuelle Felder auf den Eltern dar. Sie können nicht das tags-Feld auf Blog_Posts direkt PATCHEN - Sie erhalten 403 Forbidden.

Stattdessen schreiben Sie in die Junction-Tabelle:

## FALSCH: Direktes PATCHEN auf Blog_Posts schlägt fehl
client.update(post_id, {'tags': [1, 2, 3]}, collection='Blog_Posts')  # ❌ 403

## RICHTIG: Einfügen in die Junction-Tabelle
for tag_id in [1, 2, 3]:
    client.insert({'blog_posts_id': post_id, 'blog_tags_id': tag_id}, collection='Blog_Posts_Tags')

5. Übersetzungs-Sammlungen benötigen einen zweistufigen Einfügevorgang

Pro unserem Schema-Design: Erstellen Sie zuerst den Eltern-Blog_Posts-Record, dann den Kind-Blog_Posts_Translations-Record mit dem Fremdschlüssel:

## Schritt 1: Eltern (nur Metadaten)
post = client.insert({
    'status': 'published',
    'author': author_id,
    'category': category_id,
    'reading_time_minutes': 8
}, collection='Blog_Posts')

post_id = post['id']

## Schritt 2: Übersetzung (tatsächlicher Inhalt)
client.insert({
    'blog_posts_id': post_id,
    'languages_code': 'en',
    'title': 'Mein Beitrag',
    'slug': 'mein-beitrag',
    'content': '# Hallo Welt...',
    ...
}, collection='Blog_Posts_Translations')

6. Der POST-Trunkierungsfehler und die PATCH-Fix

Wir haben herausgefunden, dass große content-Feld-POSTs (>~1500 Zeichen) durch eine Gateway/Proxy-Ebene stillschweigend getrunkiert werden. Die REST-Antwort gibt Erfolg zurück, aber nur die ersten ~1,5 KB Ihres Markdowns werden gespeichert.

Abhilfe: Erstellen Sie den Übersetzungs-Record mit anfänglichen Daten, dann patchen Sie das content-Feld:

## Schritt A: Erstellen (Trunkierungsrisiko)
trans = client.insert({ ... anfängliche Felder ..., 'content': 'kurzer Platzhalter' }, collection='Blog_Posts_Translations')
trans_id = trans['id']

## Schritt B: PATCHEN des vollständigen Inhalts (umgeht Trunkierung)
client.update(trans_id, {'content': vollständiger_markdown_inhalt}, collection='Blog_Posts_Translations')

7. Überprüfen Sie Schreibzugriff vor der Veröffentlichung

Bevor Sie einen kritischen Schreibvorgang (Veröffentlichen, Massenaktualisierung) ausführen, führen Sie einen leichten Test durch:

## Senden Sie einen minimalen Test-Record
test = {'status': 'draft', 'author': 1, 'category': 33}
test_record = client.insert(test, collection='Blog_Posts')
test_id = test_record['id']

## Wenn erfolgreich, löschen Sie es
client.delete(test_id, hard=True, collection='Blog_Posts')
print('✅ Schreibzugriff bestätigt')

Wenn dies fehlschlägt mit 403/404, hat Ihr Token keine Schreibberechtigungen - kein Punkt, den vollen Vorgang zu versuchen.


Fehlerbehandlung: Was schiefgeht und wie Sie es beheben

Hier ist die Fehler-Tabelle aus der Produktion:

SymptomUrsacheAbhilfe
DirectusError: 403 Forbidden auf create_collectionFehlendes schema oder meta in Feld-PayloadFügen Sie beides zu jedem Felddefinition hinzu
DirectusError: 400 GraphQL-Validierungsfehler auf get()Verwenden von Beziehungs-Feld ohne Unterfeld-AuswahlVerwenden Sie get_expanded() mit Punktnotation oder schließen Sie verschachtelte geschweifte Klammern in die Feldliste ein
TypeError: id muss Ganzzahl sein, erhielt StringÜbergeben von GraphQL-ID-String als Fremdschlüssel-WertWandeln Sie mit int(record['id']) um, bevor Sie es als Fremdschlüssel verwenden
Stilles Inhaltstrunkieren nach EinfügenGateway-POST-Größebegrenzung (~1,5 KB)Verwenden Sie das POST-then-PATCH-Muster, um Trunkierung zu umgehen
create_field() korruptiert GraphQL-SchemaInkrementelle Feldhinzufügungen brechen das SchemaDefinieren Sie alle Felder im Voraus in create_collection()
get_collection_schema() gibt leer oder unerwartet zurückFeldname unterscheidet sich von Annahme (z. B. cta_button vs cta_button_text)Holen Sie sich immer den /fields/{collection}-Endpunkt, um die genaue Feldliste zu erhalten
Leere Antwort löst JSONDecodeError ausDELETE-Endpunkte geben 204 No Content zurückSchützen: data = json.loads(raw) if raw.strip() else {}

Der Skill behandelt die meisten davon bereits intern (v1.4.1+), aber es ist gut, die Muster zu kennen.


Erweiterte Muster: Filter, Beziehungen und Enum-Felder

Filtern mit Operatoren

Der Skill unterstützt alle Directus-Filteroperatoren:

## Gleich
ergebnisse = client.get(
    fields=['id', 'title', 'status'],
    filters={'status': {'_eq': 'published'}},
    collection='Blog_Posts',
    limit=10
)

## Ungleich
entwürfe = client.get(filters={'status': {'_neq': 'published'}}, collection='Blog_Posts')

## Enthält (case-insensitive)
suche = client.get(
    filters={'title': {'_icontains': 'sicherheit'}},
    collection='Blog_Posts'
)

## In Liste
ergebnisse = client.get(
    filters={'category': {'_in': [33, 37, 42]}},
    collection='Blog_Posts'
)

## Größer als
teuer = client.get(
    filters={'price_cents': {'_gt': 10000}},
    collection='Products'
)

## Null-Prüfung
nicht_kontaktiert = client.get(
    filters={'last_contacted_at': {'_null': True}},
    collection='Contacts'
)

## Kombiniert (ANDed zusammen)
ergebnisse = client.get(
    filters={
        'status': {'_eq': 'published'},
        'category': {'_in': [33, 37]},
        'published_at': {'_not_null': True}
    },
    collection='Blog_Posts'
)

Mehrstufige Beziehungs-Erweiterung

Mit Punktnotation können Sie verschachtelte Beziehungen in einem Aufruf abrufen:

## Abrufen von Beiträgen mit Autor, Kategorie und Tags
records = client.get_expanded(
    fields=[
        'id', 'title', 'status',
        'author.id', 'author.name', 'author.email',  # Viele-zu-Eins-Beziehung
        'category.id', 'category.name',               # Viele-zu-Eins-Beziehung
        'tags.id', 'tags.name', 'tags.slug'           # Viele-zu-Viele über Junction
    ],
    collection='Blog_Posts',
    limit=20
)
## Ergebnis: Jeder Record hat verschachtelte Dictionaries wie {'author': {'id': 1, 'name': 'Alex'}, 'tags': [{'id': 5, 'name': 'KI'}, ...]}

JSON-Felder für flexible Daten

Verwenden Sie den json-Typ für beliebige strukturierte Daten:

client.insert({
    'shipping_address': {
        'straße': '123 Tech Blvd',
        'stadt': 'Dubai',
        'land': 'VAE',
        'postleitzahl': '00000'
    },
    'metadata': {
        'utm_source': 'newsletter',
        'campaign_id': 'Q2-2026-ki-launch'
    }
}, collection='Orders')

Das JSON wird native gespeichert und ist abfragbar mit Filtern auf verschachtelten Schlüsseln.


Die Admin-API: Wenn Sie das Schema programmatisch ändern müssen

Der Skill expose create_collection() und create_field() über die Directus Admin-REST-API (/collections und /fields/{collection}), nicht GraphQL.

Admin-Token erforderlich. Ihr DIRECTUS_API_TOKEN ist für CRUD; DIRECTUS_ADMIN_TOKEN ist für Schema-Operationen.

client = DirectusClient(
    url=os.getenv('DIRECTUS_URL'),
    token=os.getenv('DIRECTUS_API_TOKEN'),         # für CRUD
    admin_token=os.getenv('DIRECTUS_ADMIN_TOKEN') # für Schema
)

## Erstellen einer neuen Sammlung
client.create_collection('TEST_Items', fields=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'field': 'name', 'type': 'string', 'schema': {}, 'meta': {'interface': 'input'}},
    {'field': 'value', 'type': 'integer', 'schema': {}, 'meta': {'interface': 'numeric'}}
])

## Hinzufügen eines Felds zu einer bestehenden Sammlung (mit Vorsicht - kann GraphQL-Schema korrupt machen)
client.create_field('TEST_Items', 'description', 'text', meta={'interface': 'textarea'})

## Auflisten aller Sammlungen
sammlungen = client.get_collections()
print(sammlungen)  # ['Blog_Posts', 'Blog_Authors', ...]

## Abrufen des Sammlungsschemas
schema = client.get_collection_schema('Blog_Posts')
print(schema['fields'].keys())  # dict_keys(['id', 'status', 'author', ...])

Warnung: Inkrementelles Hinzufügen von Feldern über create_field() kann das GraphQL-Schema für diese Sammlung korrupt machen, was dazu führt, dass alle nachfolgenden GraphQL-Abfragen mit 400 fehlschlagen. Das sicherste Muster: Definieren Sie alle Felder im Voraus in create_collection().


Alles zusammen: Ihre erste Vibe-Code-Sitzung

Hier ist, wie ein vollständiger Workflow aussieht:

## 1. Starten Sie Ihr Terminal (mit Directus-Tokens in der Umgebung)
$ export DIRECTUS_URL="https://hub.aratech.ae"
$ export DIRECTUS_API_TOKEN="sZk-st..."      # Benutzer-Token
$ export DIRECTUS_ADMIN_TOKEN="ad-..."        # Admin-Token

## 2. Starten Sie den Hermes-Agenten
$ hermes

## 3. Geben Sie den Prompt (Kopieren und Einfügen von oben)
Sie: Bauen Sie mir ein Blog-Backend mit Directus. Erstellen Sie diese Sammlungen: ...

## 4. Agent denkt nach, generiert Skript, führt aus
🤖 Agent: Erstellen von Blog_Authors... ✅
   Erstellen von Blog_Categories... ✅
   Erstellen von Blog_Tags... ✅
   Erstellen von Blog_Posts... ✅
   Erstellen von Blog_Posts_Translations... ✅
   Erstellen von Blog_Posts_Tags... ✅
   Anlegen von 2 Beispiel-Beiträgen... ✅
   
   Überprüfung:
   - Blog_Posts: 2 Records
   - Blog_Posts_Translations: 2 Records (en nur)
   - Blog_Authors: 1 Record
   - Blog_Categories: 1 Record
   - Blog_Tags: 0 Records
   
   ✅ Backend aufgebaut! Ihre Directus-Admin-Oberfläche bei https://hub.aratech.ae/admin zeigt jetzt alle Sammlungen mit Inhalt.

## 5. Sie sind fertig. Überprüfen Sie die Admin-Oberfläche oder fragen Sie:
$ python3 -c "from directus.client import DirectusClient; c = DirectusClient(); print(c.get(collection='Blog_Posts', limit=3))"

Das ist es. Von leerer Directus-Instanz zu einem vollständigen Blog-Backend mit Beziehungen und Beispiel-Daten in unter einer Minute.


Was dies ermöglicht: Schnelles Prototyping im großen Maßstab

Dies ist nicht nur darum, Zeit bei der Schemadefinition zu sparen (obwohl das huge ist). Es geht darum, den Feedback-Loop zwischen Idee und funktionierendem Prototyp zu reduzieren:

  • Wochenlange Schemadefinition → 5 Minuten, um zu beschreiben, was Sie wollen
  • Manuelle Migrationen → Ein generiertes, ausgeführtes Skript
  • API-Spezifikationen → Directus generiert automatisch REST- und GraphQL-Endpunkte
  • Admin-Oberflächen-Konfiguration → Directus-Admin-Oberfläche ist sofort verfügbar mit Ihren Sammlungen, Feldern und Berechtigungen

Sie können jetzt ein projektspezifisches Backend für:

  • Interne Tools (Inventar, Ticketing, Asset-Verfolgung)
  • Kundenportale (Bestellverlauf, Support-Tickets)
  • SaaS-Datenmodelle (Abonnements, Mandanten, Nutzungsprotokolle)
  • MVPs für Kundenarbeit (beschreiben Sie das Domänenmodell, erhalten Sie ein instantes CMS-gestütz

Inhaltsverzeichnis

  • ↗Table of Contents
  • ↗Einleitung: Das Backend ist jetzt ein Gespräch
  • ↗Was ist dieser "Directus-Skill" eigentlich?
  • ↗Voraussetzungen: Was Sie benötigen, bevor Sie beginnen
  • ↗Option B: Klonen und direkt verwenden (aktuell)
  • ↗Kopieren Sie das Paket in Ihr Projekt oder fügen Sie es zu sys.path hinzu
  • ↗Installation des Skills in Hermes Agent
  • ↗Anatomie einer einzelnen Prompt-Backend-Spezifikation
  • ↗Beispiel 1: Blog-Backend (Multilingual-Ready)
  • ↗Was dies tut
  • ↗Das generierte Code (Was unter der Haube läuft)
  • ↗1. Blog_Authors
  • ↗2. Blog_Categories
  • ↗3. Blog_Tags
  • ↗4. Blog_Posts - Eltern-Records (Metadaten nur, pro unserem Schema-Design)
  • ↗5. Blog_Posts_Translations - pro-Sprach-Inhalt (Kind-Records)
  • ↗6. Blog_Posts_Tags - Junction-Tabelle
  • ↗Legen Sie Beispiel-Daten an
  • ↗1. Erstellen Sie einen Autor (wenn nicht vorhanden)
  • ↗2. Erstellen Sie eine Kategorie
  • ↗3. Erstellen Sie den Eltern-Blog-Beitrag-Record
  • ↗4. Erstellen Sie die englische Übersetzung
  • ↗Beispiel 2: E-Commerce-Backend in einem Prompt
  • ↗Beispiel 3: Einfaches CRM (Kontakte + Unternehmen + Interaktionen)
  • ↗Wie es eigentlich funktioniert: Der Skills geheime Sauce
  • ↗Schritt 1 - Agent parse Ihr Prompt
  • ↗Schritt 2 - Skill generiert korrekte Payloads
  • ↗Schritt 3 - Admin-API-Aufrufe in Reihenfolge
  • ↗Schritt 4 - Beispiel-Daten + Überprüfung
  • ↗Produktionsbewährte Muster, die wir entdeckt haben
  • ↗1. Schema und Meta sind obligatorisch
  • ↗2. Verwenden Sie get_expanded() für Beziehungen
  • ↗Gibt Dictionaries zurück: blog_posts_id = {'id': '5', 'status': 'published'}
  • ↗3. IDs sind Strings in GraphQL, Ganzzahlen in REST
  • ↗4. Junction-Tabelle-Schreibvorgänge gehen über die Junction-Sammlung
  • ↗FALSCH: Direktes PATCHEN auf Blog_Posts schlägt fehl
  • ↗RICHTIG: Einfügen in die Junction-Tabelle
  • ↗5. Übersetzungs-Sammlungen benötigen einen zweistufigen Einfügevorgang
  • ↗Schritt 1: Eltern (nur Metadaten)
  • ↗Schritt 2: Übersetzung (tatsächlicher Inhalt)
  • ↗6. Der POST-Trunkierungsfehler und die PATCH-Fix
  • ↗Schritt A: Erstellen (Trunkierungsrisiko)
  • ↗Schritt B: PATCHEN des vollständigen Inhalts (umgeht Trunkierung)
  • ↗7. Überprüfen Sie Schreibzugriff vor der Veröffentlichung
  • ↗Senden Sie einen minimalen Test-Record
  • ↗Wenn erfolgreich, löschen Sie es
  • ↗Fehlerbehandlung: Was schiefgeht und wie Sie es beheben
  • ↗Erweiterte Muster: Filter, Beziehungen und Enum-Felder
  • ↗Filtern mit Operatoren
  • ↗Gleich
  • ↗Ungleich
  • ↗Enthält (case-insensitive)
  • ↗In Liste
  • ↗Größer als
  • ↗Null-Prüfung
  • ↗Kombiniert (ANDed zusammen)
  • ↗Mehrstufige Beziehungs-Erweiterung
  • ↗Abrufen von Beiträgen mit Autor, Kategorie und Tags
  • ↗Ergebnis: Jeder Record hat verschachtelte Dictionaries wie {'author': {'id': 1, 'name': 'Alex'}, 'tags': [{'id': 5, 'name': 'KI'}, ...]}
  • ↗JSON-Felder für flexible Daten
  • ↗Die Admin-API: Wenn Sie das Schema programmatisch ändern müssen
  • ↗Erstellen einer neuen Sammlung
  • ↗Hinzufügen eines Felds zu einer bestehenden Sammlung (mit Vorsicht - kann GraphQL-Schema korrupt machen)
  • ↗Auflisten aller Sammlungen
  • ↗Abrufen des Sammlungsschemas
  • ↗Alles zusammen: Ihre erste Vibe-Code-Sitzung
  • ↗1. Starten Sie Ihr Terminal (mit Directus-Tokens in der Umgebung)
  • ↗2. Starten Sie den Hermes-Agenten
  • ↗3. Geben Sie den Prompt (Kopieren und Einfügen von oben)
  • ↗4. Agent denkt nach, generiert Skript, führt aus
  • ↗5. Sie sind fertig. Überprüfen Sie die Admin-Oberfläche oder fragen Sie:
  • ↗Was dies ermöglicht: Schnelles Prototyping im großen Maßstab

Ähnliche Beiträge

DeepSeek V4 Flash: Das 284B-Parameter-Modell, das auf einem Laptop läuft

DeepSeek V4 Flash: Das 284B-Parameter-Modell, das auf einem Laptop läuft

Salvatore Sanfilippo (Erfinder von Redis) hat ds4 entwickelt — eine Inferenz-Engine, die DeepSeek V4 Flash (284B Parameter, 13B aktiv) auf einem MacBook mit 128 GB RAM ausführt. Benutzerdefinierte 2-Bit-Quantisierung, 1M-Token-Kontext, null Kosten pro Token.

Necolas HamwiNecolas Hamwi
27. Juni 2026 - 8 Min. Lesezeit
Ornith 1.0 — Selbstgerüstendes KI-Coding-Modell von DeepReinforce. YouTube-Video-Miniaturansicht mit Sam Witteveen.

Ornith 1.0: Das Open-Source-KI-Coding-Modell, das seine eigenen RL-Gerüste schreibt

DeepReinforce hat Ornith 1.0 veröffentlicht, ein Open-Source-KI-Modell, das selbstgerüstende LLMs für agentisches Coding einführt — Modelle, die lernen, ihre eigenen RL-Tools zu schreiben. Mit der 397B MoE-Variante, die Claude Opus 4.7 bei SWE-Bench einholt, und einer 9B-Version, die Modelle übertrifft, die dreimal so groß sind, ist dies ein Paradigmenwechsel für die Open-Source-KI-Entwicklung.

Necolas HamwiNecolas Hamwi
26. Juni 2026 - 12 Min. Lesezeit
Futuristische Roboterhand, die ein digitales Netzwerk berührt, das Multi-Agent-KI-Systeme darstellt

Multi-Agent-Systeme: Der KI-Trend, der Unternehmensabläufe 2026 neu definiert

Gartner hat Multi-Agent-Systeme als einen der wichtigsten strategischen Trends für 2026 bezeichnet. Mit 327% Wachstum bei der Unternehmenseinführung und der Prognose, dass bis 2028 15% der täglichen Entscheidungen autonom getroffen werden, erfahren Sie hier, was CTOs wissen müssen.

Necolas HamwiNecolas Hamwi
22. Juni 2026 - 8 Min. Lesezeit