Migliorare la comprensione dei documenti utilizzando LangChain e OpenAI

Potenziare la comprensione dei documenti con LangChain e OpenAI

Immagine generata utilizzando DAAL-E

Con la grande crescita dell’IA generativa e dei modelli di linguaggio nella comprensione ed estrazione di informazioni dai documenti, stiamo assistendo a una nuova era in cui le macchine come GPT stanno aiutando gli esseri umani nell’estrazione, interpretazione ed estrazione delle conoscenze.

In questo articolo, esploreremo un caso simile in cui utilizziamo le API di OpenAI, insieme a LangChain, e creiamo un sistema in grado di estrarre informazioni da un documento e rispondere a domande. Cominciamo.

Passo 0: Configura il tuo ambiente

Per lo scopo di questo articolo, utilizzeremo il Notebook di Jupyter e l’API di OpenAI.

Ecco i moduli di cui avremo bisogno per questa guida.

pip install openai tiktoken chromadb langchain BeautifulSoup4

Dovremo anche impostare le credenziali dell’API di OpenAI

import osos.environ["OPENAI_API_KEY"] = "sk-xxxx"

Una volta fatto ciò, cominciamo.

Passo 1: Ottenere il contenuto del documento

Utilizzeremo un articolo dal blog di Berkeley Artificial Intelligence Research https://bair.berkeley.edu/blog/2023/07/14/ddpo/

LangChain fornisce un modo pratico per leggere i dati da un URL web e convertirli in un formato Documento. Puoi leggere di più sui caricatori di documenti qui.

Faremo uso di un WebBaseLoader come mostrato di seguito.

