Archiviazione e parsing strutturati di output LLM in Python

Archiviazione e analisi strutturata degli output LLM in Python

Introduzione

L’IA generativa è attualmente utilizzata ampiamente in tutto il mondo. La capacità dei grandi modelli di linguaggio di comprendere il testo fornito e generare un testo basato su di esso ha portato a numerose applicazioni, dai chatbot agli analizzatori di testo. Ma spesso questi grandi modelli di linguaggio generano testo così com’è, in modo non strutturato. A volte vogliamo che l’output generato dai grandi modelli di linguaggio sia in un formato strutturato, ad esempio un formato JSON (JavaScript Object Notation). Supponiamo di analizzare un post sui social media utilizzando LLM, e abbiamo bisogno che l’output generato da LLM sia all’interno del codice stesso come una variabile JSON/python per eseguire un’altra operazione. Ottenere questo con la tecnica di Progettazione dei Suggerimenti è possibile, ma richiede molto tempo per giocare con i prompt. Per risolvere questo problema, LangChain ha introdotto gli Output Parses, con cui è possibile convertire l’output dei LLM in un formato strutturato.

Obiettivi di apprendimento

  • Interpretare l’output generato dai grandi modelli di linguaggio
  • Creare strutture dati personalizzate con Pydantic
  • Comprendere l’importanza dei modelli di suggerimenti e generarne uno formattando l’output di LLM
  • Imparare come creare istruzioni di formattazione per l’output LLM con LangChain
  • Scoprire come analizzare i dati JSON in un oggetto Pydantic

Questo articolo è stato pubblicato come parte del Data Science Blogathon.

Cos’è LangChain e l’output parsing?

LangChain è una libreria Python che ti permette di creare applicazioni con grandi modelli di linguaggio in poco tempo. Supporta una vasta gamma di modelli, tra cui i LLM di OpenAI GPT, PaLM di Google, e persino i modelli open-source disponibili in Hugging Face come Falcon, Llama e molti altri. Con LangChain, la personalizzazione dei suggerimenti per i grandi modelli di linguaggio è un gioco da ragazzi e include anche un archivio di vettori pronto all’uso, in grado di archiviare gli embedding di input e output. Può quindi essere utilizzato per creare applicazioni che possono interrogare qualsiasi documento in pochi minuti.

LangChain consente ai grandi modelli di linguaggio di accedere alle informazioni su Internet tramite agenti. Offre anche analizzatori di output, che ci consentono di strutturare i dati generati dai grandi modelli di linguaggio. LangChain include diversi analizzatori di output come List Parser, Datetime Parser, Enum Parser, e così via. In questo articolo, esamineremo il parser JSON, che ci consente di analizzare l’output generato dai LLM in un formato JSON. Di seguito possiamo osservare un tipico flusso di come un output LLM viene analizzato in un oggetto Pydantic, creando così dati pronti all’uso in variabili Python

Primi passi – Impostazione del modello

In questa sezione, configureremo il modello con LangChain. Utilizzeremo PaLM come nostro grande modello di linguaggio durante tutto l’articolo. Utilizzeremo Google Colab come ambiente. Puoi sostituire PaLM con qualsiasi altro grande modello di linguaggio. Inizieremo importando i moduli richiesti.

!pip install google-generativeai langchain
  • Questo scaricherà la libreria LangChain e la libreria google-generativeai per lavorare con il modello PaLM.
  • La libreria langchain è necessaria per creare prompt personalizzati, analizzare l’output generato dai grandi modelli di linguaggio
  • La libreria google-generativeai ci permetterà di interagire con il modello PaLM di Google.

Chiave API di PaLM

Per lavorare con il PaLM, avremo bisogno di una chiave API, che possiamo ottenere iscrivendoci al sito web di MakerSuite. Successivamente, importeremo tutte le librerie necessarie e passeremo la chiave API per istanziare il modello PaLM.

