Prima di WordPress 7.0, i plugin che aggiungevano funzionalità di AI dovevano richiedere e gestire una chiave API per comunicare con un provider di AI.

Questo comportava diversi svantaggi in termini di peso del codice e facilità di manutenzione. Dovevi includere nei tuoi plugin librerie SDK pesanti e proprietarie e scrivere richieste cURL specifiche per ogni provider.

Questo scenario frammentato è cambiato completamente con l’integrazione nativa dell’AI introdotta in WordPress 7.0. Oggi, WordPress offre un’interfaccia centralizzata per configurare le credenziali dei vari fornitori di AI, insieme a una nuova API PHP. Questa nuova architettura permette di inviare comandi, istruzioni, file multimediali e strutture di dati senza intoppi, mentre il core si occupa delle richieste.

La nuova architettura offre vantaggi sostanziali sia agli amministratori del sito che agli sviluppatori di plugin.

Gli amministratori non devono più configurare le impostazioni di AI su più plugin. A partire da WordPress 7.0, basta installare e abilitare i connettori dei plugin, inserire le chiavi API nell’interfaccia unificata dei connettori, e questi diventano immediatamente disponibili per tutti i plugin basati sull’AI presenti sul sito. Puoi monitorare facilmente l’utilizzo dell’AI, cambiare il tuo modello preferito o revocare l’accesso di un fornitore per tutti i plugin con un solo clic.

Per gli sviluppatori di plugin, i vantaggi sono ancora maggiori e spaziano dalla sicurezza dei dati alla portabilità del codice, fino a una drastica riduzione del debito tecnico.

Ti va di intraprendere questo viaggio nella nuova architettura AI di WordPress? Partiamo!

I tre livelli dell’architettura AI di WordPress

Oggi, i tuoi siti WordPress sono nativamente pronti per l’AI. Non si tratta però di funzionalità AI pronte all’uso, ma piuttosto delle basi per costruire siti web basati sull’AI.

La nuova architettura è strutturata su tre livelli distinti:

Connettore AI

Prima di WordPress 7.0, ogni plugin che aggiungeva funzionalità di AI al tuo sito aveva bisogno di un proprio sistema per archiviare e gestire le chiavi API. Le credenziali dovevano essere inserite direttamente nel codice del plugin o gestite tramite una pagina di impostazioni personalizzata. In entrambi i casi, era ben lungi dall’essere una soluzione ideale per gestire dati sensibili.

schermata Connectors
L’interfaccia centralizzata dei connettori AI nella bacheca di WordPress.

Un’interfaccia unificata permette di configurare tutti i tuoi fornitori di servizi di AI in un unico posto. Questa interfaccia offre diversi vantaggi importanti per la gestione del sito.

Dal punto di vista della gestione e della sicurezza, il vantaggio principale è che devi configurare i tuoi provider una sola volta nell’interfaccia di Connectors, dopodiché puoi non pensarci più, indipendentemente dal numero di plugin che li utilizzano. Se dovessi mai cambiare le tue chiavi API, non dovrai riconfigurare ogni singolo plugin; potrai aggiornarle tutte in una volta sola nella schermata dei Connettori.

Centralizzare le credenziali migliora anche la sicurezza del tuo sito, riducendo il rischio di esporre dati sensibili tramite plugin di terze parti che potrebbero essere scritti male o inaffidabili.

Un altro vantaggio fondamentale è la portabilità del codice. I tuoi plugin non devono più sapere quale provider di AI utilizzi, perché la nuova architettura separa l’autenticazione dalla logica del plugin. Ciò significa che se cambi provider di IA, il tuo plugin continuerà a funzionare senza richiedere la modifica di una sola riga di codice.

Tuttavia, la vera svolta in termini di portabilità è la possibilità per gli amministratori del sito di configurare più connettori contemporaneamente. Quando un plugin invia una richiesta, WordPress seleziona automaticamente il provider di AI e il modello più adatti per generare la risposta, in base sia alla configurazione specifica del plugin sia alle capacità dei modelli disponibili.

AI Client

Mentre la schermata “Connettori” offre l’interfaccia utente per la configurazione dei provider di AI, il AI client fornisce agli sviluppatori lo strumento operativo per comunicare con i modelli di AI.

Si tratta di un’interfaccia software nativa che standardizza l’interazione con i modelli di intelligenza artificiale tramite la funzione globale wp_ai_client_prompt() e un insieme unificato di metodi PHP.

Riduzione del debito tecnico

Per gli sviluppatori, uno dei principali vantaggi della nuova architettura AI è la riduzione del debito tecnico e delle dipendenze. Prima di WordPress 7.0, aggiungere funzionalità AI comportava un costo molto elevato in termini di manutenzione del codice. Dovevi integrare SDK proprietari di terze parti (come le librerie ufficiali di OpenAI o Anthropic) e monitorare costantemente le versioni delle librerie. Questo comportava un codice del plugin molto pesante e apriva la strada a errori di compatibilità.

