• 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
Inicio / Blog / Vibe-Coding un backend en 2026: cómo Directus y la habilidad nikola66 convierten el lenguaje natural en esquemas de producción

Vibe-Coding un backend en 2026: cómo Directus y la habilidad nikola66 convierten el lenguaje natural en esquemas de producción

¿Qué pasaría si pudiera crear un backend completo, completo con colecciones, relaciones y datos, con un solo mensaje? Así es como Directus y la

3 de mayo de 2026 - 25 min de lectura

Puntos clave

ExpandCollapse
  • - La habilidad Directus es un cliente GraphQL universal e independiente de la colección que permite a los agentes de IA crear y administrar cualquier esquema de Directus sin modelos codificados.
  • - Codificar un backend con Vibe significa describir su modelo de datos completo en lenguaje natural y luego dejar que el agente lo diseñe todo en una sola ejecución: colecciones, campos, relaciones e incluso datos iniciales.
  • - Los patrones de producción incluyen definiciones de campos de todo lo que necesita en una sola llamada, requisitos de token de administrador y el patrón de creación de publicaciones de blog de dos pasos (registros principales y luego de traducción).
Vibe codifica un backend completo con Directus

Table of Contents

  • Introducción: el backend es ahora una conversación
  • ¿Qué es esta "habilidad Directus" de todos modos
  • Requisitos previos: lo que necesita antes de comenzar
  • Instalación de la habilidad en Hermes Agent
  • Anatomía de una especificación de backend de un solo mensaje
  • Ejemplo 1: Backend de blog (preparado para varios idiomas)
    • ¿Qué hace esto
    • El código generado (lo que se ejecuta bajo el capó)
  • Ejemplo 2: backend de comercio electrónico en un solo mensaje
  • Ejemplo 3: CRM simple (Contactos + Empresas + Interacciones)
  • Cómo funciona realmente: la salsa secreta de la habilidad
    • Paso 1: el agente analiza su mensaje
    • Paso 2: la habilidad genera cargas útiles correctas
    • Paso 3: llamadas a la API de administrador en orden
    • Paso 4 - Datos de semillas + Verificación
  • Patrones probados en producción que hemos descubierto
    • 1. El esquema y el meta son obligatorios
    • 2. Utilice get_expanded() para relaciones
    • 3. Los ID son cadenas en GraphQL, enteros en REST
    • 4. Las escrituras de la tabla de conexiones revisan la colección de conexiones
    • 5. Las colecciones de traducción necesitan inserciones de dos pasos
    • 6. El error de truncamiento POST y la solución PATCH
    • 7. Verifique el acceso de escritura antes de publicar
  • Manejo de errores: qué sale mal y cómo solucionarlo
  • Patrones avanzados: filtros, relaciones y campos de enumeración
    • Filtrado con operadores
    • Expansión de relaciones multinivel
    • Campos JSON para datos flexibles
  • La API de administración: cuando necesita tocar el esquema mediante programación
  • Poniéndolo todo junto: su primera sesión de Vibe-Code
  • Qué permite esto: creación rápida de prototipos a escala
  • Limitaciones y trampas
    • No todos los patrones de backend se ajustan a Directus
    • Aún necesitas pensar en el modelado de datos
    • Los permisos aún necesitan configuración
    • El contenido grande requiere parches
  • Conclusión: el backend es ahora una conversación
  • Próximos pasos

Introducción: el backend es ahora una conversación

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

Aquí hay un patrón frustrante que la mayoría de los desarrolladores conocen bien:

  1. Tienes una idea brillante para una aplicación.
  2. Comienzas a crear andamios en la base de datos: usuarios, publicaciones, órdenes
  3. Usted construye la capa API: puntos finales REST, solucionadores GraphQL
  4. Conectas autenticación, permisos y validación.
  5. Tres días después, finalmente llegas a la función real que querías crear

Esa fricción es real. Y en 2026, estará muerto.

¿Qué pasaría si pudieras omitir los pasos 2 a 4 por completo? ¿Qué pasaría si pudiera describir todo su backend en inglés sencillo, presionar Intro y tener un esquema, una API y un panel de administración listos para producción?

Eso es lo que significa codificar un backend por vibración. Y con Directus, el CMS headless de código abierto que convierte su base de datos en una API instantánea, junto con la nikola66 Directus skills (un cliente GraphQL universal para agentes de IA), ahora es posible crear una capa de datos completa de una sola vez.

Esta no es una demostración de juguete. Este es un flujo de trabajo real que estamos utilizando en Ainex para poner en marcha los backends del proyecto en minutos, no en días. En esta guía, aprenderá:

  • Qué hace realmente la habilidad Directus bajo el capó
  • Cómo instalarlo y conectarse a su instancia de Directus
  • La anatomía de una especificación de backend de un solo mensaje
  • Ejemplos paso a paso: creación de un blog, una tienda de comercio electrónico y un CRM
  • Patrones de producción, manejo de errores y trampas que ya hemos encontrado en la naturaleza.
  • Cómo verificar que su backend recientemente estructurado esté activo y sea consultable

Entremos en ello.


¿Qué es esta "habilidad Directus" de todos modos?

La habilidad en nikola66/directus-skill es un cliente Python que habla directamente las API GraphQL y REST de Directus. Está diseñado para agentes de IA como Hermes, pero también puedes usarlo como una biblioteca independiente.

Propiedades clave que hacen posible la codificación por vibración:

  • Independiente de la colección: No importa si estás trabajando con Blog_Posts o Ecom_Products. Los mismos métodos funcionan en cualquier colección.
  • Superficie CRUD completa: get, insert, update, delete, count e incluso create_collection y create_field para operaciones de esquema (solo administrador).
  • Expansión de relación inteligente: utilice notación de puntos como autor.nombre o order_items.product.title y la habilidad creará los conjuntos de selección GraphQL anidados correctos.
  • Operadores de filtro: todos los filtros Directus compatibles: _eq, _contains, _in, _gt, _null, etc.
  • Manejo de errores: Genera DirectusError con detalles estructurados para que sepas exactamente por qué algo falló.

Cuando carga esta habilidad en un agente de IA, le brinda a ese agente la capacidad de iniciar un esquema de base de datos completo a través de una conversación.


Requisitos previos: lo que necesita antes de comenzar

Antes de poder codificar un backend, necesitas tres cosas:

  1. Una instancia de Directus: ya sea autohospedada o Directus Cloud. Corremos en https://hub.aratech.ae.
  2. Un token API con los permisos adecuados. Para la creación de esquemas, necesitará un token de administrador. Consíguelo en Directus → Configuración → Tokens API → Crear (ámbito de administrador, todos los permisos).
  3. Python 3.9+ con la habilidad instalada:
# Opción A: Instalar desde PyPI (cuando se publique)
pip instalar directus-habilidad

