articolo 3 7 giugno 2024

L'inclusione dei servizi di intelligenza artificiale.

Nell’articolo precedente abbiamo osservato come sia relativamente facile fornire manualmente dei dati ad un motore di intelligenza artificiale in modo che li possa commentare. Abbiamo osservato quanto sia pertinente la risposta, quanto sia professionalmente utile il documento prodotto. Abbiamo effettuato il test su tre diversi motori forniti da tre diverse aziende: OpenAI, Athropic, Mistral. La scelta di queste tre aziende non è casuale, osserveremo i dettagli più avanti nell’articolo. Al fine di comprendere le tecniche di inclusione dei servizi di intelligenza artificiale nel codice di programma occorre approfondire la conoscenza delle tecniche che permettono alle applicazioni software di inter-operare, vale a dire di lavorare insieme in modo coordinato. Tali tecniche sono conosciute attraverso l’acronimo in lingua inglese API, Application Program Interface. La parola chiave è “interfaccia”, elemento mediatore fra diversi programmi software. Attraverso le tecniche API è possibile inviare i dati aggregati dal programma di contabilità ad un motore di intelligenza artificiale, attendere la risposta, registrarla e proporla all’utente nelle forme e modalità indicate dalle istruzioni registrate nel programma di contabilità.

Lo schema seguente riassume i concetti spiegati nel testo:

API

Il quesito che viene naturale dall’osservazione dello schema è: “chi fornisce l’API?” Gli schemi generali sono soliti integrare l’API in un blocco di software, il che è formalmente corretto, ma non rende l’idea concettuale del suo effettivo funzionamento, lo schema sopra proposto mostra l’API come un elemento a sé stante perché in effetti il meccanismo API è costruito dall’insieme dei programmi software che necessitano di coordinazione. Un API concettualmente non è mai fine a sé stessa, deve la sua esistenza alla codificazione coordinata di almeno due programmi software. Accade che uno dei due software imponga i suoi standard, metaforicamente comunica all’esterno con la seguente frase: “se vuoi comunicare con me devi seguire le mie regole”. Va da sé che in questo tipo di comunicazione il programma software gerarchicamente ad un livello superiore sia il motore di intelligenza artificiale, dunque il software di contabilità si deve adeguare. L’adeguamento riguarda il protocollo di comunicazione che viene attuato indipendentemente dai linguaggi di programmazione, i quali però determinano la complessità dell’adeguamento. Per complessità si intende il suo aspetto quantitativo, vale a dire la quantità di codice scritto necessario alla sua attuazione.

I servizi di intelligenza artificiale forniti dalle aziende nel mercato pongono a disposizione degli sviluppatori di software delle interfacce API scritte nei linguaggi di programmazione che loro stessi usano per sviluppare i loro software. La scelta del linguaggio di programmazione dipende dalla disponibilità di librerie, le librerie sono una collezione di routine standard che permettono di velocizzare il lavoro di programmazione. Per esempio se ho bisogno di disegnare un cerchio sullo schermo dovrò mettere in pratica la formula matematica che mi permette di disegnare un cerchio sul piano cartesiano, ciò perché sia lo schermo che il piano cartesiano si trovano su un piano appunto. La forma generale dell’equazione è x² + y² + ax + by + c = 0 che si può sviluppare nella forma complessa, (cosθ + i · sinθ)² = r², fino ad arrivare alla sua forma esponenziale completa z + re Si sceglie la forma canonica, polare, esponenziale a seconda dei casi. Si può ben immaginare che ogni volta che c’è la necessità di disegnare un cerchio lo sviluppatore preferisce un linguaggio di programmazione che gli fornisce una routine specializzata sulla quale fornisce solo i parametri che gli servono, una routine del tipo disegna_cerchio(centro,raggio).

Attualmente il linguaggio che fornisce una libreria dotata di una collezione di routine sufficientemente pingue per lo sviluppo dell’intelligenza artificiale si chiama Python. Di conseguenza l’ API viene fornita attraverso il linguaggio Python. Al fine di avere una buona capacità di penetrazione nel mercato software, le aziende forniscono API scritte anche in altri linguaggi, tipicamente linguaggi legati allo sviluppo di applicazioni in rete internet, generalmente chiamate applicazioni web.