Inoltre, era necessario scrivere molte righe di codice per gestire la logica di rete e l’analisi delle risposte. A peggiorare le cose, il codice era specifico per ogni fornitore, quindi se decidevi di cambiare fornitore di AI, dovevi riscrivere l’intera architettura di rete del tuo plugin.

AI Client risolve questo problema alla radice, trasferendo tutto questo lavoro pesante al core di WordPress. Il tuo codice diventa completamente indipendente dal fornitore di AI; devi solo scrivere le istruzioni una volta, e WordPress le tradurrà nel “dialetto” specifico del modello.

Selezione intelligente dei modelli

Una potente funzionalità dell’interfaccia Fluent di AI Client è la possibilità di impostare i modelli preferiti tramite il metodo using_model_preference(), disponibile tramite la funzione di costruzione wp_ai_client_prompt(). Questo metodo ti permette di dichiarare un elenco ordinato di modelli per l’attività specifica del tuo plugin. Ad esempio, il codice seguente richiede la generazione di testo puntando a 3 modelli preferiti:

$text_result = wp_ai_client_prompt( 'Convert the following transcript into a concise, blog-ready draft.' )
	->using_model_preference(
		'gemini-2.5-flash',
		'claude-3-5-sonnet',
		'gpt-4o'
	)
	->generate_text();

WordPress controllerà i provider configurati nella schermata “Connettori” e analizzerà l’elenco dei modelli definiti nel codice del plugin, selezionando il primo connettore disponibile anche sul sito. Se nessuno dei modelli specificati nel tuo codice è disponibile tra i connettori attivi, WordPress ignorerà l’elenco delle preferenze dei modelli e ricorrerà al primo modello compatibile configurato sul sito.

Questo meccanismo garantisce che il tuo plugin funzioni sempre, anche se l’amministratore del sito passa a un fornitore di AI diverso.

Provider AI

Un provider di AI è l’azienda che possiede, addestra e ospita i modelli linguistici di grandi dimensioni (LLM) che usiamo ogni giorno. OpenAI, Google Gemini e Anthropic sono i provider di AI più comuni supportati tramite connettori dedicati in WordPress 7.0, ma gli sviluppatori possono registrare ulteriori provider di AI personalizzati.

Quando il codice del plugin chiama il metodo generate_text() — o qualsiasi altro metodo di generazione — WordPress compila e invia un payload di dati al fornitore di AI tramite l’endpoint stabilito dal connettore. Ecco la sequenza di operazioni che avviene dietro le quinte:

  • Come primo passo, il provider di AI riceve il testo di input insieme a eventuali file multimediali allegati (payload di dati).
  • Una volta ricevuta, elabora la richiesta, applicando eventuali istruzioni di sistema.
  • Da lì, genera l’output strutturato come testo libero o come oggetto JSON.
  • Infine, invia l’output a WordPress tramite una risposta HTTP.

Ogni provider offre un’ampia varietà di modelli con diverse funzionalità, velocità e prezzi. Questi vanno da modelli specializzati esclusivamente nell’elaborazione del testo a modelli multimodali che accettano file multimediali (audio, immagini, video) insieme a un prompt di testo, fino a modelli progettati per compiti specifici, come la generazione di immagini o la conversione da voce a testo.

modelli Gemini 3
La famiglia di modelli Gemini 3 di Google.

Anche in questo caso, i modelli disponibili per un sito WordPress dipendono dai fornitori di AI che l’utente configura nella schermata “Connettori”. Questo significa che il plugin non impone quale fornitore specifico utilizzare.

Un’analisi approfondita della funzione wp_ai_client_prompt()

La funzione wp_ai_client_prompt() permette ai plugin di comunicare con i modelli di AI in modo standardizzato: non dovrai installare librerie esterne, gestire configurazioni specifiche per ogni fornitore né scrivere manualmente richieste HTTP.

Si tratta di un’interfaccia software che permette di scrivere il codice una sola volta, lasciando che sia WordPress a occuparsi del lavoro più impegnativo e a tradurre le istruzioni nel “dialetto” specifico di ciascun modello.

La funzione restituisce un’istanza della classe WP_AI_Client_Prompt_Builder, che offre un’interfaccia fluida di metodi concatenabili per personalizzare i tuoi prompt. La funzione è descritta come segue:

/**
 * Generatore "fluent" per la creazione di prompt di IA, che restituisce un WP_Error in caso di errore.
 *
 * Questa classe fornisce un'interfaccia "fluent" per la creazione di prompt con vari
 * tipi di contenuto e configurazioni di modello. Incorpora il PromptBuilder dell'SDK PHP AI Client
 * e aggiunge comportamenti specifici per WordPress, tra cui la gestione di WP_Error
 * al posto delle eccezioni, la denominazione dei metodi in snake_case e l'integrazione
 * con l'API di Abilities.
 *
 * Solo i metodi di generazione restituiranno un WP_Error, per non compromettere l’interfaccia
 * fluida. Non appena viene intercettata un’eccezione in una catena di chiamate ai metodi,
 * l’istanza restituita entrerà in uno stato di errore e tutte le successive chiamate ai metodi
 * saranno operazioni nulle che restituiranno semplicemente la stessa istanza in stato di errore. Solo
 * quando viene chiamato un metodo di generazione, verrà restituito il WP_Error.
 */

wp_ai_client_prompt() non effettua una richiesta HTTP immediata; invece, istanzia e restituisce un oggetto WP_AI_Client_Prompt_Builder. Più di 50 metodi di configurazione popolano le proprietà private dell’oggetto utilizzando un’interfaccia fluida, il che rende il codice altamente leggibile e facile da scrivere.

Ecco un elenco non esaustivo dei metodi che userai più spesso:

  • with_text(): aggiunge del testo al messaggio corrente.
  • with_file(): aggiunge un file al messaggio corrente.
  • with_history(): aggiunge i messaggi della cronologia della conversazione.
  • using_model_preference(): imposta i modelli preferiti da valutare in ordine.
  • using_system_instruction(): imposta l’istruzione di sistema.
  • using_max_tokens(): imposta il numero massimo di token da generare.
  • using_temperature(): imposta la temperatura per la generazione.
  • using_top_p(): imposta il valore top-p per la generazione.
  • using_top_k(): imposta il valore top-k per la generazione.
  • as_output_file_type(): imposta il tipo di file di output.
  • as_json_response(): configura il prompt per l’output della risposta JSON.
  • is_supported_for_text_generation(): verifica se la generazione di testo è supportata dalla configurazione attiva.
  • is_supported_for_image_generation(): verifica se la generazione di immagini è supportata dalla configurazione attiva.
  • is_supported_for_text_to_speech_conversion(): verifica se la conversione da testo a voce è supportata dalla configurazione attiva.
  • is_supported_for_video_generation(): verifica se la generazione di video è supportata dalla configurazione attiva.
  • generate_text(): genera un risultato testuale dal prompt.
  • generate_image(): genera un’immagine dal prompt.
  • convert_text_to_speech(): converte il testo in voce.
  • generate_speech(): genera un messaggio vocale dal prompt.
  • generate_video(): genera un video dal prompt.

Per l’elenco completo dei metodi, dai un’occhiata al codice sorgente di WordPress.

Supponiamo che tu voglia trascrivere con precisione il contenuto di un file audio. Potresti usare la funzione come segue:

$transcription_builder = wp_ai_client_prompt( $prompt )
	->with_file( $audio_base64, $mime_type )
	->using_temperature( 0.1 );

if ( ! $transcription_builder->is_supported_for_text_generation() ) {
	// No configured provider supports the current prompt configuration.
	return new WP_Error(
		'no_supported_model',
		'No configured AI model can process this request. Configure a provider in Settings > Connectors.',
		array( 'status' => 400 )
	);
}

$transcript = $transcription_builder->generate_text();

Ecco cosa fa questo codice:

  • $prompt: rappresenta la stringa principale contenente le tue istruzioni principali.
  • with_file(): sblocca le funzionalità multimodali dell’interfaccia. Nell’esempio sopra, abbiamo passato il payload audio binario pre-codificato come stringa codificata in Base64 insieme al relativo tipo MIME.
  • using_temperature(): controlla il determinismo della risposta. Mentre un valore basso (0,1) costringe il modello a rimanere fedele all’audio, un valore più alto permette una maggiore libertà creativa. Puoi combinare questo metodo con quello “ using_top_p() ” (Top-Probability) per un controllo più preciso sull’output.
  • is_supported_for_text_generation(): verifica se i connettori attivi supportano i requisiti del prompt corrente prima di impegnare risorse in una chiamata di rete.
  • generate_text(): questo è il metodo di chiusura dell’interfaccia Fluent. Invia la richiesta HTTP unificata al provider attivo e restituisce la stringa di testo generata oppure, in caso di errore, un oggetto WP_Error.

In breve, abbiamo passato al provider AI un prompt di testo e un file audio allegato. Abbiamo impostato una temperatura bassa per garantire il risultato più deterministico possibile, verificato che la configurazione attiva supportasse la generazione di testo e infine eseguito la trascrizione da voce a testo in base alla risposta dell’AI.

Con un altro prompt, possiamo restituire la trascrizione grezza all’AI per generare una risposta strutturata come oggetto JSON:

$structured_json = wp_ai_client_prompt(
	"Convert the following transcript into a concise, blog-ready draft in American English.n" .
	"Return JSON with a post title and body sections.n" .
	"Each section must have: heading, level (2 or 3), and paragraphs (array).n" .
	"If useful, include bullet_points (array) for short actionable lists.n" .
	"Use short, clear headings and readable paragraph text.nn" .
	"Transcript:n" . $transcript
)
	->using_system_instruction( "You are a professional WordPress content editor. Always write in American English (use appropriate spelling, grammar, and conventions for that language variant)." )
	->using_temperature( 0.4 )
	->as_json_response( $schema )
	->generate_text();

Per questo secondo prompt, usiamo metodi aggiuntivi per sfruttare altre funzionalità dell’API:

  • using_system_instruction(): definisce il contesto operativo e il ruolo comportamentale del modello, separando nettamente la sua identità (“un redattore professionista di contenuti WordPress”) dal payload dei dati.
  • using_temperature( 0.4 ): imposta una “temperatura” più alta rispetto al precedente compito di trascrizione, permettendo al modello di usare un vocabolario più ricco e produrre un contenuto più fluido.
  • as_json_response(): obbliga il modello a restituire una stringa JSON strutturata che corrisponda al layout definito nella variabile $schema. È utile quando prepari contenuti per Gutenberg.

Con un output strutturato come JSON, puoi estrarre singoli campi e mapparli a livello di programmazione nei blocchi nativi di Gutenberg utilizzando le funzioni principali di WordPress.

Per una panoramica più approfondita dell’AI Client, dai un’occhiata anche alla nota di sviluppo “Introduzione all’AI Client in WordPress 7.0”.

Convertire un file audio in contenuto pronto per Gutenberg con l’AI

Ora che hai una migliore comprensione dei tre livelli dell’architettura AI di WordPress, vediamo come tutto questo si integra con un esempio pratico. In questa sezione impareremo a costruire la logica di base di un plugin basato sull’intelligenza artificiale, progettato per generare una bozza di post ben strutturata direttamente da un file audio.

I casi d’uso di questa funzionalità sono vasti e variegati. Immagina di creare un post completo per il blog partendo da una breve nota vocale inviata tramite la tua app di messaggistica preferita, oppure di trascrivere un’intervista audio registrata sul tuo smartphone.

Per implementare questa funzionalità sul tuo sito WordPress, dovrai creare un plugin personalizzato. Qui non tratteremo i file boilerplate né l’intero processo di registrazione del plugin; per le nozioni di base sullo sviluppo dei plugin, puoi consultare altri tutorial sul blog di Kinsta o la documentazione ufficiale di WordPress.org.

Ci concentreremo sulla logica di base che permette al plugin di comunicare con il provider di AI. Ma non preoccuparti, il plugin è disponibile per la consultazione e il download in questo repository GitHub.

Cosa fa questo plugin

Per iniziare, vai alla pagina del progetto su GitHub e scarica l’archivio ZIP del plugin. Poi, accedi alla tua dashboard di WordPress 7.0 e caricalo da Plugin > Aggiungi plugin > Carica plugin. Una volta installato e attivato il plugin, avrai tutto ciò che serve per seguire questo tutorial.

Il plugin AI Content Builder genera una barra laterale delle impostazioni personalizzate, accessibile tramite un’icona situata nell’angolo in alto a destra dell’interfaccia dell’editor a blocchi. Questa barra laterale presenta un’interfaccia dedicata per caricare file audio e un pulsante che permette all’AI di sovrascrivere il titolo attuale del post.

La barra laterale di AI Content Builder
Il plugin AI Content Builder aggiunge una barra laterale delle impostazioni personalizzate all’editor a blocchi.

Il pulsante Upload audio note apre il caricatore multimediale di WordPress, permettendoti di caricare un nuovo file audio o di selezionarne uno esistente dalla libreria multimediale.

La libreria multimediale di WordPress
Seleziona o carica file audio nella libreria multimediale di WordPress.

Una volta caricato il file audio, il pulsante Generate Content avvia una richiesta asincrona al provider di AI attivo.

La barra laterale del plugin
La barra laterale del plugin con il pulsante “Genera contenuto” attivo.

L’immagine qui sotto mostra la bozza finale del post generata dall’AI in pochi secondi.

Markup generato dall'AI
Una bozza di post per il blog ben formattata, generata dall’AI a partire da un file audio grezzo.

Il contenuto risultante è strutturato in blocchi nativi di Gutenberg, inclusi paragrafi, titoli ed elenchi.

Markup ben strutturato nell’editor di codice di WordPress.
Markup ben strutturato nell’editor di codice di WordPress.

Ora vediamo un po’ come funziona il plugin.

Cosa serve per questo plugin

Ecco i requisiti di base per creare un plugin WordPress che si integri con la nuova architettura AI per generare i contenuti dei post:

  • WordPress 7.0
  • Una chiave API di un provider di AI che offra un modello in grado di convertire il parlato in testo. Nel nostro esempio useremo Google AI.
  • Il tuo IDE preferito. Per questo plugin abbiamo usato VS Code.
  • Una solida conoscenza dello sviluppo di WordPress e Gutenberg, delle API REST, di PHP e JavaScript.

