Introduzione agli agenti LLM con Langchain: quando RAG non basta |  di Alex Honchar |  Marzo 2024

 | Intelligenza-Artificiale

Principi del primo ordine della struttura cerebrale per gli assistenti AI

Ciao a tutti, questo articolo è la forma scritta di un tutorial che ho condotto due settimane fa Laboratorio dei neuroni. Se preferisci un percorso narrativo, puoi trovare il video di YouTube qui:

Come sempre, puoi trovare il codice su GitHubed ecco i notebook Colab separati:

  1. Pianificazione e ragionamento
  2. Diversi tipi di ricordi
  3. Vari tipi di strumenti
  4. Creazione di agenti completi
Illustrazione dell'autore. Gli LLM sono spesso arricchiti con memoria esterna tramite l'architettura RAG. Gli agenti estendono questo concetto alla memoria, al ragionamento, agli strumenti, alle risposte e alle azioni

Iniziamo la lezione esplorando vari esempi di agenti LLM. Sebbene l’argomento sia ampiamente discusso, pochi utilizzano attivamente gli agenti; spesso, ciò che percepiamo come agenti sono semplicemente grandi modelli linguistici. Consideriamo un compito così semplice come cercare i risultati delle partite di calcio e salvarli come file CSV. Possiamo confrontare diversi strumenti disponibili:

  • GPT-4 con ricerca e plugin: come troverete nel cronologia chat quiGPT-4 non è riuscito a eseguire l'attività a causa di errori di codice
  • AutoGPT Attraverso https://evo.ninja/ almeno potrebbe generare una sorta di CSV (non ideale però):

Poiché gli strumenti disponibili non sono eccezionaliimpariamo dai primi principi su come costruire agenti da zero. Sto usando Amazing L'articolo del blog di Lilian come riferimento alla struttura ma aggiungendo altri esempi da solo.

La differenza visiva tra il semplice utilizzo del LLM “input-output” e tecniche come una catena di pensiero, una catena di pensiero con autocoerenza, un albero di pensiero

Potresti esserti imbattuto in varie tecniche volte a migliorare le prestazioni di modelli linguistici di grandi dimensioni, come offrendo suggerimenti o addirittura minacciandoli scherzosamente. Una tecnica popolare è chiamata “catena di pensiero,” dove il Al modello viene chiesto di pensare passo dopo passo, consentendo l'autocorrezione. Questo approccio si è evoluto in versioni più avanzate come “catena di pensiero con coerenza” e il generalizzato “albero dei pensieri“,” dove più pensieri vengono creati, rivalutati e consolidati per fornire un risultato.

In questo tutorial, sto usando pesantemente Langsmithuna piattaforma per la produzione di applicazioni LLM. Ad esempio, mentre creo i suggerimenti dell'albero dei pensieri, salvo i miei suggerimenti secondari nel file richiede il repository e caricarli:

from langchain import hub
from langchain.chains import SequentialChain

cot_step1 = hub.pull("rachnogstyle/nlw_jan24_cot_step1")
cot_step2 = hub.pull("rachnogstyle/nlw_jan24_cot_step2")
cot_step3 = hub.pull("rachnogstyle/nlw_jan24_cot_step3")
cot_step4 = hub.pull("rachnogstyle/nlw_jan24_cot_step4")

model = "gpt-3.5-turbo"

chain1 = LLMChain(
llm=ChatOpenAI(temperature=0, model=model),
prompt=cot_step1,
output_key="solutions"
)

chain2 = LLMChain(
llm=ChatOpenAI(temperature=0, model=model),
prompt=cot_step2,
output_key="review"
)

chain3 = LLMChain(
llm=ChatOpenAI(temperature=0, model=model),
prompt=cot_step3,
output_key="deepen_thought_process"
)

chain4 = LLMChain(
llm=ChatOpenAI(temperature=0, model=model),
prompt=cot_step4,
output_key="ranked_solutions"
)

overall_chain = SequentialChain(
chains=(chain1, chain2, chain3, chain4),
input_variables=("input", "perfect_factors"),
output_variables=("ranked_solutions"),
verbose=True
)

Puoi vedere dentro questo quaderno il risultato di tale ragionamento, il punto che voglio sottolineare qui è il giusto processo per definire i passaggi del ragionamento e rappresentarli in tale modo un sistema LLMOps come Langsmith. Inoltre, puoi vedere altri esempi di tecniche di ragionamento popolari nei repository pubblici come ReAct o Self-ask con ricerca:

prompt = hub.pull("hwchase17/react")
prompt = hub.pull("hwchase17/self-ask-with-search")

Altri approcci degni di nota sono:

  • riflessione (Shinn e Labash 2023) è un quadro per dotare gli agenti di memoria dinamica e capacità di auto-riflessione per migliorare le capacità di ragionamento.
  • Catena del senno di poi (CoH; Liu et al. 2023) incoraggia il modello a migliorare i propri risultati presentandolo esplicitamente con una sequenza di risultati passati, ciascuno annotato con feedback.