Dalle considerazioni sopra scritte nasce il primo problema da risolvere rispetto al software di contabilità, esso è scritto nel linguaggio usato per i plugin di Wordpress, cioè il linguaggio dal nome PHP. Guarda caso i servizi di intelligenza artificiale non forniscono API in linguaggio PHP, è il caso di dire che le cose dunque si complicano. Ad ogni modo i servizi di intelligenza artificiale forniscono sempre una versione API cosiddetta di basso livello, significa una versione a livello di equazione, nell’esempio precedente del disegno di un cerchio. Tale versione costringe lo sviluppatore ad un lavoro intenso, ne consegue un aumento dei tempi di sviluppo ed una percentuale di probabilità di errore maggiore.

A questo punto, se si desidera comprendere come si evolve il successo di un motore di intelligenza artificiale si deve prima comprendere l’ambiente nel quale si sviluppa, l’ambiente è costituito da diversi strati, una trattazione completa deve analizzare ognuno di questi strati, ma ai fini pratici di questa trattazione è sufficiente osservare lo strato più esterno, quello della società civile. La società civile dei paesi occidentali ha da tempo compreso quanto sia deleteria la segretezza, quanto sia ostacolo allo sviluppo ed al benessere della società stessa. Ben inteso che esistono limiti di tutela dei diritti e delle prerogative, la società occidentale agisce, sempre che sia possibile, nella logica della democrazia, questa logica permette di affrontare problemi comuni attraverso la dinamica collettiva. Tutto ciò per arrivare al punto di interesse, esistono comunità di sviluppatori che insieme si attivano al fine comune di provvedere a fornire gli strumenti che le aziende non forniscono. La ricerca in rete di API scritte in linguaggio PHP risulta in siti internet che pongono a disposizione del pubblico API PHP per i servizi delle aziende OpenAI, Athropic e Mistral, da qui la scelta delle loro API.

Azienda Indirizzo
OpenAIhttps://github.com/openai-php/client
Anthropichttps://github.com/mozex/anthropic-php
Mistralhttps://github.com/partITech/php-mistral

L’attuazione del codice fornito via Github necessita di competenze di ingegneria software, in particolare l’uso di “composer”. Composer è un gestore di dipendenze per il linguaggio di programmazione PHP. Semplifica l'installazione, l'aggiornamento e la gestione delle librerie di terze parti che vengono utilizzate nei progetti software. Le dipendenze sono componenti esterni che il proprio codice non attua direttamente, ma da cui dipende per svolgere alcune sue funzionalità. A questo proposito viene utile l’esempio del cerchio. Lo sviluppatore scrive una routine che serve a riempire uno spazio con dei cerchi, per fare ciò usa una libreria esistente che contiene la funzione per disegnare un cerchio. Non conviene allo sviluppatore riscrivere una funzione per disegnare un cerchio quindi usa la funzione esistente, include la libreria che contiene la funzione nella sua routine, così facendo crea una dipendenza, la sua routine dipende da una libreria che è stata acquisita da una fonte esterna.

La precisazione su “Composer”, le dipendenze e le librerie esterne è fondamentale per capire come includere i client API nel codice del software di contabilità. Un client API è un programma software che interagisce con un'API per inviare richieste e ricevere risposte, un messaggero che invia le richieste all'API e riporta le risposte. Dopo aver usato Composer per adattare il codice del client API al proprio codice ed al proprio ambiente, si può procedere all’inclusione del codice generato da Composer, vale a dire l’integrazione del servizio di intelligenza artificiale nel software di contabilità. La struttura dell’organizzazione dei file del software di contabilità è mostrata nella figura a lato. Si nota la cartella “ai” che contiene i client API delle tre aziende selezionate.tree_plugin

Una trattazione completa di Composer richiede la scrittura di un documento specifico interamente dedicato all’argomento, si rimanda l’approfondimento al sito getcomposer.org dove esiste un’ampia documentazione in lingua inglese. In lingua italiana si segnalano, fra altre a disposizione, due risorse utili: https://doc.nette.org/it/best-practices/composer e https://kinsta.com/it/blog/creare-pacchetto-composer/

L’installazione dei client corrisponde metaforicamente al montaggio delle porte di entrata, la metafora introduce una serie di concetti legati all’immagine della porta, quali la dimensione, il passaggio, la separazione, il controllo. I concetti enumerati presentano la similitudine sufficiente alla comprensione dei meccanismi ai quali il client API permette l’accesso, primo fra i quali l’immagine della chiave.

