Dominando o Code Interpreter da OpenAI: um guia rápido

Dominando o Code Interpreter da OpenAI: um guia rápido
André Santana
André Santana

Compartilhe

O uso de Inteligência Artificial Generativa vem crescendo bastante no mercado de computação e ultrapassando as fronteiras de produtividade, no que diz respeito a geração de código.

Dentro dos times de desenvolvimento, por exemplo, é possível otimizar o tempo de trabalho utilizando as IAs generativas como a OpenAI, com o uso de ferramentas específicas para interpretação e análise de código, como é o caso do Code Interpreter.

O que é o Code Interpreter?

O Code Interpreter fornece uma interface interativa para a execução e interpretação de códigos em diversas linguagens.

Esta ferramenta se destaca por várias funcionalidades que a tornam indispensável para desenvolvedores, cientistas de dados e outros profissionais da área de tecnologia.

Vamos entender melhor sobre a tecnologia e o ecossistema em que ela está inserida?

Funcionalidades e limitações do Code Interpreter

O Code Interpreter é utilizado em conjunto com os assistentes da OpenAI que inclui os modelos da família GPT, tais quais GPT-4o, GPT-4 Turbo, GPT-4 e GPT-3.5 Turbo.

Com ele é possível inserir um arquivo de código para ser utilizado de diversas formas diferentes.

Esta abordagem também inclui o uso de RAG (Geração Aumentada de Recuperação, em português), além de interpretar e criar código em tempo real.

Quando falamos de RAG particularmente, destacamos um processo para otimizar a construção de respostas por parte dos LLMs (Grandes Modelos de Linguagem, do inglês, Large, Language Models) por meio de acesso a conhecimento externo aos dados utilizados durante o treinamento de uma LLM.

Nesta abordagem, o modelo é alimentado com uma base de conhecimento confiável, utilizada para apoiar o processo de criação das respostas.

Essa base pode ser estruturada como um documento único ou um conjunto de arquivos, que serão analisados, vetorizados e recuperados para utilização durante a geração de textos pelo modelo.

No contexto de códigos de programação, essa base possibilita que o modelo possa analisar, sugerir, modificar, transformar, revisar e, em alguns casos, executar os documentos associados.

Por exemplo, se uma empresa possui um guia de implementação de testes automatizados e desejamos utilizar LLMs para a criação de novos testes, podemos fornecer a documentação existente com os princípios e processos definidos. A LLM, então, será instruída a criar novos testes com base na documentação.

Custos do Code Interpreter

Ao utilizar o Code Interpreter é importante destacar que existe um custo associado. No momento da escrita do artigo (junho de 2024), a OpenAi estabelece uma cobrança de $0,03 (dólares) por sessão de uso dos assistentes com a ferramenta.

Isso quer dizer que se existem duas janelas de contextos, duas sessões serão criadas e esta cobrança será realizada duas vezes.

Cada sessão fica ativa por uma hora, permitindo que a pessoa desenvolvedora utilize os recursos com apenas uma cobrança durante esse período.

Funcionalidades do Code Interpreter

As principais funcionalidades do Code Interpreter:

1. Execução de código em tempo real

Esta capacidade possibilita a execução de código em tempo real, oferecendo um ambiente interativo no qual podemos escrever, testar e depurar scripts ou outros arquivos que a API permita.

Isso é especialmente útil para desenvolvimento ágil e experimentação rápida. Assim, o assistente cria um ambiente seguro (sandbox) para executar os scripts e detalha todo o processo realizado até chegar na resposta final.

Os resultados podem incluir arquivos de texto ou em outros formatos como parte da saída gerada pelo Assistente.

Por exemplo: se precisamos reescrever um trecho de código ou revisar algum padrão de projeto, podemos fornecer nosso script para o Code Interpreter e enviar uma consulta (via prompt) para extrair uma versão otimizada do código.