## Opción B: Clonar y usar directamente (actual)
clon de git https://github.com/nikola66/directus-skill.git
## Copie el paquete en su proyecto o agréguelo a sys.path

A partir de abril de 2026, la habilidad se mantiene activamente y se valida en producción frente a una instancia de Directus 10+ con CRUD completo, operadores de filtro y gestión de colecciones funcionando de manera confiable.


Instalación de la habilidad en Hermes Agent

Si está ejecutando Hermes Agent (nuestra plataforma de orquestación de múltiples agentes), agregar la habilidad es un solo comando:

habilidades de hermes instalar directo

O para agregar la versión ascendente de GitHub directamente:

Las habilidades de npx agregan nikola66/directus-skill

Una vez instalada, la habilidad directus se carga automáticamente cuando preguntas sobre las operaciones de Directus. No es necesario importar nada manualmente: el agente se encarga de eso.

Configure sus variables de entorno (las mantenemos en ~/.bashrc o la sesión de puerta de enlace):

exportar DIRECTUS_URL="https://hub.aratech.ae"
exportar DIRECTUS_API_TOKEN="user_token_here" # operaciones CRUD
export DIRECTUS_ADMIN_TOKEN="admin_token_here" # Gestión de esquemas

Nota: En la puerta de enlace de Hermes, estos se inyectan automáticamente desde la configuración de la puerta de enlace. Si está ejecutando secuencias de comandos independientes, configúrelas usted mismo.


Anatomía de una especificación de backend de un solo mensaje

La magia ocurre cuando describe todo su modelo de datos en un mensaje de lenguaje natural. Aquí está el patrón:

Constrúyeme un backend [TIPO] con Directus. Crea estas colecciones:

1. [Nombre de la colección] - [propósito]
   - nombre_campo (tipo), campo2 (tipo), ...
   - relaciones: [detalles de la relación]

2. [Nombre de la colección] - ...
   ...

Después de crear todas las colecciones:
- Verifique llamando a get_collections() e imprimiendo la lista
- Semillas [N] registros de muestra para cada colección
- Generar el script Python completo

El agente interpreta esto, lo traduce en llamadas a la API de administración de Directus ("POST /collections" con definiciones de campo completas), lo ejecuta y devuelve un esquema de trabajo.

La habilidad hace el trabajo pesado:

  1. Crea la estructura de carga útil correcta para los peculiares requisitos de "esquema" y "meta" de Directus.
  2. Llama a create_collection() por colección con la lista de campos completa
  3. Opcionalmente, genera datos de muestra mediante operaciones CRUD.
  4. Verifica el éxito con get_collections()

Ejecución todo en uno, sin intervención manual.


Ejemplo 1: Backend de blog (preparado para varios idiomas)

Comencemos con un clásico: un blog compatible con 5 idiomas. Aquí está el mensaje completo que le daría al agente:

Constrúyeme un backend de blog multilingüe con Directus. Crea estas colecciones:

1. Blog_Authors - perfiles de autor
   - nombre (cadena), slug (cadena, único), biografía (texto), avatar (archivo), social_twitter (cadena, anulable)
   - estado: borrador/publicado
   - Campos: id, creado_at, actualizado_at

2. Blog_Categories: taxonomía jerárquica
   - nombre (cadena), slug (cadena, único), descripción (texto), parent_category (varios a uno → Blog_Categories, anulable)
   - icono (cadena, nombre del icono), color (cadena, hexadecimal)
   - Campos: id, sort_order

3. Blog_Tags: etiquetas planas
   - nombre (cadena), slug (cadena, único), color (cadena, hexadecimal)
   - Campos: identificación

4. Blog_Posts: registros principales (solo metadatos, según nuestro diseño de esquema)
   - estado (borrador/publicado), publicado_en (fecha y hora, anulable)
   - autor (varios a uno → Blog_Authors), categoría (varios a uno → Blog_Categories)
   - imagen_presentada (archivo), minutos_tiempo_lectura (entero)
   - is_featured (booleano), is_pillar (booleano)
   - Campos: id, creado_at, actualizado_at

5. Blog_Posts_Translations: contenido por idioma (registros secundarios)
   - blog_posts_id (entero FK → Blog_Posts), idiomas_code (cadena: en/ar/de/es/fr)
   - título (cadena), slug (cadena), contenido (texto de rebajas)
   - extracto (texto, máximo 200 caracteres), key_takeaways (matriz json, 3-5 elementos)
   - meta_title (cadena, ≤60), meta_description (cadena, ≤160)
   -feature_image_alt (cadena)
   - cta_headline (cadena), cta_button_text (cadena), cta_button_url (cadena)
   - esquema_markup (json - Artículo esquema.org)
   - Campos: identificación

6. Blog_Posts_Tags: unión para publicaciones de muchos a muchos ↔ etiqueta
   - blog_posts_id (FK → Blog_Posts), blog_tags_id (FK → Blog_Tags)
   - Campos: identificación

Importante:
- Utilice create_collection() para las 6 colecciones.
- Cada campo debe incluir esquema: {} y meta: {} en la carga útil
- Defina TODOS los campos por adelantado (no se agregan campos incrementales)
- Después de crear colecciones, genere un mínimo de 2 publicaciones de blog de muestra:
  * Publicación 1: "Introducción a la seguridad de la IA" - autor=1, categoría=33 (IA y LLM), publicada
  * Publicación 2: "Comprensión del cumplimiento de SOC 2" - autor=1, categoría=37 (Cumplimiento), borrador
  * Para cada publicación, cree solo traducción EN (omita AR/DE/ES/FR por ahora)
- Verificación de impresión: enumera todas las colecciones y sus recuentos de registros

¿Qué hace esto?

Cuando ejecuta este mensaje a través de un agente con la habilidad Directus cargada:

  1. Crea 6 colecciones con definiciones de campo completas en el orden correcto (principalmente padres, luego uniones, luego traducciones)
  2. Agrega relaciones adecuadas - Muchos a uno desde Publicaciones → Autores/Categoría, Muchos a muchos a través de una tabla de unión
  3. Respeta el diseño de su esquema real - Los registros de traducción son una colección secundaria separada vinculada por blog_posts_id
  4. Semillas de datos reales: dos publicaciones de muestra con los campos obligatorios completados
  5. Verifica - Imprime lo que se creó

El código generado (lo que se ejecuta bajo el capó)

El agente produce algo como este script de Python:

desde directus.client importar DirectusClient
importar sistema operativo

cliente = DirectusCliente(
    url=os.getenv('DIRECTUS_URL'),
    token=os.getenv('DIRECTUS_ADMIN_TOKEN') # token de administrador para operaciones de esquema
)