Al fine di aprire il canale API ed usufruire dei servizi forniti dai motori di intelligenza artificiale occorre generare le chiavi di accesso. Una chiave API è un codice univoco utilizzato per autenticare richieste tra programmi software e servizi API. Funge da identificatore unico e segreto per l'utente o l'applicazione che effettua la richiesta, garantendo sicurezza e controllo sull'accesso alle risorse del servizio. L’autorizzazione definisce quali risorse e funzionalità sono accessibili ad un determinato utente e applicazione. La distinzione fra utente e applicazione è fondamentale, infatti un utente può essere autorizzato ad accedere ad una serie di servizi che invece l’applicazione che l’utente usa non ha. È vero anche il contrario, può essere che una applicazione possa accedere a servizi che vanno oltre le prerogative di un utente. Nel caso dell’applicazione in esame, il plugin di Wordpress per la gestione della contabilità di una azienda od organizzazione, gli accessi ai servizi sono un sottoinsieme dell’insieme di servizi a cui l’utente può accedere. L’utilità del plugin risiede nella capacità di automatizzare tutte le possibili richieste dell’utente al motore di intelligenza artificiale in uso.

La generazione delle chiavi API necessita di una trattazione separata per fornitore, in quanto ognuno di essi impone una procedura differente, lo scopo è comunque lo stesso, fornire una chiave unica di accesso. Occorre ricordare che l’uso delle API non è gratuito, i servizi forniti sono a pagamento ed il pagamento dipende dall’uso sia in termini di quantità che di qualità, ad ogni modo si tratta di un costo che dipende dall’uso, non ci sono costi aggiuntivi nel caso i servizi non venissero usati, dunque costo a consumo. Va da sé che ogni fornitore imporrà delle regole specifiche al fornitore, nonostante esista una logica comune è ben difficile che due fornitori impongano una serie di regole assolutamente eguali. La generazione di chiavi API coincide con la formalizzazione di un rapporto economico fra l’utente ed il fornitore dei servizi accessibili attraverso le API, tale formalizzazione è rappresentata da un contratto, dunque da tutta la legislazione in materia di contratti privati. Il software di contabilità non ha voce in questo specifico capitolo. Ciò che sarà necessario attuare è l’inclusione del codice denominato “chiave API” nel database di programma, in modo che ad oni chiamata API del servizio di intelligenza artificiale, verrà inclusa la chiave API, dunque la chiamata stessa verrà identificata dal servizio.

A questo proposito il software di contabilità dispone di una opzione di menu specifica, dal nome “Chiavi API”, di seguito l’immagine della schermata che permette la registrazione di una chiave API associata ad un fornitore.

Il codice di proramma che gestisce le chiavi API rivolge una attenzione particolare alla sicurezza, in virtù del fatto che possedere chiavi API equivale alla gestione di un contratto commerciale ed alle spese ad esso associate. Una chiave API in mano a terze parti può esporre l’utente non solo a spese non controllate, ma anche a pratiche che possono sfuggire alle consuetudini scelte dall’utente.
Nel momento in cui si attiva il plugin di contabilità all’interno di Wordpress viene generata una chiave interna aleatoria, basata sulla casualità. Dunque la chiave generata non è preventivamente conosciuta da nessuna terza parte. Essa viene immediatamente registrata nel database.

$key = bin2hex(random_bytes(32));
update_option('key',$key);

Nel momento in cui la chiave API generata dal servizio di intelligenza artificiale verrà registrata nel programma essa verrà criptata sulla base della chiave interna generata all’atto di attivazione del plugin. Ciò stabilisce un primo passo di protezione. Un’altro passo di protezione si attiva nel momento di registrazione della chiave API, il software applicativo di contabilità calcola il tempo di immissione della chiave API nel modulo presentato a schermo, se esso è minore di un tempo stabilito allora c’è il sospetto che ad immettere la chiave API non sia un essere umano, dunque non accetta l’immissione. Le linee di codice sono le seguenti:

if (isset($_SESSION['form_start_time'])) {
	$start_time = $_SESSION['form_start_time'];
	$end_time = microtime(true);
	$elapsed_time = $end_time - $start_time;
	$acceptable_time = 10; // seconds
	if ($elapsed_time < $acceptable_time) { exit; }
	unset($_SESSION['form_start_time']);
}

Naturalmente non possono mancare i canonici controlli di congruità:

if ( strlen($provider) < 3 ) { exit; }
if ( strlen($api_key) < 10 ) { exit; }

