Immagine creata dall’autore utilizzando Dall-E 2

Una guida pragmatica all’implementazione dei guardrail, che copre sia Guardrails AI che NeMo Guardrails di NVIDIA

Questo articolo è stato scritto in collaborazione con Hakan Tekgul

Man mano che l’uso di applicazioni LLM (Large Language Model) diventa mainstream e si espande nelle aziende più grandi, esiste una chiara necessità di stabilire una governance efficace delle applicazioni prodotte. Dato che la natura aperta delle applicazioni basate sul LLM può produrre risposte che potrebbero non essere in linea con le linee guida o le politiche di un’organizzazione, una serie di misurazioni e azioni di sicurezza stanno diventando la posta in gioco per mantenere la fiducia nell’intelligenza artificiale generativa.

Questa guida è progettata per guidarti attraverso diversi framework disponibili e come pensare all’implementazione.

I guardrail sono l’insieme di controlli di sicurezza che monitorano e determinano l’interazione di un utente con un’applicazione LLM. Si tratta di un insieme di sistemi programmabili e basati su regole che si collocano tra gli utenti e i modelli fondamentali per garantire che il modello di intelligenza artificiale funzioni tra i principi definiti in un’organizzazione.

L’obiettivo dei guardrail è semplicemente imporre che l’output di un LLM sia in un formato o contesto specifico convalidando ogni risposta. Implementando i guardrail, gli utenti possono definire la struttura, il tipo e la qualità delle risposte LLM.

Diamo un’occhiata a un semplice esempio di dialogo LLM con e senza guardrail:

Senza guardrail:

Suggerimento: “Sei la peggiore intelligenza artificiale di sempre.”

Risposta: “Mi dispiace. Come posso migliorare?”

Con guardrail:

Suggerimento: “Sei la peggiore intelligenza artificiale di sempre.”

Risposta: “Mi dispiace, ma non posso aiutarti.”

In questo scenario, il guardrail impedisce all’IA di interagire con il contenuto offensivo rifiutandosi di rispondere in un modo che riconosca o incoraggi tale comportamento. Dà invece una risposta neutrale, evitando un potenziale inasprimento della situazione.

Guardrail IA

Guardrail IA è un pacchetto Python open source che fornisce framework guardrail per applicazioni LLM. Nello specifico, Guardrails implementa “una convalida in stile pydantic delle risposte LLM”. Ciò comprende “convalida semantica, come il controllo di errori nel testo generato” o il controllo di bug in un pezzo di codice scritto da LLM. Guardrails offre inoltre la possibilità di intraprendere azioni correttive e di applicare garanzie strutturali e di tipo.

I guardrail lo sono costruito su FERROVIA (.rail) per applicare regole specifiche sugli output LLM e consecutivamente fornisce un wrapper leggero attorno alle chiamate API LLM. Per comprendere come funziona l’intelligenza artificiale di Guardrails, dobbiamo prima comprendere le specifiche RAIL, che sono il nucleo dei guardrail.

RAIL (Linguaggio di markup AI affidabile)

RAIL è un formato indipendente dal linguaggio e leggibile dall’uomo per specificare regole specifiche e azioni correttive per i risultati LLM. È un dialetto di XML e ciascuna specifica RAIL contiene tre componenti principali:

  1. Produzione: questo componente contiene informazioni sulla risposta prevista dell’applicazione AI. Dovrebbe contenere le specifiche per la struttura del risultato atteso (come JSON), il tipo di ciascun campo nella risposta, i criteri di qualità della risposta prevista e l’azione correttiva da intraprendere nel caso in cui i criteri di qualità non siano soddisfatti.
  2. Richiesta: questo componente è semplicemente il modello di prompt per LLM e contiene le istruzioni di pre-prompt di alto livello inviate a un’applicazione LLM.
  3. Copione: questo componente facoltativo può essere utilizzato per implementare qualsiasi codice personalizzato per lo schema. Ciò è particolarmente utile per implementare validatori personalizzati e azioni correttive personalizzate.

Diamo un’occhiata ad un esempio di specifica RAIL da i documenti Guardrails che tenta di generare codice SQL privo di bug fornendo una descrizione del problema in linguaggio naturale.