## 1. Blog_Autores
client.create_collection('Blog_Authors', campos=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'campo': 'nombre', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'entrada'}},
    {'field': 'slug', 'type': 'string', 'schema': {'is_unique': True}, 'meta': {'interface': 'input'}},
    {'campo': 'bio', 'tipo': 'texto', 'esquema': {}, 'meta': {'interfaz': 'textarea'}},
    {'campo': 'avatar', 'tipo': 'archivo', 'esquema': {}, 'meta': {'interfaz': 'archivo', 'opciones': {'accepted_files': 'image/*'}}},
    {'campo': 'social_twitter', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'entrada'}},
    {'campo': 'estado', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'seleccionar', 'opciones': {'opciones': ['borrador', 'publicado']}}},
    {'field': 'created_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}},
    {'campo': 'updated_at', 'tipo': 'marca de tiempo', 'esquema': {}, 'meta': {'interfaz': 'fecha y hora', 'solo lectura': Verdadero}}
])

## 2. Blog_Categorías
client.create_collection('Categorías_Blog', campos=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'campo': 'nombre', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'entrada'}},
    {'field': 'slug', 'type': 'string', 'schema': {'is_unique': True}, 'meta': {'interface': 'input'}},
    {'campo': 'descripción', 'tipo': 'texto', 'esquema': {}, 'meta': {'interfaz': 'textarea'}},
    {'field': 'parent_category', 'type': 'integer', 'schema': {}, 'meta': {'interface': 'relation', 'options': {' related_collection': 'Blog_Categories'}}},
    {'campo': 'icono', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'entrada'}},
    {'campo': 'color', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'color'}},
    {'field': 'sort_order', 'type': 'integer', 'schema': {}, 'meta': {'interface': 'numeric'}},
    {'field': 'created_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}},
    {'campo': 'updated_at', 'tipo': 'marca de tiempo', 'esquema': {}, 'meta': {'interfaz': 'fecha y hora', 'solo lectura': Verdadero}}
])

## 3. Etiquetas de blog
client.create_collection('Blog_Tags', campos=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'campo': 'nombre', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'entrada'}},
    {'field': 'slug', 'type': 'string', 'schema': {'is_unique': True}, 'meta': {'interface': 'input'}},
    {'campo': 'color', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'color'}},
    {'campo': 'created_at', 'tipo': 'marca de tiempo', 'esquema': {}, 'meta': {'interfaz': 'fecha y hora', 'solo lectura': Verdadero}}
])

## 4. Blog_Posts: registro de metadatos principal
client.create_collection('Blog_Posts', campos=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'campo': 'estado', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'seleccionar', 'opciones': {'opciones': ['borrador', 'publicado']}}},
    {'field': 'published_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': False}},
    {'campo': 'autor', 'tipo': 'entero', 'esquema': {}, 'meta': {'interfaz': 'relación', 'opciones': {' related_collection': 'Blog_Authors'}}},
    {'campo': 'categoría', 'tipo': 'entero', 'esquema': {}, 'meta': {'interfaz': 'relación', 'opciones': {' related_collection': 'Blog_Categories'}}},
    {'campo': 'featured_image', 'tipo': 'archivo', 'esquema': {}, 'meta': {'interfaz': 'archivo', 'opciones': {'accepted_files': 'imagen/*'}}},
    {'campo': 'reading_time_ Minutes', 'tipo': 'entero', 'esquema': {}, 'meta': {'interfaz': 'numérico'}},
    {'campo': 'is_featured', 'tipo': 'booleano', 'esquema': {}, 'meta': {'interfaz': 'booleano'}},
    {'campo': 'is_pillar', 'tipo': 'booleano', 'esquema': {}, 'meta': {'interfaz': 'booleano'}},
    {'field': 'created_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}},
    {'campo': 'updated_at', 'tipo': 'marca de tiempo', 'esquema': {}, 'meta': {'interfaz': 'fecha y hora', 'solo lectura': Verdadero}}
])

## 5. Blog_Posts_Translations: contenido por idioma
client.create_collection('Blog_Posts_Translations', campos=[
    {'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']}}},
    {'campo': 'título', 'tipo': 'cadena', 'esquema': {'is_required': Verdadero}, 'meta': {'interfaz': 'entrada'}},
    {'field': 'slug', 'type': 'string', 'schema': {'is_required': True, 'is_unique': True}, 'meta': {'interface': 'input'}},
    {'campo': 'contenido', 'tipo': 'texto', 'esquema': {}, 'meta': {'interfaz': 'markdown'}},
    {'campo': 'extracto', 'tipo': 'texto', 'esquema': {}, 'meta': {'interfaz': 'textarea'}},
    {'campo': 'key_takeaways', 'tipo': 'json', 'esquema': {}, 'meta': {'interfaz': 'lista'}},
    {'campo': 'meta_title', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'entrada'}},
    {'campo': 'meta_descripción', 'tipo': 'texto', 'esquema': {}, 'meta': {'interfaz': 'textarea'}},
    {'campo': 'featured_image_alt', 'tipo': 'texto', 'esquema': {}, 'meta': {'interfaz': 'textarea'}},
    {'campo': 'cta_headline', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'entrada'}},
    {'campo': 'cta_button_text', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'entrada'}},
    {'campo': 'cta_button_url', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'entrada'}},
    {'campo': 'schema_markup', 'tipo': 'json', 'esquema': {}, 'meta': {'interfaz': 'json'}},
    {'field': 'created_at', 'type': 'timestamp', 'schema': {}, 'meta': {'interface': 'datetime', 'readonly': True}},
    {'campo': 'updated_at', 'tipo': 'marca de tiempo', 'esquema': {}, 'meta': {'interfaz': 'fecha y hora', 'solo lectura': Verdadero}}
])

## 6. Blog_Posts_Tags - tabla de unión
client.create_collection('Blog_Posts_Tags', campos=[
    {'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'}}},
    {'campo': 'created_at', 'tipo': 'marca de tiempo', 'esquema': {}, 'meta': {'interfaz': 'fecha y hora', 'solo lectura': Verdadero}}
])

## Datos de muestra de semillas
## 1. Crear autor (si no existe)
autor = client.insert({'nombre': 'Alex Chen', 'slug': 'alex-chen', 'bio': 'Ingeniero de seguridad en Ainex.', 'status': 'publicado'}, colección = 'Blog_Authors')
autor_id = autor['id']

## 2. Crear categoría
categoría = client.insert({'nombre': 'AI y LLM', 'slug': 'ai-llms', 'descripción': 'Artículos sobre seguridad de IA y LLM.', 'sort_order': 1}, colección = 'Blog_Categories')
categoría_id = categoría['id']

## 3. Crear un registro de publicación de blog para padres
publicación = cliente.insertar({
    'estado': 'publicado',
    'autor': autor_id,
    'categoría': categoría_id,
    'tiempo_lectura_minutos': 8,
    'is_featured': Falso,
    'publicado_en': '2026-05-03T10:00:00.000Z'
}, colección='Blog_Posts')
post_id = publicación['id']

