Una guida in linguaggio semplice per il reverse engineering dell’algoritmo di Twitter con LangChain, Activeloop e DeepInfra

A simple guide to reverse engineering Twitter's algorithm with LangChain, Activeloop, and DeepInfra

Immagina di scrivere un pezzo di software che potrebbe capire, assistere e persino generare codice, simile a come farebbe un sviluppatore esperto.

Bene, è possibile con LangChain. Sfruttando modelli avanzati come VectorStores, Conversational RetrieverChain e LLM, LangChain ci porta a un nuovo livello di comprensione e generazione del codice.

In questa guida, faremo una reverse engineering dell’algoritmo di raccomandazione di Twitter per comprendere meglio la base del codice e fornire spunti per creare contenuti migliori. Utilizzeremo la tecnologia di embedding di OpenAI e uno strumento chiamato Activeloop per rendere il codice comprensibile e un LLM ospitato su DeepInfra chiamato Dolly per conversare con il codice.

Quando avremo finito, saremo in grado di abbreviare il lavoro difficile che richiederebbe capire l’algoritmo chiedendo a un’intelligenza artificiale di rispondere alle nostre domande più urgenti anziché trascorrere settimane a cercare di capirlo personalmente. Iniziamo.

Una panoramica concettuale per la comprensione del codice con LangChain

LangChain è uno strumento molto utile che può analizzare i repository di codice su GitHub. Riunisce tre parti importanti: VectorStores, Conversational RetrieverChain e un LLM (Language Model) per aiutarti a comprendere il codice, rispondere alle domande su di esso nel contesto e persino generare nuovo codice all’interno dei repository di GitHub.

Il sistema Conversational RetrieverChain aiuta a trovare e recuperare informazioni utili da un VectorStore. Utilizza tecniche intelligenti come il filtraggio e il ranking consapevoli del contesto per determinare quali frammenti di codice e informazioni sono più rilevanti per la tua domanda o query specifica. Ciò che lo distingue è che tiene conto della storia della conversazione e del contesto in cui viene posta la domanda. Ciò significa che può fornirti risultati di alta qualità e pertinenti che affrontano specificamente le tue esigenze. In termini più semplici, è come avere un assistente intelligente che comprende il contesto delle tue domande e ti fornisce le migliori risposte possibili basate su quel contesto.

Ora, vediamo il flusso di lavoro di LangChain e vediamo come funziona a livello generale:

Indicizza la base del codice

Il primo passo è clonare il repository di destinazione che desideri analizzare. Carica tutti i file all’interno del repository, suddividili in porzioni più piccole e avvia il processo di indicizzazione. Puoi saltare questo passaggio se hai già un dataset indicizzato.

Embedding e Code Store

Per rendere i frammenti di codice più facilmente comprensibili, LangChain utilizza un modello di embedding consapevole del codice. Questo modello aiuta a catturare l’essenza del codice e archivia i frammenti di codice incorporati in un VectorStore, rendendoli facilmente accessibili per future query.

In termini più semplici, LangChain utilizza una tecnica speciale chiamata embedding consapevole del codice per rendere i frammenti di codice più facili da capire. Ha un modello che può analizzare il codice e catturarne le caratteristiche importanti. Successivamente, archivia questi frammenti di codice analizzati in un VectorStore, che è come un luogo di archiviazione per un accesso facile. In questo modo, i frammenti di codice sono organizzati e pronti per essere recuperati rapidamente quando hai domande o query in futuro.

Comprensione della query

Qui entra in gioco il tuo LLM. Puoi utilizzare un modello come databricks/dolly-v2-12b per elaborare le tue query. Il modello analizza le tue query e ne comprende il significato considerando il contesto ed estraendo informazioni importanti. Facendo ciò, il modello aiuta LangChain a interpretare con precisione le tue query e fornirti risultati precisi e pertinenti.

Costruisci il Retriever

Una volta che la tua domanda o query è chiara, entra in gioco il Conversational RetrieverChain. Esamina il VectorStore, dove sono archiviati i frammenti di codice, e trova i frammenti di codice più rilevanti per la tua query. Questo processo di ricerca è molto flessibile e può essere personalizzato per soddisfare le tue esigenze. Puoi regolare le impostazioni e applicare filtri specifici alle tue esigenze, garantendo di ottenere i risultati più accurati e utili per la tua query.

Costruisci la Catena Conversazionale

Una volta configurato il retriever, è il momento di costruire la Catena Conversazionale. Questo passaggio prevede di regolare le impostazioni del retriever per adattarle meglio alle tue esigenze e applicare eventuali filtri aggiuntivi che potrebbero essere necessari. Facendo ciò, puoi restringere la ricerca e assicurarti di ricevere i risultati più precisi, accurati e pertinenti per le tue query. Fondamentalmente, ti consente di ottimizzare il processo di recupero per ottenere le informazioni più utili per te.

Fai domande: Ora arriva la parte eccitante!