Non devi preoccuparti di Node.js, dei processi di compilazione o dell’importazione di librerie esterne, perché questo plugin si basa interamente sulle API native del core di WordPress. Il risultato è un plugin leggero e sicuro, senza alcun debito tecnico.

Struttura del plugin e versione minima di WordPress

Il plugin AI Content Builder è composto da soli due file:

  • ai-content-builder.php
  • editor.js.

La versione minima richiesta di WordPress è la 7.0, quindi assicurati di impostarla nell’intestazione del plugin:

<?php
/**
 * Plugin Name: AI Content Builder
 * Description: Gutenberg sidebar plugin that uploads audio and generates post content using the WordPress 7.0 AI Client.
 * Version: 1.0.0
 * Requires at least: 7.0
 * Requires PHP: 8.0
 * Author: Your Name
 * License: GPL-2.0-or-later
 * Text Domain: ai-content-builder
 */

Tenendo presente questo, diamo un’occhiata al processo di creazione di un plugin basato sull’AI per WordPress.

Il flusso dei dati del plugin

Prima di addentrarci nel codice, diamo un’occhiata a come i dati fluiscono dal backend di WordPress (l’editor a blocchi) al server PHP e al provider di AI, per poi tornare indietro.

1. Dal browser al server – chiamata REST asincrona: il browser invia l’ID dell’audio all’endpoint REST personalizzato del plugin. Per evitare che l’interfaccia utente si blocchi, registriamo un endpoint REST che consente richieste asincrone al server PHP.

2. Primo passaggio dell’AI – trascrizione da voce a testo: il server intercetta la richiesta, recupera l’audio dal database e interroga il client AI per estrarre la trascrizione testuale grezza.

3. Secondo passaggio dell’AI – strutturazione dei contenuti: il server rimanda la trascrizione grezza al client AI e richiede che venga formattata come oggetto JSON strutturato.

4. Hydration dei dati e generazione dei blocchi: lo script JavaScript (JS) riceve l’oggetto JSON strutturato, lo normalizza e mappa i campi ai blocchi nativi di Gutenberg.

Ora diamo un’occhiata alla logica alla base di ogni fase.

1. Registrare un endpoint API personalizzato

Il primo passo per creare il plugin AI Content Builder è registrare un endpoint API. Questo è fondamentale perché l’elaborazione di un file audio e la generazione di una risposta possono richiedere diversi secondi (o addirittura minuti) al modello di AI. Registrare un endpoint REST permette di effettuare richieste asincrone tramite i controlli della barra laterale, evitando che l’interfaccia utente si blocchi.

Registrare un endpoint API permette anche di effettuare chiamate AI sicure senza esporre le credenziali di accesso, sfruttando il sistema di autenticazione nativo di WordPress.

La logica per registrare e inizializzare l’endpoint è gestita nel file PHP del plugin utilizzando i due metodi di classe init() e register_rest_routes().

public static function init(): void {

	// Register the custom REST endpoint used by the sidebar JS.
	add_action( 'rest_api_init', array( __CLASS__, 'register_rest_routes' ) );

	...
}

Collegando la chiamata alla funzione all’hook rest_api_init, il plugin registra la root dell’endpoint solo quando viene attivata una richiesta API REST. Questo migliora le prestazioni evitando ritardi inutili nel caricamento della pagina.

Puoi configurare i percorsi usando il metodo register_rest_routes() come mostrato nel codice qui sotto:

public static function register_rest_routes(): void {
	register_rest_route(
		self::REST_NAMESPACE,
		self::REST_ROUTE,
		array(
			'methods'             => WP_REST_Server::CREATABLE, // Alias for POST.
			'callback'            => array( __CLASS__, 'handle_generate_request' ),
			'permission_callback' => static function (): bool {
				// Reject unauthenticated or insufficiently privileged requests early.
				return current_user_can( 'edit_posts' );
			},
			'args'                => array(
				'audio_id' => array(
					'type'     => 'integer',
					'required' => true,
				),
			),
		)
	);
}

Questo metodo fa quanto segue:

  • La funzione register_rest_route() accetta tre parametri: lo spazio dei nomi del percorso, il percorso stesso e un array di configurazione.
  • WP_REST_Server::CREATABLE è un alias per il metodo di trasporto POST, utilizzato per garantire la massima compatibilità con l’architettura interna di WordPress.
  • permission_callback è una funzione anonima che limita l’accesso agli utenti autenticati che hanno il permesso di creare e modificare i propri post. WordPress blocca quindi la richiesta prima di elaborarla e restituisce automaticamente un errore 401 Unauthorized o 403 Forbidden in caso di accesso non autorizzato.
  • args È un array opzionale di parametri aggiuntivi che puoi usare per modificare la risposta dell’API. Permette di specificare i dati che la richiesta all’endpoint deve restituire.
  • audio_id è un array di parametri che specifica il tipo di dati richiesti. Se il tipo di dati restituito non è un numero intero o manca, l’API REST interrompe l’esecuzione e genera un errore.