import osimport google.generativeai as palmfrom langchain.embeddings import GooglePalmEmbeddingsfrom langchain.llms import GooglePalmos.environ['GOOGLE_API_KEY']= 'LA TUA CHIAVE API'palm.configure(api_key=os.environ['GOOGLE_API_KEY'])llm = GooglePalm()llm.temperature = 0.1prompts = ["Elencare 5 pianeti e fornirne una descrizione"]llm_result = llm._generate(prompts)print(llm_result.generations[0][0].text)
  • Qui abbiamo creato una istanza del modello Google PaLM (Pathways Language Model) e l’abbiamo assegnata alla variabile llm
  • Nel passaggio successivo, abbiamo impostato la temperatura del nostro modello a 0.1, impostandola bassa perché non vogliamo che il modello crei contenuti fasulli
  • Successivamente, abbiamo creato un prompt come una lista e lo abbiamo passato alla variabile prompts
  • Per passare il prompt al PaLM, chiamiamo il metodo ._generate() e passiamo ad esso la lista del prompt, i risultati vengono quindi memorizzati nella variabile llm_result
  • Infine, stampiamo il risultato nell’ultimo passaggio chiamando .generations e convertendolo in testo chiamando il metodo .text

L’output per questo prompt può essere visto di seguito

Possiamo vedere che il Large Language Model ha generato un output coerente e il LLM ha anche cercato di aggiungere alcune linee per dare struttura. Ma cosa succede se voglio memorizzare le informazioni di ogni modello in una variabile? Cosa succede se voglio memorizzare separatamente i nomi dei pianeti, il periodo orbitale e la distanza dal sole? L’output generato dal modello così com’è non può essere utilizzato direttamente per ottenere questo risultato. Ecco perché serve l’Output Parser.

Creazione di un Parser di Output Pydantic e di un Template di Prompt

In questa sezione, discuteremo del parser di output pydantic di langchain. Nell’esempio precedente, l’output era in un formato non strutturato. Vediamo come possiamo memorizzare le informazioni generate dal Large Language Model in un formato strutturato.

Implementazione del codice

Iniziamo guardando il seguente codice:

from pydantic import BaseModel, Field, validatorfrom langchain.output_parsers import PydanticOutputParserclass PlanetData(BaseModel):    planet: str = Field(description="Questo è il nome del pianeta")    orbital_period: float = Field(description="Questo è il periodo orbitale in giorni terrestri")    distance_from_sun: float = Field(description="Questo è un float che indica la distanza dal sole in milioni di chilometri")    interesting_fact: str = Field(description="Questa è una curiosità interessante sul pianeta")
  • Qui stiamo importando il pacchetto Pydantic per creare una struttura dati. In questa struttura dati, memorizzeremo l’output parsando l’output dal LLM.
  • Abbiamo creato una struttura dati utilizzando Pydantic chiamata PlanetData che memorizza i seguenti dati
  • Pianeta: Questo è il nome del pianeta che forniremo come input al modello
  • Periodo Orbitale: Questo è un valore float che contiene il periodo orbitale in giorni terrestri di un particolare pianeta.
  • Distanza dal Sole: Questo è un valore float che indica la distanza tra un pianeta e il Sole
  • Curiosità Interessante: Questa è una stringa che contiene una curiosità interessante sul pianeta chiesto

Ora, vogliamo interrogare il Large Language Model per informazioni su un pianeta e memorizzare tutti questi dati nella struttura dati PlanetData parsando l’output del LLM. Per parsare un output del LLM in una struttura dati Pydantic, LangChain offre un parser chiamato PydanticOutputParser. Passiamo la classe PlanetData a questo parser, che può essere definita come segue:

planet_parser = PydanticOutputParser(pydantic_object=PlanetData)

Memorizziamo il parser in una variabile chiamata planet_parser. L’oggetto parser ha un metodo chiamato get_format_instructions() che dice al LLM come generare l’output. Proviamo a stamparlo

from pprint import pppp(planet_parser.get_format_instructions())

