<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Fabio Simoes</title>
    <description>The latest articles on DEV Community by Fabio Simoes (@fsimoes).</description>
    <link>https://dev.to/fsimoes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1260797%2Fcbc6d35c-907a-4e4a-b040-f7024a18f637.png</url>
      <title>DEV Community: Fabio Simoes</title>
      <link>https://dev.to/fsimoes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fsimoes"/>
    <language>en</language>
    <item>
      <title>Resumindo vídeos do Youtube com auxílio de LLM's</title>
      <dc:creator>Fabio Simoes</dc:creator>
      <pubDate>Sat, 19 Oct 2024 13:19:49 +0000</pubDate>
      <link>https://dev.to/fsimoes/resumindo-videos-do-youtube-com-auxilio-de-llms-1j3c</link>
      <guid>https://dev.to/fsimoes/resumindo-videos-do-youtube-com-auxilio-de-llms-1j3c</guid>
      <description>&lt;p&gt;Algumas vezes encontro vídeos realmente interessantes no Youtube, se não o vídeo todo, mas partes dele. Com frequência costumo salvar esses vídeos em alguma lista de reprodução para assistir mais tarde e anotar em algum lugar seu elementos do seu conteúdo para que eu possa ter como referência no futuro. &lt;/p&gt;

&lt;p&gt;O caso é que quase sempre, não me lembro mais qual vídeo era, e quando tento retomar esses vídeos, mesmo os que eu salvei, é raro que eu encontre o que estava procurando.&lt;/p&gt;

&lt;p&gt;Não é de hoje que me interesso bastante por &lt;strong&gt;NLP&lt;/strong&gt; (Processamento de Linguagem Natural) e venho estudando uma série assuntos relacionados ao tema, e aí me toquei que não é difícil usar &lt;strong&gt;LLM's&lt;/strong&gt; para resumir videos do Youtube, gerar um resumo em texto, e dessa forma facilitar a busca do assunto que me interessa, posso inclusive usar LLM's nessa etapa também. &lt;/p&gt;

&lt;p&gt;Mas hoje, vamos falar só da primeira parte desse projeto. Vamos criar uma ferramenta que irá resumir vídeos do Youtube, destacando os principais tópicos abordados, e depois disso iremos salvar isso em um arquivo Markdown, que poderá ser armazenado no GitHub/GitLab se preferir, se você utiliza o Obsidian para gerenciar uma biblioteca de markdowns, fica perfeito. &lt;/p&gt;

&lt;p&gt;Vamos começar criando um diretório para o nosso projeto e as pastas necessárias, eu estou usando Linux, mas a lógica é a mesma para outros sistemas operacionais.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;youtube-summarizer
&lt;span class="nb"&gt;cd &lt;/span&gt;youtube-summarizer
&lt;span class="nb"&gt;mkdir &lt;/span&gt;data
&lt;span class="nb"&gt;mkdir &lt;/span&gt;notebook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos iniciar a configuração do nosso projeto, eu gosto de utilizar o &lt;a href="https://python-poetry.org/" rel="noopener noreferrer"&gt;Poetry&lt;/a&gt;, mas se você preferir utilizar o Pip com &lt;a href="https://virtualenv.pypa.io/en/latest/" rel="noopener noreferrer"&gt;Virtualenv&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo &lt;/span&gt;inicia o projeto
poetry init
&lt;span class="nb"&gt;echo &lt;/span&gt;ativa ambiente virtual
poetry shell
&lt;span class="nb"&gt;echo &lt;/span&gt;instala as bibliotecas
poetry add python-dotenv langchain-community langchain-groq langchain ipykernel youtube-transcript-api pytube
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Observação&lt;/strong&gt;: Se você preferir, poderá usar o &lt;a href="https://colab.google/" rel="noopener noreferrer"&gt;Google Colab&lt;/a&gt;, que irá funcionar da mesma forma. Só vamos trocar a instalação das bibliotecas, no Colab vamos usar o PIP.&lt;/p&gt;