from langchain.document_loaders import WebBaseLoaderloader = WebBaseLoader("https://bair.berkeley.edu/blog/2023/07/14/ddpo/")data = loader.load()print(data[0].page_content

Step 2: Trasforma i documenti in frammenti di lunghezza fissa

Una volta ottenuto il contenuto del documento, il passo successivo è convertirlo in frammenti di dimensioni fisse in modo che il testo si adatti alla finestra di contesto scelta dei nostri modelli. Utilizzeremo RecursiveCharacterTextSplitter con una dimensione dei frammenti di 500.

from langchain.text_splitter import RecursiveCharacterTextSplittertext_splitter = RecursiveCharacterTextSplitter(chunk_size = 500, chunk_overlap = 0)all_splits = text_splitter.split_documents(data)print(all_splits[0])print(all_splits[1])> page_content='Addestramento di modelli di diffusione con apprendimento per rinforzo - Il blog di Berkeley Artificial Intelligence Research\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nIscriviti\nInformazioni\nArchivio\nBAIR\n\n\n\n\n\n\n\n\nAddestramento di modelli di diffusione con apprendimento per rinforzo\n\nKevin Black \xa0\xa0\n  \n  \n  14 luglio 2023\n  \n  \n\n\n\n\n\n\n\n\n\n\nAddestramento di modelli di diffusione con apprendimento per rinforzo\n\n\n\n\n\n\nreplay' metadata={'source': 'https://bair.berkeley.edu/blog/2023/07/14/ddpo/', 'title': 'Addestramento di modelli di diffusione con apprendimento per rinforzo - Il blog di Berkeley Artificial Intelligence Research', 'description': 'Il blog BAIR', 'language': 'Nessuna lingua trovata.'}page_content='I modelli di diffusione sono recentemente emersi come lo standard de facto per la generazione di output complessi e di alta dimensione. Li potresti conoscere per la loro capacità di produrre arte AI sbalorditiva e immagini sintetiche iper-realistiche, ma hanno trovato successo anche in altre applicazioni come il design dei farmaci\xa0e il controllo continuo. L'idea chiave alla base dei modelli di diffusione è di trasformare in modo iterativo il rumore casuale in un campione, come un'immagine o una struttura proteica. Questo è tipicamente motivato come massima verosimiglianza' metadata={'source': 'https://bair.berkeley.edu/blog/2023/07/14/ddpo/', 'title': 'Addestramento di modelli di diffusione con apprendimento per rinforzo - Il blog di Berkeley Artificial Intelligence Research', 'description': 'Il blog BAIR', 'language': 'Nessuna lingua trovata.'}

Step 3: Memorizzazione dei frammenti di documento utilizzando il vettore store

Dopo aver suddiviso il documento in frammenti, il passo successivo è creare embedding per il testo e memorizzarlo nel vettore store. Possiamo farlo come mostrato di seguito.

from langchain.embeddings import OpenAIEmbeddingsfrom langchain.vectorstores import Chromavectorstore = Chroma.from_documents(documents=all_splits, embedding=OpenAIEmbeddings())retriever = vectorstore.as_retriever()

Step 4: Recupera documenti simili in base alla query

Dopo aver generato gli embedding per il testo, possiamo ottenere frammenti di documento pertinenti per una query utilizzando una ricerca di similitudine vettoriale.

question = "Quali sono i passaggi utilizzati per l'algoritmo DDPO?"docs = vectorstore.similarity_search(question)print(f"Recuperati {len(docs)} documenti")print(docs[0].page_content)> Recuperati 4 documentiL'idea chiave del nostro algoritmo, che chiamiamo ottimizzazione di una politica di diffusione con eliminazione del rumore (DDPO), è che possiamo massimizzare meglio la ricompensa del campione finale se prestiamo attenzione all'intera sequenza di passaggi di eliminazione del rumore che ci ha condotti lì. Per fare ciò, riformuliamo il processo di diffusione come un processo decisionale Markoviano a più fasi (MDP). In terminologia MDP: ogni passo di eliminazione del rumore è un'azione e l'agente riceve una ricompensa solo all'ultimo passo di ogni traiettoria di eliminazione del rumore quando viene prodotto il campione finale.

Step 5: Generare una risposta utilizzando i documenti distillati

Ora che abbiamo i documenti distillati per la nostra query, possiamo creare una catena LLM per formulare una risposta alla nostra query basata sul contesto fornito dal recuperatore vectorstore. Genereremo un prompt che istruirà l'LLM a rispondere alla query e specificare un messaggio fisso in caso di incertezza.

```python
da langchain.prompts import PromptTemplatetemplate = """Usa i seguenti frammenti di contesto per rispondere alla domanda alla fine. Se non conosci la risposta, semplicemente di' che non lo sai, non cercare di inventare una risposta. Spiega la risposta in al massimo 3 frasi. Sii conciso. Alla fine della risposta, di' sempre "Fatto!". {context}Domanda: {question}Risposta:"""prompt = PromptTemplate.from_template(template)

Con questo prompt, creeremo una catena LLM come segue

da langchain.schema.runnable import RunnablePassthroughda langchain.chat_models import ChatOpenAIllm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)qa_chain = (    {"context": retriever, "question": RunnablePassthrough()}     | prompt     | llm )

Nel codice sopra, abbiamo un termine nuovo — RunnablePassThrough. È un protocollo che semplifica la creazione di catene LLM personalizzate permettendoci di connettere insieme componenti come abbiamo fatto qui sopra.

Ora possiamo utilizzare la nostra catena LLM per rispondere alla nostra query.

qa_chain.invoke("Quali sono i passaggi utilizzati per l'algoritmo DDPO?").content> 'L'algoritmo DDPO utilizza una sequenza di passaggi di denoising per massimizzare la ricompensa del campione finale. Ogni passaggio di denoising viene considerato un'azione in un processo decisionale di Markov a più passi (MDP). L'agente riceve una ricompensa solo nell'ultimo passo di ogni traiettoria di denoising quando viene prodotto il campione finale. Fatto!'qa_chain.invoke("Qual è l'idea principale discussa nell'articolo?").content> 'L'idea principale discussa nell'articolo è il problema dell'overottimizzazione e la necessità di un metodo generale per prevenirlo. Fatto!'

Il codice completo per il quaderno Python può essere trovato qui.

In questo modo, abbiamo a disposizione un sistema funzionale che può essere facilmente utilizzato per aiutare l’interpretazione e la comprensione dei documenti.

Se sei intrigato da ciò che può essere fatto utilizzando le meravigliose capacità dell’IA generativa e di LangChain, resta sintonizzato per i prossimi articoli in cui esploreremo diversi altri casi d’uso.

“`