Nel codice sopra, vediamo che le istruzioni di formato contengono informazioni su come formattare l’output generato dal LLM. Dice al LLM di generare i dati in uno schema JSON, in modo che questo JSON possa essere analizzato nella struttura dati Pydantic. Fornisce anche un esempio di uno schema di output. Successivamente, creeremo un prompt di modello.

Prompt di modello

from langchain import PromptTemplate, LLMChaintemplate_string = """Sei un esperto quando si tratta di rispondere a domande su pianeti \Ti verrà dato il nome di un pianeta e dovrai restituire il nome del pianeta, il suo periodo orbitale in giorni \Anche la sua distanza dal sole in milioni di chilometri e un fatto interessante```{planet_name}```{format_instructions}"""planet_prompt = PromptTemplate(    template=template_string,    input_variables=["planet_name"],    partial_variables={"format_instructions": planet_parser.get_format_instructions()})
  • Nel nostro Prompt di modello, diciamo che forniremo il nome di un pianeta come input e il LLM dovrà generare un output che include informazioni come il periodo di orbita, la distanza dal sole e un fatto interessante sul pianeta
  • Quindi assegniamo questo modello alPrompTemplate() e quindi forniamo il nome della variabile di input al parametroinput_variables, nel nostro caso èplanet_name
  • Forniamo anche le istruzioni di formato, che abbiamo visto in precedenza, che dicono al LLM come generare l’output in formato JSON

Proviamo a fornire un nome di pianeta e osservare come appare il Prompt prima di essere inviato al Large Language Modello

input_prompt = planet_prompt.format_prompt(planet_name='mercury')pp(input_prompt.to_string())

Nell’output vediamo che il modello che abbiamo definito appare prima con l’input “mercury”. Seguito da quello ci sono le istruzioni di formato. Queste istruzioni di formato contengono le istruzioni che il LLM può usare per generare dati JSON.

Test del Large Language Modello

In questa sezione, invieremo il nostro input al LLM ed osserveremo i dati generati. Nella sezione precedente, vediamo come sarà la nostra stringa di input, quando inviata al LLM.

input_prompt = planet_prompt.format_prompt(planet_name='mercury')output = llm(input_prompt.to_string())pp(output)

Possiamo vedere l’output generato dal Large Language Modello. L’output è effettivamente generato in formato JSON. I dati JSON contengono tutte le chiavi che abbiamo definito nella nostra Struttura dati di PlanetData. E ogni chiave ha un valore che ci aspettiamo di avere.

Ora dobbiamo analizzare questi dati JSON nella Struttura dati che abbiamo fatto. Ciò può essere facilmente fatto con il PydanticOutputParser che abbiamo definito in precedenza. Diamo un’occhiata a quel codice:

parsed_output = planet_parser.parse(output)print("Pianeta: ",parsed_output.planet)print("Periodo orbitale: ",parsed_output.orbital_period)print("Distanza dal sole (in milioni di KM): ",parsed_output.distance_from_sun)print("Fatto interessante: ",parsed_output.interesting_fact)

Chiamando il metodo parse() per il planet_parser, prenderà l’output e lo analizza e lo converte in un oggetto Pydantic, nel nostro caso un oggetto di PlanetData. Quindi l’output, cioè il JSON generato dal Large Language Modello viene analizzato nella Struttura dati di PlannetData e ora possiamo accedere ai singoli dati da esso. L’output per quanto sopra sarà

Vediamo che le coppie chiave-valore dai dati JSON sono state elaborate correttamente in Dati di Pydantic. Proviamo con un altro pianeta e osserviamo l’output

input_prompt = planet_prompt.format_prompt(planet_name='venus')output = llm(input_prompt.to_string())parsed_output = planet_parser.parse(output)print("Pianeta: ",parsed_output.planet)print("Periodo orbitale: ",parsed_output.orbital_period)print("Distanza dal Sole: ",parsed_output.distance_from_sun)print("Fatto interessante: ",parsed_output.interesting_fact)