&lt;p&gt;Na primeira célula do notebook no Colab, digite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;U&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="n"&gt;langchain&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;community&lt;/span&gt; &lt;span class="n"&gt;langchain&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;groq&lt;/span&gt; &lt;span class="n"&gt;langchain&lt;/span&gt; &lt;span class="n"&gt;youtube&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;transcript&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="n"&gt;pytube&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você estiver usando o VSCode como eu, e estiver no diretório do projeto, &lt;strong&gt;youtube-summarizer&lt;/strong&gt; agora basta digitar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;code &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mãos a obra
&lt;/h2&gt;

&lt;p&gt;Para simplificar vamos utilizar o Jupyter Notebook, eu estou utilizando dentro do VSCode, num segundo momento você pode transferir o código do notebook para uma classe Python. Notebooks são muito bons para prototipação, no entanto não considero recomendável que sejam utilizados como "biblioteca de códigos", se passamos para arquivos .py ou estruturamos uma classe, fica muito mais simples de reutilizar esses códigos em projetos futuros. Mas para um tutorial como esse, eles são ótimos, por isso optei pelo Jupyter. &lt;/p&gt;

&lt;p&gt;Para criar um notebook no VSCode, selecione o diretório notebook, clique no ícone 'new file', e adicione um novo arquivo conforme imagem abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvn3owmqzekk6bqg4mxze.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvn3owmqzekk6bqg4mxze.png" alt="Criar um Jupyter Notebook no VSCode" width="482" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Qualquer arquivo que você adicionar a extensão .ipynb será reconhecido pelo VSCode como um Jupyter Notebook desde que você tenha a extensão do Jupyter instalada. Qualquer coisa, basta instalar as extensões mostradas na figura abaixo. As duas primeira são primordiais, as duas seguintes podem ser úteis em outras situações, a &lt;strong&gt;Jupyter Cell Tags&lt;/strong&gt;, por exemplo, é muito importante caso queira usar o &lt;a href="https://github.com/nteract/papermill" rel="noopener noreferrer"&gt;&lt;strong&gt;Papermill&lt;/strong&gt;&lt;/a&gt; (assunto para outra oportunidade) para orquestrar seus projetos pessoais.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzk7ot08dn8msgoii781u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzk7ot08dn8msgoii781u.png" alt="Extensões para o Jupyter" width="479" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Importação das Bibliotecas
&lt;/h3&gt;

&lt;p&gt;Uma vez que criamos nosso notebook podemos iniciar a prototipação. Na primeira célula do notebook, vamos importar as bibliotecas necessárias, conforme mostrado abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;textwrap&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;IPython.display&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Markdown&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_community.document_loaders&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;YoutubeLoader&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_groq&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatGroq&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.output_parsers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrOutputParser&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Criação da chave de acesso para API do Groq
&lt;/h3&gt;

&lt;p&gt;Nós instalamos a biblioteca &lt;strong&gt;langchain_groq, que nos permite acessar modelos armazenados no&lt;/strong&gt; &lt;a href="https://groq.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Groq&lt;/strong&gt;&lt;/a&gt; 🙃. Ok, se você não conhece, o Grop armazena uma série de modelos open source, como o Llama3. Nós podemos utilizar o Ollama para servir modelos como esse, no entanto, precisamos de uma máquina bastante poderosa para poder rodar um modelo 70b, e nos meus testes, o 8b não performou bem, por isso vamos fazer uma conta no Groq, criar uma chave, e utilizar aqui, que vai nos dar um ótimo resultado, e até o momento que escrevo isso, não há custos para desenvolvedores. Então vá até esse endereço, &lt;a href="https://console.groq.com/keys" rel="noopener noreferrer"&gt;https://console.groq.com/keys&lt;/a&gt;, crie uma chave:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpv00bllnfnh2p3b9a6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpv00bllnfnh2p3b9a6p.png" alt="Criar Groq API Key" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você deve copiar a chave, ela não será exibida novamente, caso precise de outra, crie uma nova.&lt;br&gt;
Agora na raiz do projeto crie um arquivo chamado &lt;strong&gt;.env&lt;/strong&gt; e adicione a sua chave conforme exemplo abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm8326q2wywk6pnuyuzai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm8326q2wywk6pnuyuzai.png" alt="Criando arquivo .env" width="800" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se for mandar seu código para o GitHub ou GitLab, por exemplo, lembre-se de adicionar esse arquivo ao .gitignore, nunca mande o seu arquivo &lt;strong&gt;.env&lt;/strong&gt; para nenhum repositório, público ou privado. &lt;/p&gt;

