Merge pull request #888 from santclear/community-contributions-branch

Translated README, setup files, week1/day1.ipynb and week1/scraper.py…
This commit is contained in:
Ed Donner
2025-11-01 20:29:42 -04:00
committed by GitHub
10 changed files with 2679 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
# LLM Engineering - Domine IA e LLMs
## Sua jornada de 8 semanas rumo à proficiência começa hoje
![Voyage](assets/voyage.jpg)
_Se você estiver vendo isto no Cursor, clique com o botão direito no nome do arquivo no Explorer à esquerda e selecione "Open preview" para visualizar a versão formatada._
Estou muito feliz por você se juntar a mim nesta jornada. Construiremos projetos extremamente gratificantes nas próximas semanas. Alguns serão fáceis, outros desafiadores, e muitos vão surpreender você! Os projetos se complementam para que você desenvolva experiência cada vez mais profunda a cada semana. De uma coisa tenho certeza: você vai se divertir bastante pelo caminho.
# COMUNICADO IMPORTANTE - OUTUBRO DE 2025 - LEIA POR FAVOR
Estou implementando gradualmente novas versões atualizadas de todos os vídeos do curso, com novos vídeos e novo código. Sei que isso pode ser desconcertante para quem já está no curso, e farei o possível para que a transição seja a mais tranquila possível.
- As duas séries de vídeos estarão disponíveis na Udemy e você poderá assistir a qualquer uma delas. Um novo conjunto de vídeos deve ficar disponível a cada semana conforme fizermos a atualização.
- Você pode seguir os vídeos originais ou os novos vídeos - ambos funcionarão muito bem. Alterne entre eles quando quiser.
- O código mais recente está publicado no repositório. Você pode acompanhar com o código novo ou voltar ao código original.
Os detalhes completos dessa atualização estão nos recursos do curso, em roxo no topo:
https://edwarddonner.com/2024/11/13/llm-engineering-resources/
A mudança mais significativa é que a nova versão usa o excelente uv em vez do Anaconda. Mas também há uma enorme quantidade de conteúdo inédito, incluindo novos modelos, ferramentas e técnicas. Cache de prompts, LiteLLM, técnicas de inferência e muito mais.
### Como isso está organizado na Udemy
Estamos disponibilizando as novas semanas, mas mantendo o conteúdo original em um apêndice:
Na Udemy:
Seção 1 = NOVA SEMANA 1
Seção 2 = NOVA SEMANA 2
Seção 3 = NOVA SEMANA 3
Seção 4 = Semana 4 original
Seção 5 = Semana 5 original
Seção 6 = Semana 6 original
Seção 7 = Semana 7 original
Seção 8 = Semana 8 original
E, como apêndice/arquivo:
Seção 9 = Semana 1 original
Seção 10 = Semana 2 original
Seção 11 = Semana 3 original
### Como voltar à versão original do código, consistente com os vídeos originais (Anaconda + virtualenv)
Se preferir manter o código dos vídeos originais, faça o seguinte a partir do Prompt do Anaconda ou do Terminal:
`git fetch`
`git checkout original`
E pronto! Qualquer dúvida, fale comigo na Udemy ou em ed@edwarddonner.com. Mais detalhes no topo dos recursos do curso [aqui](https://edwarddonner.com/2024/11/13/llm-engineering-resources/).
### Antes de começar
Estou aqui para ajudá-lo a obter o máximo sucesso na sua aprendizagem. Se encontrar qualquer dificuldade ou tiver ideias de como posso melhorar o curso, entre em contato pela plataforma ou envie um e-mail diretamente para mim (ed@edwarddonner.com). É sempre ótimo conectar com as pessoas no LinkedIn para fortalecer a comunidade - você me encontra aqui:
https://www.linkedin.com/in/eddonner/
E esta é uma novidade para mim, mas também estou experimentando o X/Twitter em [@edwarddonner](https://x.com/edwarddonner) - se você estiver no X, mostre-me como se faz!
Os recursos que acompanham o curso, incluindo slides e links úteis, estão aqui:
https://edwarddonner.com/2024/11/13/llm-engineering-resources/
E uma FAQ útil com perguntas frequentes está aqui:
https://edwarddonner.com/faq/
## Instruções de Gratificação Instantânea para a Semana 1, Dia 1 - com Llama 3.2 **não** Llama 3.3
### Nota importante: veja meu alerta sobre a Llama3.3 abaixo - ela é grande demais para computadores domésticos! Fique com a llama3.2 - vários alunos já ignoraram esse aviso...
Vamos começar o curso instalando o Ollama para que você veja resultados imediatamente!
1. Baixe e instale o Ollama em https://ollama.com. Observe que, em PCs, talvez você precise de permissões de administrador para que a instalação funcione corretamente.
2. No PC, abra um Prompt de Comando / Powershell (pressione Win + R, digite `cmd` e pressione Enter). No Mac, abra o Terminal (Aplicativos > Utilitários > Terminal).
3. Execute `ollama run llama3.2` ou, para máquinas mais modestas, `ollama run llama3.2:1b` - **atenção:** evite o modelo mais recente da Meta, o llama3.3, porque com 70B parâmetros ele é grande demais para a maioria dos computadores domésticos!
4. Se isso não funcionar: talvez seja necessário executar `ollama serve` em outro Powershell (Windows) ou Terminal (Mac) e tentar o passo 3 novamente. No PC, talvez você precise estar em uma instância administrativa do Powershell.
5. E, se ainda assim não funcionar na sua máquina, configurei tudo na nuvem. Está no Google Colab, que exige uma conta Google para entrar, mas é gratuito: https://colab.research.google.com/drive/1-_f5XZPsChvfU1sJ0QqCePtIuc55LSdu?usp=sharing
Se surgir qualquer problema, entre em contato comigo!
## Em seguida, instruções de configuração
Depois de concluirmos o projeto rápido com o Ollama e após eu me apresentar e apresentar o curso, partimos para configurar o ambiente completo.
Espero ter feito um bom trabalho para tornar esses guias à prova de falhas - mas entre em contato comigo imediatamente se encontrar obstáculos:
NOVAS INSTRUÇÕES para a nova versão do curso (lançada em outubro de 2025): [Novas instruções de configuração para todas as plataformas](setup/SETUP-new.md)
INSTRUÇÕES ORIGINAIS para quem está na versão anterior a outubro de 2025:
- Usuários de PC, sigam as instruções aqui: [Instruções originais para PC](setup/SETUP-PC.md)
- Usuários de Mac, sigam as instruções aqui: [Instruções originais para Mac](setup/SETUP-mac.md)
- Usuários de Linux, sigam as instruções aqui: [Instruções originais para Linux](setup/SETUP-linux.md)
### Um ponto importante sobre custos de API (que são opcionais! Não é preciso gastar se você não quiser)
Durante o curso, vou sugerir que você experimente os modelos de ponta, conhecidos como Frontier models. Também vou sugerir que execute modelos de código aberto usando o Google Colab. Esses serviços podem gerar alguns custos, mas manterei tudo no mínimo - alguns centavos por vez. E fornecerei alternativas caso você prefira não usá-los.
Monitore seu uso de APIs para garantir que os gastos estejam confortáveis para você; incluí os links abaixo. Não há necessidade de gastar mais que alguns dólares durante todo o curso. Alguns provedores de IA, como a OpenAI, exigem um crédito mínimo de US$5 ou equivalente local; devemos gastar apenas uma fração disso, e você terá bastante oportunidade de usar o restante em seus próprios projetos. Na Semana 7 você terá a opção de gastar um pouco mais se estiver curtindo o processo - eu mesmo gasto cerca de US$10 e os resultados me deixam muito feliz! Mas isso não é de forma alguma obrigatório; o importante é focar no aprendizado.
### Alternativa gratuita às APIs pagas
Consulte o [Guia 9](guides/09_ai_apis_and_ollama.ipynb) no diretório de guias para o passo a passo detalhado, com código exato para Ollama, Gemini, OpenRouter e muito mais!
### Como este repositório está organizado
Há pastas para cada uma das "semanas", que representam módulos da turma e culminam em uma poderosa solução autônoma baseada em agentes na Semana 8, reunindo muitos elementos das semanas anteriores.
Siga as instruções de configuração acima, depois abra a pasta da Semana 1 e prepare-se para se divertir.
### A parte mais importante
O mantra do curso é: a melhor forma de aprender é **FAZENDO**. Eu não digito todo o código durante o curso; executo-o para que você veja os resultados. Trabalhe comigo ou depois de cada aula, executando cada célula e inspecionando os objetos para compreender em detalhes o que está acontecendo. Em seguida, ajuste o código e deixe-o com a sua cara. Há desafios suculentos ao longo do curso. Ficarei muito feliz se você quiser enviar um Pull Request com seu código (veja o guia sobre GitHub na pasta guides) para que eu possa disponibilizar suas soluções a outras pessoas e compartilharmos o seu progresso; como benefício adicional, você será reconhecido no GitHub pela sua contribuição ao repositório. Embora os projetos sejam divertidos, eles são antes de tudo _educacionais_, ensinando habilidades de negócios que você poderá aplicar no seu trabalho.
## A partir da Semana 3, também usaremos o Google Colab para executar com GPUs
Você deverá conseguir usar o nível gratuito ou gastar bem pouco para concluir todos os projetos da turma. Eu, pessoalmente, assinei o Colab Pro+ e estou adorando - mas isso não é obrigatório.
Conheça o Google Colab e crie uma conta Google (se ainda não tiver uma) [aqui](https://colab.research.google.com/)
Os links do Colab estão nas pastas de cada semana e também aqui:
- Para a semana 3, dia 1, este Google Colab mostra o que [o Colab é capaz de fazer](https://colab.research.google.com/drive/1DjcrYDZldAXKJ08x1uYIVCtItoLPk1Wr?usp=sharing)
- Para a semana 3, dia 2, aqui está um Colab para a [API pipelines](https://colab.research.google.com/drive/1aMaEw8A56xs0bRM4lu8z7ou18jqyybGm?usp=sharing) da HuggingFace
- Para a semana 3, dia 3, temos o Colab sobre [Tokenizers](https://colab.research.google.com/drive/1WD6Y2N7ctQi1X9wa6rpkg8UfyA4iSVuz?usp=sharing)
- Para a semana 3, dia 4, vamos a um Colab com [modelos](https://colab.research.google.com/drive/1hhR9Z-yiqjUe7pJjVQw4c74z_V3VchLy?usp=sharing) da HuggingFace
- Para a semana 3, dia 5, voltamos ao Colab para criar nosso [produto de Atas de Reunião](https://colab.research.google.com/drive/1KSMxOCprsl1QRpt_Rq0UqCAyMtPqDQYx?usp=sharing)
- Para a semana 7, usaremos estes notebooks no Colab: [Dia 1](https://colab.research.google.com/drive/15rqdMTJwK76icPBxNoqhI7Ww8UM-Y7ni?usp=sharing) | [Dia 2](https://colab.research.google.com/drive/1T72pbfZw32fq-clQEp-p8YQ4_qFKv4TP?usp=sharing) | [Dias 3 e 4](https://colab.research.google.com/drive/1csEdaECRtjV_1p9zMkaKKjCpYnltlN3M?usp=sharing) | [Dia 5](https://colab.research.google.com/drive/1igA0HF0gvQqbdBD4GkcK3GpHtuDLijYn?usp=sharing)
### Monitoramento de gastos com APIs
Você pode manter seus gastos com APIs muito baixos durante todo o curso; acompanhe tudo nos painéis: [aqui](https://platform.openai.com/usage) para a OpenAI, [aqui](https://console.anthropic.com/settings/cost) para a Anthropic.
Os custos dos exercícios deste curso devem ser sempre bem reduzidos, mas, se quiser mantê-los no mínimo, escolha sempre as versões mais baratas dos modelos:
1. Para a OpenAI: use sempre o modelo `gpt-4.1-nano` no código
2. Para a Anthropic: use sempre o modelo `claude-3-haiku-20240307` no código em vez dos outros modelos Claude
3. Durante a semana 7, siga minhas instruções para usar o conjunto de dados mais econômico
Por favor, envie uma mensagem ou e-mail para ed@edwarddonner.com se algo não funcionar ou se eu puder ajudar de alguma forma. Mal posso esperar para saber como você está progredindo.
<table style="margin: 0; text-align: left;">
<tr>
<td style="width: 150px; height: 150px; vertical-align: middle;">
<img src="assets/resources.jpg" width="150" height="150" style="display: block;" />
</td>
<td>
<h2 style="color:#f71;">Outros recursos</h2>
<span style="color:#f71;">Preparei esta página com recursos úteis para o curso. Ela inclui links para todos os slides.<br/>
<a href="https://edwarddonner.com/2024/11/13/llm-engineering-resources/">https://edwarddonner.com/2024/11/13/llm-engineering-resources/</a><br/>
Mantenha este link nos favoritos - continuarei adicionando materiais úteis lá ao longo do tempo.
</span>
</td>
</tr>
</table>

View File

@@ -0,0 +1,193 @@
# LLM Engineering - Domine IA e LLMs
## Instruções de configuração para Windows
**Estas são as instruções originais correspondentes à versão original dos vídeos, anteriores a outubro de 2025. Para a nova versão, consulte [SETUP-new.md](SETUP-new.md).**
Bem-vindas e bem-vindos, usuários de PC!
Preciso confessar logo de cara: configurar um ambiente poderoso para trabalhar na vanguarda da IA não é tão simples quanto eu gostaria. Para a maioria das pessoas, estas instruções funcionam perfeitamente; mas, em alguns casos, por algum motivo, você pode encontrar um problema. Não hesite em pedir ajuda — estou aqui para colocar tudo em funcionamento rapidamente. Não há nada pior do que se sentir _travado_. Envie uma mensagem, um e-mail ou um recado pelo LinkedIn e eu vou destravar tudo rapidinho!
E-mail: ed@edwarddonner.com
LinkedIn: https://www.linkedin.com/in/eddonner/
Eu utilizo uma plataforma chamada Anaconda para configurar o ambiente. É uma ferramenta poderosa que monta um ambiente científico completo. O Anaconda garante que você esteja usando a versão correta do Python e que todos os pacotes sejam compatíveis com os meus, mesmo que nossos sistemas sejam completamente diferentes. Ele demanda mais tempo de instalação e ocupa mais espaço em disco (mais de 5 GB), mas, depois de configurado, é muito confiável.
Dito isso: se tiver algum problema com o Anaconda, ofereço uma abordagem alternativa. Ela é mais rápida e simples e deve colocar tudo para rodar rapidamente, com um pouco menos de garantia de compatibilidade.
Se você é relativamente novo no Prompt de Comando, aqui está um excelente [guia](https://chatgpt.com/share/67b0acea-ba38-8012-9c34-7a2541052665) com instruções e exercícios. Recomendo passar por ele primeiro para ganhar confiança.
## ATENÇÃO - QUESTÕES "GOTCHA" NO PC: os quatro pontos a seguir merecem sua atenção, especialmente os itens 3 e 4
Por favor, analise esses itens. O item 3 (limite de 260 caracteres do Windows) causará um erro "Archive Error" na instalação do pytorch se não for corrigido. O item 4 causará problemas de instalação.
Há quatro armadilhas comuns ao desenvolver no Windows:
1. Permissões. Confira este [tutorial](https://chatgpt.com/share/67b0ae58-d1a8-8012-82ca-74762b0408b0) sobre permissões no Windows.
2. Antivírus, firewall, VPN. Eles podem interferir em instalações e no acesso à rede; tente desativá-los temporariamente quando necessário.
3. O terrível limite de 260 caracteres para nomes de arquivos no Windows — aqui está uma [explicação completa com a correção](https://chatgpt.com/share/67b0afb9-1b60-8012-a9f7-f968a5a910c7)!
4. Se você ainda não trabalhou com pacotes de Data Science no computador, talvez precise instalar o Microsoft Build Tools. Aqui estão as [instruções](https://chatgpt.com/share/67b0b762-327c-8012-b809-b4ec3b9e7be0). Uma aluna também comentou que [estas instruções](https://github.com/bycloudai/InstallVSBuildToolsWindows) podem ajudar quem estiver no Windows 11.
### Parte 1: Fazer o clone do repositório
Isso garante que você tenha uma cópia local do código na sua máquina.
1. **Instale o Git** (se ainda não estiver instalado):
- Baixe o Git em https://git-scm.com/download/win
- Execute o instalador e siga as instruções, usando as opções padrão (aperte OK várias vezes!).
- Após a instalação, talvez seja necessário abrir uma nova janela do Powershell para usá-lo (ou até reiniciar o computador).
2. **Abra o Prompt de Comando:**
- Pressione Win + R, digite `cmd` e pressione Enter.
3. **Navegue até a pasta de projetos:**
Se você já tem uma pasta para projetos, navegue até ela com o comando `cd`. Por exemplo:
`cd C:\Users\SeuUsuario\Documents\Projects`
Substitua `SeuUsuario` pelo seu usuário do Windows.
Se não tiver uma pasta de projetos, crie uma:
```
mkdir C:\Users\SeuUsuario\Documents\Projects
cd C:\Users\SeuUsuario\Documents\Projects
```
4. **Clone o repositório:**
Digite o seguinte no prompt dentro da pasta Projects:
`git clone https://github.com/ed-donner/llm_engineering.git`
Isso cria um novo diretório `llm_engineering` dentro da pasta Projects e baixa o código da turma. Execute `cd llm_engineering` para entrar nele. Esse diretório `llm_engineering` é o "diretório raiz do projeto".
### Parte 2: Instalar o ambiente Anaconda
Se esta Parte 2 apresentar qualquer problema, há uma Parte 2B alternativa logo abaixo que pode ser utilizada.
1. **Instale o Anaconda:**
- Baixe o Anaconda em https://docs.anaconda.com/anaconda/install/windows/
- Execute o instalador e siga as instruções. Ele ocupa vários gigabytes e leva algum tempo para instalar, mas será uma plataforma poderosa para você usar no futuro.
2. **Configure o ambiente:**
- Abra o **Anaconda Prompt** (procure por ele no menu Iniciar).
- Navegue até o "diretório raiz do projeto" digitando algo como `cd C:\Users\SeuUsuario\Documents\Projects\llm_engineering`, usando o caminho real da sua pasta `llm_engineering`. Execute `dir` e verifique se você enxerga subpastas para cada semana do curso.
- Crie o ambiente: `conda env create -f environment.yml`
- **Se aparecer um ArchiveError, isso é causado pelo limite de 260 caracteres do Windows — veja a armadilha nº 3 acima e corrija antes de tentar novamente.**
- Ative o ambiente: `conda activate llms`
- Com o ambiente ativo, instale kernels adicionais: `python -m ipykernel install --user --name llms --display-name "Python (llms)"`
- Para confirmar se o ambiente funciona, execute: `python -c "import torch, platform; print('Torch version:', torch.__version__); print('Python version:', platform.python_version())"`
- Por fim, rode `jupyter lab`
Se isso funcionar, você está pronto! Abra a pasta `week1`, clique em `day1.ipynb` e comece.
### Parte 2B: Alternativa ao Anaconda (se você teve problemas na Parte 2)
Essa abordagem cria um ambiente virtual usando `python -m venv` e instala os pacotes necessários manualmente.
1. **Certifique-se de que o Python 3.11 esteja instalado:**
- Baixe em https://www.python.org/downloads/windows/ (o executável do instalador).
- Durante a instalação, marque a opção **Add Python to PATH**.
- Depois da instalação, abra um novo Powershell e rode `python --version` para verificar se tudo deu certo.
2. **Crie e ative um ambiente virtual:**
- No Powershell, navegue até o diretório raiz do projeto com `cd` (mesmo caminho da Parte 1).
- Crie o ambiente: `python -m venv llms`
- Ative o ambiente: `llms\Scripts\activate`
- Verifique se `(llms)` aparece no início do prompt.
3. **Atualize os instaladores e instale os pacotes necessários:**
```
python -m pip install --upgrade pip
pip install -r requirements-windows.txt
```
- Em seguida, instale o kernel do Jupyter vinculado ao ambiente: `python -m ipykernel install --user --name llms --display-name "Python (llms)"`
4. **Teste a instalação:**
- Execute `python -c "import torch, platform; print('Torch version:', torch.__version__); print('Python version:', platform.python_version())"`
5. **Inicie o Jupyter Lab:**
- Ainda com o ambiente ativo, rode `jupyter lab`
- Abra a pasta `week1` e clique em `day1.ipynb`.
### Parte 3 - Configure suas contas de API (OpenAI, Anthropic, Google, etc.)
Durante o curso você precisará de algumas chaves de API, principalmente para OpenAI (semana 1) e, mais adiante, Anthropic e Google. É melhor organizar isso com antecedência.
Para a semana 1, você só precisa da OpenAI; os demais serviços podem ser adicionados mais tarde, se desejar.
1. Crie uma conta na OpenAI, se ainda não tiver, acessando:
https://platform.openai.com/
2. A OpenAI exige um crédito mínimo para usar a API. Nos Estados Unidos, o valor é US$ 5. As chamadas à API utilizarão esse crédito. No curso, usaremos apenas uma pequena fração dele. Recomendo fazer esse investimento, pois você poderá aproveitar bastante em seus projetos. Se preferir não pagar pela API, apresento uma alternativa com o Ollama durante o curso.
Você pode adicionar saldo em Settings > Billing:
https://platform.openai.com/settings/organization/billing/overview
Recomendo desativar o recarregamento automático.
3. Crie sua chave de API
A página para criar a chave é https://platform.openai.com/api-keys — clique no botão verde "Create new secret key" e depois em "Create secret key". Guarde a chave em um local seguro; não será possível recuperá-la posteriormente pela interface da OpenAI. Ela deve começar com `sk-proj-`.
Na semana 2 configuraremos também as chaves da Anthropic e da Google, que você poderá gerar aqui quando chegar o momento.
- Claude API: https://console.anthropic.com/ (Anthropic)
- Gemini API: https://ai.google.dev/gemini-api (Google)
Mais adiante no curso usaremos a excelente plataforma HuggingFace; a conta é gratuita em https://huggingface.co — crie um token de API no menu do avatar >> Settings >> Access Tokens.
Nas semanas 6/7 utilizaremos o Weights & Biases em https://wandb.ai para acompanhar os treinamentos. As contas também são gratuitas, e o token é criado de forma semelhante.
### Parte 4 - Arquivo .env
Quando tiver essas chaves, crie um novo arquivo chamado `.env` no diretório raiz do projeto. O nome do arquivo deve ser exatamente os quatro caracteres ".env", e não "minhas-chaves.env" ou ".env.txt". Veja como fazer:
1. Abra o Notepad (Windows + R para abrir a caixa Executar, digite `notepad`).
2. No Notepad, digite o seguinte, substituindo `xxxx` pela sua chave de API (que começa com `sk-proj-`):
```
OPENAI_API_KEY=xxxx
```
Se tiver outras chaves, você pode adicioná-las agora ou voltar a este arquivo nas semanas seguintes:
```
GOOGLE_API_KEY=xxxx
ANTHROPIC_API_KEY=xxxx
DEEPSEEK_API_KEY=xxxx
HF_TOKEN=xxxx
```
Verifique se não há espaços antes ou depois do sinal `=` e nenhum espaço ao final da chave.
3. Vá em File > Save As. Em "Save as type", selecione All Files. No campo "File name", digite exatamente **.env**. Escolha o diretório raiz do projeto (a pasta `llm_engineering`) e clique em Save.
4. Abra essa pasta no Explorer e confira se o arquivo foi salvo como ".env", e não como ".env.txt". Se necessário, renomeie para ".env". Talvez você precise ativar a opção "Mostrar extensões de arquivo" para visualizar as extensões. Se isso não fizer sentido, mande uma mensagem ou e-mail!
Esse arquivo não aparecerá no Jupyter Lab porque arquivos iniciados com ponto ficam ocultos. O `.env` já está listado no `.gitignore`, portanto não será versionado, mantendo suas chaves em segurança.
### Parte 5 - Hora do show!
- Abra o **Anaconda Prompt** (se usou o Anaconda) ou um Powershell (se seguiu a alternativa da Parte 2B).
- Navegue até o "diretório raiz do projeto" digitando algo como `cd C:\Users\SeuUsuario\Documents\Projects\llm_engineering`, usando o caminho real da sua pasta `llm_engineering`. Execute `dir` e confirme se as subpastas de cada semana estão lá.
- Ative o ambiente com `conda activate llms` se usou o Anaconda, ou `llms\Scripts\activate` se usou a alternativa da Parte 2B.
- Você deve ver `(llms)` no prompt — esse é o sinal de que tudo está certo. Agora, digite `jupyter lab` e o Jupyter Lab deverá abrir, pronto para você começar. Abra a pasta `week1` e dê um duplo clique em `day1.ipynb`.
E pronto: pé na estrada!
Observe que, sempre que iniciar o Jupyter Lab no futuro, você precisará seguir novamente as instruções da Parte 5: estar dentro do diretório `llm_engineering` com o ambiente `llms` ativado antes de executar `jupyter lab`.
Para quem é novo no Jupyter Lab / Jupyter Notebook, trata-se de um ambiente de Data Science muito agradável: basta apertar Shift+Enter em qualquer célula para executá-la; comece no topo e vá seguindo! Há um notebook na pasta `week1` com um [Guia para o Jupyter Lab](week1/Guide%20to%20Jupyter.ipynb) e um tutorial de [Python Intermediário](week1/Intermediate%20Python.ipynb), caso ajude. Quando passarmos para o Google Colab na semana 3, você verá a mesma interface para executar Python na nuvem.
Se tiver qualquer problema, há um notebook em `week1` chamado [troubleshooting.ipynb](week1/troubleshooting.ipynb) para ajudar a diagnosticar.
Por favor, envie uma mensagem ou e-mail para ed@edwarddonner.com se algo não funcionar ou se eu puder ajudar de alguma forma. Estou ansioso para saber como você está avançando.

View File

@@ -0,0 +1,212 @@
# LLM Engineering - Domine IA e LLMs
## Instruções de configuração originais para Linux
**Estas são as instruções originais correspondentes à versão original dos vídeos, anteriores a outubro de 2025. Para a nova versão, consulte [SETUP-new.md](SETUP-new.md).**
Bem-vindas e bem-vindos, usuários de Linux!
Preciso admitir que pedi ao ChatGPT para gerar este documento com base nas instruções para Mac e depois revisei e ajustei algumas seções. Se alguma parte não funcionar na sua distro, avise-me — resolveremos juntos e atualizarei as instruções para o futuro.
___
Configurar um ambiente robusto para trabalhar na vanguarda da IA exige algum esforço, mas estas instruções devem guiá-lo sem dificuldades. Se encontrar qualquer problema, fale comigo. Estou aqui para garantir que tudo fique pronto sem dor de cabeça.
E-mail: ed@edwarddonner.com
LinkedIn: https://www.linkedin.com/in/eddonner/
Usaremos o Anaconda para criar um ambiente confiável para o seu trabalho com IA. Também ofereço uma alternativa mais leve, caso prefira evitar o Anaconda. Vamos lá!
### Parte 1: Fazer o clone do repositório
Assim você obtém uma cópia local do código.
1. **Instale o Git**, caso ainda não esteja disponível:
- Abra um terminal.
- Execute `git --version`. Se o Git não estiver instalado, siga as instruções para sua distribuição:
- Debian/Ubuntu: `sudo apt update && sudo apt install git`
- Fedora: `sudo dnf install git`
- Arch: `sudo pacman -S git`
2. **Navegue até a pasta de projetos:**
Se você já tem uma pasta específica para projetos, vá até ela com `cd`. Por exemplo:
`cd ~/Projects`
Se não tiver, crie uma:
```
mkdir ~/Projects
cd ~/Projects
```
3. **Clone o repositório:**
Execute:
`git clone https://github.com/ed-donner/llm_engineering.git`
Isso cria um diretório `llm_engineering` dentro de `Projects` e baixa o código do curso. Entre nele com `cd llm_engineering`. Esse é o "diretório raiz do projeto".
### Parte 2: Instalar o ambiente Anaconda
Se esta Parte 2 apresentar problemas, consulte a Parte 2B alternativa.
1. **Instale o Anaconda:**
- Baixe o instalador para Linux em https://www.anaconda.com/download.
- Abra um terminal e vá até a pasta onde o `.sh` foi salvo.
- Execute o instalador: `bash Anaconda3*.sh` e siga as instruções. Atenção: você precisará de mais de 5 GB de espaço em disco.
2. **Configure o ambiente:**
- No terminal, acesse o diretório raiz do projeto:
`cd ~/Projects/llm_engineering` (ajuste conforme o seu caminho).
- Execute `ls` para confirmar a presença das subpastas semanais.
- Crie o ambiente: `conda env create -f environment.yml`
A instalação pode levar vários minutos (até uma hora para quem nunca usou Anaconda). Se demorar demais ou ocorrerem erros, use a Parte 2B.
- Ative o ambiente: `conda activate llms`.
Você deve ver `(llms)` no prompt, sinal de que a ativação deu certo.
Em algumas distribuições pode ser necessário garantir que o ambiente apareça no Jupyter Lab:
`conda install ipykernel`
`python -m ipykernel install --user --name=llmenv`
3. **Inicie o Jupyter Lab:**
Estando na pasta `llm_engineering`, execute `jupyter lab`.
O Jupyter Lab abrirá no navegador. Após confirmar que funciona, feche-o e siga para a Parte 3.
### Parte 2B - Alternativa à Parte 2 se o Anaconda der trabalho
1. **Instale o Python 3.11 (se necessário):**
- Debian/Ubuntu: `sudo apt update && sudo apt install python3.11`
- Fedora: `sudo dnf install python3.11`
- Arch: `sudo pacman -S python`
2. **Acesse o diretório raiz do projeto:**
`cd ~/Projects/llm_engineering` e confirme o conteúdo com `ls`.
3. **Crie um ambiente virtual:**
`python3.11 -m venv llms`
4. **Ative o ambiente virtual:**
`source llms/bin/activate`
O prompt deve exibir `(llms)`.
5. **Instale os pacotes necessários:**
Execute `python -m pip install --upgrade pip` e depois `pip install -r requirements.txt`.
Se surgir algum problema, tente o plano B:
`pip install --retries 5 --timeout 15 --no-cache-dir --force-reinstall -r requirements.txt`
###### Usuários de Arch
Algumas atualizações quebram dependências (principalmente numpy, scipy e gensim). Para contornar:
`sudo pacman -S python-numpy python-pandas python-scipy` — não é a opção ideal, pois o pacman não se integra ao pip.
Outra alternativa, caso ocorram conflitos de compilação:
`sudo pacman -S gcc gcc-fortran python-setuptools python-wheel`
*Observação:* o gensim pode falhar com versões recentes do scipy. Você pode fixar o scipy em uma versão mais antiga ou remover temporariamente o gensim do requirements.txt. (Veja: https://aur.archlinux.org/packages/python-gensim)
Por fim, para que o kernel apareça no Jupyter Lab após o passo 6:
`python -m ipykernel install --user --name=llmenv`
`ipython kernel install --user --name=llmenv`
6. **Inicie o Jupyter Lab:**
Na pasta `llm_engineering`, execute `jupyter lab`.
### Parte 3 - Chave da OpenAI (OPCIONAL, mas recomendada)
Nas semanas 1 e 2 você escreverá código que chama APIs de modelos de ponta.
Na semana 1 basta a OpenAI; as demais chaves podem vir depois.
1. Crie uma conta na OpenAI, se ainda não tiver:
https://platform.openai.com/
2. A OpenAI exige um crédito mínimo para liberar a API. Nos EUA, são US$ 5. As chamadas descontarão desse valor. No curso usaremos apenas uma pequena parte. Recomendo fazer esse investimento, pois será útil para projetos futuros. Caso não queira pagar, ofereço uma alternativa com o Ollama ao longo das aulas.
Adicione crédito em Settings > Billing:
https://platform.openai.com/settings/organization/billing/overview
Sugiro desativar a recarga automática.
3. Gere sua chave de API:
Acesse https://platform.openai.com/api-keys, clique em "Create new secret key" (botão verde) e depois em "Create secret key". Guarde a chave em local seguro; não será possível recuperá-la posteriormente. Ela deve começar com `sk-proj-`.
Na semana 2 criaremos também chaves para Anthropic e Google:
- Claude API: https://console.anthropic.com/
- Gemini API: https://ai.google.dev/gemini-api
Mais adiante utilizaremos a ótima plataforma HuggingFace; a conta gratuita está em https://huggingface.co — gere um token em Avatar >> Settings >> Access Tokens.
Nas semanas 6/7 empregaremos o Weights & Biases em https://wandb.ai para monitorar os treinamentos. As contas também são gratuitas e o token é criado de modo semelhante.
### PARTE 4 - Arquivo .env
Quando tiver as chaves, crie um arquivo `.env` no diretório raiz do projeto. O nome deve ser exatamente ".env" — nada de "minhas-chaves.env" ou ".env.txt". Passo a passo:
1. Abra um terminal.
2. Navegue até o diretório raiz do projeto com `cd ~/Projects/llm_engineering` (ajuste conforme necessário).
3. Crie o arquivo com:
`nano .env`
4. Digite suas chaves no nano, substituindo `xxxx` pelo valor correto (ex.: começa com `sk-proj-`):
```
OPENAI_API_KEY=xxxx
```
Se já tiver outras chaves, você pode incluí-las agora ou mais tarde:
```
GOOGLE_API_KEY=xxxx
ANTHROPIC_API_KEY=xxxx
DEEPSEEK_API_KEY=xxxx
HF_TOKEN=xxxx
```
5. Salve o arquivo:
Control + O
Enter (para confirmar)
Control + X para sair
6. Liste os arquivos, inclusive ocultos:
`ls -a`
Confirme que o `.env` está presente.
O arquivo não aparecerá no Jupyter Lab porque arquivos iniciados com ponto ficam ocultos. Ele já está no `.gitignore`, então não será versionado e suas chaves ficam protegidas.
### Parte 5 - Hora do show!
1. Abra um terminal.
2. Vá até o diretório raiz do projeto:
`cd ~/Projects/llm_engineering`.
3. Ative seu ambiente:
- Com Anaconda: `conda activate llms`
- Com a alternativa: `source llms/bin/activate`
Você deve ver `(llms)` no prompt. Execute `jupyter lab` para começar.
Aproveite a jornada rumo ao domínio de IA e LLMs!

View File

@@ -0,0 +1,197 @@
# LLM Engineering - Domine IA e LLMs
## Instruções de configuração originais para Mac
**Estas são as instruções originais correspondentes à versão original dos vídeos, anteriores a outubro de 2025. Para a nova versão, consulte [SETUP-new.md](SETUP-new.md).**
Bem-vindas e bem-vindos, usuários de Mac!
Preciso confessar logo de cara: configurar um ambiente poderoso para trabalhar na vanguarda da IA não é tão simples quanto eu gostaria. Para a maioria das pessoas, estas instruções funcionarão muito bem; mas, em alguns casos, por algum motivo, você pode encontrar um problema. Não hesite em pedir ajuda — estou aqui para colocar tudo em funcionamento rapidamente. Não há nada pior do que se sentir _travado_. Envie uma mensagem, um e-mail ou um recado pelo LinkedIn e eu destravo tudo sem demora!
E-mail: ed@edwarddonner.com
LinkedIn: https://www.linkedin.com/in/eddonner/
Uso uma plataforma chamada Anaconda para configurar o ambiente. É uma ferramenta poderosa que monta um ecossistema científico completo. O Anaconda garante que você utilize a versão correta do Python e que todos os pacotes sejam compatíveis com os meus, mesmo que nossos sistemas sejam completamente diferentes. A configuração leva mais tempo e consome mais espaço em disco (mais de 5 GB), mas é muito confiável depois de instalada.
Dito isso: se tiver qualquer problema com o Anaconda, forneço uma abordagem alternativa. Ela é mais rápida e simples e deve colocá-lo para rodar rapidamente, com um pouco menos de garantia de compatibilidade.
### Antes de começar
Se você ainda não tem tanta familiaridade com o Terminal, consulte este excelente [guia](https://chatgpt.com/canvas/shared/67b0b10c93a081918210723867525d2b) com explicações e exercícios.
Se estiver iniciando o desenvolvimento no Mac, talvez seja necessário instalar as ferramentas de desenvolvedor do Xcode. Aqui estão as [instruções](https://chatgpt.com/share/67b0b8d7-8eec-8012-9a37-6973b9db11f5).
Um ponto de atenção: se você usa antivírus, VPN ou firewall, eles podem interferir em instalações ou no acesso à rede. Desative-os temporariamente caso surjam problemas.
### Parte 1: Fazer o clone do repositório
Isto garante que você tenha uma cópia local do código.
1. **Instale o Git** caso ainda não esteja instalado (na maioria das vezes já estará).
- Abra o Terminal (Aplicativos > Utilitários > Terminal).
- Digite `git --version`. Se o Git não estiver instalado, o sistema pedirá a instalação automaticamente.
- Depois da instalação, talvez seja necessário abrir uma nova janela do Terminal (ou até reiniciar) para utilizá-lo.
2. **Navegue até a pasta de projetos:**
Se você já possui uma pasta específica para projetos, navegue até ela usando `cd`. Por exemplo:
`cd ~/Documents/Projects`
Se não tiver uma pasta de projetos, crie-a:
```
mkdir ~/Documents/Projects
cd ~/Documents/Projects
```
3. **Clone o repositório:**
No Terminal, dentro da pasta Projects, digite:
`git clone https://github.com/ed-donner/llm_engineering.git`
Isso cria um novo diretório `llm_engineering` dentro da pasta Projects e baixa o código do curso. Execute `cd llm_engineering` para entrar nele. Esse diretório `llm_engineering` é o "diretório raiz do projeto".
### Parte 2: Instalar o ambiente Anaconda
Se esta Parte 2 apresentar qualquer problema, você pode usar a Parte 2B alternativa logo abaixo.
1. **Instale o Anaconda:**
- Baixe o Anaconda em https://docs.anaconda.com/anaconda/install/mac-os/
- Dê um duplo clique no arquivo baixado e siga as instruções de instalação. O processo ocupa vários gigabytes e leva algum tempo, mas fornecerá uma plataforma poderosa para você no futuro.
- Após a instalação, abra um Terminal totalmente novo para poder usar o Anaconda (talvez seja até necessário reiniciar).
2. **Configure o ambiente:**
- Abra um **novo** Terminal (Aplicativos > Utilitários > Terminal).
- Navegue até o "diretório raiz do projeto" com `cd ~/Documents/Projects/llm_engineering` (substitua pelo caminho real da sua cópia local). Execute `ls` e verifique se há subpastas para cada semana do curso.
- Crie o ambiente: `conda env create -f environment.yml`
- Aguarde alguns minutos até que todos os pacotes sejam instalados — se for a primeira vez com o Anaconda, isso pode levar 20 a 30 minutos ou mais, dependendo da conexão. Coisas importantes estão acontecendo! Se levar mais de 1 hora e 15 minutos ou se aparecerem erros, siga para a Parte 2B.
- Agora você construiu um ambiente dedicado para engenharia de LLMs, vetores e muito mais! Ative-o com: `conda activate llms`
- O prompt deve exibir `(llms)`, indicando que o ambiente está ativo.
3. **Inicie o Jupyter Lab:**
- No Terminal, ainda dentro da pasta `llm_engineering`, digite: `jupyter lab`
O Jupyter Lab deve abrir no navegador. Se você nunca usou o Jupyter Lab, explicarei em breve! Por ora, feche a aba do navegador e o Terminal, e avance para a Parte 3.
### Parte 2B - Alternativa à Parte 2 se o Anaconda der trabalho
Esta abordagem utiliza `python -m venv` para criar um ambiente virtual e instalar manualmente os pacotes necessários.
1. **Garanta que o Python 3.11 esteja instalado:**
- No macOS 13+ o Python 3 normalmente já está disponível via `python3`, mas recomendo instalar uma versão oficial em https://www.python.org/downloads/macos/
- Execute o instalador e siga as instruções.
- Após a instalação, abra um novo Terminal e rode `python3 --version` para confirmar.
2. **Crie e ative um ambiente virtual:**
- No Terminal, navegue até o diretório raiz do projeto (`cd ~/Documents/Projects/llm_engineering`, ajustando conforme o seu caminho).
- Crie o ambiente: `python3 -m venv llms`
- Ative o ambiente: `source llms/bin/activate`
- Verifique se `(llms)` aparece no início do prompt.
3. **Atualize os instaladores e instale os pacotes necessários:**
```
python -m pip install --upgrade pip
pip install -r requirements-mac.txt
```
- Em seguida, instale o kernel do Jupyter vinculado ao ambiente: `python -m ipykernel install --user --name llms --display-name "Python (llms)"`
4. **Teste a instalação:**
- Execute `python -c "import torch, platform; print('Torch version:', torch.__version__); print('Python version:', platform.python_version())"`
5. **Inicie o Jupyter Lab:**
- Com o ambiente ainda ativo, rode `jupyter lab`
- Abra a pasta `week1` e clique em `day1.ipynb`.
### Parte 3 - Configure suas contas de API (OpenAI, Anthropic, Google, etc.)
Ao longo do curso você precisará de chaves de API, começando pela OpenAI na semana 1. Mais adiante, adicionaremos Anthropic e Google. Organize isso com antecedência.
Para a semana 1, você só precisa da OpenAI; as demais chaves podem ser criadas posteriormente.
1. Crie uma conta na OpenAI, se necessário:
https://platform.openai.com/
2. A OpenAI exige um crédito mínimo para liberar o uso da API. Nos EUA, são US$ 5. As chamadas à API descontarão desse valor. No curso, usaremos apenas uma fração dele. Recomendo fazer esse investimento, porque você aproveitará bastante. Caso prefira não pagar, apresento uma alternativa com o Ollama ao longo das aulas.
Você pode adicionar crédito em Settings > Billing:
https://platform.openai.com/settings/organization/billing/overview
Desative o recarregamento automático, se desejar.
3. Crie sua chave de API:
A página para criar a chave é https://platform.openai.com/api-keys — clique no botão verde "Create new secret key" e depois em "Create secret key". Guarde a chave em local seguro; não será possível recuperá-la depois. Ela deve começar com `sk-proj-`.
Na semana 2 criaremos também as chaves da Anthropic e da Google, quando for o momento.
- Claude API: https://console.anthropic.com/ (Anthropic)
- Gemini API: https://ai.google.dev/gemini-api (Google)
Mais adiante usaremos a excelente plataforma HuggingFace; a conta gratuita está em https://huggingface.co — crie um token no menu do avatar >> Settings >> Access Tokens.
Nas semanas 6/7 utilizaremos o sensacional Weights & Biases em https://wandb.ai para monitorar os treinamentos. As contas também são gratuitas e o token é criado de modo parecido.
### PARTE 4 - arquivo .env
Quando tiver as chaves, crie um arquivo chamado `.env` no diretório raiz do projeto. O nome precisa ser exatamente ".env" — nada de "minhas-chaves.env" ou ".env.txt". Veja como fazer:
1. Abra o Terminal (Aplicativos > Utilitários > Terminal).
2. Navegue até o "diretório raiz do projeto" com `cd ~/Documents/Projects/llm_engineering` (ajuste conforme o seu caminho).
3. Crie o arquivo `.env` com:
`nano .env`
4. Digite as suas chaves no nano, substituindo `xxxx` pela chave (que começa com `sk-proj-`):
```
OPENAI_API_KEY=xxxx
```
Se tiver outras chaves, você pode adicioná-las agora ou mais tarde:
```
GOOGLE_API_KEY=xxxx
ANTHROPIC_API_KEY=xxxx
DEEPSEEK_API_KEY=xxxx
HF_TOKEN=xxxx
```
5. Salve o arquivo:
Control + O
Enter (para confirmar a gravação)
Control + X para sair do editor
6. Liste os arquivos no diretório raiz com:
`ls -a`
e confirme que o `.env` está lá.
O arquivo não aparecerá no Jupyter Lab porque arquivos iniciados com ponto ficam ocultos. Ele já está no `.gitignore`, portanto não será versionado e suas chaves permanecem seguras.
### Parte 5 - Hora do show!
- Abra o Terminal (Aplicativos > Utilitários > Terminal).
- Navegue até o "diretório raiz do projeto" com `cd ~/Documents/Projects/llm_engineering` (ajuste conforme o seu caminho). Execute `ls` e verifique se as subpastas semanais estão visíveis.
- Ative o ambiente com `conda activate llms` (ou `source llms/bin/activate` se você usou a alternativa da Parte 2B).
- `(llms)` deve aparecer no prompt — sinal de que tudo está pronto. Agora digite `jupyter lab` e o Jupyter Lab será aberto, pronto para começar. Abra a pasta `week1` e dê um duplo clique em `day1.ipynb`.
E pronto: pé na estrada!
Sempre que iniciar o Jupyter Lab no futuro, siga novamente as instruções desta Parte 5: esteja dentro do diretório `llm_engineering` com o ambiente `llms` ativado antes de rodar `jupyter lab`.
Para quem é novo no Jupyter Lab / Jupyter Notebook, trata-se de um ambiente de Data Science muito amigável: basta pressionar Shift+Enter em qualquer célula para executá-la; comece do topo e vá seguindo! Incluí um notebook chamado "Guide to Jupyter" mostrando mais recursos. Quando migrarmos para o Google Colab na semana 3, você verá a mesma interface para executar Python na nuvem.
Se surgir qualquer problema, há um notebook na semana 1 chamado [troubleshooting.ipynb](week1/troubleshooting.ipynb) para ajudar no diagnóstico.
Por favor, envie uma mensagem ou e-mail para ed@edwarddonner.com se algo não funcionar ou se eu puder ajudar de algum modo. Estou ansioso para saber como você está progredindo.

View File

@@ -0,0 +1,209 @@
# LLM Engineering - Domine IA e LLMs
## Novas instruções de configuração para PC, Mac e Linux
**Estas são as instruções de configuração da nova versão do curso a partir de outubro de 2025. Para as versões originais (Anaconda), consulte os outros arquivos deste diretório correspondentes à sua plataforma.**
_Se você estiver visualizando isto no Cursor, clique com o botão direito no nome do arquivo no Explorer à esquerda e selecione "Open preview" para ver a versão formatada._
Bem-vindas e bem-vindos, engenheiras e engenheiros de LLM em formação!
Preciso confessar logo de início: configurar um ambiente poderoso para trabalhar na linha de frente da IA não é tão simples quanto eu gostaria. Para a maioria das pessoas, estas instruções funcionarão muito bem; mas, em alguns casos, por qualquer motivo, você pode esbarrar em um problema. Não hesite em pedir ajuda — estou aqui para colocar tudo em funcionamento rapidamente. Não há nada pior do que se sentir _travado_. Envie uma mensagem pela Udemy ou um e-mail e vou destravar a situação sem demora!
E-mail: ed@edwarddonner.com
LinkedIn: https://www.linkedin.com/in/eddonner/
## Etapa 0 - Antes de começar - tratando dos "GOTCHAS" que derrubam muita gente
Ignore esta seção por sua conta e risco! 80% das dúvidas que recebo sobre a configuração são resolvidas por estes problemas comuns de sistema.
1. Quem usa PC: Permissões. Dê uma olhada neste [tutorial](https://chatgpt.com/share/67b0ae58-d1a8-8012-82ca-74762b0408b0) sobre permissões no Windows. Se aparecer algum erro dizendo que você não tem direitos/permissões/capacidade de executar um script ou instalar software, leia isso primeiro. O ChatGPT pode explicar tudo o que você precisa saber sobre permissões no Windows.
2. Antivírus, firewall, VPN. Esses elementos podem atrapalhar instalações e o acesso à rede; tente desativá-los temporariamente quando necessário. Use o hotspot do seu celular para confirmar se o problema é realmente de rede.
3. Quem usa PC: o terrível limite de 260 caracteres para nomes de arquivos no Windows — aqui está uma [explicação completa com a correção](https://chatgpt.com/share/67b0afb9-1b60-8012-a9f7-f968a5a910c7)!
4. Quem usa PC: se você nunca trabalhou com pacotes de Data Science no seu computador, talvez precise instalar o Microsoft Build Tools. Aqui estão as [instruções](https://chatgpt.com/share/67b0b762-327c-8012-b809-b4ec3b9e7be0). Uma aluna também mencionou que [estas instruções](https://github.com/bycloudai/InstallVSBuildToolsWindows) podem ajudar quem estiver no Windows 11.
5. Quem usa Mac: se está começando a desenvolver no Mac agora, talvez seja necessário instalar as ferramentas de desenvolvedor do Xcode. Aqui estão as [instruções](https://chatgpt.com/share/67b0b8d7-8eec-8012-9a37-6973b9db11f5).
6. SSL e outros problemas de rede por causa de segurança corporativa: se você tiver erros de SSL, como falhas de conexão com API, qualquer problema de certificado ou erro ao baixar arquivos do Ollama (erro do Cloudflare), veja a pergunta 15 [aqui](https://edwarddonner.com/faq).
## ETAPA 1 - instalando git, diretório de projetos e Cursor
Esta é a única seção com passos separados para quem usa PC e para quem usa Mac/Linux! Escolha o seu bloco abaixo e, depois, volte aqui para a Etapa 2...
___
**ETAPA 1 PARA QUEM USA PC:**
1. **Instale o Git** (se ainda não estiver instalado):
- Abra um novo prompt do Powershell (menu Iniciar >> Powershell). Se surgirem erros de permissão, tente abrir o Powershell clicando com o botão direito e escolhendo "Executar como administrador".
- Execute o comando `git` e veja se ele responde com detalhes do comando ou com um erro.
- Se aparecer erro, baixe o Git em https://git-scm.com/download/win
- Execute o instalador e siga as instruções, aceitando as opções padrão (aperte OK várias vezes!)
2. **Crie o diretório de projetos, se necessário**
- Abra um novo prompt do Powershell, conforme o passo anterior. Você deve estar no seu diretório pessoal, algo como `C:\Users\SeuUsuario`
- Você já tem um diretório `projects`? Descubra digitando `cd projects`
- Se aparecer erro, crie o diretório de projetos: `mkdir projects` e depois `cd projects`
- Agora você deve estar em `C:\Users\SeuUsuario\projects`
- Você pode escolher outro local conveniente, mas evite diretórios que estejam no OneDrive
3. **Faça o git clone:**
Digite o seguinte no prompt dentro da pasta `projects`:
`git clone https://github.com/ed-donner/llm_engineering.git`
Isso cria um novo diretório `llm_engineering` dentro da pasta de projetos e baixa o código da turma.
Execute `cd llm_engineering` para entrar nele. Esse diretório `llm_engineering` é o "diretório raiz do projeto".
4. **Cursor** Instale o Cursor, se necessário, e abra o projeto:
Visite https://cursor.com
Clique em Download for Windows. Execute o instalador. Aceite e mantenha os padrões em tudo.
Depois, abra o menu Iniciar, digite cursor. O Cursor será aberto e talvez você precise responder a algumas perguntas. Em seguida, deve aparecer a tela de "new window", onde você pode clicar em "Open Project". Se não aparecer, vá ao menu File >> New Window. Depois clique em "Open Project".
Localize o diretório `llm_engineering` dentro da sua pasta de projetos. Dê dois cliques em `llm_engineering` para visualizar o conteúdo dele. Em seguida, clique em Open ou Open Folder.
O Cursor deve então abrir o `llm_engineering`. Você saberá que deu tudo certo se vir LLM_ENGINEERING em letras maiúsculas no canto superior esquerdo.
___
**ETAPA 1 PARA QUEM USA MAC/LINUX**
1. **Instale o Git** (se ainda não estiver instalado):
Abra um Terminal. No Mac, abra uma janela do Finder e vá para Aplicativos >> Utilitários >> Terminal. No Linux, vocês praticamente vivem no Terminal... quase não precisam das minhas instruções!
- Execute `git --version` e verifique se aparece um número de versão do git. Caso contrário, você deve ver orientações para instalá-lo, ou siga o gotcha nº 5 no topo deste documento.
2. **Crie o diretório de projetos, se necessário**
- Abra uma nova janela do Terminal, como no passo anterior. Digite `pwd` para ver onde está. Você deve estar no seu diretório pessoal, algo como `/Users/usuario`
- Você já tem um diretório `projects`? Verifique digitando `cd projects`
- Se aparecer erro, crie o diretório de projetos: `mkdir projects` e depois `cd projects`
- Se você rodar `pwd` agora, deve estar em `/Users/usuario/projects`
- Você pode escolher outro local conveniente, mas evite diretórios que estejam no iCloud
3. **Faça o git clone:**
Digite o seguinte no prompt dentro da pasta `projects`:
`git clone https://github.com/ed-donner/llm_engineering.git`
Isso cria um novo diretório `llm_engineering` dentro da sua pasta de projetos e baixa o código da turma.
Execute `cd llm_engineering` para entrar nele. Esse diretório `llm_engineering` é o "diretório raiz do projeto".
4. **Cursor** Instale o Cursor, se necessário, e abra o projeto:
Visite https://cursor.com
Clique em Download for Mac OS ou para Linux. Em seguida, execute o instalador. Aceite e mantenha os padrões em tudo.
Depois, procure por Cursor (Spotlight, menu Iniciar etc.). O Cursor será aberto e talvez apareçam algumas perguntas. Em seguida, você deverá ver a tela de "new window", onde pode clicar em "Open Project". Se não aparecer, vá ao menu File >> New Window e clique em "Open Project".
Localize o diretório `llm_engineering` dentro da sua pasta de projetos. Dê dois cliques em `llm_engineering` para visualizar o conteúdo dele. Depois clique em Open.
O Cursor deve então abrir o `llm_engineering`. Você saberá que deu tudo certo se vir LLM_ENGINEERING em letras maiúsculas no canto superior esquerdo.
___
## ETAPA 2: Instalando o fantástico **uv** e executando `uv sync`
Para este curso, usamos o uv, o gerenciador de pacotes incrivelmente rápido. Ele conquistou a comunidade de Data Science — e com razão.
É veloz e confiável. Você vai adorar!
Primeiro, dentro do Cursor, selecione View >> Terminal para abrir um terminal integrado. Digite `pwd` para confirmar que está no diretório raiz do projeto.
Agora digite `uv --version` para ver se o uv está instalado. Se aparecer um número de versão, ótimo! Caso surja um erro, siga as instruções deste link para instalar o uv — recomendo utilizar o método Standalone Installer logo no começo da página, mas qualquer método serve. Execute os comandos no terminal do Cursor. Se uma abordagem não funcionar, tente outra.
https://docs.astral.sh/uv/getting-started/installation/
Depois de instalar o uv, abra uma nova janela de terminal no Cursor (o sinal de mais ou Ctrl+Shift+crase) para que o `uv --version` funcione. Verifique!
Quaisquer problemas na instalação ou no uso do uv, consulte [a pergunta 11 na minha página de FAQ](https://edwarddonner.com/faq/#11) para uma explicação completa.
### Agora que está instalado:
Execute `uv self update` para garantir que você está com a versão mais recente do uv.
Em seguida, simplesmente rode:
`uv sync`
O uv deve instalar tudo de forma extremamente rápida. Qualquer problema, veja novamente [a pergunta 11 na página de FAQ](https://edwarddonner.com/faq/#11).
Você agora tem um ambiente completo!
Usar o uv é simples e rápido:
1. Em vez de `pip install xxx`, use `uv add xxx`
2. Você nunca precisa ativar um ambiente — o uv faz isso automaticamente.
3. Em vez de `python xxx`, use `uv run xxx`
___
## ETAPA 3 - OPCIONAL - Crie sua conta na OpenAI
Alternativa: consulte o Guia 9 na pasta `guides` para opções gratuitas!
Acesse https://platform.openai.com
- Clique em Sign Up para criar uma conta, caso ainda não tenha. Talvez seja necessário clicar em alguns botões para criar uma Organization primeiro — insira dados razoáveis. Veja o Guia 4 na pasta Guides se estiver em dúvida sobre as diferenças entre o ChatGPT e a API da OpenAI.
- Clique no ícone Settings no canto superior direito e, em seguida, em Billing no menu lateral esquerdo.
- Certifique-se de que o Auto-Recharge esteja desativado. Se necessário, clique em "Add to Credit Balance" e escolha o valor adiantado de US$ 5, garantindo que adicionou um meio de pagamento válido.
- Ainda em Settings, selecione API keys no menu lateral esquerdo (perto do topo).
- Clique em "Create new secret key" — selecione "Owned by you", dê o nome que quiser, escolha "Default project" no campo Project e mantenha Permissions em All.
- Clique em "Create secret key" e você verá a nova chave. Clique em Copy para copiá-la para a área de transferência.
___
## ETAPA 4 - necessária para qualquer modelo como OpenAI ou Gemini (mas dispensável se você usar apenas o Ollama) - crie (e SALVE) o seu arquivo .env
**Seja meticuloso nesta etapa!** Qualquer erro na chave será muito difícil de diagnosticar! Recebo um volume enorme de perguntas de estudantes que cometem algum deslize aqui... Acima de tudo, lembre-se de salvar o arquivo depois de alterá-lo.
1. Crie o arquivo `.env`
- Volte ao Cursor
- No Explorador de Arquivos à esquerda, clique com o botão direito no espaço em branco abaixo de todos os arquivos, selecione "New File" e dê ao seu arquivo o nome `.env`
- Não canso de repetir: o arquivo precisa se chamar EXATAMENTE `.env` — essas quatro letras, nem mais nem menos. Nada de ".env.txt", nem "joao.env", nem "openai.env" ou qualquer outra coisa! E ele precisa estar no diretório raiz do projeto.
Se estiver se perguntando por que reforço tanto isso: recebo muitas, muitas mensagens de pessoas frustradas que (apesar de todos os meus apelos) deram outro nome ao arquivo e acharam que estava tudo certo. Não está! Ele precisa se chamar `.env` dentro do diretório `llm_engineering`. :)
2. Preencha o arquivo `.env` e depois salve:
Selecione o arquivo à esquerda. Você verá um arquivo vazio à direita. Digite isto no conteúdo do arquivo:
`OPENAI_API_KEY=`
Em seguida, cole a sua chave! Você deve ver algo como:
`OPENAI_API_KEY=sk-proj-lots-and-lots-of-digits`
Mas, claro, com a sua chave real, não com as palavras "sk-proj-lots-and-lots-of-digits"...
Agora TENHA CERTEZA de salvar o arquivo! File >> Save ou Ctrl+S (PC) / Command+S (Mac). Muitas pessoas esquecem de salvar. Você precisa salvar o arquivo!
Você provavelmente verá um ícone de sinal de parada ao lado do .env — não se preocupe, isso é algo bom! Consulte a pergunta 7 [aqui](https://edwarddonner.com/faq) se quiser entender o motivo.
__
## ETAPA 5 - Instale as extensões do Cursor, abra o Dia 1, configure o kernel e VAMOS NESSA!
(Se o Cursor sugerir instalar extensões recomendadas, basta aceitar! É um bom atalho para esta etapa.)
- Vá ao menu View e selecione Extensions.
- Procure por "python" para exibir as extensões de Python. Selecione a extensão Python desenvolvida por "ms-python" ou "anysphere" e instale-a se ainda não estiver instalada.
- Procure por "jupyter" e selecione a extensão desenvolvida por "ms-toolsai"; instale-a se ainda não estiver instalada.
Agora vá em View >> Explorer. Abra a pasta `week1` e clique em `day1.ipynb`.
- Veja onde aparece "Select Kernel" perto do canto superior direito? Clique ali e escolha "Python Environments".
- Selecione a opção superior com uma estrela, algo como `.venv (Python 3.12.x) .venv/bin/python Recommended`.
- Se essa opção não aparecer, abra o laboratório de troubleshooting na pasta Setup.
# PARABÉNS!! Você conseguiu! O restante do curso é tranquilo :)

View File

@@ -0,0 +1,54 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "73287ed4-81e3-496a-9e47-f0e8c3770ce9",
"metadata": {},
"source": [
"# Coletando informações diagnósticas essenciais\n",
"\n",
"## Execute a próxima célula para coletar alguns dados importantes\n",
"\n",
"Execute a próxima célula; ela deve levar cerca de um minuto para rodar (principalmente o teste de rede).\n",
"Em seguida, envie por e-mail o resultado da última célula para ed@edwarddonner.com. \n",
"Como alternativa: isso criará um arquivo chamado report.txt - basta anexar o arquivo ao seu e-mail."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ed8056e8-efa2-4b6f-a4bb-e7ceb733c517",
"metadata": {},
"outputs": [],
"source": [
"# Execute meu relatório de diagnósticos para coletar informações essenciais de depuração\n",
"# Por favor, envie os resultados por e-mail. Você pode copiar e colar a saída ou anexar o arquivo report.txt\n",
"\n",
"!pip install -q requests speedtest-cli psutil setuptools\n",
"from diagnostics import Diagnostics\n",
"Diagnostics().run()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,421 @@
import os
import sys
import platform
import subprocess
import shutil
import time
import ssl
import tempfile
from pathlib import Path
from datetime import datetime
class Diagnostics:
FILENAME = 'report.txt'
def __init__(self):
self.errors = []
self.warnings = []
if os.path.exists(self.FILENAME):
os.remove(self.FILENAME)
def log(self, message):
print(message)
with open(self.FILENAME, 'a', encoding='utf-8') as f:
f.write(message + "\n")
def start(self):
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self.log(f"Iniciando diagnósticos às {now}\n")
def end(self):
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self.log(f"\n\nDiagnósticos concluídos às {now}\n")
print("\nEnvie estes diagnósticos para mim em ed@edwarddonner.com")
print(f"Copie e cole a saída acima em um e-mail ou anexe o arquivo {self.FILENAME} que foi criado neste diretório.")
def _log_error(self, message):
self.log(f"ERRO: {message}")
self.errors.append(message)
def _log_warning(self, message):
self.log(f"AVISO: {message}")
self.warnings.append(message)
def run(self):
self.start()
self._step1_system_info()
self._step2_check_files()
self._step3_git_repo()
self._step4_check_env_file()
self._step5_anaconda_check()
self._step6_virtualenv_check()
self._step7_network_connectivity()
self._step8_environment_variables()
self._step9_additional_diagnostics()
if self.warnings:
self.log("\n===== Avisos Encontrados =====")
self.log("Os avisos abaixo foram identificados. Eles podem não impedir a execução do programa, mas podem provocar comportamentos inesperados:")
for warning in self.warnings:
self.log(f"- {warning}")
if self.errors:
self.log("\n===== Erros Encontrados =====")
self.log("Os problemas críticos a seguir foram encontrados. Solucione-os antes de prosseguir:")
for error in self.errors:
self.log(f"- {error}")
if not self.errors and not self.warnings:
self.log("\n✅ Todos os diagnósticos foram concluídos com êxito!")
self.end()
def _step1_system_info(self):
self.log("===== Informações do Sistema =====")
try:
system = platform.system()
self.log(f"Sistema Operacional: {system}")
if system == "Windows":
release, version, csd, ptype = platform.win32_ver()
self.log(f"Release do Windows: {release}")
self.log(f"Versão do Windows: {version}")
elif system == "Darwin":
release, version, machine = platform.mac_ver()
self.log(f"Versão do macOS: {release}")
else:
self.log(f"Plataforma: {platform.platform()}")
self.log(f"Arquitetura: {platform.architecture()}")
self.log(f"Máquina: {platform.machine()}")
self.log(f"Processador: {platform.processor()}")
try:
import psutil
ram = psutil.virtual_memory()
total_ram_gb = ram.total / (1024 ** 3)
available_ram_gb = ram.available / (1024 ** 3)
self.log(f"RAM total: {total_ram_gb:.2f} GB")
self.log(f"RAM disponível: {available_ram_gb:.2f} GB")
if available_ram_gb < 2:
self._log_warning(f"RAM disponível baixa: {available_ram_gb:.2f} GB")
except ImportError:
self._log_warning("Módulo psutil não encontrado. Não foi possível determinar as informações de RAM.")
total, used, free = shutil.disk_usage(os.path.expanduser("~"))
free_gb = free / (1024 ** 3)
self.log(f"Espaço livre em disco: {free_gb:.2f} GB")
if free_gb < 5:
self._log_warning(f"Pouco espaço em disco: {free_gb:.2f} GB livres")
except Exception as e:
self._log_error(f"Falha na verificação das informações do sistema: {e}")
def _step2_check_files(self):
self.log("\n===== Informações do Sistema de Arquivos =====")
try:
current_dir = os.getcwd()
self.log(f"Diretório atual: {current_dir}")
# Verifica permissões de escrita
test_file = Path(current_dir) / ".test_write_permission"
try:
test_file.touch(exist_ok=True)
test_file.unlink()
self.log("Permissão de escrita: OK")
except Exception as e:
self._log_error(f"Sem permissão de escrita no diretório atual: {e}")
self.log("\nArquivos no diretório atual:")
try:
for item in sorted(os.listdir(current_dir)):
self.log(f" - {item}")
except Exception as e:
self._log_error(f"Não é possível listar o conteúdo do diretório: {e}")
except Exception as e:
self._log_error(f"Falha na verificação do sistema de arquivos: {e}")
def _step3_git_repo(self):
self.log("\n===== Informações do Repositório Git =====")
try:
result = subprocess.run(['git', 'rev-parse', '--show-toplevel'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode == 0:
git_root = result.stdout.strip()
self.log(f"Raiz do repositório Git: {git_root}")
result = subprocess.run(['git', 'rev-parse', 'HEAD'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode == 0:
self.log(f"Commit atual: {result.stdout.strip()}")
else:
self._log_warning(f"Não foi possível obter o commit atual: {result.stderr.strip()}")
result = subprocess.run(['git', 'remote', 'get-url', 'origin'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode == 0:
self.log(f"Remoto 'origin': {result.stdout.strip()}")
else:
self._log_warning("Remoto 'origin' não configurado")
else:
self._log_warning("Não é um repositório Git")
except FileNotFoundError:
self._log_warning("Git não está instalado ou não está no PATH")
except Exception as e:
self._log_error(f"Falha na verificação do Git: {e}")
def _step4_check_env_file(self):
self.log("\n===== Verificação do Arquivo .env =====")
try:
result = subprocess.run(['git', 'rev-parse', '--show-toplevel'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode == 0:
git_root = result.stdout.strip()
env_path = os.path.join(git_root, '.env')
if os.path.isfile(env_path):
self.log(f"Arquivo .env localizado em: {env_path}")
try:
with open(env_path, 'r') as f:
has_api_key = any(line.strip().startswith('OPENAI_API_KEY=') for line in f)
if has_api_key:
self.log("OPENAI_API_KEY encontrado no arquivo .env")
else:
self._log_warning("OPENAI_API_KEY não encontrado no arquivo .env")
except Exception as e:
self._log_error(f"Não é possível ler o arquivo .env: {e}")
else:
self._log_warning("Arquivo .env não encontrado na raiz do projeto")
# Verifica arquivos .env adicionais
for root, _, files in os.walk(git_root):
if '.env' in files and os.path.join(root, '.env') != env_path:
self._log_warning(f"Arquivo .env adicional encontrado em: {os.path.join(root, '.env')}")
else:
self._log_warning("Diretório raiz do Git não encontrado. Não é possível realizar a verificação do arquivo .env.")
except FileNotFoundError:
self._log_warning("Git não está instalado ou não está no PATH")
except Exception as e:
self._log_error(f"Falha na verificação do arquivo .env: {e}")
def _step5_anaconda_check(self):
self.log("\n===== Verificação do Ambiente Anaconda =====")
try:
conda_prefix = os.environ.get('CONDA_PREFIX')
if conda_prefix:
self.log("Ambiente Anaconda ativo:")
self.log(f"Caminho do ambiente: {conda_prefix}")
self.log(f"Nome do ambiente: {os.path.basename(conda_prefix)}")
conda_exe = os.environ.get('CONDA_EXE', 'conda')
result = subprocess.run([conda_exe, '--version'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode == 0:
self.log(f"Versão do Conda: {result.stdout.strip()}")
else:
self._log_warning("Não foi possível determinar a versão do Conda")
self._check_python_packages()
else:
self.log("Nenhum ambiente Anaconda ativo detectado")
except Exception as e:
self._log_error(f"Falha na verificação do ambiente Anaconda: {e}")
def _step6_virtualenv_check(self):
self.log("\n===== Verificação do Virtualenv =====")
try:
virtual_env = os.environ.get('VIRTUAL_ENV')
if virtual_env:
self.log("Virtualenv ativo:")
self.log(f"Caminho do ambiente: {virtual_env}")
self.log(f"Nome do ambiente: {os.path.basename(virtual_env)}")
self._check_python_packages()
else:
self.log("Nenhum virtualenv ativo detectado")
if not virtual_env and not os.environ.get('CONDA_PREFIX'):
self._log_warning("Nem virtualenv nem ambiente Anaconda estão ativos")
except Exception as e:
self._log_error(f"Falha na verificação do virtualenv: {e}")
def _check_python_packages(self):
self.log("\nAmbiente Python:")
self.log(f"Versão do Python: {sys.version}")
self.log(f"Executável do Python: {sys.executable}")
required_packages = ['openai', 'python-dotenv', 'requests', 'gradio', 'transformers']
try:
import pkg_resources
installed = {pkg.key: pkg.version for pkg in pkg_resources.working_set}
self.log("\nVersões dos pacotes necessários:")
for package in required_packages:
if package in installed:
self.log(f"{package}: {installed[package]}")
else:
self._log_error(f"Pacote obrigatório '{package}' não está instalado")
# Verifica pacotes potencialmente conflitantes
problem_pairs = [
('openai', 'openai-python'),
('python-dotenv', 'dotenv')
]
for pkg1, pkg2 in problem_pairs:
if pkg1 in installed and pkg2 in installed:
self._log_warning(f"Pacotes potencialmente conflitantes: {pkg1} e {pkg2}")
except ImportError:
self._log_error("Não foi possível importar 'pkg_resources' para verificar os pacotes instalados")
except Exception as e:
self._log_error(f"Falha na verificação de pacotes: {e}")
def _step7_network_connectivity(self):
self.log("\n===== Verificação da Conectividade de Rede =====")
try:
self.log(f"Versão do SSL: {ssl.OPENSSL_VERSION}")
import requests
import speedtest # Importa a biblioteca speedtest-cli
# Verificação básica de conectividade
urls = [
'https://www.google.com',
'https://www.cloudflare.com'
]
connected = False
for url in urls:
try:
start_time = time.time()
response = requests.get(url, timeout=10)
elapsed_time = time.time() - start_time
response.raise_for_status()
self.log(f"✅ Conectado a {url}")
self.log(f" Tempo de resposta: {elapsed_time:.2f}s")
if elapsed_time > 2:
self._log_warning(f"Resposta lenta de {url}: {elapsed_time:.2f}s")
connected = True
break
except requests.exceptions.RequestException as e:
self._log_warning(f"Falha ao conectar-se a {url}: {e}")
else:
self.log("Conectividade básica OK")
if not connected:
self._log_error("Falha ao conectar-se a qualquer URL de teste")
return
# Teste de largura de banda usando speedtest-cli
self.log("\nRealizando teste de largura de banda com speedtest-cli...")
try:
st = speedtest.Speedtest()
st.get_best_server()
download_speed = st.download() # Bits por segundo
upload_speed = st.upload() # Bits por segundo
download_mbps = download_speed / 1e6 # Converte para Mbps
upload_mbps = upload_speed / 1e6
self.log(f"Velocidade de download: {download_mbps:.2f} Mbps")
self.log(f"Velocidade de upload: {upload_mbps:.2f} Mbps")
if download_mbps < 1:
self._log_warning("Velocidade de download baixa")
if upload_mbps < 0.5:
self._log_warning("Velocidade de upload baixa")
except speedtest.ConfigRetrievalError:
self._log_error("Falha ao obter a configuração do speedtest")
except Exception as e:
self._log_warning(f"Falha no teste de largura de banda: {e}")
except ImportError:
self._log_error("Pacotes obrigatórios não estão instalados. Instale-os com 'pip install requests speedtest-cli'")
except Exception as e:
self._log_error(f"Falha na verificação da conectividade de rede: {e}")
def _step8_environment_variables(self):
self.log("\n===== Verificação das Variáveis de Ambiente =====")
try:
# Verifica os caminhos do Python
pythonpath = os.environ.get('PYTHONPATH')
if pythonpath:
self.log("\nPYTHONPATH:")
for path in pythonpath.split(os.pathsep):
self.log(f" - {path}")
else:
self.log("\nPYTHONPATH não está definido.")
self.log("\nsys.path do Python:")
for path in sys.path:
self.log(f" - {path}")
# Verifica OPENAI_API_KEY
from dotenv import load_dotenv
load_dotenv()
api_key = os.environ.get('OPENAI_API_KEY')
if api_key:
self.log("OPENAI_API_KEY definido após chamar load_dotenv()")
if not api_key.startswith('sk-proj-') or len(api_key) < 12:
self._log_warning("Formato de OPENAI_API_KEY parece incorreto após chamar load_dotenv()")
else:
self._log_warning("Variável de ambiente OPENAI_API_KEY não está definida após chamar load_dotenv()")
except Exception as e:
self._log_error(f"Falha na verificação das variáveis de ambiente: {e}")
def _step9_additional_diagnostics(self):
self.log("\n===== Diagnósticos Adicionais =====")
try:
# Obtém os caminhos dos diretórios site-packages
import site
site_packages_paths = site.getsitepackages()
if hasattr(site, 'getusersitepackages'):
site_packages_paths.append(site.getusersitepackages())
# Função que verifica se um caminho está dentro de site-packages
def is_in_site_packages(path):
return any(os.path.commonpath([path, sp]) == sp for sp in site_packages_paths)
# Verifica possíveis conflitos de nome no diretório atual e no sys.path
conflict_names = ['openai.py', 'dotenv.py']
# Verifica o diretório atual
current_dir = os.getcwd()
for name in conflict_names:
conflict_path = os.path.join(current_dir, name)
if os.path.isfile(conflict_path):
self._log_warning(f"Encontrado '{name}' no diretório atual, o que pode causar conflitos de importação: {conflict_path}")
# Verifica os diretórios em sys.path
for path in sys.path:
if not path or is_in_site_packages(path):
continue # Ignora site-packages e caminhos vazios
for name in conflict_names:
conflict_file = os.path.join(path, name)
if os.path.isfile(conflict_file):
self._log_warning(f"Potencial conflito de nomenclatura: {conflict_file}")
# Verifica o diretório temporário
try:
with tempfile.NamedTemporaryFile() as tmp:
self.log(f"Diretório temporário é gravável: {os.path.dirname(tmp.name)}")
except Exception as e:
self._log_error(f"Não é possível gravar no diretório temporário: {e}")
except Exception as e:
self._log_error(f"Falha na execução dos diagnósticos adicionais: {e}")
if __name__ == "__main__":
diagnostics = Diagnostics()
diagnostics.run()

View File

@@ -0,0 +1,547 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "2a793b1d-a0a9-404c-ada6-58937227cfce",
"metadata": {},
"source": [
"# Puxa vida!\n",
"\n",
"Se você chegou até aqui, ainda está enfrentando problemas para configurar o seu ambiente. Sinto muito! Aguente firme e logo devemos colocar tudo para funcionar.\n",
"\n",
"Configurar um ambiente de Ciência de Dados pode ser desafiador porque há muita coisa acontecendo nos bastidores. Mas vamos chegar lá.\n",
"\n",
"E lembre-se: estou à disposição para ajudar. Envie uma mensagem ou e-mail para ed@edwarddonner.com e eu assumo o caso. A última célula deste notebook contém alguns diagnósticos que vão me ajudar a entender o que está acontecendo.\n",
"\n",
"Talvez você queira dar uma olhada rápida no [faq](https://edwarddonner.com/faq) do meu site caso o seu problema já esteja descrito por lá.\n"
]
},
{
"cell_type": "markdown",
"id": "8ebcd34f",
"metadata": {},
"source": [
"# Se você está fazendo a nova versão do curso (usando uv e Cursor, em vez de Anaconda), confira esta seção primeiro; caso contrário, vá direto para a próxima seção intitulada \"Começando pelo básico\"\n",
"\n",
"## 1. Verifique as extensões do Cursor\n",
"\n",
"Só para confirmar que as extensões estão instaladas:\n",
"- Abra as extensões (View >> Extensions)\n",
"- Pesquise por python e, quando os resultados aparecerem, clique na ms-python e instale se ainda não estiver instalada\n",
"- Pesquise por jupyter e, quando os resultados aparecerem, clique na da Microsoft e instale se ainda não estiver instalada \n",
"Depois vá em View >> Explorer para trazer de volta o File Explorer.\n",
"\n",
"## 2. Conecte este kernel:\n",
"\n",
"Se você vir as palavras `Select Kernel` em um botão próximo ao canto superior direito desta janela, clique nele!\n",
"\n",
"Você deve ver um menu suspenso com o título \"Select kernel for..\" ou talvez precise escolher \"Python environment\" primeiro.\n",
"\n",
"Escolha a opção que começa com `.venv python 3.12` — ela deve ser a primeira opção. Talvez seja necessário clicar em \"Python Environments\" antes.\n",
"\n",
"Agora deve estar escrito `.venv (Python 3.12.x)` onde antes aparecia `Select Kernel`.\n",
"\n",
"Depois de clicar em \"Select Kernel\", se não houver nenhuma opção como `.venv (Python 3.12.x)`, siga o passo a passo: \n",
"1. No Mac: no menu Cursor, escolha Settings >> VS Code Settings (ATENÇÃO: selecione `VSCode Settings`, não `Cursor Settings`); \n",
"Ou no Windows PC: no menu File, escolha Preferences >> VS Code Settings (ATENÇÃO: selecione `VSCode Settings`, não `Cursor Settings`) \n",
"2. Na barra de busca das configurações, digite \"venv\" \n",
"3. No campo \"Path to folder with a list of Virtual Environments\", informe o caminho da raiz do projeto, como C:\\Users\\username\\projects\\llm_engineering (no Windows) ou /Users/username/projects/llm_engineering (no Mac ou Linux). \n",
"Em seguida, tente novamente.\n",
"\n",
"## 3. Problemas com o uv\n",
"\n",
"Confira este guia completo no meu [FAQ Q11](https://edwarddonner.com/faq/#11)"
]
},
{
"cell_type": "markdown",
"id": "98787335-346f-4ee4-9cb7-6181b0e1b964",
"metadata": {},
"source": [
"# Começando pelo básico\n",
"\n",
"## Verificando sua conexão com a internet\n",
"\n",
"Primeiro, vamos verificar se não há problemas com VPN, firewall ou certificados.\n",
"\n",
"Clique na célula abaixo e pressione Shift+Return para executá-la. \n",
"Se isso gerar problemas, tente seguir estas instruções para resolver: \n",
"https://chatgpt.com/share/676e6e3b-db44-8012-abaa-b3cf62c83eb3\n",
"\n",
"Também ouvi que você pode ter problemas se estiver usando um computador corporativo com o software de segurança zscaler.\n",
"\n",
"Alguns conselhos de alunos nessa situação com o zscaler:\n",
"\n",
"> No prompt do Anaconda, isto ajudou às vezes, embora ainda ocorressem falhas ocasionais ao executar código no Jupyter:\n",
"`conda config --set ssl_verify false` \n",
"Outra coisa que ajudou foi adicionar `verify=False` sempre que houver `request.get(..)`, então `request.get(url, headers=headers)` se torna `request.get(url, headers=headers, verify=False)`"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d296f9b6-8de4-44db-b5f5-9b653dfd3d81",
"metadata": {},
"outputs": [],
"source": [
"import urllib.request\n",
"\n",
"try:\n",
" response = urllib.request.urlopen(\"https://www.google.com\", timeout=10)\n",
" if response.status != 200:\n",
" print(\"Não foi possível acessar o Google - pode haver problemas com sua internet / VPN / firewall?\")\n",
" else:\n",
" print(\"Conectado à internet e com acesso ao Google\")\n",
"except Exception as e:\n",
" print(f\"Falha na conexão com este erro: {e}\")"
]
},
{
"cell_type": "markdown",
"id": "d91da3b2-5a41-4233-9ed6-c53a7661b328",
"metadata": {},
"source": [
"## Mais alguns \"perrengues\" ocasionais para quem está no PC\n",
"\n",
"Existem 4 armadilhas no Windows das quais você deve estar ciente: \n",
"1. Permissões. Consulte este [tutorial](https://chatgpt.com/share/67b0ae58-d1a8-8012-82ca-74762b0408b0) sobre permissões no Windows\n",
"2. Antivírus, firewall e VPN. Eles podem interferir em instalações e no acesso à rede; tente desativá-los temporariamente, se necessário\n",
"3. O terrível limite de 260 caracteres para nomes de arquivo no Windows - aqui está uma [explicação e correção](https://chatgpt.com/share/67b0afb9-1b60-8012-a9f7-f968a5a910c7) completas!\n",
"4. Se você nunca trabalhou com pacotes de Ciência de Dados no seu computador, talvez precise instalar o Microsoft Build Tools. Aqui estão as [instruções](https://chatgpt.com/share/67b0b762-327c-8012-b809-b4ec3b9e7be0). Um aluno também mencionou que [estas instruções](https://github.com/bycloudai/InstallVSBuildToolsWindows) podem ser úteis para quem está no Windows 11. \n",
"\n",
"## E para quem usa Mac\n",
"\n",
"1. Se você está começando a desenvolver no Mac, pode precisar instalar as ferramentas de desenvolvedor do XCode. Aqui estão as [instruções](https://chatgpt.com/share/67b0b8d7-8eec-8012-9a37-6973b9db11f5).\n",
"2. Assim como no PC, antivírus, firewall e VPN podem causar problemas. Eles interferem em instalações e no acesso à rede; tente desativá-los temporariamente, se necessário"
]
},
{
"cell_type": "markdown",
"id": "f5190688-205a-46d1-a0dc-9136a42ad0db",
"metadata": {},
"source": [
"# Passo 1\n",
"\n",
"Tente executar a próxima célula (clique na célula abaixo desta e pressione shift+return).\n",
"\n",
"Se isso gerar um erro, provavelmente você não está executando em um ambiente \"ativado\". Consulte a Parte 5 do guia SETUP para [PC](../SETUP-PC.md) ou [Mac](../SETUP-mac.md) para configurar o ambiente Anaconda (ou virtualenv) e ativá-lo antes de rodar `jupyter lab`.\n",
"\n",
"Se observar o prompt do Anaconda (PC) ou o Terminal (Mac), você deve ver `(llms)` no prompt onde inicia `jupyter lab` - esse é o sinal de que o ambiente llms está ativado.\n",
"\n",
"Se você já estiver em um ambiente ativado, a próxima tentativa é reiniciar tudo:\n",
"1. Feche todas as janelas do Jupyter, como esta aqui\n",
"2. Encerre todos os prompts de comando / terminais / Anaconda\n",
"3. Repita a Parte 5 das instruções de SETUP para iniciar um novo ambiente ativado e executar `jupyter lab` a partir do diretório `llm_engineering` \n",
"4. Volte a este notebook e vá em Kernel >> Restart Kernel and Clear Outputs of All Cells\n",
"5. Tente executar novamente a célula abaixo.\n",
"\n",
"Se **isso** não funcionar, entre em contato comigo! Vou responder rapidamente e vamos resolver. Execute os diagnósticos (última célula deste notebook) para que eu possa depurar. Se você usou Anaconda, pode ser que, por algum motivo, o ambiente tenha sido corrompido; nesse caso, a solução mais simples é usar a abordagem com virtualenv (Parte 2B nos guias de setup)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7c8c0bb3-0e94-466e-8d1a-4dfbaa014cbe",
"metadata": {},
"outputs": [],
"source": [
"# Algumas verificações rápidas para garantir que o seu ambiente Conda ou VirtualEnv está como esperado\n",
"# O nome do ambiente deve ser: llms\n",
"\n",
"import os\n",
"conda_name, venv_name = \"\", \"\"\n",
"\n",
"conda_prefix = os.environ.get('CONDA_PREFIX')\n",
"if conda_prefix:\n",
" print(\"O ambiente Anaconda está ativo:\")\n",
" print(f\"Caminho do ambiente: {conda_prefix}\")\n",
" conda_name = os.path.basename(conda_prefix)\n",
" print(f\"Nome do ambiente: {conda_name}\")\n",
"\n",
"virtual_env = os.environ.get('VIRTUAL_ENV')\n",
"if virtual_env:\n",
" print(\"O virtualenv está ativo:\")\n",
" print(f\"Caminho do ambiente: {virtual_env}\")\n",
" venv_name = os.path.basename(virtual_env)\n",
" print(f\"Nome do ambiente: {venv_name}\")\n",
"\n",
"if conda_name != \"llms\" and venv_name != \"llms\" and venv_name != \"venv\" and venv_name != \".venv\":\n",
" print(\"Nem o Anaconda nem o virtualenv parecem estar ativados com o nome esperado 'llms', 'venv' ou '.venv'\")\n",
" print(\"Você executou 'jupyter lab' a partir de um ambiente ativado com (llms) aparecendo na linha de comando?\")\n",
" print(\"Em caso de dúvida, feche todos os jupyter lab e siga a Parte 5 do guia SETUP-PC ou SETUP-mac.\")"
]
},
{
"cell_type": "markdown",
"id": "45e2cc99-b7d3-48bd-b27c-910206c4171a",
"metadata": {},
"source": [
"# Passo 1.1\n",
"\n",
"## Hora de verificar se o ambiente está configurado e as dependências foram instaladas\n",
"\n",
"Agora, a próxima célula deve executar sem gerar saída — sem erros de importação. \n",
"\n",
"Para quem está na nova versão do curso (a partir de outubro de 2025), um erro indica que o kernel selecionado não é o correto.\n",
"\n",
"Para quem está na versão original do curso:\n",
"\n",
"> Erros de importação podem indicar que você iniciou o jupyter lab sem ativar o ambiente. Veja a Parte 5 do SETUP. \n",
"> Talvez seja preciso reiniciar o kernel e o Jupyter Lab. \n",
"> Ou pode haver algo errado com o Anaconda. Nesse caso, siga estas instruções de recuperação: \n",
"> Primeiro, feche tudo e reinicie o computador. \n",
"> Depois, em um Anaconda Prompt (PC) ou Terminal (Mac), com o ambiente ativado e **(llms)** aparecendo no prompt, no diretório llm_engineering, execute: \n",
"> `python -m pip install --upgrade pip` \n",
"> `pip install --retries 5 --timeout 15 --no-cache-dir --force-reinstall -r requirements.txt` \n",
"> Observe cuidadosamente se há erros e me avise. \n",
"> Se receber instruções para instalar o Microsoft Build Tools ou o Apple XCode, siga essas instruções. \n",
"> Depois, tente novamente!\n",
"> Por fim, se ainda assim não der certo, experimente a Parte 2B do SETUP, a alternativa à Parte 2 (com Python 3.11 ou Python 3.12). \n",
"> Se continuar em dúvida, rode os diagnósticos (última célula deste notebook) e me envie um e-mail em ed@edwarddonner.com"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6c78b7d9-1eea-412d-8751-3de20c0f6e2f",
"metadata": {},
"outputs": [],
"source": [
"# Este import deve funcionar se o seu ambiente estiver ativo e as dependências estiverem instaladas!\n",
"\n",
"from openai import OpenAI"
]
},
{
"cell_type": "markdown",
"id": "b66a8460-7b37-4b4c-a64b-24ae45cf07eb",
"metadata": {},
"source": [
"# Passo 2\n",
"\n",
"Vamos verificar se o seu arquivo .env existe e se a chave da OpenAI está configurada corretamente nele. \n",
"Execute este código e verifique se ele exibe uma mensagem de sucesso; do contrário, siga as instruções dele.\n",
"\n",
"Se não houver sucesso, o código não conseguiu encontrar um arquivo chamado `.env` na pasta `llm_engineering`. \n",
"O nome do arquivo precisa ser exatamente `.env` - não vai funcionar se ele se chamar `my-keys.env` ou `.env.doc`. \n",
"É possível que o `.env` na verdade esteja com o nome `.env.txt`? No Windows, talvez seja necessário alterar uma configuração no File Explorer para garantir que as extensões de arquivo apareçam (\"Show file extensions\" em \"On\"). Você também deve ver as extensões se digitar `dir` no diretório `llm_engineering`.\n",
"\n",
"Alguns detalhes traiçoeiros para observar: \n",
"- No arquivo .env, não deve haver espaço entre o sinal de igual e a chave. Exemplo: `OPENAI_API_KEY=sk-proj-...`\n",
"- Se você copiou e colou sua chave de outro aplicativo, certifique-se de que os hífens não foram substituídos por traços longos \n",
"\n",
"Observe que o arquivo `.env` não aparece no navegador de arquivos do Jupyter Lab, porque o Jupyter oculta arquivos que começam com ponto por segurança; eles são considerados arquivos ocultos. Se precisar alterar o nome, use um terminal ou o File Explorer (PC) / Finder (Mac). Se isso estiver difícil, peça ajuda ao ChatGPT ou me envie um e-mail!\n",
"\n",
"Se estiver com dificuldade para criar o arquivo `.env`, podemos fazê-lo com código! Veja a célula após a próxima.\n",
"\n",
"É importante iniciar o `jupyter lab` a partir do diretório raiz do projeto, `llm_engineering`. Se não tiver feito isso, esta célula pode apresentar problemas."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "caa4837e-b970-4f89-aa9a-8aa793c754fd",
"metadata": {},
"outputs": [],
"source": [
"from pathlib import Path\n",
"\n",
"parent_dir = Path(\"..\")\n",
"env_path = parent_dir / \".env\"\n",
"\n",
"if env_path.exists() and env_path.is_file():\n",
" print(\"Arquivo .env encontrado.\")\n",
"\n",
" # Ler o conteúdo do arquivo .env\n",
" with env_path.open(\"r\") as env_file:\n",
" contents = env_file.readlines()\n",
"\n",
" key_exists = any(line.startswith(\"OPENAI_API_KEY=\") for line in contents)\n",
" good_key = any(line.startswith(\"OPENAI_API_KEY=sk-proj-\") for line in contents)\n",
" classic_problem = any(\"OPEN_\" in line for line in contents)\n",
" \n",
" if key_exists and good_key:\n",
" print(\"SUCESSO! OPENAI_API_KEY encontrada e com o prefixo correto\")\n",
" elif key_exists:\n",
" print(\"Foi encontrada uma OPENAI_API_KEY, mas ela não tinha o prefixo esperado sk-proj- \\nPor favor, confira sua chave no arquivo..\")\n",
" elif classic_problem:\n",
" print(\"Não encontrei uma OPENAI_API_KEY, mas percebi que 'OPEN_' aparece - será que há um erro de digitação como OPEN_API_KEY em vez de OPENAI_API_KEY?\")\n",
" else:\n",
" print(\"Não encontrei uma OPENAI_API_KEY no arquivo .env\")\n",
"else:\n",
" print(\"Arquivo .env não encontrado no diretório llm_engineering. Ele precisa ter exatamente o nome: .env\")\n",
" \n",
" possible_misnamed_files = list(parent_dir.glob(\"*.env*\"))\n",
" \n",
" if possible_misnamed_files:\n",
" print(\"\\nAviso: nenhum arquivo '.env' foi encontrado, mas os seguintes arquivos no diretório llm_engineering contêm '.env' no nome. Talvez seja preciso renomeá-los?\")\n",
" for file in possible_misnamed_files:\n",
" print(file.name)"
]
},
{
"cell_type": "markdown",
"id": "105f9e0a-9ff4-4344-87c8-e3e41bc50869",
"metadata": {},
"source": [
"## Plano B - código em Python para criar o arquivo .env para você\n",
"\n",
"Execute a próxima célula apenas se estiver com problemas para criar o arquivo .env. \n",
"Substitua o texto na primeira linha de código pela sua chave da OpenAI."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ab9ea6ef-49ee-4899-a1c7-75a8bd9ac36b",
"metadata": {},
"outputs": [],
"source": [
"# Execute este código apenas se quiser que um arquivo .env seja criado para você!\n",
"\n",
"# Coloque sua chave entre as aspas\n",
"make_me_a_file_with_this_key = \"coloque sua chave aqui entre estas aspas.. ela deve começar com sk-proj-\"\n",
"\n",
"# Altere para True se você já tiver um arquivo .env e quiser que eu o substitua\n",
"overwrite_if_already_exists = False \n",
"\n",
"from pathlib import Path\n",
"\n",
"parent_dir = Path(\"..\")\n",
"env_path = parent_dir / \".env\"\n",
"\n",
"if env_path.exists() and not overwrite_if_already_exists:\n",
" print(\"Já existe um arquivo .env - se quiser que eu crie um novo, defina a variável overwrite_if_already_exists como True acima\")\n",
"else:\n",
" try:\n",
" with env_path.open(mode='w', encoding='utf-8') as env_file:\n",
" env_file.write(f\"OPENAI_API_KEY={make_me_a_file_with_this_key}\")\n",
" print(f\".env criado com sucesso em {env_path}\")\n",
" if not make_me_a_file_with_this_key.startswith(\"sk-proj-\"):\n",
" print(f\"A chave fornecida começou com '{make_me_a_file_with_this_key[:8]}', diferente de sk-proj-; era isso mesmo que você queria?\")\n",
" print(\"Agora execute novamente a célula anterior para confirmar que o arquivo foi criado e que a chave está correta.\")\n",
" except Exception as e:\n",
" print(f\"Ocorreu um erro ao criar o arquivo .env: {e}\")"
]
},
{
"cell_type": "markdown",
"id": "0ba9420d-3bf0-4e08-abac-f2fbf0e9c7f1",
"metadata": {},
"source": [
"# Passo 3\n",
"\n",
"Agora vamos verificar se sua chave de API está configurada corretamente no arquivo `.env` e disponível com o pacote dotenv.\n",
"Tente executar a próxima célula."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0ee8e613-5a6e-4d1f-96ef-91132da545c8",
"metadata": {},
"outputs": [],
"source": [
"# Esta célula deve exibir sua chave de API na saída - siga as instruções impressas\n",
"\n",
"import os\n",
"from dotenv import load_dotenv\n",
"load_dotenv(override=True)\n",
"\n",
"api_key = os.getenv(\"OPENAI_API_KEY\")\n",
"\n",
"if not api_key:\n",
" print(\"Nenhuma chave de API foi encontrada - tente Kernel >> Restart Kernel And Clear Outputs of All Cells\")\n",
"elif not api_key.startswith(\"sk-proj-\"):\n",
" print(f\"Uma chave de API foi encontrada, mas ela começa com {api_key[:8]} em vez de sk-proj-; por favor, confirme se isso está correto.\")\n",
"elif api_key.strip() != api_key:\n",
" print(\"Uma chave de API foi encontrada, mas parece haver espaços ou tabulações no início ou no fim - remova-os, por favor\")\n",
"else:\n",
" print(\"Chave de API encontrada e tudo parece correto até agora!\")\n",
"\n",
"if api_key:\n",
" problematic_unicode_chars = ['\\u2013', '\\u2014', '\\u201c', '\\u201d', '\\u2026', '\\u2018', '\\u2019']\n",
" forbidden_chars = [\"'\", \" \", \"\\n\", \"\\r\", '\"']\n",
" \n",
" if not all(32 <= ord(char) <= 126 for char in api_key):\n",
" print(\"Possível problema: talvez haja caracteres não imprimíveis incluídos na chave?\")\n",
" elif any(char in api_key for char in problematic_unicode_chars):\n",
" print(\"Possível problema: talvez haja caracteres especiais, como traços longos ou aspas curvas na chave - você copiou de um editor de texto?\")\n",
" elif any(char in api_key for char in forbidden_chars):\n",
" print(\"Possível problema: há aspas, espaços ou linhas em branco na sua chave?\")\n",
" else:\n",
" print(\"A chave de API contém caracteres válidos\")\n",
" \n",
"print(f\"\\nAqui está a chave --> {api_key} <--\")\n",
"print()\n",
"print(\"Se a chave estiver correta, vá em Edit >> Clear Cell Output para que ela não fique visível aqui!\")"
]
},
{
"cell_type": "markdown",
"id": "f403e515-0e7d-4be4-bb79-5a102dbd6c94",
"metadata": {},
"source": [
"## Deve aparecer algumas verificações com algo assim:\n",
"\n",
"`Here is the key --> sk-proj-blahblahblah <--`\n",
"\n",
"Se nenhuma chave foi exibida, espero que as mensagens tenham dado informação suficiente para resolver. Caso contrário, fale comigo!\n",
"\n",
"Existe ainda um último recurso, se preferir: você pode dispensar o uso de arquivos .env e sempre fornecer sua chave de API manualmente. \n",
"Sempre que encontrar isto no código: \n",
"`openai = OpenAI()` \n",
"Você pode substituir por: \n",
"`openai = OpenAI(api_key=\"sk-proj-xxx\")`\n"
]
},
{
"cell_type": "markdown",
"id": "42afad1f-b0bf-4882-b469-7709060fee3a",
"metadata": {},
"source": [
"# Passo 4\n",
"\n",
"Agora execute o código abaixo e, com sorte, você verá que o GPT consegue lidar com aritmética básica!!\n",
"\n",
"Se não funcionar, veja a célula abaixo."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cccb58e7-6626-4033-9dc1-e7e3ff742f6b",
"metadata": {},
"outputs": [],
"source": [
"from openai import OpenAI\n",
"from dotenv import load_dotenv\n",
"load_dotenv(override=True)\n",
"\n",
"my_api_key = os.getenv(\"OPENAI_API_KEY\")\n",
"\n",
"print(f\"Usando a chave de API --> {my_api_key} <--\")\n",
"\n",
"openai = OpenAI()\n",
"completion = openai.chat.completions.create(\n",
" model='gpt-4o-mini',\n",
" messages=[{\"role\":\"user\", \"content\": \"What's 2+2?\"}],\n",
")\n",
"print(completion.choices[0].message.content)\n",
"print(\"Agora vá em Edit >> Clear Cell Output para remover a exibição da sua chave.\")"
]
},
{
"cell_type": "markdown",
"id": "81046a77-c359-4388-929f-ffc8ad5cb93c",
"metadata": {
"jp-MarkdownHeadingCollapsed": true
},
"source": [
"## Se a chave foi configurada corretamente e ainda assim não funcionou\n",
"\n",
"### Se houver um erro da OpenAI sobre a sua chave ou um Rate Limit Error, há algo de errado com a sua chave de API!\n",
"\n",
"Primeiro, confira [esta página](https://platform.openai.com/settings/organization/billing/overview) para garantir que você tem saldo positivo.\n",
"A OpenAI exige que você mantenha um saldo positivo e estabelece valores mínimos, normalmente em torno de US$5 na moeda local. Minha defesa da OpenAI é que isso vale muito para a sua formação: por menos do que o preço de um álbum de música, você ganha uma grande experiência comercial. Mas isso não é obrigatório para o curso; o README traz instruções para usar modelos open-source gratuitos via Ollama sempre que utilizarmos a OpenAI.\n",
"\n",
"A página de cobrança da OpenAI com o saldo fica aqui: \n",
"https://platform.openai.com/settings/organization/billing/overview \n",
"A OpenAI pode levar alguns minutos para liberar sua chave depois que você reforça o saldo. \n",
"Um aluno fora dos EUA comentou que precisou habilitar pagamentos internacionais no cartão de crédito para que tudo funcionasse. \n",
"\n",
"É improvável, mas se houver algo de errado com sua chave, você pode tentar criar uma nova (botão no canto superior direito) aqui: \n",
"https://platform.openai.com/api-keys\n",
"\n",
"### Verifique se você consegue usar o gpt-4o-mini no playground da OpenAI\n",
"\n",
"Para confirmar que a cobrança está ativa e sua chave está válida, experimente usar o gtp-4o-mini diretamente: \n",
"https://platform.openai.com/playground/chat?models=gpt-4o-mini\n",
"\n",
"### Se houver um erro relacionado a certificados\n",
"\n",
"Se você encontrou um erro de certificados como: \n",
"`ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)` \n",
"Então substitua:\n",
"`openai = OpenAI()` \n",
"por: \n",
"`import httpx` \n",
"`openai = OpenAI(http_client=httpx.Client(verify=False))` \n",
"E substitua também: \n",
"`requests.get(url, headers=headers)` \n",
"por: \n",
"`requests.get(url, headers=headers, verify=False)` \n",
"Se isso funcionar, você está em boa forma. Será preciso ajustar os labs do mesmo jeito sempre que encontrar esse erro de certificado. \n",
"Essa abordagem não é adequada para código de produção, mas serve para nossos experimentos. Talvez seja necessário falar com o suporte de TI para entender se há restrições no seu ambiente.\n",
"\n",
"## Se nada disso funcionar:\n",
"\n",
"(1) Tente colar o seu erro no ChatGPT ou no Claude! É impressionante como eles resolvem muitas situações\n",
"\n",
"(2) Tente criar outra chave, substituir no arquivo .env e executar novamente!\n",
"\n",
"(3) Fale comigo! Rode os diagnósticos na célula abaixo e me envie um e-mail com os problemas para ed@edwarddonner.com\n",
"\n",
"Muito obrigado, e desculpe por todo esse transtorno!"
]
},
{
"cell_type": "markdown",
"id": "dc83f944-6ce0-4b5c-817f-952676e284ec",
"metadata": {},
"source": [
"# Coletando informações diagnósticas essenciais\n",
"\n",
"## Execute a próxima célula para coletar alguns dados importantes\n",
"\n",
"Execute a próxima célula; ela deve levar cerca de um minuto para rodar. A maior parte desse tempo verifica a sua largura de banda.\n",
"Depois, envie por e-mail o resultado da última célula para ed@edwarddonner.com. \n",
"Como alternativa: isso criará um arquivo chamado report.txt - basta anexá-lo ao seu e-mail."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "248204f0-7bad-482a-b715-fb06a3553916",
"metadata": {},
"outputs": [],
"source": [
"# Execute meu relatório de diagnósticos para coletar informações essenciais de depuração\n",
"# Por favor, envie os resultados por e-mail. Você pode copiar e colar a saída ou anexar o arquivo report.txt\n",
"\n",
"!pip install -q requests speedtest-cli psutil setuptools\n",
"from diagnostics import Diagnostics\n",
"Diagnostics().run()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e1955b9a-d344-4782-b448-2770d0edd90c",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,662 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "d15d8294-3328-4e07-ad16-8a03e9bbfdb9",
"metadata": {},
"source": [
"# SEU PRIMEIRO LAB\n",
"### Por favor, leia esta seção. Ela é valiosa para deixar você preparado, mesmo que seja uma leitura longa -- é um conteúdo importante.\n",
"\n",
"### Também não deixe de ler [README.md](../README.md)! Mais informações sobre os vídeos atualizados no README e [no topo dos recursos do curso em roxo](https://edwarddonner.com/2024/11/13/llm-engineering-resources/)\n",
"\n",
"## Seu primeiro projeto com um LLM de fronteira\n",
"\n",
"Ao final deste curso, você terá construído uma solução autônoma de IA agentica com 7 agentes que colaboram para resolver um problema de negócios. Tudo a seu tempo! Vamos começar com algo menor...\n",
"\n",
"Nosso objetivo é programar um novo tipo de navegador web. Dê a ele uma URL e ele responderá com um resumo. O Reader's Digest da internet!!\n",
"\n",
"Antes de começar, você deve ter concluído a configuração indicada no README.\n",
"\n",
"### Se você é novo em trabalhar com \"Notebooks\" (também conhecidos como Labs ou Jupyter Lab)\n",
"\n",
"Bem-vindo ao maravilhoso mundo da experimentação em Data Science! Simplesmente clique em cada \"célula\" que tiver código, como a célula logo abaixo deste texto, e pressione Shift+Return para executar aquela célula. Certifique-se de rodar todas as células, começando do topo, em ordem.\n",
"\n",
"Por favor, consulte a [pasta Guides](../guides/01_intro.ipynb) para ver todos os guias.\n",
"\n",
"## Estou aqui para ajudar\n",
"\n",
"Se você tiver qualquer problema, por favor, entre em contato. \n",
"Estou disponível pela plataforma, ou via ed@edwarddonner.com, ou em https://www.linkedin.com/in/eddonner/ caso você queira se conectar (e eu adoro me conectar!) \n",
"E isso é novo para mim, mas também estou experimentando o X em [@edwarddonner](https://x.com/edwarddonner) - se você estiver no X, por favor me mostre como é que se faz 😂 \n",
"\n",
"## Mais soluções de problemas\n",
"\n",
"Consulte o notebook [troubleshooting](../setup/troubleshooting.ipynb) na pasta de configuração para diagnosticar e corrigir problemas comuns. No final dele há um script de diagnósticos com algumas informações úteis de depuração.\n",
"\n",
"## Se isso já for rotina!\n",
"\n",
"Se você já estiver confortável com o material de hoje, segure as pontas; você pode avançar rapidamente pelos primeiros labs - iremos nos aprofundar muito mais conforme as semanas avançam. No fim, ajustaremos finamente nosso próprio LLM para competir com a OpenAI!\n",
"\n",
"<table style=\"margin: 0; text-align: left;\">\n",
" <tr>\n",
" <td style=\"width: 150px; height: 150px; vertical-align: middle;\">\n",
" <img src=\"../assets/important.jpg\" width=\"150\" height=\"150\" style=\"display: block;\" />\n",
" </td>\n",
" <td>\n",
" <h2 style=\"color:#900;\">Por favor, leia - nota importante</h2>\n",
" <span style=\"color:#900;\">A forma como colaboro com você pode ser diferente de outros cursos que você já fez. Prefiro não digitar código enquanto você assiste. Em vez disso, executo Jupyter Labs, como este, e lhe dou uma intuição sobre o que está acontecendo. Minha sugestão é que você execute tudo com atenção por conta própria, <b>depois</b> de assistir à aula. Adicione instruções de print para entender o que está acontecendo e depois crie suas próprias variações. Se você tiver uma conta no Github, use-a para mostrar suas variações. Isso não é apenas prática essencial, como também demonstra suas habilidades para outras pessoas, incluindo talvez futuros clientes ou empregadores...</span>\n",
" </td>\n",
" </tr>\n",
"</table>\n",
"<table style=\"margin: 0; text-align: left;\">\n",
" <tr>\n",
" <td style=\"width: 150px; height: 150px; vertical-align: middle;\">\n",
" <img src=\"../assets/resources.jpg\" width=\"150\" height=\"150\" style=\"display: block;\" />\n",
" </td>\n",
" <td>\n",
" <h2 style=\"color:#f71;\">Este código é um recurso vivo - fique de olho nos meus e-mails</h2>\n",
" <span style=\"color:#f71;\">Eu publico atualizações do código regularmente. À medida que as pessoas fazem perguntas, adiciono mais exemplos ou comentários aprimorados. Como resultado, você notará que o código abaixo não é idêntico ao dos vídeos. Tudo dos vídeos está aqui; mas também acrescentei explicações melhores e novos modelos como o DeepSeek. Considere isto como um livro interativo.<br/><br/>\n",
" Tento enviar e-mails regularmente com atualizações importantes relacionadas ao curso. Você pode encontrá-los na seção 'Announcements' da Udemy na barra lateral esquerda. Você também pode optar por receber meus e-mails pelas suas Configurações de Notificação na Udemy. Respeito a sua caixa de entrada e sempre procuro acrescentar valor nas minhas mensagens!\n",
" </span>\n",
" </td>\n",
" </tr>\n",
"</table>\n",
"<table style=\"margin: 0; text-align: left;\">\n",
" <tr>\n",
" <td style=\"width: 150px; height: 150px; vertical-align: middle;\">\n",
" <img src=\"../assets/business.jpg\" width=\"150\" height=\"150\" style=\"display: block;\" />\n",
" </td>\n",
" <td>\n",
" <h2 style=\"color:#181;\">Valor de negócios destes exercícios</h2>\n",
" <span style=\"color:#181;\">Um último pensamento. Embora eu tenha desenhado estes notebooks para serem educacionais, também procurei deixá-los divertidos. Faremos coisas legais, como fazer LLMs contarem piadas e discutirem entre si. Mas, fundamentalmente, meu objetivo é ensinar habilidades que você possa aplicar nos negócios. Vou explicar as implicações para o negócio ao longo do caminho, e vale a pena ter isso em mente: à medida que você ganha experiência com modelos e técnicas, pense em maneiras de colocar isso em prática no trabalho hoje. Por favor, entre em contato se quiser conversar mais ou se tiver ideias para compartilhar comigo.</span>\n",
" </td>\n",
" </tr>\n",
"</table>"
]
},
{
"cell_type": "markdown",
"id": "83f28feb",
"metadata": {},
"source": [
"### Se necessário, instale as extensões do Cursor\n",
"\n",
"1. No menu View, selecione Extensions\n",
"2. Pesquise por Python\n",
"3. Clique em \"Python\" feito por \"ms-python\" e selecione Install se ainda não estiver instalado\n",
"4. Pesquise por Jupyter\n",
"5. Clique em \"Jupyter\" feito por \"ms-toolsai\" e selecione Install se ainda não estiver instalado\n",
"\n",
"\n",
"### Em seguida, selecione o Kernel\n",
"\n",
"Clique em \"Select Kernel\" no canto superior direito\n",
"\n",
"Escolha \"Python Environments...\"\n",
"\n",
"Depois escolha aquele que se parece com `.venv (Python 3.12.x) .venv/bin/python` - ele deve estar marcado como \"Recommended\" e ter uma estrela grande ao lado.\n",
"\n",
"Qualquer problema com isso? Vá para o troubleshooting.\n",
"\n",
"### Observação: você precisará definir o Kernel em cada notebook.."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "4e2a9393-7767-488e-a8bf-27c12dca35bd",
"metadata": {},
"outputs": [],
"source": [
"# importações\n",
"\n",
"import os\n",
"from dotenv import load_dotenv\n",
"from scraper import fetch_website_contents\n",
"from IPython.display import Markdown, display\n",
"from openai import OpenAI\n",
"\n",
"# Se você receber um erro ao executar esta célula, vá para o notebook de solução de problemas!"
]
},
{
"cell_type": "markdown",
"id": "6900b2a8-6384-4316-8aaa-5e519fca4254",
"metadata": {},
"source": [
"# Conectando-se à OpenAI (ou ao Ollama)\n",
"\n",
"A próxima célula é onde carregamos as variáveis de ambiente do seu arquivo `.env` e fazemos a conexão com a OpenAI. \n",
"\n",
"Se preferir usar o Ollama gratuito, consulte a seção \"Free Alternative to Paid APIs\" no README e, caso não saiba como fazer isso, há uma solução completa na pasta de soluções (day1_with_ollama.ipynb).\n",
"\n",
"## Solução de problemas caso você tenha dificuldades:\n",
"\n",
"Se você receber um \"Name Error\" - você executou todas as células de cima para baixo? Vá para o guia Python Foundations para um método infalível de encontrar e corrigir todos os Name Errors.\n",
"\n",
"Se isso não resolver, vá para o notebook [troubleshooting](../setup/troubleshooting.ipynb) para obter código passo a passo que identifica a causa raiz e corrige o problema!\n",
"\n",
"Ou então, fale comigo! Envie uma mensagem ou um e-mail para ed@edwarddonner.com e faremos isso funcionar.\n",
"\n",
"Alguma preocupação com custos de API? Veja minhas notas no README - os custos devem ser mínimos e você pode controlá-los a todo momento. Você também pode usar o Ollama como alternativa gratuita, que discutimos no Dia 2."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "7b87cadb-d513-4303-baee-a37b6f938e4d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Chave de API encontrada e, até aqui, parece tudo certo!\n"
]
}
],
"source": [
"# Carregue as variáveis de ambiente em um arquivo chamado .env\n",
"\n",
"load_dotenv(override=True)\n",
"api_key = os.getenv('OPENAI_API_KEY')\n",
"\n",
"# Verifique a chave\n",
"\n",
"if not api_key:\n",
" print(\"Nenhuma chave de API foi encontrada - por favor, vá até o notebook de solução de problemas nesta pasta para identificar e corrigir!\")\n",
"elif not api_key.startswith(\"sk-proj-\"):\n",
" print(\"Uma chave de API foi encontrada, mas ela não começa com sk-proj-; verifique se você está usando a chave correta - consulte o notebook de solução de problemas\")\n",
"elif api_key.strip() != api_key:\n",
" print(\"Uma chave de API foi encontrada, mas parece que ela pode ter caracteres de espaço ou tab no início ou no fim - remova-os, por favor - consulte o notebook de solução de problemas\")\n",
"else:\n",
" print(\"Chave de API encontrada e, até aqui, parece tudo certo!\")\n"
]
},
{
"cell_type": "markdown",
"id": "442fc84b-0815-4f40-99ab-d9a5da6bda91",
"metadata": {},
"source": [
"# Vamos fazer uma chamada rápida a um modelo de fronteira para começar, como uma prévia!"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "a58394bf-1e45-46af-9bfd-01e24da6f49a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'role': 'user',\n",
" 'content': 'Olá, GPT! Esta é minha primeira mensagem para você! Oi!'}]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Para dar uma prévia -- chamar a OpenAI com estas mensagens é tão simples. Qualquer problema, vá para o notebook de solução de problemas.\n",
"\n",
"message = \"Olá, GPT! Esta é minha primeira mensagem para você! Oi!\"\n",
"\n",
"messages = [{\"role\": \"user\", \"content\": message}]\n",
"\n",
"messages\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "08330159",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Oi! Prazer em te conhecer. Sou o ChatGPT. Posso ajudar com várias coisas, por exemplo:\\n- esclarecer dúvidas e explicar temas\\n- escrever ou revisar textos (e-mails, trabalhos, posts)\\n- revisar gramática e estilo\\n- gerar ideias e brainstorms\\n- traduzir entre idiomas\\n- ajudar com programação\\n- planejar tarefas, estudos, viagens\\n\\nO que você quer fazer hoje? Conte-me o tema ou a tarefa, e o nível de detalhe que você prefere.'"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"openai = OpenAI()\n",
"\n",
"response = openai.chat.completions.create(model=\"gpt-5-nano\", messages=messages)\n",
"response.choices[0].message.content"
]
},
{
"cell_type": "markdown",
"id": "2aa190e5-cb31-456a-96cc-db109919cd78",
"metadata": {},
"source": [
"## OK, em frente com nosso primeiro projeto"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "2ef960cf-6dc2-4cda-afb3-b38be12f4c97",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Home - Edward Donner\n",
"\n",
"Home\n",
"Connect Four\n",
"Outsmart\n",
"An arena that pits LLMs against each other in a battle of diplomacy and deviousness\n",
"About\n",
"Posts\n",
"Well, hi there.\n",
"Im Ed. I like writing code and experimenting with LLMs, and hopefully youre here because you do too. I also enjoy DJing (but Im badly out of practice), amateur electronic music production (\n",
"very\n",
"amateur) and losing myself in\n",
"Hacker News\n",
", nodding my head sagely to things I only half understand.\n",
"Im the co-founder and CTO of\n",
"Nebula.io\n",
". Were applying AI to a field where it can make a massive, positive impact: helping people discover their potential and pursue their reason for being. Recruiters use our product today to source, understand, engage and manage talent. Im previously the founder and CEO of AI startup untapt,\n",
"acquired in 2021\n",
".\n",
"We work with groundbreaking, proprietary LLMs verticalized for talent, weve\n",
"patented\n",
"our matching model, and our award-winning platform has happy customers and tons of press coverage.\n",
"Connect\n",
"with me for more!\n",
"September 15, 2025\n",
"AI in Production: Gen AI and Agentic AI on AWS at scale\n",
"May 28, 2025\n",
"Connecting my courses become an LLM expert and leader\n",
"May 18, 2025\n",
"2025 AI Executive Briefing\n",
"April 21, 2025\n",
"The Complete Agentic AI Engineering Course\n",
"Navigation\n",
"Home\n",
"Connect Four\n",
"Outsmart\n",
"An arena that pits LLMs against each other in a battle of diplomacy and deviousness\n",
"About\n",
"Posts\n",
"Get in touch\n",
"ed [at] edwarddonner [dot] com\n",
"www.edwarddonner.com\n",
"Follow me\n",
"LinkedIn\n",
"Twitter\n",
"Facebook\n",
"Subscribe to newsletter\n",
"Type your email…\n",
"Subscribe\n"
]
}
],
"source": [
"# Vamos testar este utilitário\n",
"\n",
"ed = fetch_website_contents(\"https://edwarddonner.com\")\n",
"print(ed)"
]
},
{
"cell_type": "markdown",
"id": "6a478a0c-2c53-48ff-869c-4d08199931e1",
"metadata": {},
"source": [
"## Tipos de prompts\n",
"\n",
"Você talvez já saiba disso - mas, caso não, vai ficar muito familiarizado!\n",
"\n",
"Modelos como o GPT foram treinados para receber instruções de uma maneira específica.\n",
"\n",
"Eles esperam receber:\n",
"\n",
"**Um prompt de sistema** que lhes diz qual tarefa estão realizando e qual tom devem usar\n",
"\n",
"**Um prompt de usuário** -- o início da conversa ao qual devem responder"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "abdb8417-c5dc-44bc-9bee-2e059d162699",
"metadata": {},
"outputs": [],
"source": [
"# Defina nosso prompt de sistema - você pode experimentar com isso depois, alterando a última frase para \"Respond in markdown in Spanish.\"\n",
"\n",
"system_prompt = \"\"\"\n",
"Você é um assistente sarcástico que analisa o conteúdo de um site,\n",
"e fornece um resumo curto, sarcástico e bem-humorado, ignorando textos que possam estar relacionados à navegação.\n",
"Responda em markdown. Não coloque o markdown dentro de um bloco de código - responda apenas com o markdown.\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "f0275b1b-7cfe-4f9d-abfa-7650d378da0c",
"metadata": {},
"outputs": [],
"source": [
"# Defina nosso prompt de usuário\n",
"\n",
"user_prompt_prefix = \"\"\"\n",
"Aqui está o conteúdo de um site.\n",
"Forneça um resumo curto deste site.\n",
"Se ele incluir notícias ou anúncios, então resuma-os também.\n",
"\n",
"\"\"\""
]
},
{
"cell_type": "markdown",
"id": "ea211b5f-28e1-4a86-8e52-c0b7677cadcc",
"metadata": {},
"source": [
"## Mensagens\n",
"\n",
"A API da OpenAI espera receber mensagens em uma estrutura específica.\n",
"Muitas das outras APIs compartilham essa estrutura:\n",
"\n",
"```python\n",
"[\n",
" {\"role\": \"system\", \"content\": \"system message goes here\"},\n",
" {\"role\": \"user\", \"content\": \"user message goes here\"}\n",
"]\n",
"```\n",
"Para dar uma prévia, as próximas 2 células fazem uma chamada bem simples - ainda não vamos exigir muito do poderoso GPT!"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "f25dcd35-0cd0-4235-9f64-ac37ed9eaaa5",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'2 + 2 é igual a 4.'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"messages = [\n",
" {\"role\": \"system\", \"content\": \"Você é um assistente prestativo\"},\n",
" {\"role\": \"user\", \"content\": \"Quanto é 2 + 2?\"}\n",
"]\n",
"\n",
"response = openai.chat.completions.create(model=\"gpt-4.1-nano\", messages=messages)\n",
"response.choices[0].message.content"
]
},
{
"cell_type": "markdown",
"id": "d06e8d78-ce4c-4b05-aa8e-17050c82bb47",
"metadata": {},
"source": [
"## E agora vamos construir mensagens úteis para o GPT-4.1-mini, usando uma função"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "0134dfa4-8299-48b5-b444-f2a8c3403c88",
"metadata": {},
"outputs": [],
"source": [
"# Veja como esta função cria exatamente o formato acima\n",
"\n",
"def messages_for(website):\n",
" return [\n",
" {\"role\": \"system\", \"content\": system_prompt},\n",
" {\"role\": \"user\", \"content\": user_prompt_prefix + website}\n",
" ]"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "36478464-39ee-485c-9f3f-6a4e458dbc9c",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'role': 'system',\n",
" 'content': '\\nVocê é um assistente sarcástico que analisa o conteúdo de um site,\\ne fornece um resumo curto, sarcástico e bem-humorado, ignorando textos que possam estar relacionados à navegação.\\nResponda em markdown. Não coloque o markdown dentro de um bloco de código - responda apenas com o markdown.\\n'},\n",
" {'role': 'user',\n",
" 'content': '\\nAqui está o conteúdo de um site.\\nForneça um resumo curto deste site.\\nSe ele incluir notícias ou anúncios, então resuma-os também.\\n\\nHome - Edward Donner\\n\\nHome\\nConnect Four\\nOutsmart\\nAn arena that pits LLMs against each other in a battle of diplomacy and deviousness\\nAbout\\nPosts\\nWell, hi there.\\nIm Ed. I like writing code and experimenting with LLMs, and hopefully youre here because you do too. I also enjoy DJing (but Im badly out of practice), amateur electronic music production (\\nvery\\namateur) and losing myself in\\nHacker News\\n, nodding my head sagely to things I only half understand.\\nIm the co-founder and CTO of\\nNebula.io\\n. Were applying AI to a field where it can make a massive, positive impact: helping people discover their potential and pursue their reason for being. Recruiters use our product today to source, understand, engage and manage talent. Im previously the founder and CEO of AI startup untapt,\\nacquired in 2021\\n.\\nWe work with groundbreaking, proprietary LLMs verticalized for talent, weve\\npatented\\nour matching model, and our award-winning platform has happy customers and tons of press coverage.\\nConnect\\nwith me for more!\\nSeptember 15, 2025\\nAI in Production: Gen AI and Agentic AI on AWS at scale\\nMay 28, 2025\\nConnecting my courses become an LLM expert and leader\\nMay 18, 2025\\n2025 AI Executive Briefing\\nApril 21, 2025\\nThe Complete Agentic AI Engineering Course\\nNavigation\\nHome\\nConnect Four\\nOutsmart\\nAn arena that pits LLMs against each other in a battle of diplomacy and deviousness\\nAbout\\nPosts\\nGet in touch\\ned [at] edwarddonner [dot] com\\nwww.edwarddonner.com\\nFollow me\\nLinkedIn\\nTwitter\\nFacebook\\nSubscribe to newsletter\\nType your email…\\nSubscribe'}]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Experimente isto e depois teste com mais alguns sites\n",
"\n",
"messages_for(ed)"
]
},
{
"cell_type": "markdown",
"id": "16f49d46-bf55-4c3e-928f-68fc0bf715b0",
"metadata": {},
"source": [
"## Hora de juntar tudo - a API da OpenAI é muito simples!"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "905b9919-aba7-45b5-ae65-81b3d1d78e34",
"metadata": {},
"outputs": [],
"source": [
"# E agora: chame a API da OpenAI. Você vai ficar muito familiarizado com isso!\n",
"\n",
"def summarize(url):\n",
" website = fetch_website_contents(url)\n",
" response = openai.chat.completions.create(\n",
" model = \"gpt-4.1-mini\",\n",
" messages = messages_for(website)\n",
" )\n",
" return response.choices[0].message.content"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "05e38d41-dfa4-4b20-9c96-c46ea75d9fb5",
"metadata": {},
"outputs": [],
"source": [
"summarize(\"https://edwarddonner.com\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3d926d59-450e-4609-92ba-2d6f244f1342",
"metadata": {},
"outputs": [],
"source": [
"# Uma função para exibir isso de forma agradável na saída, usando markdown\n",
"\n",
"def display_summary(url):\n",
" summary = summarize(url)\n",
" display(Markdown(summary))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3018853a-445f-41ff-9560-d925d1774b2f",
"metadata": {},
"outputs": [],
"source": [
"display_summary(\"https://edwarddonner.com\")"
]
},
{
"cell_type": "markdown",
"id": "b3bcf6f4-adce-45e9-97ad-d9a5d7a3a624",
"metadata": {},
"source": [
"# Vamos testar mais sites\n",
"\n",
"Observe que isso só funciona em sites que podem ser raspados usando esta abordagem simplista.\n",
"\n",
"Sites renderizados com Javascript, como apps em React, não aparecerão. Consulte a pasta community-contributions para uma implementação em Selenium que contorna isso. Você precisará ler sobre como instalar o Selenium (pergunte ao ChatGPT!)\n",
"\n",
"Além disso, sites protegidos com CloudFront (e semelhantes) podem retornar erros 403 - muito obrigado ao Andy J por apontar isso.\n",
"\n",
"Mas muitos sites funcionarão muito bem!"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "45d83403-a24c-44b5-84ac-961449b4008f",
"metadata": {},
"outputs": [],
"source": [
"display_summary(\"https://cnn.com\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "75e9fd40-b354-4341-991e-863ef2e59db7",
"metadata": {},
"outputs": [],
"source": [
"display_summary(\"https://anthropic.com\")"
]
},
{
"cell_type": "markdown",
"id": "c951be1a-7f1b-448f-af1f-845978e47e2c",
"metadata": {},
"source": [
"<table style=\"margin: 0; text-align: left;\">\n",
" <tr>\n",
" <td style=\"width: 150px; height: 150px; vertical-align: middle;\">\n",
" <img src=\"../assets/business.jpg\" width=\"150\" height=\"150\" style=\"display: block;\" />\n",
" </td>\n",
" <td>\n",
" <h2 style=\"color:#181;\">Aplicações de negócios</h2>\n",
" <span style=\"color:#181;\">Neste exercício, você conheceu como chamar a API em nuvem de um modelo de fronteira (um modelo líder na vanguarda da IA) pela primeira vez. Usaremos APIs como a OpenAI em muitas etapas do curso, além de construir nossos próprios LLMs.\n",
"\n",
"Mais especificamente, aplicamos isso à sumarização - um caso de uso clássico de IA generativa para produzir um resumo. Isso pode ser aplicado a qualquer vertical de negócios - resumir notícias, resumir desempenho financeiro, resumir um currículo em uma carta de apresentação - as aplicações são ilimitadas. Considere como você poderia aplicar a sumarização no seu negócio e tente prototipar uma solução.</span>\n",
" </td>\n",
" </tr>\n",
"</table>\n",
"\n",
"<table style=\"margin: 0; text-align: left;\">\n",
" <tr>\n",
" <td style=\"width: 150px; height: 150px; vertical-align: middle;\">\n",
" <img src=\"../assets/important.jpg\" width=\"150\" height=\"150\" style=\"display: block;\" />\n",
" </td>\n",
" <td>\n",
" <h2 style=\"color:#900;\">Antes de continuar - agora tente você mesmo</h2>\n",
" <span style=\"color:#900;\">Use a célula abaixo para criar seu próprio exemplo comercial simples. Mantenha-se no caso de uso de sumarização por enquanto. Aqui vai uma ideia: escreva algo que pegue o conteúdo de um e-mail e sugira uma linha de assunto curta e apropriada para o e-mail. Esse é o tipo de recurso que poderia ser incorporado a uma ferramenta comercial de e-mail.</span>\n",
" </td>\n",
" </tr>\n",
"</table>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "00743dac-0e70-45b7-879a-d7293a6f68a6",
"metadata": {},
"outputs": [],
"source": [
"# Passo 1: Crie seus prompts\n",
"\n",
"system_prompt = \"something here\"\n",
"user_prompt = \"\"\"\n",
" Muito texto\n",
" Pode ser colado aqui\n",
"\"\"\"\n",
"\n",
"# Passo 2: Monte a lista de mensagens\n",
"\n",
"messages = [] # preencha isto\n",
"\n",
"# Passo 3: Chame a OpenAI\n",
"# response =\n",
"\n",
"# Passo 4: imprima o resultado\n",
"# print("
]
},
{
"cell_type": "markdown",
"id": "36ed9f14-b349-40e9-a42c-b367e77f8bda",
"metadata": {},
"source": [
"## Um exercício extra para quem gosta de web scraping\n",
"\n",
"Você pode notar que, se tentar `display_summary(\"https://openai.com\")`, não funciona! Isso acontece porque a OpenAI tem um site sofisticado que usa Javascript. Existem muitas maneiras de contornar isso com as quais alguns de vocês talvez estejam familiarizados. Por exemplo, Selenium é um framework extremamente popular que executa um navegador nos bastidores, renderiza a página e permite consultá-la. Se você tiver experiência com Selenium, Playwright ou similares, fique à vontade para melhorar a classe Website para usá-los. Na pasta community-contributions, você encontrará um exemplo de solução em Selenium enviada por um aluno (obrigado!)"
]
},
{
"cell_type": "markdown",
"id": "eeab24dc-5f90-4570-b542-b0585aca3eb6",
"metadata": {},
"source": [
"# Compartilhando seu código\n",
"\n",
"Eu adoraria que você compartilhasse seu código depois para que eu possa compartilhá-lo com outras pessoas! Você perceberá que alguns alunos já fizeram alterações (incluindo uma implementação em Selenium) que você encontrará na pasta community-contributions. Se quiser adicionar suas mudanças a essa pasta, envie um Pull Request com suas novas versões naquela pasta e eu farei o merge das suas alterações.\n",
"\n",
"Se você não for especialista em git (e eu também não sou!), o GPT forneceu algumas instruções legais sobre como enviar um Pull Request. É um processo um pouco trabalhoso, mas depois que você faz uma vez fica bem claro. Uma dica profissional: é melhor limpar as saídas dos seus notebooks Jupyter (Edit >> Clean outputs of all cells e depois Save) para manter os notebooks limpos.\n",
"\n",
"Aqui vão boas instruções, cortesia de um amigo IA: \n",
"https://chatgpt.com/share/677a9cb5-c64c-8012-99e0-e06e88afd293"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,37 @@
from bs4 import BeautifulSoup
import requests
# Cabeçalhos padrão para acessar um site
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"
}
def fetch_website_contents(url):
"""
Retorna o título e o conteúdo do site fornecido na URL;
trunca para 2.000 caracteres como limite razoável
"""
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.content, "html.parser")
title = soup.title.string if soup.title else "Nenhum título encontrado"
if soup.body:
for irrelevant in soup.body(["script", "style", "img", "input"]):
irrelevant.decompose()
text = soup.body.get_text(separator="\n", strip=True)
else:
text = ""
return (title + "\n\n" + text)[:2_000]
def fetch_website_links(url):
"""
Retorna os links do site na URL fornecida
Reconheço que isso é ineficiente, pois analisamos duas vezes! Isso mantém o código do laboratório simples.
Sinta-se à vontade para usar uma classe e otimizá-lo!
"""
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.content, "html.parser")
links = [link.get("href") for link in soup.find_all("a")]
return [link for link in links if link]