Puoi fare domande sul codebase utilizzando ConversationalRetrievalChain. Genererà risposte complete e consapevoli del contesto per te. Il tuo LLM, essendo parte della Conversational Chain, tiene conto dei frammenti di codice recuperati e della cronologia della conversazione per fornirti risposte dettagliate e accurate.

Seguendo questo flusso di lavoro, puoi utilizzare efficacemente LangChain per ottenere una comprensione più approfondita del codice, ottenere risposte consapevoli del contesto alle tue domande e persino generare frammenti di codice all’interno dei repository GitHub. Ora, vediamolo in azione, passo dopo passo.

Guida passo passo

Andiamo nella vera implementazione.

Acquisizione delle chiavi

Per iniziare, devi registrarti presso i rispettivi siti web e ottenere le chiavi API per Activeloop, DeepInfra e OpenAI.

Configurazione del file Indexer.py

Crea un file Python, ad esempio indexer.py, per indicizzare i dati. Importa i moduli necessari e imposta le chiavi API come variabili d’ambiente:

Gli embeddings, in parole semplici, sono rappresentazioni di testo che catturano il significato e la correlazione di diverse stringhe di testo. Sono vettori numerici o elenchi di numeri utilizzati per misurare la similarità o la distanza tra diversi input di testo.

Gli embeddings vengono comunemente utilizzati per vari compiti come la ricerca, il clustering, le raccomandazioni, il rilevamento di anomalie, la misurazione della diversità e la classificazione. Nella ricerca, gli embeddings aiutano a classificare la pertinenza dei risultati di ricerca rispetto a una query. Nel clustering, gli embeddings raggruppano insieme stringhe di testo simili.

Le raccomandazioni sfruttano gli embeddings per suggerire elementi con stringhe di testo correlate. Il rilevamento di anomalie utilizza gli embeddings per identificare valori anomali con scarsa correlazione. La misurazione della diversità consiste nell’analizzare la distribuzione delle similarità tra le stringhe di testo. La classificazione utilizza gli embeddings per assegnare le stringhe di testo alla loro etichetta più simile.

La distanza tra due vettori di embedding indica quanto le stringhe di testo corrispondenti sono correlate o simili. Distanze più piccole suggeriscono una correlazione elevata, mentre distanze più grandi indicano una correlazione ridotta.

Clonare e indicizzare il repository di destinazione

Successivamente, cloneremo il repository dell’algoritmo di Twitter, caricheremo, divideremo e indicheremo i documenti. Puoi clonare l’algoritmo da questo link.

Questo codice attraversa una directory e le sue sottodirectory (os.walk(root_dir)). Per ogni file che incontra (nomi file), cerca di eseguire i seguenti passaggi:

  • Crea un oggetto TextLoader, specificando il percorso del file che sta elaborando attualmente (os.path.join(dirpath, file)) e impostando la codifica su UTF-8.
  • Quindi chiama il metodo load_and_split() dell’oggetto TextLoader, che probabilmente legge il contenuto del file, esegue qualche operazione di elaborazione o divisione e restituisce i dati di testo risultanti.
  • I dati di testo ottenuti vengono quindi aggiunti a una lista esistente chiamata docs utilizzando il metodo extend().
  • Se si verifica un’eccezione durante questo processo, viene intercettata dal blocco try-except e semplicemente ignorata (`pass`).

Questo frammento di codice attraversa in modo ricorsivo una directory, carica e divide i dati di testo dai file e aggiunge i dati risultanti a una lista chiamata docs.

Embedding dei frammenti di codice

Successivamente, utilizziamo gli embeddings di OpenAI per incorporare i frammenti di codice. Questi embeddings vengono quindi archiviati in un VectorStore, che ci permetterà di effettuare una ricerca di similarità efficiente:

Questo codice importa la classe CharacterTextSplitter e inizializza un’istanza con una dimensione di chunk di 1000 caratteri e nessuna sovrapposizione. Quindi suddivide i documenti forniti in frammenti di testo più piccoli utilizzando il metodo split_documents e li archivia nella variabile texts.

Successivamente, imposta il nome utente (quello che hai utilizzato per registrarti su Activeloop!). Crea un’istanza di DeepLake chiamata db con un percorso del dataset che punta a un dataset pubblicamente disponibile ospitato su “app.activeloop.ai” con il nome utente specificato. La funzione di embedding gestisce gli embeddings necessari.

Infine, aggiunge i testi al db utilizzando il metodo add_documents, presumibilmente per scopi di archiviazione o ulteriori elaborazioni.

Esegui il file, quindi attendi alcuni minuti (potrebbe sembrare bloccato per un po’… di solito non più di 5 minuti). Quindi, passiamo al passaggio successivo.

Utilizzo di dolly-v2-12b per elaborare e comprendere le query degli utenti

Ora impostiamo un altro file Python, question.py, per utilizzare dolly-v2-12b, un modello di linguaggio disponibile nella piattaforma DeepInfra, per elaborare e comprendere le richieste degli utenti.