&lt;p&gt;Uma vez que o arquivo .env esteja corretamente configurado, voltamos ao notebook e vamos carregar a chave utilizando o comando abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuração do Modelo
&lt;/h3&gt;

&lt;p&gt;Esse comando lê o arquivo .env e carrega todas as chaves que encontrar lá, inclusive se você tiver outras chaves, ou preferir utilizar outros modelos como os da Open AI, basta configurar no .env.&lt;/p&gt;

&lt;p&gt;Agora vamos carregar nossa LLM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatGroq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llama-3.1-70b-versatile&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;streaming&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Usando no Colab
&lt;/h4&gt;

&lt;p&gt;Caso você opte pelo Colab, adicione o a sua chave conforme indicado na imagem abaixo, e não esqueça de marcar "Acesso ao notebook"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcklmggcaddmfj33eev0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcklmggcaddmfj33eev0g.png" alt="Adicionando a chave da api no Colab" width="479" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao invés de &lt;code&gt;load_dotenv()&lt;/code&gt;, use o código abaixo para carregar informações da sua API key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.colab&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;userdata&lt;/span&gt;
&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GROQ_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userdata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GROQ_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pronto, agora todo o resto funcionará da mesma forma que no Jupyter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuração do Prompt
&lt;/h3&gt;

&lt;p&gt;Com a LLM carregada, o próximo passo é configurar o &lt;strong&gt;prompt&lt;/strong&gt;, vou usar a classe PromptTemplate do Langchain, conforme exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prompt_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PromptTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;input_variables&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;video_transcript&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        Task: Carefully read the entire transcript. If a chapter list is provided, summarize each chapter concisely.

        Information Extraction: Extract key points and relevant information for each chapter or section of the video. 
        Focus on capturing the essence without including unnecessary details.

        Summary Style: Use clear, engaging language that is accessible to a general audience. 
        Keep summaries concise, but comprehensive enough to convey core insights.

        Special Attention:
        Prioritize including any statistical data, expert opinions, or unique insights if present. Highlight these in the summary.
        If numerical or statistical data is mentioned, provide accurate figures and clarify their relevance.

    Video transcript: {video_transcript} &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A variável &lt;strong&gt;prompt_template&lt;/strong&gt; configurada acima, será usada logo mais para receber a transcrição do vídeo, e junto com as instruções pré-configuradas, retornar um resumo do vídeo. O prompt está configurado em inglês, porque tive a impressão em alguns testes, que independente da língua da transcrição extraída, quando o prompt está em inglês o modelo performa melhor.&lt;/p&gt;

&lt;p&gt;Para quem não sabe o ChatGPT tem algumas ferramentas, eu usei a "Prompt Engineer", conforme imagem abaixo, para me ajudar a melhorar esse prompt, existem outras disponíveis, mas essa é uma das que mais gostei até agora.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fer5vhx85w1cdjqi2kby3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fer5vhx85w1cdjqi2kby3.png" alt="ChatGPT - Ferramentas" width="178" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Extração da transcrição
&lt;/h3&gt;

&lt;p&gt;O nosso próximo passo é extrair a transcrição de um vídeo do Youtube. Mesmo que não sejam criadas legendas pelo autor o próprio Youtube gera transcrições automáticas, e nós vamos usar a classe YoutubeLoader da biblioteca langchain_community para extrair esses dados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;video_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.youtube.com/watch?v=m_YJgE1Go4c&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;video_lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pt-BR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;YoutubeLoader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_youtube_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;video_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;add_video_info&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;language&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;video_lang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;
&lt;span class="n"&gt;transcript&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;page_content&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explicando o que está acontecendo no código acima, temos duas variáveis, uma com o link para o vídeo no Youtube, e outra com as linguagens aceitáveis. Essa variável é importante quando usamos o YoutubeLoader, porque se nada for especificado, o loader por padrão irá procurar por transcrições em inglês, se não houver vai dar erro. Passando uma lista de possíveis linguagens nós evitamos o erro. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;loader.load()&lt;/strong&gt; irá carregar uma lista com dados sobre o vídeo, que inclui o título, data de publicação, autor etc., que estão na chave &lt;strong&gt;metadata&lt;/strong&gt;. E o mais importante para nós aqui, que é a transcrição está na chave &lt;strong&gt;page_content&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurando a Chain
&lt;/h3&gt;

