Como o GPT4Free Funciona em Python e Por Que Você Não Deveria Usá-lo
Olá, comunidade do Habr! Hoje, vamos discutir um projeto que causou muito alvoroço na comunidade – g4f (GPT4Free). Muitos já o viram no GitHub, mas a maioria provavelmente nunca se perguntou como ele funciona.
Como Usar g4f em Código Python
A API g4f se parece com a da OpenAI. Isso é feito especificamente para que os programadores não precisem aprender novos comandos e métodos para chamar o código em g4f. Basta substituir import openai por import g4f. Exemplo de código:
Com a biblioteca oficial openai:
pythonfrom openai import OpenAI client = OpenAI(api_key="sk-...") response = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": "SEU_PEDIDO"}] ) print(response.choices[0].message.content)
Com a biblioteca oficial g4f:
pythonfrom g4f.client import Client client = Client() response = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": "SEU_PEDIDO"}] ) print(response.choices[0].message.content)
Ambos os códigos enviam solicitações ao GPT4, mas o primeiro código requer uma chave de API do site oficial da OpenAI, enquanto o segundo não. Essa é a principal razão para a existência do g4f.
Instalação e Preparação do g4f
Para instalar o g4f em seu computador, você precisa digitar o seguinte comando no terminal da IDE ou na linha de comando:
bashpython.exe -m pip install g4f
Após isso, o repositório do projeto será instalado em seu computador e poderá ser usado imediatamente em scripts Python. Você também pode clonar o repositório usando o git. Esta é a maneira mais adequada. Para fazer isso, digite o seguinte comando na linha de comando:
bashgit clone https://github.com/xtekky/gpt4free.git
Após clonar o repositório, a pasta "gpt4free" aparecerá no disco rígido.
O Que Está Dentro do g4f
Agora, a parte mais interessante – como este projeto funciona. Na pasta "gpt4free", há muitos arquivos. Estamos interessados na pasta com os arquivos "g4f". Dentro, há muitos arquivos diferentes, mas estamos interessados na pasta "Provider". Em seguida, vemos scripts python, onde a imitação da interação do usuário com a interface do site é configurada para cada site provedor. Vamos dar uma olhada no exemplo do código EasyChat.py:
pythonfrom __future__ import annotations # Melhora o trabalho com anotação de tipos import os # Trabalhando com arquivos e variáveis de ambiente import asyncio # Permite executar várias tarefas simultaneamente (assincronamente) import requests # Envio de solicitações HTTP regulares para sites import json # Leitura e gravação de dados em formato JSON try: import zendriver as nodriver # Biblioteca para controlar um navegador Chromium real sem uma janela except ImportError: pass # Se a biblioteca não estiver instalada – não importa, mas algumas funções não estarão disponíveis from ..typing import AsyncResult, Messages # Descrições auxiliares de tipos de dados from ..config import DEFAULT_MODEL # O nome do modelo que é usado por padrão from ..requests import get_args_from_nodriver, raise_for_status # Funções: coletar dados do navegador e verificar o sucesso da solicitação from ..providers.base_provider import AuthFileMixin # Adiciona a capacidade de salvar/carregar dados de autorização em um arquivo from .template import OpenaiTemplate # Classe base que copia o comportamento da API OpenAI from .helper import get_last_user_message # Obtém a última mensagem do usuário de toda a correspondência from .. import debug # Saída simples de mensagens de depuração class EasyChat(OpenaiTemplate, AuthFileMixin): # Esta classe é responsável por acessar o serviço EasyChat, repetindo o estilo OpenAI url = "https://chat3.eqing.tech" # Endereço do site EasyChat base_url = f"{url}/api/openai/v1" # Base para todas as solicitações à sua API api_endpoint = f"{base_url}/chat/completions" # Caminho específico para onde a solicitação de geração de resposta é enviada working = False # Diz que este método de acesso não está funcionando agora (pode mudar) active_by_default = True # Por padrão, incluído na lista de métodos disponíveis use_model_names = True # Use nomes de modelos sem alterações default_model = DEFAULT_MODEL.split("/")[-1] # Do nome completo, pegamos apenas o nome curto do modelo model_aliases = { DEFAULT_MODEL: f"{default_model}-free", # Você pode se referir pelo nome curto, "-free" será adicionado internamente } captchaToken: str = None # O código de passagem entrará aqui após passar na verificação "Eu não sou um robô" share_url: str = None # Link para compartilhar a sessão pronta (se quisermos compartilhar) looked: bool = False # Sinalizador para não tentar carregar a sessão infinitamente via share_url guestId: str = None # Número exclusivo de convidado que o site atribui ao visitante @classmethod def get_models(cls, **kwargs) -> list[str]: # Retorna uma lista de modelos que o site oferece if not cls.models: # Se ainda não perguntamos models = super().get_models(**kwargs) # Pegamos a lista da classe pai (da API do site) models = {m.replace("-free", ""): m for m in models if m.endswith("-free")} # Deixamos apenas modelos gratuitos cls.model_aliases.update(models) # Lembramos que o nome curto corresponde ao nome completo cls.models = list(models) # Salvamos a lista de modelos para acesso rápido return cls.models @classmethod async def create_async_generator( # Método principal: envia uma solicitação e retorna a resposta em partes em tempo real cls, model: str, # Qual modelo estamos pedindo messages: Messages, # Histórico de correspondência stream: bool = True, # Se deve retornar a resposta gradualmente (geralmente sim) proxy: str = None, # Servidor proxy, se você precisar ocultar seu IP extra_body: dict = None, # Dados adicionais que irão junto com a solicitação **kwargs # Quaisquer outros parâmetros ) -> AsyncResult: # Retorna um gerador de pedaços de resposta cls.share_url = os.getenv("G4F_SHARE_URL") # Verificamos se há um link para compartilhar a sessão nas configurações model = cls.get_model(model.replace("-free", "")) # Transformamos o nome curto em completo, se necessário args = None # Aqui serão armazenadas todas as configurações técnicas para a solicitação (cabeçalhos, cookies, etc.) cache_file = cls.get_cache_file() # Arquivo no qual esconderemos os dados da sessão para não passar pelo captcha toda vez async def callback(page): # Esta função será executada no navegador imediatamente após a abertura da página cls.captchaToken = None # Limpamos a passagem antiga def on_request(event: nodriver.cdp.network.RequestWillBeSent, page=None): # Monitoramos todas as solicitações que o site envia if event.request.url != cls.api_endpoint: # Estamos interessados apenas na solicitação à API return if not event.request.post_data: # Se a solicitação estiver vazia – ignoramos return cls.captchaToken = json.loads(event.request.post_data).get("captchaToken") # Pegamos o código de passagem da solicitação await page.send(nodriver.cdp.network.enable()) # Ativamos o rastreamento de solicitações de rede page.add_handler(nodriver.cdp.network.RequestWillBeSent, on_request) # Anexamos um interceptador de solicitações button = await page.find("我已知晓") # Procuramos o botão de concordância na página if button: await button.click() # Clicamos nele else: debug.error("No 'Agree' button found.") # Imprimimos um erro se o botão não for encontrado for _ in range(3): # Tentamos até três vezes ativar a sessão await asyncio.sleep(1) for _ in range(300): # Esperamos até que a verificação "Verifying..." esteja em andamento modal = await page.find("Verifying...") if not modal: break debug.log("EasyChat: Waiting for captcha verification...") await asyncio.sleep(1) if cls.captchaToken: # Se o código de passagem já foi recebido debug.log("EasyChat: Captcha token found, proceeding.") break textarea = await page.select("[contenteditable=\"true\"]", 180) # Procuramos o campo de entrada if textarea is not None: await textarea.send_keys("Hello") # Digitamos uma mensagem de teste await asyncio.sleep(1) button = await page.select("button[class*='chat_chat-input-send']") # Procuramos o botão de envio if button: await button.click() # Enviamos uma mensagem de teste for _ in range(300): # Esperamos que o código de passagem apareça, se ainda não chegou await asyncio.sleep(1) if cls.captchaToken: break cls.guestId = await page.evaluate( # Pegamos o ID do convidado da memória do navegador '"" + JSON.parse(localStorage.getItem("user-info") || "{}")?.state?.guestId' ) await asyncio.sleep(3) # Uma pequena pausa para que tudo seja salvo if cache_file.exists(): # Se os dados da sessão salvos já estiverem no disco with cache_file.open("r") as f: args = json.load(f) # Lemos eles cls.captchaToken = args.pop("captchaToken") # Extraímos o código de passagem cls.guestId = args.pop("guestId", None) # Extraímos o ID do convidado if cls.captchaToken: debug.log("EasyChat: Using cached captchaToken.") # Usamos os dados salvos elif not cls.looked and cls.share_url: # Se não houver uma sessão salva e o URL de compartilhamento for especificado cls.looked = True try: debug.log("No cache file found, trying to fetch from share URL.") response = requests.get(cls.share_url, params={ # Acessamos o link de compartilhamento "prompt": get_last_user_message(messages), "model": model, "provider": cls.__name__ }) raise_for_status(response) # Verificamos se a resposta foi bem-sucedida text, *sub = response.text.split("\n" * 10 + "<!--", 1) # Separamos o texto da resposta dos dados técnicos ocultos if sub: # Se houver dados técnicos debug.log("Save args to cache file:", str(cache_file)) with cache_file.open("w") as f: f.write(sub[0].strip()) # Salvamos eles para solicitações futuras yield text # Retornamos o texto recebido como resultado finally: cls.looked = False return for _ in range(2): # Fazemos até duas tentativas caso a primeira falhe if not args: # Se ainda não houver configurações técnicas args = await get_args_from_nodriver( # Abrimos o site no navegador e coletamos todos os dados necessários cls.url, proxy=proxy, callback=callback, user_data_dir=None ) if extra_body is None: extra_body = {} extra_body.setdefault("captchaToken", cls.captchaToken) # Adicionamos o código de passagem ao corpo da solicitação try: last_chunk = None async for chunk in super().create_async_generator( # Enviamos uma solicitação através da classe pai (modelo OpenAI) model=model, messages=messages, stream=True, extra_body=extra_body, **{ **args, "headers": { "X-Guest-Id": cls.guestId, # Adicionamos o ID do convidado aos cabeçalhos **args.get("headers", {}) } }, **kwargs ): if last_chunk == "\n" and chunk == "\n": # Removemos a linha de publicidade no final ("Fornecido pelo serviço...") break last_chunk = chunk yield chunk # Retornamos um pedaço da resposta except Exception as e: if "CLEAR-CAPTCHA-TOKEN" in str(e): # O servidor disse que nosso código de passagem expirou debug.log("EasyChat: Captcha token expired, clearing cache file.") cache_file.unlink(missing_ok=True) # Removemos o arquivo com dados desatualizados args = None # Nos preparamos para coletar novos dados através do navegador continue raise e break if not args: # Se, após todas as tentativas, os dados não forem obtidos raise ValueError("Failed to retrieve arguments for EasyChat.") if os.getenv("G4F_SHARE_AUTH"): # Se for permitido compartilhar dados técnicos da sessão yield "\n" * 10 yield "<!--" yield json.dumps({**args, "captchaToken": cls.captchaToken, "guestId": cls.guestId}) with cache_file.open("w") as f: # Salvamos os dados técnicos no arquivo para entrada rápida na próxima vez json.dump({**args, "captchaToken": cls.captchaToken, "guestId": cls.guestId}, f)
Aqui, mostrei claramente como este pedaço de código funciona em g4f. O princípio básico de funcionamento é a engenharia reversa. Este é o processo de análise de um produto acabado para entender como ele é estruturado internamente, sem acesso ao seu código-fonte. O programa interage com os serviços de IA em nome do usuário, passa por captchas, lida com a interface do site, estrutura a resposta para o modelo especificado. O usuário apenas executa o código, e ele envia solicitações automáticas e, contornando a proteção dos serviços contra bots, exibe a resposta.
Quão Seguro é Usar Isso?
O mito mais perigoso é: "Como não estou pagando, ninguém sabe o que estou perguntando". Na verdade, é o contrário. Se, ao usar a API OpenAI normal, a cadeia for assim:
Seu código → Servidor OpenAI → Resposta do modelo GPT de alta qualidade
Então, ao usar g4f, a cadeia será mais ou menos assim:
Seu código → g4f Client → Site 1 (erro: bot detectado) → Site 2 (longa espera) → Site 3 (acesso negado) → Usando proxy → Site 3 → Servidor LLM desconhecido → Resposta de qualidade duvidosa
Ao mesmo tempo, g4f, mesmo que você não saiba, pode se conectar através de servidores proxy aleatórios, substituir cabeçalhos e fingir ser um navegador para contornar a maioria das verificações padrão para um robô. Se o site não estiver disponível – g4f pode fazer uma longa cadeia de seleção de muitos sites, enviando sua solicitação para o primeiro que funcionar. E se o site proibir o acesso devido a solicitações muito frequentes – g4f mascarará seu IP sem o seu conhecimento.
E o mais perigoso é o enorme risco de vazamento de dados. Sua solicitação passa por muitos servidores aleatórios que g4f seleciona em tempo real. Qualquer um desses sites pode registrar tudo o que passa por ele: código-fonte, informações comerciais, dados pessoais. Como resultado, você perde o controle de onde suas informações acabarão. E o mais assustador: provar que o vazamento ocorreu através do g4f será impossível – a biblioteca já apagou os rastros, e ninguém nunca saberá em quem seus dados estavam e quando eles funcionarão contra você.
Comparação Visual do g4f com a API OpenAI Oficial
| Critério | OpenAI (API oficial) | g4f (GPT4Free) |
|---|---|---|
| Modelo | Você recebe exatamente o modelo que solicitou | O modelo na maioria dos casos nunca será exatamente aquele que você especificou no código |
| Canal | Canal direto e seguro, os dados não saem do servidor OpenAI | A solicitação percorre dezenas de servidores de terceiros |
| Estabilidade | Garantida, 99% | Pode cair a qualquer momento devido à mudança dos algoritmos de segurança dos sites aos quais g4f se refere |
| Legalidade | Totalmente legal, não viola o Contrato do Usuário OpenAI | Viola os termos de uso tanto do próprio OpenAI quanto dos sites participantes na cadeia de seleção através dos quais a solicitação é feita |
| Controle de IP | Você trabalha do seu IP | O tráfego passa por proxies aleatórios sem o seu conhecimento |
| Qualidade da resposta | Previsível e reproduzível. Se você não estiver satisfeito com a resposta, basta alterar o modelo no código e obter a qualidade de resposta correspondente | Caótico, a resposta pode vir de um LLM desconhecido. G4F simplesmente alterará o estilo da resposta para o modelo selecionado. Mudar o modelo no código é inútil – a qualidade da resposta não mudará com isso |
| Armazenamento de sessões | Chave de API – o único identificador | Tokens de captcha, cookies de terceiros são armazenados em cache |
| Risco de vazamento | Mínimo, o tráfego é criptografado | Crítico: os dados podem se instalar em qualquer nó |
| Preço | Pode ser encontrado no site oficial da OpenAI | "Gratuito" ao custo de sua privacidade e segurança |
| Velocidade da resposta | Quase instantânea, 1-5 segundos | Pode levar vários minutos. Tudo depende de quanto tempo g4f levará para selecionar sites e resolver captchas |
| Suporte técnico | Documentação oficial, há suporte técnico, página de status, relatórios de incidentes | Ausente por completo. Você pode escrever um problema no GitHub, mas a garantia de que ele será notado está ausente |
Como resultado, você mesmo pode ver: a API oficial da OpenAI oferece previsibilidade, segurança e controle total sobre os dados por um preço que, para a maioria das tarefas, é medido em centavos. G4F oferece "queijo grátis", que a qualquer momento pode se transformar em vazamento, bloqueio ou apenas código que não funciona – e sem nenhuma possibilidade de obter ajuda. A escolha entre essas abordagens não se resume a economizar dinheiro, mas a uma pergunta simples: você está pronto para confiar seus dados pessoais e a estabilidade do produto a uma cadeia transparente de servidores aleatórios e nenhuma responsabilidade?
Espero que este artigo ajude você a fazer a escolha certa entre g4f e a API OpenAI no futuro. Obrigado por ler até o fim, e que seu código sempre funcione de forma previsível e seus dados permaneçam apenas em suas mãos!