Un ulteriore passo di protezione è attuato dalla presenza di un campo di immissione nascosto alla vista di un operatore umano, ma non nascosto alla rilevazione di un meccanismo automatico:

<tr style="display:none;">
	<td>
		<label for="personia_contab_falso">Falso</label>
		<input type="text" name="falso" id="personia_contab_falso">
 	</td>
</tr>

L’immissione di un dato in questo campo corrisponde alla rilevazione di una operazione effettuata da un operatore non umano, l’intera operazione di immissione dati viene invalidata. La funzione PHP che si occupa della procedura di registrazione della chiave API si chiama api_keys_input().

La gestione delle chiavi API non si risolve alla sola acquisizione del codice di chiave API, l’utente deve anche selezionare il modello di linguaggio che intende usare, si entra dunque nella complessità dell’uso e gestione del servizio di intelligenza artificiale. L’acronimo dalla lingua inglese, oramai entrato nella letteratura, è LLM, che si traduce con “modello di linguaggio esteso” o “grande”, il concetto che esprime l’acronimo riguarda l’enorme mole di dati che è necessaria per la costruzione del modello e che i dati sono rappresentati da vocaboli. Per enorme si intende una quantità tale da non poter essere gestita dai computer che normalmente si trovano nelle case o negli uffici, occorrono investimenti parecchio impegnativi per assemblare computer in grado di funzionare con la mole di dati necessaria ed anche con la necessaria velocità. Al momento della scrittura di questo articolo, i dispositivi capaci di garantire la necessaria velocità sono le GPU, i processori di grafica che fino a poco tempo fa erano quasi esclusivamente dedicati alla gestione della grafica su schermo.

La scelta del modello LLM API espone il codice ad un primo uso dell’API attraverso una chiamata specifica, la chiamata che interroga il motore di intelligenza artificiale sugli LLM dei quali dispone. Una precisazione è necessaria: non tutti i provider mettono a disposizione questa chiamata, nel nostro caso ed al momento possiamo effettuare la chiamata ai fornitori OpenAI e Mistral. Anthropic informa gli utenti solo attraverso le pagine web del loro sito, non permette, al momento, alcun automatismo. Questa situazione si riflette nel codice di programma dove alle voci OpenAI e Mistral corrisponde la chiamata API, alla voce Anthropic corrisponde una lista manuale di LLM disponibili.

function models($provider,$encryptedApikey) {
    switch ($provider) {
        case 'Mistral':
            require_once 'ai/mistral/vendor/autoload.php';
            $clientMistral = new Partitech\PhpMistral\MistralClient( decrypt_string($encryptedApikey, get_option('key')) );
            $models = [];
            try {
                $result = $clientMistral->listModels();
                foreach ($result['data'] as $m) {
                    $models[] = $m['id'];
                }
            	return $models;
            } catch (Partitech\PhpMistral\MistralClientException $e) {
                error_log($e);
            	return ['Nessuno'];
            }
        break;
        case 'Anthropic':
            $models = ['claude-3-haiku-20240307','claude-3-sonnet-20240229','claude-3-opus-20240229'];
            return $models;
        break;
        case 'Openai':
            require_once 'ai/openai/vendor/autoload.php';
            $clientOpenai = OpenAI::client( decrypt_string($encryptedApikey, get_option('key')) );
            $models = [];
            try {
                $data = $clientOpenai->models()->list();
                foreach ($data['data'] as $m) {
                    $models[] = $m['id'];
                }
            	return $models;
            } catch (Exception $e) {
                error_log($e);
            	return ['Nessuno'];
            }
        break;
        default:
    }
}

La selezione di un LLM per ogni provider conclude la procedura di inclusione del servizio di intelligenza artificiale nel software applicativo di contabilità, però dato che si è scelto di includere più di un provider, si è pensato opportuno creare una gerarchia di priorità fra i provider. La presenza multipla serve quasi esclusivamente a prevenire blocchi dovuti alla temporanea indisponibilità di un servizio, in tal maniera quando un provider non è disponibile si effettua la chiamata ad un altro provider, la gerarchia di priorità deve essere intesa esclusivamente in questo senso. L’applicativo è dotato di una opzione di menu che permette all’utente di stabilire la gerarchia, così come si può vedere nell’immagine che segue.

L’opzione di menu “Tabella API” consente di osservare l’insieme di informazioni relative ai motori di intelligenza artificiale accessibili da programma.