&lt;p&gt;Vamos usar o conceito de &lt;a href="https://www.promptingguide.ai/techniques/cot" rel="noopener noreferrer"&gt;&lt;strong&gt;Chain of Thought&lt;/strong&gt;&lt;/a&gt;. A ideia dessa técnica é que ao invés de o modelo dar a resposta direta, ele deve seguir um fluxo de raciocínio, passando por etapas lógicas antes de dar a resposta final. Imagine que vou ensinar a vocês uma receita culinária. Primeiro vamos falar dos ingredientes (organizar os dados), depois passamos a seguir a receita (aplicar a lógica de negócio, e cálculos), verificar o resultado (dar a resposta). &lt;/p&gt;

&lt;p&gt;No código abaixo &lt;strong&gt;prompt_template,&lt;/strong&gt; é o roteiro da receita, as instruções e perguntas que você quer que o modelo responda, llm, é o 'chef' que vai seguir a receita, o StrOutputParser é o garçom que irá organizar o prato e entregar o resultado (acho que no restaurante o garçom não organiza o prato, mas espero que tenha sido capaz de explicar o conceito).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prompt_template&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;StrOutputParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora nós podemos invocar essa cadeia de "raciocínio" através do comando abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;video_transcript&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transcript&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando fizemos a configuração do Prompt Template, nós criamos uma variável lá, &lt;strong&gt;video_transcript,&lt;/strong&gt; e agora nós atribuímos a transcrição extraída a essa variável que será incorporada ao restante do template. Após executar o código acima, podemos visualizar o resultado como no exemplo abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29gtvw6yy99nz86d9sfg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29gtvw6yy99nz86d9sfg.png" alt="Resultado do modelo" width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O modelo faz um ótimo trabalho resumindo os pontos chaves do vídeo. Um ponto específico acho importante comentar, a última linha, na parte de &lt;strong&gt;Estatística e Dados&lt;/strong&gt;, a informação de que a linguagem Python é a mais usada no mundo atualmente não é verdadeira, numa rápida pesquisa constatei que JavaScript é a mais usada. No vídeo é comentando que a linguagem Python é a mais usada no mundo para Inteligência Artificial, especificamente nesse contexto.&lt;/p&gt;

&lt;p&gt;Então o resumo em si não de ser usado como fonte de verdade absoluta, aliás nunca use a resposta de um modelo de inteligência artificial como verdade absoluta. Meu objetivo aqui é poder criar uma biblioteca com informações que eu possa pesquisar no futuro com mais facilidade, então encontrando os assuntos que me interessam assistir o vídeo e aí sim tirar minhas próprias conclusões. &lt;/p&gt;

&lt;p&gt;Dito isso, vamos para o próximo passo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Salvando o resultado
&lt;/h3&gt;

&lt;p&gt;Como quero criar uma biblioteca de dados, quero salvar cada resumo em um arquivo &lt;strong&gt;.md&lt;/strong&gt; diferente, vamos criar uma função para facilitar esse processo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_video_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;infos_video&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;textwrap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dedent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;## Video Summary

    Title: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
    Author: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;author&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
    Date: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;publish_date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
    URL: https://www.youtube.com/watch?v=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

    &lt;span class="n"&gt;infos_video&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;textwrap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dedent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;## Summary

    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;infos_video&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;textwrap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dedent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;final&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;infos_video&lt;/span&gt; 

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;final&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função acima vai receber o resumo gerado pelo modelo LLM e os metadados extraídos anteriormente, e criar uma Markdown, essa função retorna também o título do vídeo que nós iremos utilizar como nome do arquivo.&lt;/p&gt;

