Dies ist das erste Proposal für eine YAML-API, die tatsächlich umgesetzten Features findest du hier:
Inline Text-Generierung
Generieren-Buttons im Neos Inspector
Juni 2023
In unseren Releases der letzten Monate haben wir konkrete Anwendungsfälle gelöst, indem wir eine chatbasierte KI in Neos CMS integriert haben. Wir haben Prompts optimiert und externe Dienste integriert.
Aber die große Stärke der Neos Community sind kreative und intelligente Entwickler. Wir wollen Sie in die Lage versetzen, Ihre Anwendungsfälle zu realisieren.
Der folgende Vorschlag skizziert Erweiterungspunkte für Entwickler:
Ist die Namensgebung konsistent und klar? Sind die Optionen für die Anwendungsfälle, die Sie sich vorstellen können, geeignet? Wie könnte man es noch besser machen?
Oder auf Slack #neos-general und erwähne @rolandschuetz
Das Verfassen effektiver Briefings verbessert die Qualität des erstellten Textes drastisch. Vielleicht möchten Sie, dass Ihre Redakteure bestimmten Vorlagen folgen und seitenbezogene Briefings und Zielgruppen verwenden.
Wir schlagen zwei neue Optionen vor:
Beide Optionen unterstützen ClientEval, und wir verwenden JavaScript-String-Literale, um den Text in diesem Beispiel zu erzeugen:
'Vendor.Site:Document.LangingPage':
...
ui:
inspector:
groups:
briefing:
label: Page Briefing
icon: route
position: 10
tab: seo
options:
sidekick:
focusKeyword: 'ClientEval: node.properties.focusKeyword'
targetAudience: 'ClientEval: node.properties.targetAudience'
pageBriefing: 'ClientEval: node.properties.problemDescription && `Die Seite sollte zuerst das folgende Problem beschreiben: ${node.properties.problemDescription}. Dann sollte sie beschreiben, wie wir es lösen: ${node.properties.problemSolutionDescription || ''}. Unser Ziel ist es, Konversionen zu optimieren.`'
properties:
focusKeyword:
type: string
ui:
label: SEO Focus Keyword
inspector:
group: 'briefing'
position: 10
editor: 'Neos.Neos/Inspector/Editors/TextFieldEditor'
targetAudience:
type: string
ui:
label: Target Audience
inspector:
group: 'briefing'
position: 20
editor: 'Neos.Neos/Inspector/Editors/TextAreaEditor'
validation:
'Neos.Neos/Validation/StringLengthValidator':
maximum: 450
problemDescription:
type: string
ui:
label: Kunden Problem
inspector:
group: 'briefing'
position: 30
editor: 'Neos.Neos/Inspector/Editors/TextAreaEditor'
validation:
'Neos.Neos/Validation/StringLengthValidator':
maximum: 450
problemSolutionDescription:
type: string
ui:
label: Wie wir es lösen
inspector:
group: 'briefing'
position: 40
editor: 'Neos.Neos/Inspector/Editors/TextAreaEditor'
validation:
'Neos.Neos/Validation/StringLengthValidator':
maximum: 450
Dies würde die folgende Inspektorengruppe für den Editor erstellen.
Bei jeder Änderung dieser Eigenschaften erhält NEOSidekick ein aktualisiertes Briefing.
Als Redakteur möchte man oft nur eine anständige Textbeschreibung haben, ohne zu viel Zeit darauf zu verwenden.
Ein typisches Beispiel ist die Meta-Beschreibung. Redakteure können eine Beschreibung auf der Grundlage des Inhalts der aktuellen Seite mit nur einem Mausklick erstellen.
Wir möchten es Ihnen ermöglichen, Eigenschaften mit generiertem Text zu füllen, der auf Ihrer eigenen Logik basiert. Dies wird erreicht mit:
'Neos.Seo:SeoMetaTagsMixin':
properties:
metaDescription:
ui:
inspector:
editor: 'NEOSidekick.AiAssistant/Inspector/Editors/MagicTextAreaEditor'
editorOptions:
placeholder: 'Neos.Seo:NodeTypes.SeoMetaTagsMixin:properties.metaDescription.textAreaEditor.placeholder'
module: 'meta_description'
Ein weiterer häufiger Fall ist die Generierung von Alternativtext für ein Bild. Unser Ziel ist es, eine allgemeine API für viele künftige Module zu definieren.
Unsere vorgeschlagene API:
'Vendor.Site:Content.Image':
superTypes:
'Neos.Neos:Content': true
ui:
label: Image
properties:
image:
type: Neos\Media\Domain\Model\ImageInterface
ui:
label: 'Image'
reloadIfChanged: true
showInCreationDialog: true
inspector:
group: general
position: 50
alternativeText:
type: string
ui:
label: 'Alternative Text'
reloadIfChanged: false
inspector:
group: general
position: 100
editor: 'NEOSidekick.AiAssistant/Inspector/Editors/MagicTextAreaEditor'
editorOptions:
module: 'alt_tag_generator'
arguments:
url: 'ClientEval: AssetUri(node.properties.image)'
An dieser Stelle wird es wirklich interessant. Wir möchten Sie als Integratoren in die Lage versetzen, Ihre eigene Textgenerierungslogik zu erstellen. Da die Texterzeugung Zeit in Anspruch nimmt, wollen wir den Text direkt in die Knoteneigenschaft übertragen.
Nehmen wir an, Sie möchten einen Content NodeType "Magic Text" erstellen, der auf Basis des aktuellen Seiteninhalts und des Titels einen vollständigen Absatz generiert. Dies können Sie mit YAML realisieren:
'Vendor.Site:Content.Text':
superTypes:
'Neos.Neos:Content': true
ui:
label: Magic Text
...
properties:
title:
type: string
ui:
label: Titel
showInCreationDialog: true
inlineEditable: true
text:
type: string
ui:
inlineEditable: true
options:
sidekick:
onCreate:
module: paragraph_generation
arguments:
topic: 'ClientEval: node.properties.title'
Jedes Texterzeugungsmodul kann je nach Modul mehrere Argumente haben. Alle Werte werden auf dem Client ausgewertet, wenn Sie ClientEval verwenden.
Sie sind nicht auf unsere vorgefertigten Module angewiesen. Nehmen wir an, Sie möchten einen TLDR erstellen, dann könnte Ihr NodeType wie folgt aussehen:
'NEOSidekick.Site:Content.TLDR':
superTypes:
'Neos.Neos:Content': true
ui:
label: TLDR
...
properties:
text:
type: string
ui:
inlineEditable: true
options:
sidekick:
onCreate:
module: free_conversation
arguments:
content: 'Erzeugen Sie eine TLDR für diese Seite, als Aufzählung von Punkten. Machen Sie ihn ansprechend, damit die Besucher die ganze Seite lesen wollen.'
writingStyle: 'marketing_genius'
Als Integrator wollen wir es Ihnen ermöglichen, automatisch generierte Knoten zu erstellen und mit Text zu füllen. Da die Texterstellung Zeit in Anspruch nimmt, möchten wir den Text direkt in die Knoten streamen.
Nehmen wir an, Sie erstellen einen Blogbeitrag und möchten einen FAQ-Abschnitt hinzufügen. Eine typische FAQ hat mehrere untergeordnete Knoten.
Beachten Sie, dass dieses Beispiel absichtlich komplex ist. Wir können keine unabhängigen Antworten generieren, da sie eine konsistente FAQ bilden sollen.
Wir verwenden NodeTemplates, um einen FAQ-Abschnitt mit Elementen zu erstellen. Jetzt kann jedes Element Knoten innerhalb der Antwort haben, mit einem Textknoten als Standard. Dann verwenden wir eine KI-Fähigkeit, um sie zu füllen.
ACHTUNG: Dies ist nicht die endgültige API, wir erforschen derzeit, wie dies intuitiv gemacht werden kann.
'Vendor.Site:Content.FAQ':
superTypes:
'Neos.Neos:Content': true
'Neos.Neos:ContentCollection': true
ui:
label: FAQ Section
creationDialog:
elements:
numberOfItems:
type: integer
defaultValue: 3
ui:
label: 'Questions to create:'
validation:
'Neos.Neos/Validation/NotEmptyValidator': [ ]
constraints:
nodeTypes:
'*': false
'Vendor.Site:Content.FAQ.Item': true
options:
template:
childNodes:
item:
name: '${"item" + item}'
type: 'NEOSidekick.Site:Content.FAQ.Item'
withItems: '${Array.range(1, data.numberOfItems)}'
aiProperties:
title: '${"faq_generator." + data.numberOfItems + ".question"}'
childNodes:
text:
type: 'Vendor.Site:Content.Text.Block'
properties:
text: '${"result." + data.numberOfItems + ".answer"}'
sidekick:
onCreated:
faq:
module: faq_generator
'Vendor.Site:Content.FAQ.Item':
superTypes:
'Neos.Neos:Content': true
'Neos.Neos:ContentCollection': true
ui:
label: FAQ Item
...
constraints:
nodeTypes:
'*': false
'Vendor.Site:Constraint.Content.Block': true
Ist die Namensgebung konsistent und klar? Sind die Optionen für die Anwendungsfälle, die Sie sich vorstellen können, geeignet? Wie könnte man es noch besser machen?
Oder auf Slack #neos-general und erwähne @rolandschuetz