WEB3DEV

Cover image for Crie seu pr√≥prio YouTubeGPT usando LangChain e OpenAI ūü¶ú ūüĒó
Adriano P. Araujo
Adriano P. Araujo

Posted on

Crie seu pr√≥prio YouTubeGPT usando LangChain e OpenAI ūü¶ú ūüĒó

Desbloqueando o poder do YouTube: Aproveite a intelig√™ncia coletiva dos v√≠deos do YouTube e ative conversas inteligentes com o conte√ļdo.

Image description

Introdução

Na era digital de hoje, o YouTube revolucionou a maneira como consumimos e compartilhamos conte√ļdo de v√≠deo. De document√°rios a v√≠deos de m√ļsica cativantes, o YouTube oferece uma imensa biblioteca de v√≠deos que atendem a diversos interesses. Mas e se pud√©ssemos transformar esse vasto reposit√≥rio de conte√ļdo visual em uma conversa interativa e inteligente? Imagine poder conversar com seus v√≠deos favoritos do YouTube, extrair informa√ß√Ķes valiosas e participar de discuss√Ķes instigantes. Esse conceito agora √© uma realidade gra√ßas aos not√°veis avan√ßos da intelig√™ncia artificial ( AI ) e √† integra√ß√£o inovadora do modelo de linguagem do OpenAI.

Neste blog, orientarei voc√™ no processo de cria√ß√£o de um chatbot que transforma sua lista de reprodu√ß√£o do YouTube em uma base de conhecimento abrangente. Ao utilizar o LangChain, uma tecnologia de ponta de processamento de idiomas, podemos aproveitar a intelig√™ncia coletiva dos v√≠deos do YouTube e permitir conversas inteligentes com o conte√ļdo.

Por meio de uma abordagem passo a passo, cobriremoss principais etapas: como converter v√≠deos do YouTube em documentos de texto, gerar representa√ß√Ķes vetoriais do conte√ļdo e armazen√°-los em um poderoso banco de dados vetorial. Tamb√©m nos aprofundaremos na implementa√ß√£o de pesquisas sem√Ęnticas para recuperar informa√ß√Ķes relevantes e empregar um grande modelo de linguagem para gerar respostas em linguagem natural.

Para ajudá-lo nessa jornada, usaremos uma combinação de ferramentas poderosas, incluindo LangChain para gerenciamento de conversas, Streamlit para interface de usuário ( UI ) e ChromaDB para o banco de dados vetorial.

Antes de entrarmos no código, entederemos como podemos conseguir isso. Estas são as etapas que seguiremos:

  1. Crie uma lista dos links de vídeo do YouTube que você deseja usar para sua base de conhecimento.

  2. Converter esses vídeos do YouTube em documentos de texto individuais com a transcrição do vídeo.

  3. Converter cada documento em uma representação vetorial usando um Modelo de Incorporação.

  4. Armazenar os empreendimentos no Banco de Dados de Vetorial para recuperação.

  5. Fornecer memória para a capacidade de inferir de conversas anteriores.

  6. Fazer uma pesquisa sem√Ęntica no Banco de Dados Vetorial para obter os fragmentos relevantes de informa√ß√Ķes para a resposta.

  7. Usar um modelo de idioma grande para converter as informa√ß√Ķes relevantes em uma resposta sensata ao idioma natural.

Agora comecemos com o código. Você pode encontrar o código completo no repositório do YouTube vinculado no final desta postagem.

Em um novo diretório, abra o Código VS e, usando o terminal, crie um novo ambiente usando

pip install langchain youtube-transcript-api streamlit-chat chromadb tiktoken openai

Enter fullscreen mode Exit fullscreen mode

Crie um arquivo .env para armazenar sua chave de API OpenAI. Você pode criar uma nova chave de API em https://platform.openai.com/account/api-keys. Adicione a chave ao arquivo .env.


OPENAI_API_KEY = < sua chave api vai aqui >

Enter fullscreen mode Exit fullscreen mode

Em seguida, crie um novo arquivo Python. Vamos chamá-lo youtube_gpt.py. Importe todas as dependências e carregue o ambiente:


from youtube_transcript_api import YouTubeTranscriptApi