&lt;p&gt;Abaixo está a função que irá salvar o arquivo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_summary_to_markdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com as duas funções acima criadas podemos agora finalmente salvar nosso resumo, conforme exemplo abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;final_summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;video_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_video_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;transcript_path_file_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;../data/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;video_title&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.md&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="nf"&gt;save_summary_to_markdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;final_summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;transcript_path_file_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No final teremos algo como o apresentado abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fii8u1auv4abi4lvzwwk2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fii8u1auv4abi4lvzwwk2.png" alt="Arquivo Markdown gerado" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;LLM's são modelos muito dinâmicos, é muito fácil perceber o resultado, e a cada dia temos uma gama maior de alternativas, seja para estudar esses modelos, ou para a utilização deles tanto pessoal como profissional. Temos hoje uma gama muito grande de informações e dados a nossa disposição, nem sempre temos tempo, ou sabemos como catalogar esses dados para que possamos utilizar em momentos futuros, mas uma aplicação simples como a demostrada nesse artigo, consegue de forma muito simples e em poucos minutos gerar documentos que facilitam demais a busca por informações, se você tentar por conta própria criar um resumo de cada vídeo interessante que você encontrar na internet, vai perceber que isso leva bastante tempo. &lt;/p&gt;

&lt;p&gt;Para facilitar a execução, deixo aqui o &lt;a href="https://colab.research.google.com/drive/1LCwaJnOUFYWcXuMSTXZ_XFvIo5sA5KgQ?usp=sharing" rel="noopener noreferrer"&gt;link&lt;/a&gt; para o notebook no Google Colab.&lt;/p&gt;

&lt;p&gt;Espero que o exemplo demonstrado aqui possa ser útil, muito obrigado pelo seu tempo, e até a próxima.&lt;/p&gt;

</description>
      <category>python</category>
      <category>llm</category>
      <category>langchain</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Tutorial Duckdb</title>
      <dc:creator>Fabio Simoes</dc:creator>
      <pubDate>Mon, 29 Apr 2024 21:44:40 +0000</pubDate>
      <link>https://dev.to/fsimoes/tutorial-duckdb-324</link>
      <guid>https://dev.to/fsimoes/tutorial-duckdb-324</guid>
      <description>&lt;p&gt;Duckdb é um banco de dados OLAP. Que em resumo é um sistema de banco de dados voltado para consultas. Não necessita de uma rede complexa de servidores para funcionar, e desempenha seu papel de maneira surpreendentemente rápido.&lt;/p&gt;

&lt;h1&gt;
  
  
  Características
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Simplicidade:&lt;/strong&gt; É muito simples instalar, seja de distribuir, pois não possui dependências externa, roda no mesmo processo do aplicativo principal, ou como um binário único.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Portável:&lt;/strong&gt; Tem versões para Linux, Windows e macOS, nas arquiteturas x86 ou ARM. É altamente escalável, o que significa que conforme surgir a necessidade ele pode trabalhar com mais CPUs e memória. Tem APIs para Java, C, C++, Go, Node.js entre outras linguagens. É altamente integrado ao Python e R, nessas linguagens funciona é como se você estivesse utilizando Pandas, por exemplo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recursos:&lt;/strong&gt; Com Duckdb usamos um SQL, com uma alta gama de recursos disponíveis. Ele pode ler diretamente arquivos no formato CSV, Parquet e JSON, em arquivos locais, e também a partir de locais remotos como buckets S3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rápido:&lt;/strong&gt; As consultas rodam extremamente rápido graças ao seu motor colunar que suporta consultas em paralelo e pode processar volumes maiores que a memória.&lt;/p&gt;

&lt;p&gt;Extensível: Permite o desenvolvimento e instalação de extensões de terceiros, para acrescentar suporte a novos tipos de dados, funções, e formatos de arquivos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Grátis:&lt;/strong&gt; É um projeto open source sob a licença MIT.&lt;/p&gt;

&lt;p&gt;A seguir quero demonstrar como utilizar o Duckbd para fazer consultas. Ele pode ser um ótimo substituto para bibliotecas como Pandas, e muito útil para estudantes que querem aprender SQL, também para analistas que precisam fazer consultas, já conhecem SQL, e querem evitar a curva de aprendizado para o Pandas, o PySpark, por exemplo.&lt;/p&gt;

&lt;p&gt;Nunca vou dizer a ninguém que devem evitar aprender qualquer coisa, mas pensando em Pandas e suas limitações, em especial para datasets maiores, em vários cenários o o Duckdb será uma ferramenta muito mais util, tanto do ponto de vista de aprendizado, quanto de resultados.&lt;/p&gt;

&lt;p&gt;Sem mais delongas, vamos para o tutorial.&lt;/p&gt;

&lt;h1&gt;
  
  
  Instalação
&lt;/h1&gt;