Infine, assicurati che la barra laterale dell’editor sappia dove inviare i dati. Per farlo, usa la funzione wp_localize_script() all’interno del metodo enqueue_editor_assets().

public static function enqueue_editor_assets(): void {
	...

	wp_localize_script(
		'ai-content-builder-editor',
		'AICBData',
		array(
			'restPath' => '/' . self::REST_NAMESPACE . self::REST_ROUTE,
			'nonce'    => wp_create_nonce( 'wp_rest' ),
		)
	);
}
  • La funzione wp_localize_script() viene usata principalmente per associare uno script registrato ai dati di una variabile JavaScript, ma qui la usiamo per passare i dati da PHP a JavaScript tramite l’oggetto globale AICBData.
  • restPath è l’indirizzo dell’endpoint; specificarlo qui ti permette di evitare di inserirlo in modo statico nel file JavaScript.
  • nonce imposta un token di sicurezza per impedire accessi non autorizzati.

2. Accedere al client AI per estrarre il testo da un file audio

Il cuore del nostro plugin è il metodo handle_generate_request(). Questo metodo esegue una sequenza di operazioni, che inizia con i controlli di sicurezza e termina con la generazione del contenuto del post da inserire nell’editor dei blocchi.

Per prima cosa, verifica che il client AI sia disponibile e che il supporto AI non sia stato disabilitato sul sito.

public static function handle_generate_request( WP_REST_Request $request ) {
	if ( ! function_exists( 'wp_ai_client_prompt' ) ) {
		return new WP_Error(
			'ai_client_unavailable',
			'WordPress AI Client is not available. This plugin requires WordPress 7.0 .',
			array( 'status' => 500 )
		);
	}

	if ( function_exists( 'wp_supports_ai' ) && ! wp_supports_ai() ) {
		return new WP_Error(
			'ai_disabled',
			'AI support is disabled on this site.',
			array( 'status' => 403 )
		);
	}
	...
}

In caso di errore, i controlli restituiscono rispettivamente un errore 500 o 403.

Il blocco di codice successivo esegue le seguenti azioni:

  • Estrae l’ID del file audio dalla richiesta
  • Si assicura che l’ID del file audio sia un numero intero positivo
  • Controlla il tipo di file
  • Recupera il tipo MIME
  • Estrae e codifica il contenuto del file in Base64
$audio_id = absint( $request->get_param( 'audio_id' ) );
if ( ! $audio_id ) {
	return new WP_Error( 'invalid_audio_id', 'Invalid audio ID.', array( 'status' => 400 ) );
}

$attachment = get_post( $audio_id );
if ( ! $attachment || 'attachment' !== $attachment->post_type ) {
	return new WP_Error( 'audio_not_found', 'Audio attachment not found.', array( 'status' => 404 ) );
}

$mime_type = (string) get_post_mime_type( $audio_id );
if ( 0 !== strpos( $mime_type, 'audio/' ) ) {
	return new WP_Error( 'invalid_audio_type', 'Attachment must be an audio file.', array( 'status' => 400 ) );
}

$audio_path = get_attached_file( $audio_id );
if ( ! $audio_path || ! file_exists( $audio_path ) ) {
	return new WP_Error( 'audio_path_missing', 'Audio file path not found on server.', array( 'status' => 404 ) );
}

$audio_bytes = file_get_contents( $audio_path );
if ( false === $audio_bytes ) {
	return new WP_Error( 'audio_read_failed', 'Unable to read audio file.', array( 'status' => 500 ) );
}

$audio_base64 = base64_encode( $audio_bytes );
Errore: tipo di file non valido
Viene generato un messaggio di errore quando l’utente prova a elaborare un tipo di file non valido

In questo modo, il file binario è stato convertito in una stringa che può essere passata all’AI Client. Ora possiamo passare all’estrazione del testo:

$output_language = self::get_output_language();

$transcription_builder = wp_ai_client_prompt(
	"Transcribe this voice note accurately into $output_language. Return plain text only."
)
	->with_file( $audio_base64, $mime_type )
	->using_temperature( 0.1 );

if ( ! $transcription_builder->is_supported_for_text_generation() ) {
	return new WP_Error(
		'no_supported_model',
		'No configured AI model can process this request. Configure a provider in Settings > Connectors.',
		array( 'status' => 400 )
	);
}

$transcript = $transcription_builder->generate_text();