# Dependências LangChain 

from langchain import ConversationChain, PromptTemplate

from langchain.embeddings import OpenAIEmbeddings

from langchain.indexes import  VectorstoreIndexCreator

from langchain.document_loaders import TextLoader, DirectoryLoader

from langchain.llms import OpenAI

from langchain.memory import VectorStoreRetrieverMemory



# Dependências StreamLit

import streamlit as st

from streamlit_chat import message



# Dependências de Ambiente 

from dotenv import load_dotenv

import os



load_dotenv()

OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')

Enter fullscreen mode Exit fullscreen mode

Convertendo os vídeos do YouTube em documentos de texto

Como a primeira etapa do nosso pipeline, precisamos converter uma lista dos seus v√≠deos favoritos em uma cole√ß√£o de documentos de texto. Usaremos a biblioteca youtube-transcript-api para isso, que fornece uma transcri√ß√£o com carimbo de data e hora de todo o v√≠deo com o video-id como entrada. Voc√™ pode obter o ID do v√≠deo da √ļltima sequ√™ncia de caracteres no link do v√≠deo do YouTube. Por exemplo, https://www.youtube.com/watch?v=GKaVb3jc2No, o v√≠deo-id √© GKaVb3jc2No


video_links = ["https://www.youtube.com/watch?v=9lVj_DZm36c", "https://www.youtube.com/watch?v=ZUN3AFNiEgc", "https://www.youtube.com/watch?v=8KtDLu4a-EM"]



if os.path.exists('transcripts'):

    print('Directory already exists')

else:

    os.mkdir('transcripts')

for video_link in video_links:

    video_id = video_link.split('=')[1]

    dir = os.path.join('transcripts',video_id )

    print(video_id)

    transcript = YouTubeTranscriptApi.get_transcript(video_id)

    with open(dir+'.txt', 'w') as f:

        for line in transcript:

            f.write(f"{line['text']}\n")

Enter fullscreen mode Exit fullscreen mode

Isso criará um novo diretório com o nome transcripts, que terá documentos de texto com o ID do vídeo como nome do arquivo. Dentro dele, você pode ver a transcrição do arquivo.

Carregue os documentos no LangChain e crie um banco de dados vetorial

Ap√≥s termos os documentos de transcri√ß√£o, precisamos carreg√°-los no LangChain usando DirectoryLoader e TextLoader. O que DirectoryLoader faz √©, ele carrega todos os documentos em um caminho e os converte em peda√ßos usando TextLoader. Salvamos esses arquivos de texto convertidos na interface loader. Ap√≥s carregados, usamos a ferramenta Embeddings do OpenAI para converter os peda√ßos carregados em representa√ß√Ķes vetoriais que tamb√©m s√£o chamadas de incorpora√ß√Ķes. Em seguida, salvamos as incorpora√ß√Ķes no banco de dados vetorial. Aqui usamos o banco de dados vetorial do ChromaDB.

No c√≥digo a seguir, carregamos os documentos de texto, os convertendo em incorpora√ß√Ķes e salvando no banco de dados vetorial.


loader = DirectoryLoader(path='./', glob = "**/*.txt", loader_cls=TextLoader,

                       show_progress=True)

embeddings = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY)

index = VectorstoreIndexCreator(embedding=embeddings).from_loaders([loader])

Enter fullscreen mode Exit fullscreen mode