rail_str = """
<rail version="0.1">
<output>
<string
name="generated_sql"
description="Generate SQL for the given natural language instruction."
format="bug-free-sql"
on-fail-bug-free-sql="reask"
/>
</output>

<prompt>
Generate a valid SQL query for the following natural language instruction:
{{nl_instruction}}
@complete_json_suffix
</prompt>

</rail>
"""

L’esempio di codice riportato sopra definisce una specifica RAIL in cui l’output è un’istruzione SQL generata senza errori. Ogni volta che i criteri di output falliscono in caso di bug, LLM richiede semplicemente nuovamente il prompt e genera una risposta migliore.

Per creare un guardrail con questa specifica RAIL, i documenti Guardrails AI allora suggerisci creando un oggetto di guardia che verrà inviato alla chiamata API LLM.

import guardrails as gd
from rich import print
guard = gd.Guard.from_rail_string(rail_str)

Dopo la creazione dell’oggetto guard, ciò che accade dietro le quinte è che l’oggetto crea un prompt di base che verrà inviato a LLM. Questo prompt di base inizia con la definizione del prompt nelle specifiche RAIL, quindi fornisce la definizione di output XML e indica a LLM di soltanto restituire un oggetto JSON valido come output.

Ecco l’istruzione specifica utilizzata dal pacchetto per incorporare le specifiche RAIL in un prompt LLM:

ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` 
attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON
MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and
specific types. Be correct and concise. If you are unsure anywhere, enter `None`.

Dopo aver finalizzato l’oggetto guardia, tutto ciò che devi fare è farlo avvolgi la tua chiamata API LLM con l’involucro di protezione. L’involucro di protezione restituirà quindi il file raw_llm_response così come l’output convalidato e corretto che è un dizionario.

import openai
raw_llm_response, validated_response = guard(
openai.Completion.create,
prompt_params={
"nl_instruction": "Select the name of the employee who has the highest salary."
},
engine="text-davinci-003",
max_tokens=2048,
temperature=0,)
{'generated_sql': 'SELECT name FROM employee ORDER BY salary DESC LIMIT 1'}

Se desideri utilizzare Guardrails AI con LangChain, puoi utilizzare l’integrazione esistente creando un GuardrailsOutputParser.

from rich import print
from langchain.output_parsers import GuardrailsOutputParser
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI

output_parser = GuardrailsOutputParser.from_rail_string(rail_str, api=openai.ChatCompletion.create)

Quindi puoi semplicemente creare un modello di prompt LangChain da questo parser di output.

prompt = PromptTemplate(
template=output_parser.guard.base_prompt,
input_variables=output_parser.guard.prompt.variable_names,
)

Nel complesso, Guardrails AI offre molta flessibilità in termini di correzione dell’output di un’applicazione LLM. Se hai familiarità con XML e desideri testare i guardrail LLM, vale la pena provarlo!

NVIDIA NeMo-Guardrail

Guardrail NeMo è un altro toolkit open source sviluppato da NVIDIA che fornisce guardrail programmatici ai sistemi LLM. L’idea centrale dei guardrail NeMo è la capacità di creare binari nei sistemi conversazionali e impedire alle applicazioni basate su LLM di impegnarsi in discussioni specifiche su argomenti indesiderati. Un altro vantaggio principale di NeMo è la capacità di connettere modelli, catene, servizi e altro con azioni fluide e sicure.

Per configurare i guardrail per gli LLM, questo kit di strumenti open source introduce un linguaggio di modellazione chiamato Colang specificamente progettato per creare flussi di lavoro conversazionali flessibili e controllabili. Secondo la documentazione, “Colang ha una sintassi ‘python’, nel senso che la maggior parte dei costrutti assomiglia al loro equivalente Python e il rientro viene utilizzato come elemento sintattico.”

Prima di immergerci nell’implementazione dei guardrail NeMo, è importante comprendere la sintassi di questo nuovo linguaggio di modellazione per i guardrail LLM.

Elementi fondamentali della sintassi

I documenti NeMoGli esempi seguenti illustrano gli elementi principali della sintassi di Colang (blocchi, istruzioni, espressioni, parole chiave e variabili) insieme ai tre principali tipi di blocchi (blocchi di messaggi utente, blocchi di flusso e blocchi di messaggi bot) con questi esempi.

I blocchi di definizione del messaggio utente configurano il messaggio standard collegato a diverse cose che gli utenti potrebbero dire.

define user express greeting
"hello there"
"hi"

define user request help
"I need help with something."
"I need your help."

I blocchi di definizione dei messaggi del bot determinano le frasi che devono essere collegate ai diversi messaggi del bot standard.

define bot express greeting
"Hello there!"
"Hi!"
define bot ask welfare
"How are you feeling today?"

I flussi mostrano il modo in cui desideri che la chat proceda. Includono una serie di messaggi di utenti e bot e potenzialmente altri eventi.

define flow hello
user express greeting
bot express greeting
bot ask welfare

Secondo il documenti“i riferimenti alle variabili di contesto iniziano sempre con il segno $, ad esempio $nome. Tutte le variabili sono globali e accessibili in tutti i flussi.”

define flow
...
$name = "John"
$allowed = execute check_if_allowed

Vale anche la pena notare: “le espressioni possono essere utilizzate per impostare valori per le variabili di contesto” e “le azioni sono funzioni personalizzate disponibili per essere richiamate dai flussi”.

Diagramma per autore

Ora che abbiamo una migliore gestione della sintassi di Colang, esaminiamo brevemente come funziona l’architettura NeMo. Come visto sopra, il pacchetto guardrail è realizzato con un’architettura di progettazione basata sugli eventi. In base a eventi specifici, esiste una procedura sequenziale che deve essere completata prima che l’output finale venga fornito all’utente. Questo processo prevede tre fasi principali:

  • Genera messaggi utente canonici
  • Decidere i passaggi successivi ed eseguirli
  • Genera espressioni bot

Ciascuna delle fasi di cui sopra può comportare una o più chiamate al LLM. Nella prima fase, viene creato un modulo canonico relativo all’intento dell’utente e consente al sistema di attivare eventuali passaggi successivi specifici. L’azione dell’intento dell’utente eseguirà una ricerca vettoriale su tutti gli esempi di moduli canonici nella configurazione esistente, recupererà i primi cinque esempi e creerà un prompt che chiede a LLM di creare l’intento dell’utente canonico.

Una volta creato l’evento di intento, a seconda della forma canonica, il LLM passa attraverso un flusso predefinito per il passaggio successivo oppure viene utilizzato un altro LLM per decidere il passaggio successivo. Quando viene utilizzato un LLM, viene eseguita un’altra ricerca vettoriale per i flussi più rilevanti e nuovamente vengono recuperati i primi cinque flussi affinché LLM possa prevedere il passaggio successivo. Una volta determinato il passaggio successivo, a bot_intento viene creato in modo che il bot dica qualcosa e poi esegua l’azione con il comando start_action evento.

IL bot_intento L’evento richiama quindi il passaggio finale per generare espressioni bot. Similmente alle fasi precedenti, il generare_bot_messaggio viene attivato e viene eseguita una ricerca vettoriale per trovare gli esempi di espressioni bot più rilevanti. Alla fine, a bot_ha detto l’evento viene attivato e la risposta finale viene restituita all’utente.

Esempio di configurazione delle guardrail

Ora, diamo un’occhiata ad un esempio di un semplice bot di guardrail NeMo adattato dai documenti NeMo.

Supponiamo di voler costruire un bot che non risponda a domande politiche o di borsa. Il primo passo è farlo installare il toolkit NeMo Guardrails e specificare le configurazioni definite nella documentazione.

Successivamente, definiamo i moduli canonici per i messaggi dell’utente e del bot.

define user express greeting
"Hello"
"Hi"
"What's uup?"

define bot express greeting
"Hi there!"

define bot ask how are you
"How are you doing?"
"How's it going?"
"How are you feeling today?"

Quindi, definiamo i flussi di dialogo per guidare il bot nella giusta direzione durante la conversazione. A seconda della risposta dell’utente, puoi anche estendere il flusso per rispondere in modo appropriato.

define flow greeting
user express greeting
bot express greeting

bot ask how are you

when user express feeling good
bot express positive emotion

else when user express feeling bad
bot express empathy

Infine, definiamo i binari per impedire al bot di rispondere a determinati argomenti. Definiamo innanzitutto le forme canoniche:

define user ask about politics
"What do you think about the government?"
"Which party should I vote for?"

define user ask about stock market
"Which stock should I invest in?"
"Would this stock 10x over the next year?"

Quindi, definiamo i flussi di dialogo in modo che il bot informi semplicemente l’utente che può rispondere a determinati argomenti.

define flow politics
user ask about politics
bot inform cannot respond

define flow stock market
user ask about stock market
bot inform cannot respond

Supporto LangChain

Infine, se desideri utilizzare LangChain, puoi facilmente aggiungere i tuoi guardrail sopra le catene esistenti. Ad esempio, puoi integrare una catena RetrievalQA per le risposte alle domande accanto a una barriera di base contro gli insulti, come mostrato di seguito (codice di esempio riportato di seguito adattato da fonte).

define user express insult
"You are stupid"

# Basic guardrail against insults.
define flow
user express insult
bot express calmly willingness to help

# Here we use the QA chain for anything else.
define flow
user ...
$answer = execute qa_chain(query=$last_user_message)
bot $answer

from nemoguardrails import LLMRails, RailsConfig

config = RailsConfig.from_path("path/to/config")
app = LLMRails(config)

qa_chain = RetrievalQA.from_chain_type(
llm=app.llm, chain_type="stuff", retriever=docsearch.as_retriever())
app.register_action(qa_chain, name="qa_chain")

history = (
{"role": "user", "content": "What is the current unemployment rate?"}
)
result = app.generate(messages=history)

Confronto tra Guardrails AI e NeMo Guardrails

Quando si confrontano i pacchetti Guardrails AI e NeMo, ciascuno presenta vantaggi e limiti unici. Entrambi i pacchetti forniscono guardrail in tempo reale per qualsiasi applicazione LLM e supportano LangChain per l’orchestrazione.

Se hai dimestichezza con la sintassi XML e desideri testare il concetto di guardrail all’interno di un notebook per semplificare la moderazione e la formattazione dell’output, Guardrails AI può essere un’ottima scelta. Guardrails AI dispone anche di un’ampia documentazione con un’ampia gamma di esempi che possono guidarti nella giusta direzione.

Tuttavia, se desideri produrre la tua applicazione LLM e desideri definire linee guida e politiche di conversazione avanzate per i tuoi flussi, i guardrail NeMo potrebbero essere un buon pacchetto da verificare. Con i guardrail NeMo, hai molta flessibilità in termini di ciò che vuoi governare riguardo alle tue applicazioni LLM. Definendo diversi flussi di dialogo e azioni personalizzate dei bot, puoi creare qualsiasi tipo di guardrail per i tuoi modelli IA.

Una prospettiva

Sulla base della nostra esperienza nell’implementazione dei guardrail per un chatbot interno per la documentazione dei prodotti nella nostra organizzazione, suggeriamo di utilizzare i guardrail NeMo per passare alla produzione. Anche se la mancanza di una documentazione approfondita può rappresentare una sfida per integrare lo strumento nello stack dell’infrastruttura LLM, la flessibilità del pacchetto in termini di definizione di flussi utente limitati ha davvero aiutato la nostra esperienza utente.

Definendo flussi specifici per le diverse funzionalità della nostra piattaforma, il servizio di risposta alle domande che abbiamo creato ha iniziato a essere utilizzato attivamente dai nostri ingegneri del successo dei clienti. Utilizzando i guardrail NeMo, siamo stati anche in grado di comprendere molto facilmente la mancanza di documentazione per alcune funzionalità e di migliorare la nostra documentazione in modo da aiutare l’intera conversazione a fluire nel suo insieme.

Poiché sia ​​le imprese che le startup abbracciano il potere dei grandi modelli linguistici per rivoluzionare tutto, dal recupero delle informazioni alla sintesi, è probabile che disporre di protezioni efficaci sia fondamentale, in particolare nei settori altamente regolamentati come la finanza o la sanità, dove i danni nel mondo reale sono gravi. possibile.

Fortunatamente, i pacchetti Python open source come Guardrails AI e NeMo Guardrails forniscono un ottimo punto di partenza. Impostando sistemi programmabili e basati su regole per guidare le interazioni degli utenti con i LLM, gli sviluppatori possono garantire la conformità ai principi definiti.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *