Program-Aided Language Models

PAL (Modelli linguistici assistiti da programmi)

Gao et al., (2022) (opens in a new tab) presenta un metodo che utilizza gli LLM per leggere problemi in linguaggio naturale e generare programmi come passaggi di ragionamento intermedi. Denominato PAL (Program-Aided Language Model), si differenzia dal prompt a catena di pensiero (CoT) perché, invece di utilizzare testo in forma libera per ottenere la soluzione, delega il passo della soluzione a un runtime programmatico come un interprete Python.

PAL

Fonte immagine: Gao et al., (2022) (opens in a new tab)

Vediamo un esempio che utilizza LangChain e OpenAI GPT-3. Siamo interessati a sviluppare una semplice applicazione che sia in grado di interpretare la domanda posta e fornire una risposta sfruttando l'interprete Python.

In particolare, siamo interessati a creare una funzionalità che permetta l'uso dell'LLM per rispondere a domande che richiedono la comprensione delle date. Forniremo all'LLM un prompt che include alcuni esempi adottati da qui (opens in a new tab).

Questi sono gli import necessari:

import openai
from datetime import datetime
from dateutil.relativedelta import relativedelta
import os
from langchain.llms import OpenAI
from dotenv import load_dotenv

Prima di tutto configuriamo alcune variabili:

load_dotenv()
 
# API configuration
openai.api_key = os.getenv("OPENAI_API_KEY")
 
# for LangChain
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")

Impostazione dell'istanza del modello:

llm = OpenAI(model_name='text-davinci-003', temperature=0)

Impostazione prompt + domanda:

question = "Oggi è il 27 febbraio 2023. Sono nato esattamente 25 anni fa. Qual è la data di nascita in MM/DD/YYYY?"."
 
DATE_UNDERSTANDING_PROMPT = """
# D: Il 2015 si avvicina tra 36 ore. Qual è la data di una settimana da oggi in MM/DD/YYYY?
# Se il 2015 arriverà tra 36 ore, allora oggi è 36 ore prima.
today = datetime(2015, 1, 1) - relativedelta(hours=36)
# Una settimana da oggi,
one_week_from_today = today + relativedelta(weeks=1)
# La risposta formattata come %m/%d/%Y è
one_week_from_today.strftime('%m/%d/%Y')
# D: Se il primo giorno del 2019 è un martedì e oggi è il primo lunedì del 2019, allora oggi è 6 giorni dopo.
today = datetime(2019, 1, 1) + relativedelta(days=6)
# La risposta formattata come %m/%d/%Y è
today.strftime('%m/%d/%Y')
# D: Il concerto era previsto per il 06/01/1943, ma è stato posticipato di un giorno a oggi. Qual è la data di 10 giorni fa in MM/DD/YYYY?
# Se il concerto era previsto per il 06/01/1943, ma è stato posticipato di un giorno a oggi, allora oggi è un giorno successivo.
today = datetime(1943, 6, 1) + relativedelta(days=1)
# 10 giorni fa,
ten_days_ago = today - relativedelta(days=10)
# La risposta formattata come %m/%d/%Y è
ten_days_ago.strftime('%m/%d/%Y')
# D: Oggi è il 4/19/1969. Qual è la data di 24 ore dopo in MM/DD/YYYY?
# Oggi è il 4/19/1969.
today = datetime(1969, 4, 19)
# 24 ore dopo,
later = today + relativedelta(hours=24)
# La risposta formattata come %m/%d/%Y è
today.strftime('%m/%d/%Y')
# D: Jane pensava che oggi fosse il 3/11/2002, ma in realtà è il 12 marzo, cioè un giorno dopo. Qual è la data di 24 ore dopo in MM/DD/YYYY?
# Se Jane pensava che oggi fosse il 3/11/2002, ma in realtà è il 12 marzo, allora oggi è il 3/12/2002.
today = datetime(2002, 3, 12)
# 24 hours later,
later = today + relativedelta(hours=24)
# La risposta formattata come %m/%d/%Y è
later.strftime('%m/%d/%Y')
# D: Jane è nata l'ultimo giorno di febbraio del 2001. Oggi compie 16 anni. Qual è la data di ieri in MM/DD/YYYY?
# Se Jane è nata l'ultimo giorno di febbraio del 2001 e oggi compie 16 anni, allora oggi sono passati 16 anni.
today = datetime(2001, 2, 28) + relativedelta(years=16)
# Ieri,
yesterday = today - relativedelta(days=1)
# La risposta formattata come %m/%d/%Y è
yesterday.strftime('%m/%d/%Y')
# D: {question}
""".strip() + '\n'
llm_out = llm(DATE_UNDERSTANDING_PROMPT.format(question=question))
print(llm_out)

Si otterrà il seguente risultato:

# Se oggi è il 27 febbraio 2023 e io sono nato esattamente 25 anni fa, allora sono nato 25 anni prima.
today = datetime(2023, 2, 27)
# Sono nato 25 anni prima,
born = today - relativedelta(years=25)
# La risposta formattata con %m/%d/%Y è
born.strftime('%m/%d/%Y')

Il contenuto di llm_out è un frammento di codice Python. Di seguito, il comando exec viene utilizzato per eseguire questo frammento di codice Python.

exec(llm_out)
print(born)

Si otterrà il seguente risultato: 02/27/1998