Vejamos o que est√° acontecendo aqui:

  • Criamos um objeto DirectoryLoader nomeado loader. Este objeto √© respons√°vel por carregar documentos de texto de um caminho especificado. O caminho √© definido para o diret√≥rio atual ('./'). O par√Ęmetro glob √© definido como "**/*.txt", que especifica que queremos carregar todos os arquivos de texto (*.txt) recursivamente (**) do caminho especificado. O par√Ęmetro loader_cls √© definido como TextLoader, indicando que queremos usar a classe TextLoader para processar cada arquivo de texto. O par√Ęmetro show_progress √© definido como True, permitindo a exibi√ß√£o do progresso durante o processo de carregamento.

  • Em seguida, criamos uma inst√Ęncia de OpenAIEmbeddings nomeado embeddings. Esse objeto √© respons√°vel por converter documentos de texto em representa√ß√Ķes vetoriais ( embeddings ) usando o modelo de idioma do OpenAI. Passamos o openai_api_key obtido das vari√°veis de ambiente para autenticar e acessar a API OpenAI.

  • Por fim, criamos uma inst√Ęncia de VectorstoreIndexCreator nomeadoindex. Esse objeto √© respons√°vel por criar um √≠ndice vetorial para armazenar as incorpora√ß√Ķes dos documentos de texto. Por padr√£o, isso usa chromadb como a loja de vetores. Passamos o objeto embedding (embeddings) para o VectorstoreIndexCreator para associ√°-lo ao processo de cria√ß√£o de √≠ndice. O m√©todo from_loaders() √© chamado no objeto VectorstoreIndexCreator, e passamos o objeto loader (contendo os documentos de texto carregados ) como uma lista para carregar os documentos no √≠ndice.

Fornecendo memória

Para continuar uma conversa com o nosso YouTube Bot, precisamos fornecer uma memória onde ele possa armazenar as conversas que está tendo nessa sessão. Usamos o mesmo banco de dados vetorial que criamos anteriormente como memória para armazenar conversas. Podemos fazer isso usando este código:


retriever = index.vectorstore.as_retriever(search_kwargs=dict(k=5))

memory = VectorStoreRetrieverMemory(retriever=retriever)

Enter fullscreen mode Exit fullscreen mode

Neste snippet de código, criamos dois objetos: retriever e memory.

O objeto retriever √© criado acessando o atributo vectorstore do objeto index, que representa o √≠ndice vetorial criado anteriormente. Usamos o m√©todo as_retriever() no vectorstore para convert√™-lo em um recuperador, o que nos permite executar opera√ß√Ķes de pesquisa. O par√Ęmetro search_kwargs √© fornecido com um dicion√°rio contendo as configura√ß√Ķes de pesquisa. Nesse caso, k=5 especifica que queremos recuperar os 5 principais resultados mais relevantes.

O objeto memory √© criado passando o objeto retriever como par√Ęmetro para a classe VectorStoreRetrieverMemory. Esse objeto serve como um componente de mem√≥ria que armazena o recuperador e permite a recupera√ß√£o eficiente dos resultados.

Essencialmente, esses dois objetos configuram o mecanismo de recupera√ß√£o para pesquisar e recuperar informa√ß√Ķes relevantes do √≠ndice vetorial. O retriever executa as opera√ß√Ķes de pesquisa reais e¬† o componente memory ajuda a gerenciar e otimizar o processo de recupera√ß√£o.

Crie uma cadeia de conversação


_DEFAULT_TEMPLATE = """The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.



Relevant pieces of previous conversation:

{history}



(You do not need to use these pieces of information if not relevant)



Current conversation:

Human: {input}

AI:"""

PROMPT = PromptTemplate(

   input_variables=["history", "input"], template=_DEFAULT_TEMPLATE

)



llm = OpenAI(temperature=0.7, openai_api_key=OPENAI_API_KEY)  
# Pode ser qualquer LLM v√°lido





conversation_with_summary = ConversationChain(

   llm=llm,

   prompt=PROMPT,

   # Definimos um max_token_limit muito baixo para fins de teste.

   memory=memory,

)

Enter fullscreen mode Exit fullscreen mode

Aqui, definimos um modelo de conversa padr√£o e criamos uma inst√Ęncia do ConversationChain.

O _DEFAULT_TEMPLATE é uma sequência que contém um modelo de conversa amigável entre um humano e uma IA. Inclui uma seção para partes relevantes do histórico de conversas anterior e uma seção para a conversa atual onde a entrada humana será inserida. O modelo usa variáveis de espaço reservado, como  {history} e  {input} para ser substituído pelos detalhes reais da conversa.

O  PROMPT é criado usando a classe  PromptTemplate, que pega as variáveis de entrada history e input, e o _DEFAULT_TEMPLATE como o modelo.