## 4. Crear traducción al inglés
cliente.insertar({
    'blog_posts_id': post_id,
    'languages_code': 'es',
    'title': 'Introducción a la seguridad de la IA',
    'slug': 'introducción-a-la-seguridad-ai',
    'content': '# Fundamentos de seguridad de IA\n\nEste es un artículo de muestra sobre cómo proteger los sistemas de IA...\n\n## Riesgos clave\n\n- Inyección rápida\n- Fuga de datos\n- Envenenamiento de modelos\n\n## Mejores prácticas\n\nSiempre valide las entradas, la ejecución del modelo de espacio aislado y monitoree las anomalías.',
    'excerpt': 'Una guía para principiantes para comprender y mitigar los riesgos del sistema de IA.',
    'key_takeaways': ['Los sistemas de IA son vulnerables a ataques de inyección rápida', 'Validar y desinfectar siempre las entradas del modelo', 'Monitorear el comportamiento anómalo del modelo'],
    'meta_title': 'Introducción a la Seguridad de la IA - Guía Ainex',
    'meta_description': 'Aprenda los fundamentos de la seguridad de la IA, las amenazas comunes y las mejores prácticas para proteger sus aplicaciones LLM.',
    'featured_image_alt': 'Visualización abstracta de la seguridad de las redes neuronales',
    'cta_headline': '¿Listo para proteger tu IA?',
    'cta_button_text': 'Comenzar',
    'cta_button_url': '/empezar',
    'schema_markup': {
        '@context': 'https://schema.org',
        '@tipo': 'Artículo',
        'headline': 'Introducción a la seguridad de la IA',
        'autor': {'@tipo': 'Persona', 'nombre': 'Alex Chen'},
        'fecha de publicación': '2026-05-03T10:00:00.000Z',
        'description': 'Una guía para principiantes para comprender y mitigar los riesgos del sistema de IA.'
    }
}, colección='Blog_Posts_Translations')

print(f"✅ ¡Blog backend creado! ID de publicación: {post_id}")

Ese script lo genera y ejecuta el agente en un solo turno. Obtiene un esquema completo y consultable y datos inicializados de inmediato.


Ejemplo 2: backend de comercio electrónico en un solo mensaje

Vamos a ser más grandes. Así es como se estructuraría una capa de datos de comercio electrónico completa:

Cree un backend de comercio electrónico de producción con Directus. Crea estas colecciones:

1. **Productos** - artículos del catálogo
   - título, slug (único), descripción (texto), estado (borrador/disponible/agotado)
   - price_cents (entero), compare_price_cents (entero anulable), cost_cents (entero)
   - sku (único), código de barras (anulable), peso_gramos (entero)
   - cantidad_inventario, umbral_bajo_stock (predeterminado 10)
   - feature_image (archivo), imágenes (M2M a través de unión)
   - categoría (M2O → Categorías), etiquetas (M2M → Etiquetas vía cruce)
   - publicado_en

2. **Categorías** - taxonomía anidada
   - nombre, slug (único), descripción, parent_category (m2o anulable)
   - imagen (archivo), sort_order

3. **Etiquetas** - etiquetas de productos
   - nombre, babosa (única), color (hexadecimal)

4. **Clientes** - cuentas
   - correo electrónico (único), nombre, apellido, teléfono
   - dirección_de_envío_predeterminada (json), dirección_de_facturación_predeterminada (json)
   - total_spent_cents, order_count, last_order_at (anulable)
   - estado (activo/bloqueado), notas

5. **Pedidos** - transacciones
   - número de pedido (único), estado (pendiente/procesando/enviado/entregado/cancelado)
   - cliente (M2O → Clientes)
   - subtotal_cents, tax_cents, envío_cents, total_cents, descuento_cents
   - dirección_envío, dirección_facturación (json)
   - estado_pago (pagado/reembolsado/fallido), método_pago (stripe/paypal/manual)
   - Payment_intent_id (anulable), número_seguimiento (anulable)
   - notas, cancelled_at (anulable)

6. **Order_Items** - artículos de línea (tabla de unión Pedidos ↔ Productos)
   - pedido (M2O → Pedidos), producto (M2O → Productos)
   - cantidad, centavos de precio unitario, centavos de precio total
   - nombre_variante (cadena, anulable)

7. **Ajustes_de_inventario** - registro de auditoría
   - producto (M2O → Productos), motivo (reposición/venta/devolución/auditoría/ajuste)
   - cantidad_delta, cantidad_anterior, cantidad_nueva
   - reference_id (anulable - enlaces a pedido/ajuste), notas

8. **Colecciones**: agrupaciones seleccionadas
   - nombre, slug (único), identificador (cadena compatible con API)
   - tipo (manual/automático), reglas (json para reglas automáticas)
   - sort_order, publicado (booleano)

9. **Descuentos** - códigos promocionales
   - código (único, anulable para automático), tipo (porcentaje/fijo)
   - valor (int - porcentaje o centavos), max_uses, used_count
   - valid_from, valid_until (anulable)
   - se aplica_a (todos/categorías/productos), aplicables_producto_ids (matriz json)
   - min_order_amount_cents (anulable), excluir_sale_items (booleano)

Restricciones:
- Utilice create_collection() para las 9 colecciones + tablas de unión explícitas (Products_Images si es necesario)
- Cada campo: incluya esquema: {} y meta: {} al principio
- Utilice los tipos de campo Directus adecuados: entero, cadena, texto, booleano, fecha y hora, json, archivo, pivote
- Agregar índices únicos en slug, sku, número_pedido
- Semilla: cree 3 productos de muestra con imágenes de muestra (use ID de archivo si están disponibles), enlace a la categoría
- Verificar: llame a get_collections() e imprima el recuento de registros
- Generar el script Python completo

Al ejecutar esto a través del agente se produce un script de aproximadamente 300 líneas que crea todo el modelo de datos de comercio electrónico de una sola vez. De cero a "aquí está tu panel de administración" antes de que se enfríe el café.


Ejemplo 3: CRM simple (Contactos + Empresas + Interacciones)

¿Necesitas algo liviano? Aquí hay un CRM:

Cree un backend de CRM con Directus:

1. Empresas
   - nombre, dominio (único), industria, tamaño (1-10/11-50/51-200/200+)
   - sitio web, teléfono, dirección (json), ingresos_anuales_centavos (anulable)
   - propietario (M2O → Usuarios), estado (cliente potencial/cliente/prospecto/desechado)
   - last_contacted_at, notas (texto)

2. Contactos
   - nombre, apellido, correo electrónico (único), teléfono, puesto de trabajo
   - empresa (M2O → Empresas), propietario (M2O → Usuarios)
   - estado (activo/inactivo/cliente potencial), contacto_preferido (correo electrónico/teléfono/linkedin)
   - linkedin_url, notas