&lt;p&gt;Para esse projeto vou considerar que você já tenha Python, e pip instalados. &lt;br&gt;
Primeiro crie uma pasta para o projeto, vamos criar um ambiente virtual para o nosso projeto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos ativar o ambiente virtual:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No Windows não é necessário usar o comando &lt;strong&gt;"source"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Para instalar o Duckdb use o comando abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;&lt;span class="nv"&gt;duckdb&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;0.9.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos instalar o JupyterLab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;jupyterlab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para iniciar o JupyterLab, use o comando abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jupyter lab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fib9321kdoycgch08dtld.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fib9321kdoycgch08dtld.png" alt="Image description" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos criar um novo notebook e testar se o Duckdb esta funcionando como esperado. No novo notebook execute os comandos abaixo, se receber a mesma mensagem o ambiente esta corretamente configurado e podemos partir para os próximos passos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F59sqvd9o1uowucebarfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F59sqvd9o1uowucebarfb.png" alt="Image description" width="353" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Base de Dados
&lt;/h1&gt;

&lt;p&gt;A base de dados que vamos utilizar nesse tutorial pode ser encontrada no seguinte endereço: &lt;a href="https://www.kaggle.com/datasets/ankurnapa/brewery-operations-and-market-analysis-dataset"&gt;Kaggle - Brewery Operations&lt;/a&gt;. É uma base de dados grande, então podemos analisar também o desempenho do Duckdb.&lt;/p&gt;

&lt;p&gt;Faça o download da base de dados, e no mesmo diretório do projeto crie uma pasta chamada &lt;strong&gt;data&lt;/strong&gt; e copie o arquivo para lá.&lt;/p&gt;

&lt;p&gt;Agora vamos usar o Duckdb para ler os dados a partir do arquivo &lt;strong&gt;csv&lt;/strong&gt; que acabamos de fazer o download.&lt;/p&gt;

&lt;p&gt;Abaixo podemos observar o retorno da leitura, alguns registros serão exibidos como amostra.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq3h35bp7ugv30lbgg49t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq3h35bp7ugv30lbgg49t.png" alt="Image description" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos também aplicar algumas consultas &lt;strong&gt;SQL&lt;/strong&gt; diretamente lendo do csv. Como nos exemplos abaixo:&lt;/p&gt;

&lt;h2&gt;
  
  
  Contando registros
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7pgtr7l1h5kvxl3srpk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7pgtr7l1h5kvxl3srpk.png" alt="Image description" width="744" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtrando registros
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4f0l495oidk5u8gu5zd4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4f0l495oidk5u8gu5zd4.png" alt="Image description" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Ingestão de dados
&lt;/h1&gt;

&lt;p&gt;O que fizemos até o momento foi usar os recursos do Duckdb na leitura de um arquivo &lt;strong&gt;csv&lt;/strong&gt;. Pode ser feito exatamente o mesmo para outros tipos de arquivos, como &lt;strong&gt;parquet&lt;/strong&gt;, &lt;strong&gt;json&lt;/strong&gt;, entre outros.&lt;/p&gt;

&lt;p&gt;Mas é possível fazer a ingestão desses dados no Duckdb. Com isso vamos ganhar mais desempenho nas nossas consultas. Depois é possível persistir esses dados no formato do Duckdb, o que irá facilitar a leitura dos dados em um próximo momento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando a base de dados
&lt;/h2&gt;

&lt;p&gt;O comando abaixo irá gerar um arquivo chamado &lt;strong&gt;tutorial.db&lt;/strong&gt; no mesmo local onde o notebook foi criado. O extensão do arquivo não precisa ser necessariamente &lt;strong&gt;db&lt;/strong&gt;, pode ser &lt;strong&gt;duckdb&lt;/strong&gt;, ou qualquer outra que você deseje, desde que seja criada usando o comando abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;con&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tutorial.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O comando acima irá criar o arquivo &lt;em&gt;.bd&lt;/em&gt; apenas se ele não existir, senão ele irá se conectar a esse banco de dados. Logo a partir da sua criação podemos usar ele para criar novas tabelas fazer consultas sempre que for necessário.&lt;/p&gt;

&lt;p&gt;Esse banco de dados ainda não tem tabelas nele, o que vamos fazer agora é usar os dados do arquivo &lt;strong&gt;csv&lt;/strong&gt; para criar uma tabela nele.&lt;/p&gt;