Em seguida, criamos uma inst√Ęncia do modelo OpenAI de linguagem chamado llm. √Č inicializado com um valor de temperatura de 0,7, que controla a aleatoriedade das respostas do modelo. A openai_api_key √© fornecida para autenticar e acessar a API OpenAI. Observe que llm pode ser substitu√≠do por qualquer modelo de idioma v√°lido.

Finalmente, criamos uma inst√Ęncia de ConversationChain chamada conversation_with_summary. √Č inicializado com o objeto llm, o PROMPT, e o objeto memory ( que criamos anteriormente ). O memory serve como componente de recupera√ß√£o para acessar informa√ß√Ķes relevantes do √≠ndice vetorial. O ConversationChain encapsula a l√≥gica e a funcionalidade de gerar respostas com base no hist√≥rico de conversas e na entrada atual usando o modelo de idioma especificado.

No geral, esse código configura o modelo de conversa, o modelo de idioma e o mecanismo de recuperação de memória para o ConversationChain, que será usado para gerar respostas inteligentes no chatbot desenvolvido pelo YouTube.

Crie a interface do usu√°rio

Em seguida, configuramos a interface do usu√°rio para o chatbot, que mostra as mensagens e fornece na caixa de texto de entrada para interagir com o bot.


st.header("YouTubeGPT")



if 'generated' not in st.session_state:

    st.session_state['generated'] = []



if 'past' not in st.session_state:

    st.session_state['past'] = []



def get_text():

    input_text = st.text_input("You: ","Hello, how are you?", key="input")

    return input_text 



user_input = get_text()



if user_input:

    output = conversation_with_summary.predict(input = user_input)



    st.session_state.past.append(user_input)

    st.session_state.generated.append(output)



if st.session_state['generated']:



    for i in range(len(st.session_state['generated'])-1, -1, -1):

        message(st.session_state["generated"][i], key=str(i))

        message(st.session_state['past'][i], is_user=True, key=str(i) + '_user')

Enter fullscreen mode Exit fullscreen mode

Aqui está uma visão geral do que o código faz:

  1. A linha do st.header("YouTubeGPT") exibe um cabeçalho intitulado "YouTubeGPT" no aplicativo Streamlit.

  2. O c√≥digo verifica se as teclas ‚Äė geradas ‚Äô e ‚Äė passadas ‚Äô est√£o presentes no st.session_state. Se eles n√£o estiverem presentes, listas vazias ser√£o atribu√≠das a essas chaves.

  3. A função get_text() é definida para recuperar a entrada do usuário por um campo de entrada de texto usando st.text_input(). O valor padrão para o campo de entrada está definido como "Olá, como você está?". A função retorna o texto de entrada do usuário.

  4. A variável user_input é atribuída o valor retornado por get_text().

  5. Se o user_input n√£o est√° vazio, o m√©todo conversation_with_summary.predict() √© chamado com a entrada do usu√°rio como o par√Ęmetro 'input. A sa√≠da gerada do chatbot √© atribu√≠da a vari√°veloutput.

  6. A entrada do usu√°rio e a sa√≠da gerada s√£o anexadas √†s listas ‚Äė passado ‚Äô e ‚Äė geradas ‚Äô nas listas st.session_state, respectivamente.

  7. Se houver saídas geradas armazenadas no st.session_state['generated'], um loop é iniciado para iterar através deles na ordem inversa.

  8. Para cada sa√≠da gerada e entrada do usu√°rio correspondente, a fun√ß√£o message() √© chamada para exibi-las como mensagens no aplicativo Streamlit. O par√Ęmetro 'key' √© usado para diferenciar entre mensagens diferentes.

  9. √Č isso a√≠. Agora voc√™ pode executar seu aplicativo usando este comando no terminal

√Č isso a√≠. Agora voc√™ pode executar seu aplicativo usando este comando no terminal


streamlit run youtube_gpt.py



Enter fullscreen mode Exit fullscreen mode

√Č assim que ser√°. Neste exemplo, usei algumas cr√≠ticas de laptop como v√≠deos.

Image description

Repositório Git: https://github.com/akshayballal95/youtube_gpt.git

Deseja conectar?
Meu site
LinkedIn
Twitter


Este artigo foi escrito por   Akshay Ballal e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.

Top comments (0)