3. Interacciones
   - contacto (M2O → Contactos), tipo (llamada/correo electrónico/reunión/nota)
   - dirección (entrante/saliente), duración_minutos (entero)
   - resumen (texto), próximos_pasos (texto), fecha_de_vencimiento (anulable)
   - related_deal (M2O → Ofertas anulables)

4. Ofertas
   - título, valor_centavos, etapa (propuesta/negociación/ganado_cerrado/perdido_cerrado)
   - probabilidad (0-100), fecha_de_cierre (esperada)
   - contacto (M2O → Contactos), propietario (M2O → Usuarios)
   - notas

Restricciones:
- Utilice create_collection() para los 4
- Todos los campos estándar: id, creado_at, actualizado_at agregados automáticamente
- Relaciones configuradas correctamente (los FK son números enteros)
- Semilla: 2 empresas, 4 contactos, 3 interacciones, 1 trato

Nuevamente: un mensaje, una ejecución.


Cómo funciona realmente: la salsa secreta de la habilidad

Desmitifiquemos lo que sucede cuando le pide al agente que "construya un backend":

Paso 1: el agente analiza su mensaje

El agente utiliza su razonamiento para extraer:

  • Nombres de las colecciones y su finalidad.
  • Nombres, tipos y restricciones de campos.
  • Direcciones de relación (varios a uno, muchos a muchos)
  • Requisitos de datos de semillas
  • Pasos de verificación

No necesita ver un lenguaje de definición de esquema; simplemente lee su inglés simple y construye la estructura.

Paso 2: la habilidad genera cargas útiles correctas

Aquí es donde brilla la habilidad. El punto final POST /collections de Directus es notoriamente exigente:

¿Sin esquema: {} y meta: {} por campo? → 403 Prohibido (incluso con un token de administrador válido). ¿Nombre de tipo de campo incorrecto? → La colección no aparece silenciosamente. ¿Faltan metaopciones de relación? → Las relaciones no funcionan.

La habilidad conoce el contrato API de Directus y genera cargas útiles con producción correcta automáticamente. Así es como se ve una definición de campo correcta:

{
    'campo': 'precio_centavos',
    'tipo': 'entero',
    'schema': {'is_required': True}, # ← siempre incluye esto
    'meta': {'interface': 'numeric'} # ← siempre incluye esto
}

Paso 3: llamadas a la API de administrador en orden

Las colecciones se crean en orden de dependencia (padres antes que hijos, sin departamentos circulares). Para cada uno:

  1. POST /collections crea la colección con la lista de campos completa
  2. Skill verifica con GET /collections/{name} que existe
  3. Si ya existe, se elimina y se vuelve a crear (modo idempotente)

Para tablas de unión (M2M), se utilizan el tipo pivote o campos FK explícitos con meta.interface: 'relation'.

Paso 4 - Datos de semillas + Verificación

Una vez que existen todas las colecciones, el agente:

  • Inserta registros de muestra usando CRUD estándar (insert())
  • Consultas nuevamente con get() o get_expanded() para confirmar
  • Imprime un resumen en tu terminal

Patrones probados en producción que hemos descubierto

Hemos ejecutado este flujo de trabajo en https://hub.aratech.ae con nuestro esquema de blog completo. Aquí están las lecciones:

1. El esquema y el meta son obligatorios

Esto no se puede enfatizar lo suficiente. Directus 10+ devuelve 403 cuando falta alguno de ellos, pero el mensaje de error es engañoso ("No tienes permiso") cuando el problema real es la estructura de tu carga útil.

Comprueba siempre:

  • La carga útil de la colección tiene schema: {} y meta: {} en el nivel superior
  • Cada campo tiene tanto "esquema" como "meta"
  • Los valores de campo type son tipos Directus válidos (integer, no int; string, no varchar)

2. Utilice get_expanded() para relaciones

Directus GraphQL requiere conjuntos de selección anidados para campos de relación. Si lo intentas:

{ Blog_Posts_Translations { id blog_posts_id } }

Aparece un error 400: "El campo "blog_posts_id" del tipo "Blog_Posts" debe tener una selección de subcampos.

El método get_expanded() de la habilidad con notación de puntos maneja esto automáticamente:

cliente.get_expanded(
    campos = ['id', 'título', 'blog_posts_id.id', 'blog_posts_id.status'],
    colección = 'Blog_Posts_Translations',
    límite=50
)
## Devuelve dictados: blog_posts_id = {'id': '5', 'status': 'publicado'}

3. Los ID son cadenas en GraphQL, enteros en REST

GraphQL devuelve todos los campos "id" como cadenas. Pero los campos de clave externa (como blog_posts_id) son enteros cuando se usan como filtros o insertan valores.

Cuando creas una publicación y obtienes post_id = "42", debes transmitir:

cliente.insertar({
    'blog_posts_id': int(post_id), # NO post_id
    'languages_code': 'es',
    ...
}, colección='Blog_Posts_Translations')

De lo contrario, obtendrá un error de validación 400 GraphQL.

4. Las escrituras de la tabla de conexiones revisan la colección de conexiones

Directus expone las relaciones M2M como campos virtuales de solo lectura en el padre. No puedes PATCH el campo etiquetas en Blog_Posts directamente; obtienes 403 Prohibido.

En su lugar, escriba en la tabla de unión:

## INCORRECTO: El PATCH directo en Blog_Posts falla
client.update(post_id, {'etiquetas': [1, 2, 3]}, colección='Blog_Posts') # ❌ 403

## CORRECTO: Insertar en la mesa de unión
para tag_id en [1, 2, 3]:
    client.insert({'blog_posts_id': post_id, 'blog_tags_id': tag_id}, colección='Blog_Posts_Tags')

5. Las colecciones de traducción necesitan inserciones de dos pasos

Según nuestro diseño de esquema: primero cree el registro principal Blog_Posts, luego cree el registro secundario Blog_Posts_Translations con el FK:

## Paso 1: padre (solo metadatos)
publicación = cliente.insertar({
    'estado': 'publicado',
    'autor': autor_id,
    'categoría': categoría_id,
    'tiempo_lectura_minutos': 8
}, colección='Blog_Posts')

post_id = publicación['id']

## Paso 2: traducción (contenido real)
cliente.insertar({
    'blog_posts_id': post_id,
    'languages_code': 'es',
    'título': 'Mi publicación',
    'babosa': 'mi-publicación',
    'content': '#Hola mundo...',
    ...
}, colección='Blog_Posts_Translations')

6. El error de truncamiento POST y la solución PATCH