Costruzione del Retrieval

Costruiamo un retrieval utilizzando il VectorStore che abbiamo creato in precedenza.

Ecco una descrizione di ciò che fa il codice:

Il codice inizializza un oggetto DeepLake chiamato db. Legge i dati dal percorso specificato come “hub://mikelabs/twitter-algorithm”. Vale la pena notare che è necessario sostituire “mikelabs” con il proprio nome utente!

L’oggetto db viene quindi trasformato in un retriever utilizzando il metodo as_retriever(). Questo passaggio ci consente di eseguire operazioni di ricerca sui dati archiviati nel VectorStore.

Diverse opzioni di ricerca sono personalizzate modificando il dizionario retriever.search_kwargs:

La distance_metric è impostata su ‘cos’, indicando che la similarità coseno sarà utilizzata per misurare la similarità tra gli input di testo. Immagina di avere due vettori che rappresentano diversi pezzi di testo, come frasi o documenti. La similarità coseno è un modo per misurare quanto simili o correlati sono questi due pezzi di testo.

Osserviamo l’angolo tra i due vettori per calcolare la similarità coseno. Se i vettori puntano nella stessa direzione o sono molto vicini tra loro, la similarità coseno sarà vicina a 1. Ciò significa che i pezzi di testo sono molto simili tra loro.

D’altra parte, se i vettori puntano in direzioni opposte o sono lontani, la similarità coseno sarà vicina a -1. Questo indica che i pezzi di testo sono molto diversi o dissimili.

Una similarità coseno di 0 significa che i vettori sono perpendicolari o formano un angolo di 90 gradi tra loro. In questo caso, non c’è alcuna similarità tra i pezzi di testo.

Nel codice sopra, la similarità coseno viene utilizzata come misura per confrontare la similarità tra gli input di testo. Aiuta a determinare quanto sono strettamente correlati due pezzi di testo. Utilizzando la similarità coseno, il codice può classificare e recuperare le corrispondenze migliori più simili a una determinata query.

Il parametro fetch_k è impostato su 100, il che significa che il retriever recupererà le prime 100 corrispondenze più vicine sulla base della similarità coseno.

Il parametro maximal_marginal_relevance è impostato su True, suggerendo che il retriever darà priorità a risultati diversi anziché restituire corrispondenze altamente simili.

Il parametro k è impostato su 10, indicando che il retriever restituirà dieci risultati per ogni query.

Costruzione del Chain Conversazionale

Utilizziamo il ConversationalRetrievalChain per collegare il retriever e il modello di linguaggio. Ciò consente al nostro sistema di elaborare le richieste degli utenti e generare risposte consapevoli del contesto:

Il ConversationalRetrievalChain funge da collegamento tra il retriever e il modello di linguaggio. Questa connessione consente al sistema di gestire le richieste degli utenti e generare risposte consapevoli del contesto.

Porre domande

Ora possiamo porre domande sul codice di base dell’algoritmo di Twitter. Le risposte fornite dal ConversationalRetrievalChain sono consapevoli del contesto e si basano direttamente sul codice di base.

Ecco alcune domande di esempio tratte dalla documentazione di LangChain:

Ecco invece una risposta di esempio che ho ricevuto:

Risorse

Ecco alcune risorse aggiuntive che potrebbero esserti utili:

  • Documentazione di Activeloop
  • Guide di LangChain di AIModels.fyi
  • Documentazione degli embedding di OpenAI

Conclusione

In questo guida, abbiamo esplorato l’ingegneria inversa dell’algoritmo di raccomandazione di Twitter utilizzando LangChain. Sfruttando le capacità dell’IA, risparmiamo tempo ed sforzo preziosi, sostituendo l’esame manuale del codice con risposte automatiche alle query.

LangChain è uno strumento potente che rivoluziona la comprensione e la generazione del codice. Utilizzando modelli avanzati come VectorStores, Conversational RetrieverChain e un LLM ospitato su un servizio come DeepInfra, LangChain permette agli sviluppatori di analizzare efficientemente i repository di codice, fornire risposte consapevoli del contesto e generare nuovo codice.

Il flusso di lavoro di LangChain prevede l’indicizzazione della base di codice, l’embedding di frammenti di codice, l’elaborazione delle query degli utenti con modelli di linguaggio e l’utilizzo del Conversational RetrieverChain per recuperare frammenti di codice pertinenti. Personalizzando il retriever e costruendo la Chain Conversazionale, gli sviluppatori possono perfezionare il processo di recupero per ottenere risultati precisi.

Seguendo la guida passo dopo passo, puoi sfruttare LangChain per migliorare la comprensione del tuo codice, ottenere risposte consapevoli del contesto e persino generare frammenti di codice all’interno dei repository di GitHub. LangChain apre nuove possibilità per la produttività e la comprensione. Cosa costruirai con esso? Grazie per la lettura!