Possiamo mappare diversi tipi di ricordi nel nostro cervello ai componenti dell'architettura degli agenti LLM
  • Memoria sensoriale: Questa componente della memoria cattura input sensoriali immediati, come ciò che vediamo, sentiamo o sentiamo. Nel contesto del prompt engineering e dei modelli di intelligenza artificiale, un prompt funge da input transitorio, simile a un tocco o una sensazione momentanea. È lo stimolo iniziale che innesca l'elaborazione del modello.
  • Memoria a breve termine: La memoria a breve termine conserva temporaneamente le informazioni, in genere relative all'attività o alla conversazione in corso. Nell'ingegneria tempestiva, ciò equivale a conservare la cronologia recente della chat. Questa memoria consente all'agente di mantenere il contesto e la coerenza durante tutta l'interazione, garantendo che le risposte siano allineate al dialogo corrente. Nel codice, in genere lo aggiungi come cronologia delle conversazioni:
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain.agents import AgentExecutor
from langchain.agents import create_openai_functions_agent

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
tools = (retriever_tool)
agent = create_openai_functions_agent(
llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

message_history = ChatMessageHistory()
agent_with_chat_history = RunnableWithMessageHistory(
agent_executor,
lambda session_id: message_history,
input_messages_key="input",
history_messages_key="chat_history",
)

  • Memoria a lungo termine: La memoria a lungo termine immagazzina sia la conoscenza fattuale che le istruzioni procedurali. Nei modelli di intelligenza artificiale, ciò è rappresentato dai dati utilizzati per l'addestramento e il perfezionamento. Inoltre, la memoria a lungo termine supporta il funzionamento dei framework RAG, consentendo agli agenti di accedere e integrare le informazioni apprese nelle loro risposte. È come un archivio completo di conoscenze a cui gli agenti attingono per generare risultati informati e pertinenti. Nel codice, in genere lo aggiungi come database vettorizzato:
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings

loader = WebBaseLoader("https://neurons-lab.com/")
docs = loader.load()
documents = RecursiveCharacterTextSplitter(
chunk_size=1000, chunk_overlap=200
).split_documents(docs)
vector = FAISS.from_documents(documents, OpenAIEmbeddings())
retriever = vector.as_retriever()

In pratica, vuoi potenziare il tuo agente con una linea di ragionamento separata (che può essere un altro LLM, ovvero specifico del dominio o un altro modello ML per la classificazione delle immagini) o con qualcosa di più basato su regole o basato su API

ChatGPT Plugin E API OpenAI chiamata di funzione sono buoni esempi di LLM arricchiti con capacità di utilizzo di strumenti che funzionano nella pratica.

  • Strumenti Langchain integrati: Langchain ha un pleiade di strumenti integrati spaziando dalla ricerca su Internet e dal toolkit Arxiv a Zapier e Yahoo Finance. Per questo semplice tutorial, sperimenteremo la ricerca su Internet fornita da Si sono sciolti:
from langchain.utilities.tavily_search import TavilySearchAPIWrapper
from langchain.tools.tavily_search import TavilySearchResults

search = TavilySearchAPIWrapper()
tavily_tool = TavilySearchResults(api_wrapper=search)

llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.0)
agent_chain = initialize_agent(
(retriever_tool, tavily_tool),
llm,
agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
)

  • Strumenti personalizzati: è anche molto semplice definire i propri strumenti. Analizziamo il semplice esempio di uno strumento che calcola la lunghezza della stringa. È necessario utilizzare il @tooldecoratore per farlo sapere a Langchain. Quindi, non dimenticare il tipo di input e output. Ma la parte più importante sarà la funzione commento tra """ """ — ecco come il tuo agente saprà cosa fa questo strumento e confronterà questa descrizione con le descrizioni degli altri strumenti:
from langchain.pydantic_v1 import BaseModel, Field
from langchain.tools import BaseTool, StructuredTool, tool

@tool
def calculate_length_tool(a: str) -> int:
"""The function calculates the length of the input string."""
return len(a)

llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.0)
agent_chain = initialize_agent(
(retriever_tool, tavily_tool, calculate_length_tool),
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
)

Puoi trovare esempi di come funziona in questa sceneggiatura, ma puoi anche vedere un errore — non riporta la descrizione corretta dell'azienda Neurons Lab e nonostante richiami la giusta funzione personalizzata di calcolo della lunghezza, il risultato finale è sbagliato. Proviamo a risolverlo!

Sto fornendo una versione pulita della combinazione di tutti i pezzi dell'architettura insieme in questa sceneggiatura. Nota come possiamo facilmente scomporre e definire separatamente:

  • Tutti i tipi di utensili (ricerca, strumenti personalizzati, ecc.)
  • Tutti i tipi di ricordi (sensoriale come suggerimento, a breve termine come cronologia dei messaggi eseguibile e come blocco note all'interno del prompt e lungo termine come recupero dal database dei vettori)
  • Nessun tipo di strategia di pianificazione (come un parte di un prompt estratto dal sistema LLMops)

La definizione finale dell'agente sarà semplice come questa:

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
agent = create_openai_functions_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
agent_with_chat_history = RunnableWithMessageHistory(
agent_executor,
lambda session_id: message_history,
input_messages_key="input",
history_messages_key="chat_history",
)

Come puoi vedere nel output dello script (o puoi eseguirlo tu stesso), risolve il problema nella parte precedente relativa agli strumenti. Cosa è cambiato? Abbiamo definito a architettura completadove la memoria a breve termine gioca un ruolo cruciale. Il nostro agente ha ottenuto cronologia dei messaggi e un blocco per schizzi come parte della struttura del ragionamento che gli ha permesso di estrarre la descrizione corretta del sito Web e calcolarne la lunghezza.

Spero che questa panoramica degli elementi fondamentali dell'architettura dell'agente LLM ti aiuti a progettare bot funzionali per le attività cognitive che intendi automatizzare. Per completare, vorrei sottolineare ancora una volta l'importanza di disporre di tutti gli elementi dell'agente. Come possiamo vedere, la mancanza di memoria a breve termine o la descrizione incompleta di uno strumento possono confondere il ragionamento dell'agente e fornire risposte errate anche per compiti molto semplici come la generazione di un riepilogo e il calcolo della sua lunghezza. Buona fortuna con i tuoi progetti di intelligenza artificiale e non esitare di raggiungere se hai bisogno di aiuto presso la tua azienda!

Fonte: towardsdatascience.com

Lascia un commento

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