Descubrimos que los POST de campos de "contenido" grandes (>~1500 caracteres) se truncan silenciosamente mediante una capa de puerta de enlace/proxy. La respuesta REST devuelve éxito, pero solo se almacena el primer ~1,5 KB de su descuento.

Mitigación: cree el registro de traducción con datos iniciales, luego PATCH inmediatamente el campo "contenido":

## Paso A: Crear (riesgo de truncamiento)
trans = client.insert({... campos_iniciales..., 'contenido': 'marcador de posición corto' }, colección='Blog_Posts_Translations')
trans_id = trans['id']

## Paso B: PATCH contenido completo (evita el truncamiento)
client.update(trans_id, {'content': full_markdown_body}, colección='Blog_Posts_Translations')

7. Verifique el acceso de escritura antes de publicar

Antes de intentar una escritura crítica (publicación, actualización masiva), realice una prueba ligera:

## Enviar un registro de prueba mínimo
prueba = {'estado': 'borrador', 'autor': 1, 'categoría': 33}
test_record = client.insert (prueba, colección = 'Blog_Posts')
test_id = test_record['id']

## Si tiene éxito, elimínelo
client.delete(test_id, hard=True, colección='Blog_Posts')
print('✅ Acceso de escritura confirmado')

Si esto falla con 403/404, su token no tiene permisos de escritura; no tiene sentido intentar realizar la operación completa.


Manejo de errores: qué sale mal y cómo solucionarlo

Aquí está la tabla de errores de producción:

SíntomaCausaArreglar
DirectusError: 403 Prohibido en create_collectionFalta esquema o meta en la carga útil del campoAgregue ambos a CADA campo definición
DirectusError: error de validación 400 GraphQL en get()Usando campo de relación sin selección de subcampoUtilice get_expanded() con notación de puntos o incluya llaves anidadas en la lista de campos
TypeError: la identificación debe ser int, obtuvo strPasar la cadena de ID de GraphQL como valor FKTransmitir con int(record['id']) antes de usarlo como FK
Truncamiento silencioso del contenido después de la inserciónLímite de tamaño de POST de puerta de enlace (~1,5 KB)PATCH contenido completo después de la creación inicial
create_field() corrompe el esquema GraphQLLas adiciones de campos incrementales rompen el esquemaDefina todos los campos por adelantado en create_collection()
get_collection_schema() devuelve vacío o inesperadoEl nombre del campo difiere de la suposición (por ejemplo, cta_button vs cta_button_text)Busque siempre el punto final /fields/{collection} para obtener la lista de campos exacta
La respuesta vacía genera JSONDecodeErrorBORRAR retorno de puntos finales 204 Sin contenidoGuardia: data = json.loads(raw) if raw.strip() else {}

La habilidad ya maneja la mayoría de estos internamente (v1.4.1+), pero es bueno conocer los patrones.


Patrones avanzados: filtros, relaciones y campos de enumeración

Filtrado con operadores

La habilidad es compatible con todos los operadores de filtros Directus:

## Igual
resultados = cliente.get(
    campos = ['id', 'título', 'estado'],
    filtros={'status': {'_eq': 'publicado'}},
    colección = 'Blog_Posts',
    límite=10
)

## No igual
borradores = client.get(filters={'status': {'_neq': 'published'}}, collection='Blog_Posts')

## Contiene (no distingue entre mayúsculas y minúsculas)
buscar = cliente.get(
    filtros = {'título': {'_icontains': 'seguridad'}},
    colección = 'Blog_Posts'
)

## En la lista
resultados = cliente.get(
    filtros = {'categoría': {'_in': [33, 37, 42]}},
    colección = 'Blog_Posts'
)

## Mayor que
caro = cliente.get(
    filtros={'price_cents': {'_gt': 10000}},
    colección='Productos'
)

## Verificación nula
no contactado = cliente.get(
    filtros = {'last_contacted_at': {'_null': Verdadero}},
    colección='Contactos'
)

## Combinado (Y juntos)
resultados = cliente.get(
    filtros={
        'estado': {'_eq': 'publicado'},
        'categoría': {'_in': [33, 37]},
        'published_at': {'_not_null': Verdadero}
    },
    colección = 'Blog_Posts'
)

Expansión de relaciones multinivel

Con la notación de puntos, puedes recuperar relaciones anidadas en una sola llamada:

## Obtener publicaciones con autor, categoría y etiquetas
registros = client.get_expanded(
    campos=[
        'id', 'título', 'estado',
        'autor.id', 'autor.nombre', 'autor.correo electrónico', # relación M2O
        'categoría.id', 'categoría.nombre', # relación M2O
        'tags.id', 'tags.name', 'tags.slug' # M2M mediante unión
    ],
    colección = 'Blog_Posts',
    límite=20
)
## Resultado: cada registro tiene dictados anidados como {'autor': {'id': 1, 'nombre': 'Alex'}, 'etiquetas': [{'id': 5, 'nombre': 'AI'}, ...]}

Campos JSON para datos flexibles

Utilice el tipo json para datos estructurados arbitrarios:

cliente.insertar({
    'dirección_envío': {
        'calle': '123 Tech Blvd',
        'ciudad': 'Dubái',
        'país': 'EAU',
        'código_postal': '00000'
    },
    'metadatos': {
        'utm_source': 'boletín',
        'campaign_id': 'Q2-2026-ai-launch'
    }
}, colección='Pedidos')

El JSON se almacena de forma nativa y se puede consultar con filtros en claves anidadas.


La API de administración: cuando necesita tocar el esquema mediante programación

La habilidad expone create_collection() y create_field() a través de Directus admin REST API (/collections y /fields/{collection}), no GraphQL.

Se requiere token de administrador. Su DIRECTUS_API_TOKEN es para CRUD; DIRECTUS_ADMIN_TOKEN es para operaciones de esquema.

cliente = DirectusCliente(
    url=os.getenv('DIRECTUS_URL'),
    token=os.getenv('DIRECTUS_API_TOKEN'), # para CRUD
    admin_token=os.getenv('DIRECTUS_ADMIN_TOKEN') # para esquema
)

## Crea una nueva colección
client.create_collection('TEST_Items', campos=[
    {'field': 'id', 'type': 'integer', 'schema': {'is_primary_key': True, 'has_auto_increment': True}, 'meta': {'hidden': True, 'interface': 'numeric', 'readonly': True}},
    {'campo': 'nombre', 'tipo': 'cadena', 'esquema': {}, 'meta': {'interfaz': 'entrada'}},
    {'campo': 'valor', 'tipo': 'entero', 'esquema': {}, 'meta': {'interfaz': 'numérico'}}
])

## Agregar un campo a la colección existente (úselo con precaución, puede dañar el esquema GraphQL)
client.create_field('TEST_Items', 'descripción', 'texto', meta={'interfaz': 'textarea'})

## Listar todas las colecciones
colecciones = client.get_collections()
print(colecciones) # ['Blog_Posts', 'Blog_Authors', ...]

## Obtener esquema de colección
esquema = client.get_collection_schema('Blog_Posts')
print(esquema['campos'].keys()) # dict_keys(['id', 'estado', 'autor', ...])

Advertencia: Agregar campos incrementalmente a través de create_field() puede dañar el esquema GraphQL para esa colección, lo que hace que todas las consultas GraphQL posteriores fallen con 400. El patrón más seguro: defina cada campo por adelantado en create_collection().


Poniéndolo todo junto: su primera sesión de Vibe-Code

Así es como se ve un flujo de trabajo completo:

## 1. Inicie su terminal (con tokens Directus en env)
$ exportar DIRECTUS_URL="https://hub.aratech.ae"
$ export DIRECTUS_API_TOKEN="sZk-st..." # token de usuario
$ export DIRECTUS_ADMIN_TOKEN="anuncio-..." # token de administrador

## 2. Inicie el agente Hermes
$hermes

## 3. Da el mensaje (copia y pega desde arriba)
Tú: Constrúyeme un backend de blog con Directus. Crea estas colecciones:...

## 4. El agente piensa, genera script y ejecuta
🤖 Agente: Creando Blog_Autores... ✅
   Creando Blog_Categorías... ✅
   Creando Blog_Tags... ✅
   Creando publicaciones_de_blog... ✅
   Creando Blog_Publicaciones_Traducciones... ✅
   Creando etiquetas_publicaciones_blog... ✅
   Sembrando 2 publicaciones de muestra... ✅
   
   Verificación:
   - Blog_Posts: 2 registros
   - Blog_Posts_Translations: 2 registros (solo en inglés)
   - Blog_Autores: 1 registro
   - Blog_Categories: 1 registro
   - Blog_Tags: 0 registros
   
   ✅ ¡Backend andamiado exitosamente! Su panel de administración de Directus en https://hub.aratech.ae/admin ahora muestra todas las colecciones completas.

## 5. Ya terminaste. Verifique la interfaz de usuario del administrador o consulte:
$ python3 -c "de directus.client importar DirectusClient; c = DirectusClient(); print(c.get(colección='Blog_Posts', límite=3))"

Eso es todo. Desde una instancia de Directus en blanco hasta un backend de blog completo con relaciones y datos de muestra en menos de un minuto.


Qué permite esto: creación rápida de prototipos a escala

No se trata sólo de ahorrar tiempo en la creación de esquemas (aunque eso es enorme). Se trata de reducir el ciclo de retroalimentación entre la idea y el prototipo funcional:

  • Diseño de esquema de una semana → 5 minutos para describir lo que deseas
  • Archivos de migración manual → Un script generado y ejecutado
  • Redacción de especificaciones de API → Directus genera automáticamente puntos finales REST y GraphQL
  • Configuración del panel de administración → La interfaz de usuario de administración de Directus está lista inmediatamente con sus colecciones, campos y permisos

Ahora puedes activar un backend específico del proyecto para:

  • Herramientas internas (inventario, emisión de tickets, seguimiento de activos)
  • Portales de clientes (historial de pedidos, tickets de soporte)
  • Modelos de datos SaaS (suscripciones, inquilinos, registros de uso)
  • MVP para el trabajo del cliente (describa el dominio, obtenga un backend instantáneo respaldado por CMS)

Y como Directus es solo su base de datos más una capa API inteligente, usted es dueño de los datos. Sin dependencia del proveedor. Exporte el SQL en cualquier momento.


Limitaciones y trampas

No todos los patrones de backend se ajustan a Directus

Directus es la primera plataforma CMS. Destaca en:

  • Modelos centrados en contenido (blogs, noticias, documentos, catálogos)
  • Datos relacionales estructurados (usuarios, pedidos, productos)
  • Aplicaciones con muchos medios (administración de archivos integrada)

No es ideal para:

  • Sistemas transaccionales de alta frecuencia (banca, licitaciones en tiempo real)
  • Arquitecturas complejas de abastecimiento de eventos o CQRS
  • Sistemas que requieren funciones SQL personalizadas o activadores
  • Websockets en tiempo real (aunque puedes usar sus ganchos y webhooks)

Aún necesitas pensar en el modelado de datos

La codificación Vibe no reemplaza la comprensión de su dominio. Basura entra, basura sale:

  • Campos mal nombrados → API confusa
  • Índices faltantes → consultas lentas a escala
  • Estructura plana para anidamiento profundo → lecturas ineficientes

La habilidad se desarrolla según tus especificaciones. Las buenas especificaciones provienen de un buen modelado.

Los permisos aún necesitan configuración

La habilidad crea colecciones y campos como administrador, pero aún necesita configurar permisos Directus (roles y políticas) para exponer los datos correctos a los usuarios frontend. La habilidad aún no toca los permisos.

El contenido grande requiere parches

Si publica artículos con rebajas de más de 1500 caracteres, utilice siempre el patrón POST-luego-PATCH para evitar el truncamiento. La habilidad aún no se parchea automáticamente; debe manejarla en su secuencia de comandos de inicialización.


Conclusión: el backend es ahora una conversación

Construir un backend solía significar escribir migraciones de SQL, configurar un ORM, crear rutas de controlador y conectar un administrador. Días o semanas de trabajo.

En 2026, con Directus y la habilidad nikola66, es:

  1. Describe tu esquema en inglés sencillo.
  2. Deje que el agente genere y ejecute Python.
  3. Tu backend está activo

Hemos utilizado este patrón para poner en marcha tres backends de proyectos solo este mes. Lo que solía ser un obstáculo - "primero necesitamos construir la capa de datos" - ahora no es un problema. El cuello de botella se movió hacia arriba: ahora dedicamos nuestro tiempo a la lógica del producto y la UX, no a la plomería.

La era de la codificación de vibraciones está aquí. Su backend estará listo cuando usted lo esté.


Próximos pasos

  • Instalar la habilidad: npx skills add nikola66/directus-skill
  • Conectar a Directus: Establezca DIRECTUS_URL, DIRECTUS_API_TOKEN, DIRECTUS_ADMIN_TOKEN
  • Pruebe el ejemplo de blog anterior (crea un esquema multilingüe totalmente consultable)
  • Extiéndalo: agregue colecciones para comentarios, me gusta, suscripciones y registros de webhooks
  • Conectar permisos en Directus Admin → Configuración → Roles y políticas

¿Tienes preguntas? Envíenos un mensaje a Telegram @Hermdroid o abra un problema en el repositorio de habilidades. Feliz edificio.


Tiempo de lectura: ~9 minutos Categoría: Tutorial Etiquetas: Directus, desarrollo backend, agentes de IA, codificación Vibe, CMS, GraphQL, Python, esquema de base de datos, API, sin código