Vediamo che per l’input “Venere”, LLM è riuscito a generare un JSON come output ed è stato elaborato correttamente in Dati di Pydantic. In questo modo, attraverso l’elaborazione dell’output, possiamo utilizzare direttamente le informazioni generate dai Large Language Models

Potenziali applicazioni e casi d’uso

In questa sezione, esploreremo alcune potenziali applicazioni/casi d’uso reali, in cui possiamo utilizzare queste tecniche di elaborazione dell’output. L’elaborazione viene utilizzata nell’estrazione / dopo l’estrazione, ovvero quando estraiamo qualsiasi tipo di dati, vogliamo elaborarlo in modo che le informazioni estratte possano essere utilizzate da altre applicazioni. Alcune delle applicazioni includono:

  • Estrazione e analisi delle lamentele dei prodotti: Quando un nuovo marchio arriva sul mercato e rilascia nuovi prodotti, la prima cosa che desidera fare è controllare come il prodotto si sta comportando, e uno dei migliori modi per valutarlo è analizzare i post dei social media dei consumatori che utilizzano questi prodotti. Gli output parser e i LLM consentono l’estrazione di informazioni, come il marchio e i nomi dei prodotti e persino le lamentele dai post dei social media dei consumatori. Questi Large Language Models archiviano questi dati in variabili di Python attraverso l’elaborazione dell’output, consentendoti di utilizzarli per le visualizzazioni dei dati.
  • Supporto clienti: Quando si creano chatbot con LLM per il supporto clienti, una delle mansioni importanti sarà l’estrazione delle informazioni dalla cronologia delle chat dei clienti. Queste informazioni contengono dettagli chiave come quali problemi affrontano i consumatori rispetto al prodotto/servizio. È possibile estrarre facilmente questi dettagli utilizzando gli output parser di LangChain invece di creare codice personalizzato per l’estrazione di queste informazioni
  • Informazioni sulla pubblicazione di offerte di lavoro: Nello sviluppo di piattaforme di ricerca di lavoro come Indeed, LinkedIn, ecc., possiamo utilizzare LLM per estrarre dettagli dalle offerte di lavoro, tra cui titoli di lavoro, nomi delle aziende, anni di esperienza e descrizioni dei lavori. L’elaborazione dell’output può salvare queste informazioni come dati JSON strutturati per l’abbinamento e le raccomandazioni di lavoro. L’elaborazione di queste informazioni dall’output LLM direttamente attraverso gli Output Parsers di LangChain rimuove gran parte del codice ridondante necessario per eseguire questa operazione di analisi separata.

Conclusioni

I Large Language Models sono fantastici, poiché possono letteralmente adattarsi a ogni caso d’uso grazie alle loro straordinarie capacità di generazione di testo. Tuttavia, spesso falliscono quando si tratta di utilizzare effettivamente l’output generato, dove dobbiamo dedicare una quantità sostanziale di tempo all’elaborazione dell’output. In questo articolo, abbiamo esaminato questo problema e come possiamo risolverlo utilizzando gli Output Parsers di LangChain, in particolare il parser JSON che può elaborare i dati JSON generati da LLM e convertirli in un Oggetto Pydantic.

Punti salienti

Alcuni dei punti chiave di questo articolo includono:

  • LangChain è una libreria Python che consente di creare applicazioni con i Large Language Models esistenti.
  • LangChain fornisce gli Output Parsers che ci consentono di elaborare l’output generato dai Large Language Models.
  • Pydantic ci consente di definire strutture dati personalizzate, che possono essere utilizzate durante l’elaborazione dell’output dai LLM.
  • Oltre al parser JSON di Pydantic, LangChain fornisce anche diversi Output Parsers come il List Parser, Datetime Parser, Enum Parser, ecc.

Domande frequenti

I media mostrati in questo articolo non sono di proprietà di Analytics Vidhya e vengono utilizzati a discrezione dell’autore.