Se ele precisa gerar algum gráfico como resultado de um processo de avaliação de desempenho, este gráfico também pode ser resgatado da resposta.

{
    "id": "msg_abc123",
    "object": "thread.message",
    "created_at": 1698964262,
    "thread_id": "thread_abc123",
    "role": "assistant",
    "content": [
    {
      "type": "image_file",
      "image_file": {
        "file_id": "file-abc123"
      }
    }
  ]
  # ...
}

Neste bloco de resposta, por exemplo, é possível verificar que há uma imagem com um ID específico, então é possível resgatá-la, realizar a leitura de forma adequada e armazená-la para acesso posterior.

2. Suporte a múltiplas linguagens

Para auxiliar o processo de análise de código e outros formatos de arquivo, a API oferece suporte a várias linguagens de programação, incluindo Python, JavaScript, Ruby, entre outras.

Essa versatilidade permite que pessoas desenvolvedoras trabalhem em diferentes projetos sem precisar trocar de ambiente.

FORMATO DE ARQUIVOTIPO MIME
.ctext/x-c
.cstext/x-csharp
.cpptext/x-c++
.htmltext/html
.javatext/x-java
.jsonapplication/json
.phptext/x-php
.pytext/x-python
.pytext/x-script.python
.rbtext/x-ruby
.textext/x-tex
.csstext/css
.jstext/javascript
.tsapplication/typescript
.csvapplication/csv
.zipapplication/zip

Fonte: OpenAI (jun, 2024)

Acompanhe a página oficial da documentação para saber se os arquivos que você deseja ainda são suportados.

3. Análise e correção automática

Uma das características mais impressionantes do Code Interpreter é a sua capacidade de analisar e sugerir correções para o código.

Isso inclui desde a detecção de erros sintáticos até a sugestão de boas práticas de programação.

Se durante o processo, o assistente identificar algum problema, ele buscará uma nova forma de abordar a situação para tentar identificar uma solução adequada.

Por exemplo: imagine que você envia um arquivo CSV para interpretar os dados existentes e busca apoio para criar trechos que ajudem a explorar os dados. Para efetuar esta tarefa, o Assistente precisará “ler” os dados.

Se durante as etapas iniciais ele tentar abrir um arquivo CSV que utiliza separadores diferentes do padrão, algumas situações podem ocorrer: se o separador for ";" e ele tentar usar "," por padrão, a leitura do arquivo pode falhar na primeira tentativa.

O assistente pode então revisar o processo e conseguir abrir o arquivo corretamente. Para evitar esse problema, é importante deixar claro no campo de instruções do Assistente, durante a sua criação, que o arquivo utiliza um separador fora do padrão.

4. Geração de documentação

O Code Interpreter pode automaticamente gerar documentação a partir do código, incluindo comentários, explicações de funções e até diagramas de fluxo, melhorando a legibilidade e manutenção do código.

Por exemplo: se precisarmos criar a documentação de um script em Python, podemos sugerir o uso do PEP 287 para documentar um projeto.

5. Execução segura e isolada

Para evitar riscos de segurança, o Code Interpreter executa o código em um ambiente isolado, garantindo que scripts potencialmente maliciosos não afetem o sistema hospedeiro.

Limitações do Code Interpreter

Aqui estão as limitações do Code Interpreter:

1. Dependência de conectividade

Embora seja funcional, depende de uma conexão com a internet para acessar e executar suas funcionalidades avançadas, o que pode ser uma limitação em ambientes com restrições de rede.

2. Recursos computacionais limitados

A execução de código pode ser limitada pela capacidade computacional do ambiente no qual a ferramenta está sendo executada, impactando o seu desempenho em tarefas que exigem alta performance.

3. Cobertura incompleta de linguagens

Embora haja suporte para várias linguagens, a cobertura não é completa, podendo excluir linguagens menos comuns ou mais recentes, o que limita o desenvolvimento de alguns projetos.

4. Interpretação contextual

