Elenco documenti creato grazie alla IA utilizzando Comandi Rapidi
Non sono sicuramente un “credente delle IA” ma sto cercando di imparare il loro funzionamento e, soprattutto, i campi in cui poterle usare concretamente.
In questo articolo ti spiegherò come ho utilizzato gli LLM per creare in modo rapido e (quasi) senza sforzo l’elenco dei documenti di un atto giudiziario.
0. Premessa: rinvio alle basi e nomenclatura dei file
Prima di entrare nel vivo dell’articolo, tuttavia, occorre fare un passo indietro.
0.1 Articolo su come utilizzare Comandi Rapidi per dialogare con le API di Ollama
Recentemente ho pubblicato questo articolo in cui spiego i funzionamenti di base delle API di Ollama e di come utilizzare Comandi Rapidi per interfacciarvisi da remoto.
Per motivi di spazio do per scontato che tu abbia letto l’articolo in questione ed abbia preso un minimo di dimestichezza con l’argomento.
0.2 Nomenclatura dei file
Altro presupposto per il funzionamento del comando rapido che ti esporrò in questo articolo è che tu abbia abbracciato la “mia” modalità di denominare i file da depositare con gli atti.
Infatti per poter utilizzare qualsiasi LLM per tale scopo occorre dargli un nome del file sufficientemente strutturato e da cui possa “estrarre” il contenuto ed i dati effettivi del documento.
Da ultimo segnalo che, volendo, si potrebbe passare l’effettivo contenuto del documento all’LLM per far determinare la descrizione dello stesso direttamente dall’LLM. Questo approccio ha tuttavia due grossi difetti:
- Richiede un norme quantità di risorse: passare il contesto di un intero documento è limitato dalla finestra di contesto dell’LLM e, anche potendo gestire grosse finestre, richiede comunque computer con enormi quantità di vRAM;
- Richiedere ad un LLM di descrivere un documento è potenzialmente pericoloso ed un eventuale prompt sarebbe complesso e sicuramente non restituirebbe un buon risultato.
Con il mio “trucco”, grazie ad una buona denominazione iniziale del documenti (utile anche ai fini di ricerca dello stesso ed alla sua buona archiviazione), è possibile dare delle informazioni precise all’LLM ed evitare eccessive “allucinazioni”.
Fatte questo dovute premesse … iniziamo!
1. Creare il prompt
Immagina di avere i seguenti 5 documenti:
doc-01-2019-10-01-perizia_stima_geom_Bianchi.pdf
doc-02-2020-01-10-diffida_avv_Strozzi.pdf
doc-03-2021-09-23-invito_negoziazione_assisstita_e_ricevute.pdf
doc-04-2022-02-28-corrispondenza_email.pdf
doc-05-2023-03-09-senteza_tribunale_milano.pdf
Seguono la mia nomenclatura tipica. In particolare i documenti sono già stati numerati con il mio servizio di Automator (ma ho creato anche un comando rapido che fa la stessa cosa).
Oltre a ciò è presente la data del documento, nel formato ISO 8601, e c’è una sommaria descrizione del documento nel nome.
1.1 Few Shot
La tecnica del prompt few shot è piuttosto semplice e consiste nel dare alcuni esempi di “domanda” e “risposta” all’LLM per indirizzare il risultato della risposta dell’LLM.
Ho così creato una serie di esempi, basati su casi pratici (ma anonimizzati) come mostrato qui sotto:
- Il nome del file: "2023-11-06 427F preventivo accettato.pdf" deve essere convertito in "Preventivo accettato datato 06/11/2023"
E creato il prompt come segue:
##Persona
Sei un assistente preciso e puntale, rispondi in modo sintentico.
## Contesto
Il tuo compito è convertire il nome di un file in un testo descrittivo da inserire in un elenco documenti da produrre in un giudizio civile secondo gli esempi che seguono.
### 1. Esempi in cui c'è la data nel nome del file
- Il nome del file: "2023-11-06 427F preventivo accettato.pdf" deve essere convertito in "Preventivo accettato datato 06/11/2023"
- Il nome del file: "2023-11-06_427F_preventivo_macchianera_accettato.pdf" deve essere convertito in "Preventivo Macchianera accettato datato 06/11/2023"
- Il nome del file: “2019-07-17_VISURA_CATASTALE_ROSSI.pdf” deve essere convertito in "Visura catastale dell'immobile di Rossi datato 17/07/2019"
- Il nome del file: “doc-07-2021-09-21-ROSSI_MARIO_Vs_BIANCI_LUCA_PRIMA_ASSICURAZIONE_Spa_polizza_Casa_&_Servizi_nr_1_58534_148_162329271.eml” deve essere convertito in "Copia email Polizza casa & Servizi n. 1/58534/148/162329271 del 21/09/2021"
- Il nome del file: “doc-03-2024-11-14_copia_semplice_rapporto_riepilogativo_118.pdf” deve essere convertito in "Copia semplice rapporto riepilogativo del 118 datato 14/11/2024"
- Il nome del file: “2023-08-29 Cicerone a Bianchi 427F ulteriori Documentazione per OCC.eml” deve essere convertito in "Email del 29/08/2023 inviata da Cicerone a Bianchi relativa a ulteriore documentazione per l’OCC"
### 2. Esempi in cui non c'è la data nel nome del file
- Il nome del file: “doc-03copia_semplice_rapporto_riepilogativo_118.pdf” deve essere convertito in "Copia semplice rapporto riepilogativo del 118"
- Il nome del file: "427F_preventivo_macchianera_accettato.pdf" deve essere convertito in "Preventivo Macchianera accettato"
- Il nome del file: "preventivo accettato.pdf" deve essere convertito in "Preventivo accettato"
Converti il nome del file che segue, racchiuso tra " ", utilizzando lo schema fornito:
Ovviamente tu puoi personalizzare e raffinare il prompt come meglio credi. Anzi, ti consiglio di farlo perché deve essere più vicino possibile al tuo modo di denominare i documenti, altrimenti avrai risultati mediocri.
2. Quale LLM utilizzare?
I risultati migliori li ho ottenuti con i modelli di dimensioni maggiori: in particolare Mixtral, nella mia versione quantizzata a 3bit, e Gemma2 27B. Tuttavia questi modelli richiedono molta RAM, il mio MacStudio con 32Gb di RAM li riesce a gestire ma, sotto i 32Gb di vRAM non sono utilizzabili.
Risultati buoni li ho ottenuti con Mistral 7.2B (4,1 GB) che gira senza problemi sul mio MacMini M1 con 8Gb di RAM e Gemma2 9.2B (5.4 GB) che, invece, richiede più RAM.
2.1 Nella tana del bianconiglio con Llama 3.2 3B
Nei miei esperimenti ho provato ad utilizzare anche Llama 3.2 3B; come ho scritto qui infatti è un modello molto piccolo che può girare rapidamente su qualsiasi tipo di Mac con AppleSilicon.
I risultati ottenuti tuttavia erano pessimi.
Un pomeriggio però mi ci sono messo a brutto grugno e, revisionando totalmente il prompt, sono riuscito ad ottenere dei risultati “decenti”, come mostrato qui sotto. Come potrai notare la conversione non è perfetta ma, allo stato, è il meglio che sono riuscito ad ottenere.
Perizia di stima del geometra Bianchi del 01/10/2019
Email del 10/01/2020 inviata da Avv. Strozzi relativa a diffida
Email dell'invito alla negoziazione assistita e ricevuta del 23/09/2021
Corrispondenza email datata 28/02/2022
Sentenza del Tribunale di Milano datata 09/03/2023
Di seguito ti lascio il prompt che ho usato, se vuoi provarlo e/o modificarlo per le tue esigenze.
<Esempi in cui hai trovato la data nel nome del file>
- "2023-11-06 427F preventivo accettato.pdf" diventa "Preventivo accettato datato 06/11/2023"
- "2023-11-06_427F_preventivo_macchianera_accettato.pdf" diventa "Preventivo Macchianera accettato datato 06/11/2023"
- “2019-07-17_VISURA_CATASTALE_ROSSI.pdf” diventa "Visura catastale dell'immobile di Rossi datato 17/07/2019"
- “doc-07-2021-09-21-ROSSI_MARIO_Vs_BIANCHI_LUCA_PRIMA_ASSICURAZIONE_Spa_polizza_Casa_&_Servizi_nr_1_58534_148_162329271.eml” diventa "Copia email Polizza casa & Servizi n. 1/58534/148/162329271 del 21/09/2021"
- “doc-13-2023-08-29 Cicerone a Bianchi 427F ulteriori Documentazione per OCC.eml” diventa "Email del 29/08/2023 inviata da Cicerone a Bianchi relativa a ulteriore documentazione per l’OCC"
- "doc-01-2019-10-01-perizia_stima_geom_Bianchi.pdf" diventa "Perizia di stima del geometra Bianchi del 01/10/2019"
</Esempi in cui hai trovato la data nel nome del file>
<Esempi da usare se non trovi la data>
-"427F_preventivo_macchianera_accettato.pdf" diventa "Preventivo Macchianera accettato"
- "doc-99-preventivo accettato.pdf" diventa "Preventivo accettato"
- "doc-10-Tabella_elenco_crediti.pdf" diventa "Tabella elenco dei creditori"
- "doc-06-ordinanza_tribunale_reggio_emilia.pdf" diventata "Ordinanza del Tribunale di Reggio Emilia"
</Esempi da usare se non trovi la data>
<context>
Il tuo compito è convertire il nome di un file che ti verrà passato tra " " in un testo descrittivo per creare un elenco documenti secondo lo schema degli esempi che precedono.
</context>
<procedure>
Se trovi una data nel nome del file usa <Esempi in cui hai trovato la data nel nome del file>, altrimenti ragiona passo passo e riprova. Da ultimo usa <Esempi da usare se non trovi la data>.
</procedure>
<task>
Converti il nome del file che segue, racchiuso tra " ", utilizzando lo schema fornito:
</task>
Alcune considerazioni veloci sul prompt che precede:
- Ho usato più o meno gli stessi esempi ma ho dovuto bilanciarli ed anche così il modello tende a utilizzare più alcuni tipi di esempi rispetto ad altri (nella versione che ho condiviso si è “fissato” con le email);
- Ho notato che le istruzioni di maggior importanza bisogna metterle alla fine del prompt, in questo assomiglia a Mistral, “ricorda“ meglio le ultime cose;
- Ho usato il trucco dei tag xml, ovvero ho definito delle aree del prompt racchiuse da
<tag>
e</tag>
, per la definizione dei compiuti più importanti poi ho addirittura usato termini in inglese per “fami capire meglio”, questo metodo è un po' come la formattazione in markdown aiuto l’LLM ad essere più centrato; - Ho riformulato svariate volte il prompt, “raffinandolo” nel tempo per dare istruzioni che fossero seguite nel modo più puntale possibile;
- Ho anche inserito un system prompt per cercare di imbrigliare la creazione casuale dell’LLM (come meglio si vedrà nella parte dedicata alla costruzione del comando rapido).
3. Sperimentazione e raffinamento del prompt
Da quanto ho scritto fin qui puoi capire che la conversione da nome del file a testo discorsivo è stata una lunga attività di sperimentazione.
Con gli LLM, soprattutto di piccole dimensioni, raffinare il prompt è un compito necessario (ed un po' tedioso) che però, nel lungo periodo, può portare a risultati notevoli.
Il rovescio della medaglia, tuttavia, è che aspettarsi risultati perfetti al primo tentativo è tutto fuorché scontato.
Entra quindi in gioco il solito problema della automazioni: valutare se il tempo dedicato a creare una automazione ci verrà restituito con gli interessi nel futuro.
Per quanto mi riguarda, allo stato, così non è stato per questo mio piccolo esperimento ma, essendo appunto un esperimento, mi è stato utile per imparare e sperimentare sia le mia capacità di prompting sia quanto è possibile “spremere” da modelli di piccole dimensioni.
4. Il comando rapido
Predisposto il prompt ho potuto senza troppi problemi dedicarmi alla creazione del comando rapido.
Il comando svolge le seguenti operazioni:
- Cattura i file da cui estrarre il nome da passare all’LLM;
- Ordina i nomi (che abitualmente iniziano con doc-01, doc-02 etc …) in ordine alfabetico;
- Passa la lista dei nomi dei file ad un loop in cui:
- Viene fatta la chiamata all’LLM per ogni nome del file e convertito in testo,
- Estrapolata la risposta dal dizionario restituito dall’LLM a Comandi Rapidi,
- Aggiunta la risposta ad una variabile “elenco” in cui viene salvato l’elenco discorsivo dei documenti;
- Ultimato il loop viene salvato l’elenco dei documenti negli appunti, si potrebbe fare di più ma per semplicità (visto che era una prova di concetto) non sono andato oltre;
- Manda un avviso che l’operazione è ultimata, il comando infatti seppur veloce richiede qualche secondo per essere completato (soprattutto se il modello dell’LLM deve essere caricato in memoria per la prima volta).
4.1 Recuperare i file ed ordinarli
La prima cosa è permettere al comando rapido di ricevere i file selezionati in una cartella del Finder (per macOS) o di File (per iOS / iPadOS).
Occorre quindi andare nel lato destro dell’interfaccia di Comandi Rapidi e premere il pulsante i (come mostrato al punto 1 dell’immagine sottostante), a questo punto occorre abilitare le azioni rapide nel Finder dando le apposite spunte (per macOS) e la condivisione (per iOS / iPadOS), come mostrato al punto 2.
Comparirà l’azione “Ricevi” (come mostrato nell’immagine sottostante). Qui, per evitare ti passare qualsiasi cosa seleziono la sola voce “File” e, se l’oggetto passato al comando rapido non è un file scelgo l’opzione di interrompere il comando e dare un messaggio all’utente, come mostrato nell’imagine sottostante.
Ho poi aggiunto l’azione “Filtra i file”. Qui ho scelto l’opzione Ordina per: “Nome” e Ordina “Dalla A alla Z”. In questo modo i file passati saranno nell’ordine crescente (doc-01… , doc-02… e così via).
4.2 Variabile elenco e loop
A questo punto ho “dichiarato” la variabile ”elenco”, usando l’azione “imposta variabile”. La variabile in questo punto sarà vuota perché non ho dato un valore al campo “input", come mostrato nell’immagine sottostante punto 1.
Inserisco poi l’azione “Ripeti per ogni”, ovvero il loop.
Qui interessa segnalare, come mostrato nell’immagine sottostante punto 2, che passo al loop l’elenco crescente dei file ma non il file intero, solo il suo nome.
Per fare ciò occorre prima selezionare come variabile generata dall’azione “filtra i file”, del punto precedente, e poi cliccarci sopra e far comparire il menù contestuale della variabile (File nel nostro caso) qui selezionare come Tipo la voce “File” ed in Ottieni: scorrere l’elenco fino a trovare la voce “Nome”, come mostrato al punto 3 dell’immagine sottostante.
4.3 Chiamata dell’LLM
Il grosso del loop è la chiamata all’LLM che ho già spiegato in dettaglio in questo articolo.
Qui mi interessa concentrarmi sugli ultimi passaggi.
Ottenuta la risposta dell’LLM, al punto 1 dell’immagine sottostane, inserisco la stessa in una azione testo (punto 2) il cui unico scopo è aggiungere un “a capo”, per poi creare grazie alla ripetizione del loop l’elenco delle descrizioni dei file.
Posto che la risposta dell’LLM è racchiusa tra virgolette, questo testo viene “pulito” con una azione “Sostituisci testo”, punto 3 dell’immagine sottostante.
Infine, come mostrato al punto 4, l’azione “Aggiungi alla variabile” mi permette di aggiungere una risposta dopo l’altra alla variabile.
La ripetizione finisce quando sono stati passati tutti gli elementi selezionati originariamente (l’elenco dei file per intenderci).
4.4 Salvataggio elenco negli appunti e avviso all’utente
Siamo quindi arrivati alla fine del comando rapido.
Le ultime due azione salvano l’elenco ottenuto dal loop negli appunti del sistema, usando l’azione “Copia negli appunti” (punto 1 dell’immagine sottostante) e avvisano l’utente che il comando rapido ha ultimato il suo corso (punto 2) con l’azione “Mostra avviso”.
5. Il comando rapido fatto e finito da scaricare
Di seguito ti lascio i 2 comandi rapidi sia per Mistral che per Llama 3.2.
I 2 comandi funzionano sia su macOS che su iOS / iPadOS, ma bisogna abilitarli rispettivamente: nella azioni rapide del Finder per macOS e nella condivisione per iOS / iPadOS.
Oltre a ciò dovrai inserire l’indirizzo IP del tuo Mac AppleSilicon, prima dell’azione testo ho inserito un commento che spiega cosa fare (maggiori informazioni le trovi in questo articolo, sottopunto 2.4 e 2.5).
Infine, se vorrai cambiare modello di LLM, dovrai modificare il valore il parametro “model” nell’azione “Ottieni contenuti dell’URL”, come mostrato nell’immagine sottostante.
6. Le particolarità della configurazione di Llama 3.2 3B
Da ultimo ti segnalo le particolarità della configurazione del modello Llama 3.2 3B.
Come si vede nell’immagine sottostante ho modificato in parte il prompt.
In particolare, punto 1, ho personalizzato il _system prompt_on questa istruzione: Sei un assistente preciso e puntale. Rispondi a tono e solo alla domanda.
Non sono sicuro dell’utilità effettiva ma ho preferito cercare di “restringere” il campo di azione / libertà dell’LLM.
Ho poi aumentato la finestra del contesto (punto 2), ne ho parlato in dettaglio qui al punto 3.2; anche qui non credo sia necessario ma Llama 3.2 pure essendo un piccolo modella ha una finestra di contrasto di 128.000 tokens.
Ho, infine, messo al minimo la temperatura del modello, ovvero il grado di casualità della risposta del modello (punto 3).
In conclusione
In questo articolo abbiamo visto come semplificarci la vita grazie alle potenzialità linguistiche degli LLM utilizzando Comandi Rapidi.
I buoni risultati ottenuti con i vari modelli di LLM locali mostrano: da un parte le potenzialità di questi strumenti, dall’altra i limiti generali di questi sistemi.
Credo, in particolare, che i test fatti su Llama 3.2 3B dimostrino come sia possibile, con gli opportuni accorgimenti ed accortezze, lavorare anche con modelli relativamente piccoli.
Da ultimo, ho avuto modo di mostrarti il funzionamento di un loop in Comandi Rapidi. Questa opzione permette di esegui un numero enorme di operazioni ripetitive, velocizzando e semplificando le automazioni che crei.
Come sempre, se ti è piaciuto quel che hai letto o visto e non l’hai già fatto, ti suggerisco di iscriverti alla mia newsletter. Ti avvertirò dei nuovi articoli che pubblico (oltre ai podcast e video su YouTube) e, mensilmente, ti segnalerò articoli che ho raccolto nel corso del mese ed ho ritenuto interessanti.