Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Lavorare con LLM e ChatModel

Scopriamo come LangChain permette di inserire gli LLM nel nostro flusso di lavoro utilizzando apposite classi
Scopriamo come LangChain permette di inserire gli LLM nel nostro flusso di lavoro utilizzando apposite classi
Link copiato negli appunti

Gli LLM rappresentano l'elemento centrale delle architetture basate su Intelligenza Artificiale, anzi possiamo chiaramente dire che sono l'Intelligenza Artificiale innestata nelle nostre applicazioni. In questa lezione, vediamo come LangChain permetta di inserirli nel nostro flusso di lavoro utilizzando apposite classi. Proprio per comprendere il modo in cui gli LLM riescono a relazionarsi con il resto dell'ecosistema cerchiamo - in questa lezione - di utilizzarli nella maniera più isolata possibile ponendo loro semplici quesiti e leggendo le risposte che otteniamo.

Modelli testuali e chat

La documentazione di LangChain offre apposite sezioni in cui spiega quali sono i modelli a disposizione. Possiamo trovare OpenAI (con cui spesso svolgeremo le nostre prove) ma anche quelli di Anthropic, Google, Cohere, MistralAI e molti altri, per non parlare di tutti quelli locali che sapremo attivare con Ollama.

La documentazione stessa però attua una distinzione tra LLM e ChatModel dove i primi sono basati su uno scambio di testo (essenzialmente ricevono e restituiscono stringhe) mentre i secondi utilizzano in input e output messaggi, strutture dati più articolate.

LangChain implementa anche con tali modelli il protocollo Runnable che permette di uniformare la comunicazione tra componenti eterogenee mediante pipeline. Per tale motivo, sia gli LLM sia i ChatModel potranno utilizzare i metodi:

  • invoke per l'attivazione diretta;
  • stream per la fruizione dei singoli blocchi per la risposta, i chunk;
  • batch per l'inoltro di più richieste simultanee.

Oltre a ciò, l'interfaccia Runnable mette a disposizione una serie di funzionalità asincrone.

Utilizzo di LLM e ChatModel

Vediamo con qualche esempio pratico l'utilizzo sia di LLM sia di ChatModel. In entrambi i casi, useremo le API di OpenAI (nelle prossime lezioni ci sbizzarriremo anche con altri e non mancheranno modelli locali con Ollama) e per fare ciò avremo bisogno di importare la libreria LangChain che innesca la necessaria integrazione con il provider di interesse, così:

pip install -qU langchain-openai

Il modus operandi sarà generalmente simile: a seconda del provider che sceglieremo importeremo la libreria relativa ed immergeremo il tutto nel sistema di classi che LangChain ci offrirà.

Avremo bisogno a questo punto di fornire una chiave per l'utilizzo dell'LLM (sempre indispensabile per modelli accessibili in remoto) che potremo sia passare ai costruttori dei modelli come argomento sia fornire con una variabile d'ambiente:

import os
os.environ["OPENAI_API_KEY"] ="..."

Per ottenere una chiave di accesso si procederà, per ogni provider, con una procedura specifica ma che seguirà per lo più delle linee standard. Nel caso di OpenAI, accederemo alla pagina delle sue API registrandoci o facendo accesso con sistemi di autenticazione come le credenziali di Google. Una volta entrati, potremo cercare la voce API keys nel menu laterale e lì procedere con la creazione di una nuova chiave mediante il pulsante Create new secret key.

La chiave prodotta consisterà in una stringa, piuttosto lunga, che dovrà essere copiata in quel momento prima di perderne traccia.

Ogni provider pone proprie regole per il pricing e limiti gratuiti per la sperimentazione tuttavia, come vedremo, la possibilità di avere Ollama permetterà sempre sperimentazione gratuita in locale, anche all'interno di Colab.

Impiegare gli LLM

Sperimenteremo per primo il modello testuale sebbene nella maggior parte dei casi sfrutteremo i ChatModel. Impostiamo una classe OpenAI che ci servirà a scambiare richieste con il modello in formato stringa sia in ingresso che in uscita:

from langchain_openai import OpenAI
llm = OpenAI()

A questo punto possiamo utilizzarlo per un'invocazione diretta con invoke:

res=llm.invoke("Chi è stato il terzo re di Roma?")

dove res di tipo stringa conterrà:

Il terzo re di Roma è stato Tullio Ostilio, che regnò dal 673 a.C. al 642 a.C.

Analogamente, potremo richiederlo in streaming ed inviare in stampa i singoli chunk con:

res=llm.stream("Chi è stato il terzo re di roma?")
for chunk in res:
  print(chunk)

per ottenere la risposta un token alla volta:

Il
 ter
zo
 re
 di
 Roma
 è
 stato
 T
ull
us
 Host
ili
us
,
 che
 govern
ò
 dal
673
 a
.C
.
 al
642
 a
.C
.

Inoltrare richieste con batch

Infine, con batch potremo inoltrare più richieste passandone una lista, ognuna in formato stringa, e ricevendo altresì una lista di risposte sempre, ognuna, in formato stringa:

group_of_res=llm.batch(
    [
        "Chi è stato il re di roma più longevo?",
        "Qual è la seconda città più importante della Grecia?",
        "Se Andrea è il fratello di Sonia e Sonia è la moglie di Filippo, chi è la mamma di Filippo per Sonia e Filippo per Andrea?"
    ]
)

ove le risposte saranno:

['\n\nIl re di Roma più longevo è stato Servio Tullio, che regnò per 44 anni dal 578 a.C. al 534 a.C.',
 '\n\nLa seconda città più importante della Grecia è Salonicco. ',
 '\n\nLa mamma di Filippo per Sonia è la suocera, mentre Filippo è il cognato di Andrea.']

Impiegare ChatModel

Con i ChatModel avremo un qualcosa di molto simile ma la principale differenza che, anche nel caso in cui la richiesta sia una stringa come negli esempi precedenti, la risposta sarà un messaggio ed in particolare sarà un AIMessage:

from langchain_openai import ChatOpenAI
chat_model = ChatOpenAI()

e sperimentando una semplice invocazione aimsg=chat_model.invoke("Chi è stato il terzo re di roma?") otteniamo un AIMessage:

AIMessage(content='Il terzo re di Roma è stato Tullo Ostilio, che regnò dal 672 a.C. al 640 a.C.', response_metadata={'token_usage': {'completion_tokens': 29, 'prompt_tokens': 17, 'total_tokens': 46}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-fda...', usage_metadata={'input_tokens': 17, 'output_tokens': 29, 'total_tokens': 46})

contenente la risposta in aimsg.content (comunissima stringa) nonché altre informazioni su modello impiegato e token scambiati.

Potremo anche usare, tra gli altri, il metodo batch che con il medesimo approccio restituirà una lista di AIMessage ognuno fornito di contenuti e informazioni varie:

group_of_res=chat_model.batch(
    [
        "Chi è stato il re di roma più longevo?",
        "Qual è la seconda città più importante della Grecia?",
        "Se Andrea è il fratello di Sonia e Sonia è la moglie di Filippo, chi è la mamma di Filippo per Sonia e Filippo per Andrea?"
    ]
)

con una struttura di risposta di questo tipo:

[
    AIMessage(content='Il re di Roma più longevo è stato re Servio Tullio, che regnò per circa 44 anni, dal 578 al 534 a.C.', response_metadata={'token_usage': {'completion_tokens': 36, 'prompt_tokens': 19, 'total_tokens': 55}, ...),
 AIMessage(content='La seconda città più importante della Grecia è Salonicco.', ...),
 AIMessage(...)
]

Ti consigliamo anche