Ecco una spiegazione dettagliata di cosa fa il codice qui sopra.

  • get_output_language() è un metodo statico definito altrove nello script che restituisce le impostazioni locali del sito. (Vedi GitHub.)
  • wp_ai_client_prompt() inizializza una nuova richiesta passando il prompt principale.
  • with_file() comunica all’AI Client che stiamo inviando una richiesta multimodale; accetta il contenuto del file in Base64 e il tipo MIME.
  • using_temperature() permette di specificare il livello di determinismo della risposta. Impostiamo un valore basso per ottenere una trascrizione fedele dell’audio.
  • Il metodo is_supported_for_text_generation() verifica se il provider AI è in grado di generare testo dai dati forniti; se il provider non supporta l’input multimodale, il plugin si interrompe e restituisce un messaggio di errore.
  • Il metodo generate_text() avvia la richiesta HTTP.

3. Convertire la trascrizione audio in contenuto strutturato

Ora che abbiamo la trascrizione, il plugin deve comunicare di nuovo con il provider di AI per ottenere una risposta JSON strutturata. Per farlo, dobbiamo definire un array strutturato in formato JSON.

$schema = array(
	'type'       => 'object',
	'properties' => array(
		'title'    => array( 'type' => 'string' ),
		'sections' => array(
			'type'  => 'array',
			'items' => array(
				'type'       => 'object',
				'properties' => array(
					'heading'    => array( 'type' => 'string' ),
					'level'      => array(
						'type' => 'integer',
					),
					'paragraphs' => array(
						'type'  => 'array',
						'items' => array( 'type' => 'string' ),
					),
					'bullet_points' => array(
						'type'  => 'array',
						'items' => array( 'type' => 'string' ),
					),
				),
				'required'   => array( 'heading', 'level', 'paragraphs' ),
			),
		),
	),
	'required'   => array( 'title', 'sections' ),
);

Con questa struttura, l’AI risponderà con un oggetto JSON contenente un titolo e un array di sezioni. Ogni sezione deve contenere un header, un livello di header, almeno un paragrafo e dei punti elenco.

Ora che lo schema è definito, possiamo passare a configurare la seconda richiesta al client IA:

$structured_json = wp_ai_client_prompt(
	"Convert the following transcript into a concise, blog-ready draft in $output_language.n" .
	"Return JSON with a post title and body sections.n" .
	"Each section must have: heading, level (2 or 3), and paragraphs (array).n" .
	"If useful, include bullet_points (array) for short actionable lists.n" .
	"Use short, clear headings and readable paragraph text.nn" .
	"Transcript:n" . $transcript
)
	->using_system_instruction( "You are a professional WordPress content editor. Always write in $output_language (use appropriate spelling, grammar, and conventions for that language variant)." )
	->using_temperature( 0.4 )
	->as_json_response( $schema )
	->generate_text();

if ( is_wp_error( $structured_json ) ) {
	return $structured_json;
}

Analizziamo i punti chiave di questo codice:

  • using_system_instruction() definisce la personalità del modello.
  • using_temperature( 0.4 ) imposta un valore di temperatura più alto, dando all’AI maggiore libertà creativa per generare una risposta e produrre una prosa più fluida e ricca.
  • as_json_response( $schema ) indica al client di fornire la risposta in un formato strutturato.
  • Il plugin si interrompe in caso di errore.

Il passo successivo è decodificare e pulire i dati.

$structured = json_decode( (string) $structured_json, true );

if ( ! is_array( $structured ) ) {
	return new WP_Error(
		'invalid_ai_json',
		'Could not parse structured AI response.',
		array( 'status' => 500 )
	);
}

$normalized = self::normalize_structured_post( $structured );

if ( '' === $normalized['title'] && empty( $normalized['sections'] ) ) {
	return new WP_Error(
		'empty_structured_content',
		'The AI provider returned empty structured content.',
		array( 'status' => 500 )
	);
}

Nel codice qui sopra:

  • La funzione json_decode() converte la stringa JSON in un array associativo PHP.
  • Se il JSON è malformato, il controllo seguente restituisce un codice di stato 500 insieme a un messaggio di errore chiaro.
  • Il metodo statico normalize_structured_post() pulisce e normalizza l’output del provider prima di passarlo a JavaScript (dai un’occhiata alla definizione di questa funzione su GitHub).

L’unica cosa che resta da fare ora è passare l’output risultante a JavaScript per generare blocchi Gutenberg nativi.

4. Generazione dell’output pronto per Gutenberg

Il passo successivo consiste nel mappare l’output JSON ai blocchi nativi di Gutenberg. Questa fase avviene sul lato client ed è gestita dal file ` editor.js `.

Quando l’utente seleziona un file audio, viene eseguito il codice seguente:

function AIContentBuilderSidebar() {

	const [ audioId, setAudioId ] = useState( 0 );
	...

	const onSelectAudio = function ( media ) {
		if ( ! media || ! media.id ) {
			return;
		}
		setAudioId( media.id );
		setAudioLabel( media.title || media.filename || ( 'Audio #'   media.id ) );
		setNotice( null );
	};
	...
}

Questo codice recupera l’ID del file audio registrato dal database di WordPress.