&lt;p&gt;Para criar uma tabela no banco de dados, a partir do arquivo csv, vamos usar o comando abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;create table brewery_data as from &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data/brewery_data_complete_extended.csv&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O comando acima ira criar uma tabela no banco de dados chamada &lt;strong&gt;brewery_data&lt;/strong&gt;, contendo todos os dados que estavam no arquivo csv serão gravados nessa tabela.&lt;/p&gt;

&lt;p&gt;Se você tiver algum cliente SQL instalado no seu computador, como o DBeaver, por exemplo, poderá inclusive utiliza-lo para fazer consultas nesse banco de dados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fks6yg6784qgs0o6kw2b6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fks6yg6784qgs0o6kw2b6.png" alt="Image description" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ou ainda diretamente do Jupyter com Python conforme exemplo abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fny7dnkr3gz3lydb9qveu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fny7dnkr3gz3lydb9qveu.png" alt="Image description" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A partir de agora podemos sempre usar o banco de dados criado sempre que precisarmos sem a necessidade de ler diretamente do arquivo csv. Isso trás alguns benefícios, o primeiro é que todas as consultas serão muito mais rápidas.&lt;/p&gt;

&lt;p&gt;Faça a contagem dos registros, diretamente na tabela do no Duckdb e compare com o tempo que levou quando executado a partir do csv.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;select count(*) as n_reqs from brewery_data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outro ponto, é que o arquivo csv que utilizamos tem 2.6 GB, o arquivo do Duckdb ficou menos de 1 GB, já estamos economizando espaço em disco.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando tabelas a partir de dados filtrados
&lt;/h2&gt;

&lt;p&gt;Agora que temos um banco de dados criado (tutorial.db), podemos criar novas tabelas dentro dele. Ao invés de gerar diferentes arquivos quando queremos separar os dados, podemos fazer isso dentro do banco, criando novas tabelas, como no exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;create table lagers as from brewery_data where Beer_Style = &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Lager&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;select * from lagers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O que faço aqui é criar uma nova tabela, a partir da nossa tabela &lt;strong&gt;brewery_data&lt;/strong&gt;, filtrando apenas as cervejas do tipo &lt;em&gt;Lager&lt;/em&gt;, e inserindo esses registros em uma nova tabela. Tudo vai se manter dentro de um único arquivo, e conforme citado anteriormente pode ser facilmente consumido por uma ferramenta de relatórios, por exemplo.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exportando Dados
&lt;/h1&gt;

&lt;p&gt;Exportar dados, também pode ser feita de maneira bastante simplificada, veja os exemplos abaixo:&lt;/p&gt;

&lt;p&gt;No exemplo abaixo, o conteúdo da tabela lagers, será exportado para o arquivo &lt;em&gt;lagers.csv&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;select * from lagers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;lagers.csv&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seguinte a mesma lógica podemos exportar os dados para um arquivo no formato &lt;strong&gt;.parquet&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;select * from lagers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write_parquet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;lagers.parquet&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;O objetivo principal desse tutorial era demonstrar alguns dos muito recursos do Duckdb. &lt;br&gt;
Duckdb é com certeza uma ferramenta muito poderosa, escalável, e pode ser utilizada em diferentes tipos de projetos. &lt;br&gt;
Uma ferramenta como o Duckdb entrega dinamismo, pois é muito simples ler dados de diferentes fontes, e aplicar a linguagem &lt;strong&gt;SQL&lt;/strong&gt;, muito conhecida de profissionais da área de análise de dados.&lt;br&gt;
Embora não tenha sido demonstrado nesse tutorial, o Duckdb permite a rápida conversão de uma query SQL para um data frame de Pandas, ou Polars, por exemplo, o que facilita o trabalho de cientistas de dados que depois de fazer o trabalho de limpeza dos dados, necessitem desses dados no formato Pandas, por exemplo, para aplicação de algorítimos de machine learning.&lt;br&gt;
Teste o Duckdb, você vai conhecer uma ferramenta muito poderosa.&lt;/p&gt;

</description>
      <category>duckdb</category>
      <category>sql</category>
      <category>python</category>
    </item>
  </channel>
</rss>