Tabla de contenido

  • ↗Table of Contents
  • ↗Introducción: el backend es ahora una conversación
  • ↗¿Qué es esta "habilidad Directus" de todos modos?
  • ↗Requisitos previos: lo que necesita antes de comenzar
  • ↗Opción B: Clonar y usar directamente (actual)
  • ↗Copie el paquete en su proyecto o agréguelo a sys.path
  • ↗Instalación de la habilidad en Hermes Agent
  • ↗Anatomía de una especificación de backend de un solo mensaje
  • ↗Ejemplo 1: Backend de blog (preparado para varios idiomas)
  • ↗¿Qué hace esto?
  • ↗El código generado (lo que se ejecuta bajo el capó)
  • ↗1. Blog_Autores
  • ↗2. Blog_Categorías
  • ↗3. Etiquetas de blog
  • ↗4. Blog_Posts: registro de metadatos principal
  • ↗5. Blog_Posts_Translations: contenido por idioma
  • ↗6. Blog_Posts_Tags - tabla de unión
  • ↗Datos de muestra de semillas
  • ↗1. Crear autor (si no existe)
  • ↗2. Crear categoría
  • ↗3. Crear un registro de publicación de blog para padres
  • ↗4. Crear traducción al inglés
  • ↗Ejemplo 2: backend de comercio electrónico en un solo mensaje
  • ↗Ejemplo 3: CRM simple (Contactos + Empresas + Interacciones)
  • ↗Cómo funciona realmente: la salsa secreta de la habilidad
  • ↗Paso 1: el agente analiza su mensaje
  • ↗Paso 2: la habilidad genera cargas útiles correctas
  • ↗Paso 3: llamadas a la API de administrador en orden
  • ↗Paso 4 - Datos de semillas + Verificación
  • ↗Patrones probados en producción que hemos descubierto
  • ↗1. El esquema y el meta son obligatorios
  • ↗2. Utilice get_expanded() para relaciones
  • ↗Devuelve dictados: blog_posts_id = {'id': '5', 'status': 'publicado'}
  • ↗3. Los ID son cadenas en GraphQL, enteros en REST
  • ↗4. Las escrituras de la tabla de conexiones revisan la colección de conexiones
  • ↗INCORRECTO: El PATCH directo en Blog_Posts falla
  • ↗CORRECTO: Insertar en la mesa de unión
  • ↗5. Las colecciones de traducción necesitan inserciones de dos pasos
  • ↗Paso 1: padre (solo metadatos)
  • ↗Paso 2: traducción (contenido real)
  • ↗6. El error de truncamiento POST y la solución PATCH
  • ↗Paso A: Crear (riesgo de truncamiento)
  • ↗Paso B: PATCH contenido completo (evita el truncamiento)
  • ↗7. Verifique el acceso de escritura antes de publicar
  • ↗Enviar un registro de prueba mínimo
  • ↗Si tiene éxito, elimínelo
  • ↗Manejo de errores: qué sale mal y cómo solucionarlo
  • ↗Patrones avanzados: filtros, relaciones y campos de enumeración
  • ↗Filtrado con operadores
  • ↗Igual
  • ↗No igual
  • ↗Contiene (no distingue entre mayúsculas y minúsculas)
  • ↗En la lista
  • ↗Mayor que
  • ↗Verificación nula
  • ↗Combinado (Y juntos)
  • ↗Expansión de relaciones multinivel
  • ↗Obtener publicaciones con autor, categoría y etiquetas
  • ↗Resultado: cada registro tiene dictados anidados como {'autor': {'id': 1, 'nombre': 'Alex'}, 'etiquetas': [{'id': 5, 'nombre': 'AI'}, ...]}
  • ↗Campos JSON para datos flexibles
  • ↗La API de administración: cuando necesita tocar el esquema mediante programación
  • ↗Crea una nueva colección
  • ↗Agregar un campo a la colección existente (úselo con precaución, puede dañar el esquema GraphQL)
  • ↗Listar todas las colecciones
  • ↗Obtener esquema de colección
  • ↗Poniéndolo todo junto: su primera sesión de Vibe-Code
  • ↗1. Inicie su terminal (con tokens Directus en env)
  • ↗2. Inicie el agente Hermes
  • ↗3. Da el mensaje (copia y pega desde arriba)
  • ↗4. El agente piensa, genera script y ejecuta
  • ↗5. Ya terminaste. Verifique la interfaz de usuario del administrador o consulte:
  • ↗Qué permite esto: creación rápida de prototipos a escala
  • ↗Limitaciones y trampas
  • ↗No todos los patrones de backend se ajustan a Directus
  • ↗Aún necesitas pensar en el modelado de datos
  • ↗Los permisos aún necesitan configuración
  • ↗El contenido grande requiere parches
  • ↗Conclusión: el backend es ahora una conversación
  • ↗Próximos pasos

Artículos relacionados

DeepSeek V4 Flash: el modelo de 284 mil millones de parámetros que se ejecuta en un portátil

DeepSeek V4 Flash: el modelo de 284 mil millones de parámetros que se ejecuta en un portátil

Salvatore Sanfilippo (creador de Redis) construyó ds4 — un motor de inferencia que ejecuta DeepSeek V4 Flash (284B parámetros, 13B activos) en un MacBook con 128 GB de RAM. Cuantización personalizada de 2 bits, contexto de 1M tokens, cero costo por token.

Necolas HamwiNecolas Hamwi
27 de junio de 2026 - 8 min de lectura
Ornith 1.0 — Modelo de codificación IA auto-andamiante de DeepReinforce. Miniatura de video de YouTube con Sam Witteveen.

Ornith 1.0: El modelo de codificación IA de código abierto que escribe sus propios andamios RL

DeepReinforce lanzó Ornith 1.0, un modelo de IA de código abierto que presenta LLM auto-andamiantes para codificación agéntica — modelos que aprenden a escribir sus propias herramientas de aprendizaje por refuerzo. Con la variante 397B MoE igualando a Claude Opus 4.7 en SWE-Bench y la versión 9B superando a modelos tres veces más grandes, esto es un cambio de paradigma para el desarrollo de IA de código abierto.

Necolas HamwiNecolas Hamwi
26 de junio de 2026 - 12 min de lectura
Mano robótica futurista tocando una red digital que representa sistemas de IA multi-agente

Sistemas Multi-Agente: La Tendencia de IA que Redefine las Operaciones Empresariales en 2026

Gartner ha designado los sistemas multi-agente como una tendencia estratégica principal para 2026. Con un crecimiento del 327% en la adopción empresarial y predicciones de que el 15% de las decisiones diarias se tomarán de forma autónoma para 2028, esto es lo que los CTOs necesitan saber.

Necolas HamwiNecolas Hamwi
22 de junio de 2026 - 8 min de lectura