Quando l’utente clicca sul pulsante Generate Content, la funzione onGenerate()usa apiFetch() per inviare una richiesta POST all’endpoint dell’API, includendo, tra le altre cose, l’ID dell’audio.

const onGenerate = async function () {

	...

	try {
		const response = await apiFetch( {
			path: AICBData.restPath,
			method: 'POST',
			headers: {
				'X-WP-Nonce': AICBData.nonce,
			},
			data: {
				audio_id: audioId,
			},
		} );
		...
	}
	...
}
  • await mette temporaneamente in pausa la funzione per evitare che il browser si blocchi mentre si attende la risposta dell’IA.
  • Una volta ricevuto, l’oggetto JSON viene memorizzato temporaneamente nella variabile response.

Il contenuto della variabile response sarà un oggetto strutturato come segue:

{
	title: "Two Wheels to the Medina: ...",
	sections: [
		{
			heading: "A Well-Deserved Rest in the Red City",
			level: 2,
			paragraphs: [ "On April 24th, our group of seven motorcyclists..." ],
			bullet_points: []
		},
		{
			heading: "Diving into the Medina and Jemaa el-Fnaa",
			level: 2,
			paragraphs: [ "We spent the day exploring the historic Medina..." ],
			bullet_points: [ 
				"Navigating the vibrant, maze-like alleys of the ancient Medina", 
				"Tasting traditional Berber tagines and Moroccan mint tea",
				"Shopping for handmade leather goods, spices, and lanterns in the souks" 
			]
		},
		{...}
	],
	content: "Fallback plain text...",
	transcript: "Full transcript..."
}

Questo oggetto fornisce i dati necessari per creare i blocchi. Tuttavia, lo script potrebbe ricevere sia una stringa JSON che un JSON annidato all’interno di un oggetto. Pertanto, è necessario un ulteriore passaggio di normalizzazione prima di estrarre i dati per la generazione dei blocchi:

const normalizedSections = normalizeSectionsPayload( response.sections );
  • La funzione normalizeSectionsPayload() normalizza i payload incerti di sections trasformandoli in un array. (Vedi il codice su GitHub.)

Successivamente, la variabile normalizedSections viene passata come argomento alla funzione che converte i campi sections in blocchi nativi di Gutenberg:

const structuredBlocks = buildBlocksFromSections( normalizedSections );

Ecco un estratto dalla funzione buildBlocksFromSections():

function buildBlocksFromSections( sections ) {
	if ( ! Array.isArray( sections ) ) {
		return [];
	}

	const blocks = [];

	sections.forEach( function ( section ) {
		if ( ! section || 'object' !== typeof section ) {
				return;
			}

			const heading =
				( 'string' === typeof section.heading )
					? section.heading.trim()
					: '';

			const level = ( 3 === section.level ) ? 3 : 2;

			if ( heading ) {
				blocks.push(
					createBlock( 'core/heading', {
						content: heading,
						level: level,
					} )
				);
			}

			...

		} );
	return blocks;
}

Nel codice qui sopra, il ciclo forEach() scorre l’array di dati, estraendo section.heading e section.level da usare con la funzione nativa createBlock().

Per la mappatura di section.paragraphs e section.bullet_points, dai un’occhiata al codice sorgente su GitHub.

Possibilità di estensione infinite

L’introduzione dell’AI in WordPress apre orizzonti completamente nuovi sia per gli amministratori dei siti che per gli sviluppatori. Mentre prima dovevi costruire un’intera infrastruttura di rete da zero solo per integrare funzionalità di AI nel tuo sito WordPress, ora automatizzare il tuo flusso di lavoro editoriale e aggiungere funzionalità basate sull’AI è diventato incredibilmente semplice.

Il plugin di esempio presentato nella seconda parte di questo articolo mette in evidenza solo un singolo caso d’uso. Tuttavia, dimostra chiaramente come ora sia possibile creare strumenti che semplificano drasticamente la gestione del sito e la modifica dei contenuti. Inoltre, questa architettura sblocca funzionalità avanzate che prima erano troppo complesse da implementare o troppo costose.

Eppure, siamo solo all’inizio. L’intelligenza artificiale è una realtà in continua evoluzione che, senza dubbio, darà il via a un’enorme ondata di innovazione.

A proposito di innovazione… Hai già provato l’hosting di Kinsta? Se vuoi potenziare il tuo sito web con la migliore tecnologia disponibile oggi per WordPress, prova Kinsta senza rischi o contatta il nostro team commerciale per saperne di più.

Carlo Daniele Kinsta

Carlo è cultore appassionato di webdesign e front-end development. Gioca con WordPress da oltre 20 anni, anche in collaborazione con università ed enti educativi italiani ed europei. Su WordPress ha scritto centinaia di articoli e guide, pubblicati sia in siti web italiani e internazionali, che su riviste a stampa. Lo trovate su LinkedIn.