Ainda enfrenta desafios na interpretação de contextos complexos ou ambíguos, especialmente quando depende de dados externos ou de contexto específico, que não está explicitamente codificado.

5. Atualizações e manutenção

Como qualquer ferramenta de software, o Code Interpreter requer atualizações contínuas para corrigir bugs e adicionar novas funcionalidades. A frequência e a qualidade dessas atualizações podem impactar a experiência do usuário.

Banner promocional da Alura, com um design futurista em tons de azul, apresentando dois blocos de texto, no qual o bloco esquerdo tem os dizeres:

Como utilizar Code Interpreter?

Vamos mostrar aqui como utilizar o Code Interpreter em uma aplicação Python para interpretação de arquivos CSV.

Nesta seção explicaremos todas as etapas, com um exemplo de código que realiza a leitura de um arquivo CSV para interpretação de dados.

Além disso, vamos mostrar como recuperar arquivos de imagem ou texto que podem ser exemplos de respostas do Assistente.

Estrutura de um Assistente

Para começar, você pode acessar a base de dados transplantes_brasil.csv, que contém informações sobre transplantes realizados no Brasil e foi exraída da plataforma Kaggle.

Esta base de dados inclui diversos campos: uma ID que identifica cada paciente, a idade do paciente no momento do transplante, sexo biológico do paciente, tipo de transplante (por tipo de órgão ou tecido transplantado), data do procedimento resultado (sucesso ou falha) e recorrência de hemodiálise.

Para criar um assistente usando a API da OpenAI, você precisa definir alguns campos que configuram o comportamento do Assistente e suas capacidades.

A seguir, estão os principais campos necessários:

  1. Name (Nome):

    • Descrição: nome do assistente que você está criando.
    • Exemplo: "Assistente de Exploração de Dados Médicos"
  2. Instructions (Instruções):

    • Descrição: instruções detalhadas sobre a persona do assistente, seus objetivos, estilo de comunicação, e como ele deve processar as informações fornecidas.
    • Exemplo:
# Persona
- **Nome:** Dr. Insight
- **Profissão:** assistente de Exploração de Dados Médicos
- **Objetivo:** auxiliar médicos e profissionais de saúde na análise e exploração de dados de transplantes, fornecendo respostas precisas e insights valiosos para apoiar diagnósticos e decisões clínicas.

# Tipo de Saída
- **Formato de resposta:** texto explicativo, gráficos interativos, tabelas e relatórios exportáveis.
- **Estilo de comunicação:** claro, conciso e profissional, com foco na precisão dos dados e relevância clínica.
  1. Model (Modelo):

    • Descrição: o modelo de linguagem que o assistente utilizará para gerar respostas. Os modelos mais comuns são da família GPT (GPT-3.5 Turbo, GPT-4).
    • Exemplo: "gpt-4o"
  2. Code Interpreter (Interpretador de Código):

    • Descrição: ferramenta que permite ao assistente interpretar e executar código, ajudando em tarefas que envolvem processamento de dados, cálculos complexos, ou geração de gráficos e relatórios. Esta opção precisa estar ativa e pode ter um arquivo associado a ela ou não.

Além disso, também é possível enviar um arquivo durante o envio de uma mensagem (associando-o a uma thread para que seja interpretado durante o processo). Veja mais detalhes na plataforma da OpenAi, em inglês.

Como usar o Code Interpreter via API em Python

Para utilizar o Code Interpreter via API é necessário implementar o Assistente, o fluxo principal, que envolve receber uma mensagem e enviar para API, e o processamento da resposta.

A estrutura do Projeto será organizada da seguinte maneira:

projeto/
│
├── main.py
├── interpreter_utils.py
├── [transplantes_brasil.csv](https://github.com/alura-cursos/artigo-pode-interpreter/blob/main/transplantes_brasil.csv)
├── requirements.txt
└── .env

Arquivo requirements.txt

Sendo assim, primeiro instale as bibliotecas necessárias listadas no requirements.txt:

pip install -r requirements.txt

O conteúdo do arquivo requirements.txt contém as seguintes bibliotecas:

python-dotenv
openai
pillow
pandas

Arquivo .env

Armazene suas credenciais e configurações sensíveis no arquivo .env:

OPENAI_API_KEY=your_openai_api_key

Arquivo interpreter_utils.py

O arquivo interpreter_utils.py contém as funções de suporte para criar arquivos, assistentes e gerenciar threads.

from openai import OpenAI
import os
from dotenv import load_dotenv
import pandas as pd

load_dotenv()
cliente = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

def criar_arquivo(caminho_arquivo):
  file_path = caminho_arquivo
  file = cliente.files.create(
      file=open(file_path, "rb"),
      purpose="assistants"
  )
  return file

def criar_assistente_dados_medicos(file_id : str):
  assistente = cliente.beta.assistants.create(
      name="Assistente de Exploração de Dados Médicos",
      instructions="""

      # Persona

      - **Nome:** Dr. Insight
      - **Profissão:** Assistente de Exploração de Dados Médicos
      - **Objetivo:** Auxiliar médicos e profissionais de saúde na análise e exploração de dados de transplantes, fornecendo respostas precisas e insights valiosos para apoiar diagnósticos e decisões clínicas.

      # Tipo de Saída

      - **Formato de Resposta:** Texto explicativo, gráficos interativos, tabelas e relatórios exportáveis.
      - **Estilo de Comunicação:** Claro, conciso e profissional, com foco na precisão dos dados e relevância clínica.

      # Prompt para o Assistente

      **Instruções para Carregar e Explorar a Base de Dados**

      Você é Dr. Insight, um assistente de exploração de dados médicos. Seu objetivo é auxiliar médicos e profissionais de saúde na análise da base de dados "transplates_brasil.csv", que contém informações sobre transplantes. Siga estas instruções para carregar e analisar os dados, e responda às perguntas dos usuários com base nos insights extraídos.

      ## Passos para Carregar e Explorar a Base de Dados

      1. **Importar Bibliotecas Necessárias:**

          import pandas as pd

      2. **Carregar o Arquivo CSV:**

          # Carregar o arquivo CSV, que está separado por ponto e vírgula

      3. **Exibir as Primeiras Linhas da Base de Dados:**

          # Exibir as primeiras linhas do DataFrame para entender a estrutura dos dados
          print(df.head())

      4. Gráficos
          - Se for necessário responder a perguntas com gráficos utilize o seaborn ou matplotlib

      """,
      model="gpt-4o",
      tools=[
          {
              "type":"code_interpreter"
          }
      ],
      tool_resources={
          "code_interpreter":{
              "file_ids": [file_id]
          }
      }
  )
  return assistente

def criar_thread():
  return cliente.beta.threads.create()

def apagar_arquivo(file_id : str):
  cliente.files.delete(file_id)

def apagar_thread(thread_id : str):
  cliente.beta.threads.delete(thread_id)

def apagar_assistente(assistant_id : str):
  cliente.beta.assistants.delete(assistant_id)

Arquivo main.py

O arquivo main.py será o ponto de entrada principal da aplicação, onde utilizamos as funções definidas em interpreter_utils.py.

from interpreter_utils import criar_arquivo, criar_assistente_dados_medicos, criar_thread, apagar_arquivo, apagar_thread, apagar_assistente
import os
from openai import OpenAI 
from dotenv import load_dotenv

load_dotenv()
cliente = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

def main():
    file_path = "transplantes_brasil.csv"
    arquivo = criar_arquivo(caminho_arquivo=file_path)
    assistente = criar_assistente_dados_medicos(file_id=arquivo.id)
    thread = criar_thread()

    pergunta = "Quais as características dos pacientes que pertencem aos 10% que mais recorrem a hemodialise?"

    message = cliente.beta.threads.messages.create(
        thread_id=thread.id,
        role="user",
        content=pergunta
    )

    run = cliente.beta.threads.runs.create_and_poll(
        thread_id=thread.id,
        assistant_id=assistente.id
    )

    if run.status == "completed":
        mensagens_resposta = cliente.beta.threads.messages.list(
            thread_id=thread.id
        )

        for uma_mensagem in mensagens_resposta.data[0].content:
            if hasattr(uma_mensagem, "text") and uma_mensagem.text is not None:
                print("\n")
                print(uma_mensagem.text.value)
            elif hasattr(uma_mensagem, "image_file") and uma_mensagem.image_file is not None:
                resposta_da_openai = cliente.files.retrieve(uma_mensagem.image_file.file_id)
                image_data = cliente.files.content(resposta_da_openai.id)
                image_data_bytes = image_data.read()

                with open("grafico.png", "wb") as file:
                    file.write(image_data_bytes)
    else:
        print(run.status)

    apagar_arquivo(arquivo.id)
    apagar_thread(thread.id)
    apagar_assistente(assistente.id)

if __name__ == "__main__":
    main()

Explicação do Código

  1. Configuração Inicial:

    • interpreter_utils.py importa bibliotecas e configura o ambiente carregando a chave da API da OpenAI do arquivo .env.
  2. Funções de Utilidade:

    • criar_arquivo: Cria e retorna um arquivo assistente.
    • criar_assistente_dados_medicos: Cria e retorna um assistente configurado com instruções específicas.
    • criar_thread: Cria e retorna uma nova thread.
    • apagar_arquivo, apagar_thread, apagar_assistente: Funções para deletar o arquivo, thread e assistente respectivamente.
  3. Função Main:

    • main: Função principal que coordena a criação do arquivo, assistente, e thread, envia a pergunta ao assistente e processa as respostas, incluindo a exibição de texto e salvamento de gráficos gerados.

Este exemplo demonstra como usar o Code Interpreter de maneira estruturada e seguindo boas práticas em uma aplicação Python.

A abordagem pode ser empregada em diferentes cenários, desde análise de dados, como no exemplo apresentado, até nos aspectos que envolvem a criação e revisão de códigos, como para o desenvolvimento de scripts automatizados para realizar tarefas.

Conclusão

O Code Interpreter da OpenAI representa um avanço na programação e na análise de dados, pois fornece uma interface interativa para a execução e interpretação de códigos em diversas linguagens.

Além disso, oferece um ambiente que favorece o desenvolvimento ágil, a experimentação rápida e a geração automática de documentação, com análise e correção automática de códigos.

O uso de modelos de linguagem de larga escala (LLMs) como o GPT-4o, em combinação com ferramentas como o Code Interpreter, traz inúmeros benefícios. Esses modelos podem ser aprimorados com técnicas como a Geração Aumentada de Recuperação (RAG).

A RAG permite a integração de informações atualizadas e específicas de domínio, tornando as respostas mais precisas e contextualmente relevantes.

O Code Interpreter permite a execução de código em tempo real e fornecer análises detalhadas e sugestões de melhorias, o que é útil para quem trabalha com grandes volumes de dados ou projetos complexos.

A capacidade de integrá-lo com utras ferramentas de desenvolvimento, como GitHub e Jupyter Notebooks, também promove uma colaboração mais eficaz e uma gestão de projetos mais coesa.

Sendo assim, a ferramenta é poderosa para desenvolver software e analisar dados. Mas é importante estar ciente de suas limitações e dependências, garantindo um uso seguro e eficiente.

Para mais informações e acesso à documentação completa, visite a plataforma da OpenAI ou ainda acesse a formação OpenAI e Python aqui da Alura.

André Santana
André Santana

Professor no Insper | Pesquisador no LSITec (EP-USP) | Instrutor na Alura

Veja outros artigos sobre Programação