Guias e Tutoriais

Como validar um CSV localmente antes de pedir análise a uma IA

Ilustração editorial de uma planilha CSV passando por validação local antes de chegar a uma rede de inteligência artificial.

Um arquivo CSV pode parecer correto quando aberto rapidamente, mas ainda chegar à análise com colunas fundidas, acentos quebrados, cabeçalhos repetidos ou linhas com quantidades diferentes de campos. Quando isso acontece, a IA não recebe apenas dados imperfeitos. Ela recebe uma estrutura ambígua e pode produzir uma conclusão coerente sobre uma tabela que nunca existiu de fato.

Este guia mostra como validar um CSV localmente, antes de enviar qualquer conteúdo a uma IA. O resultado esperado é um registro com o hash do arquivo, o delimitador detectado, a quantidade de colunas, o número de registros, as linhas estruturalmente inconsistentes e células que merecem revisão de segurança.

Escopo: o procedimento verifica estrutura e alguns sinais de risco. Ele não prova que datas, valores, CPFs, e-mails ou demais conteúdos estejam corretos. A validação semântica continua sendo responsabilidade de quem conhece a base.

Por que um CSV pode enganar

CSV é um formato muito usado para trocar dados entre planilhas e sistemas, mas existem variações reais entre os arquivos produzidos por aplicações diferentes. A RFC 4180 documenta um formato comum e registra o tipo text/csv, enquanto a documentação do módulo csv do Python alerta que delimitadores, aspas e outros detalhes podem variar.

No Brasil, é comum encontrar ponto e vírgula no lugar da vírgula, especialmente quando a vírgula é usada como separador decimal. Também há arquivos com tabulação, campos entre aspas, quebras de linha dentro de uma célula e codificações diferentes. Por isso, contar vírgulas em um editor de texto não é uma validação suficiente.

Pré-requisitos

  • uma cópia local do CSV, preservando o original;
  • Python 3 instalado, para executar o validador estrutural;
  • PowerShell, para registrar o SHA-256 de forma independente;
  • conhecimento mínimo sobre quais colunas deveriam existir e quais não podem ficar vazias.

Não use o arquivo original como área de teste. Copie-o para uma pasta de trabalho e mantenha a origem sem alterações. Se a base contém dados pessoais, segredos comerciais ou credenciais, não a envie a um validador on-line.

Passo 1: registre o arquivo exato

No PowerShell, defina o caminho da cópia e gere um hash SHA-256:

$arquivoCsv = 'C:\Dados\clientes.csv'
Get-Item -LiteralPath $arquivoCsv |
  Select-Object Name, Length, LastWriteTime

Get-FileHash -LiteralPath $arquivoCsv -Algorithm SHA256 |
  Format-List Algorithm, Hash, Path

Guarde o hash junto do relatório. Se o conteúdo mudar, mesmo mantendo o mesmo nome, o hash também muda. A documentação do Get-FileHash explica esse uso e informa que SHA-256 é o algoritmo padrão do cmdlet.

Esse registro evita uma confusão frequente: revisar uma versão do CSV e enviar outra para a IA.

Passo 2: inspecione poucas linhas sem abrir no Excel

Leia apenas o começo do arquivo em texto:

Get-Content -LiteralPath $arquivoCsv -Encoding UTF8 -TotalCount 5

Observe três coisas:

  • os acentos aparecem corretamente;
  • a primeira linha parece conter os cabeçalhos esperados;
  • o separador aparente é vírgula, ponto e vírgula, tabulação ou outro caractere.

Se os acentos estiverem quebrados, pare. Não converta às cegas. Confirme com o sistema que exportou a base qual codificação foi usada. Uma conversão errada pode trocar caracteres de forma permanente.

Passo 3: faça a leitura estrutural

Crie um arquivo chamado validar_csv.py com o código abaixo. O script lê o CSV localmente, tenta detectar o delimitador entre quatro opções, assume que o primeiro registro é o cabeçalho e percorre o restante sem carregar toda a base na memória.

import csv
import hashlib
import pathlib
import sys

if len(sys.argv) != 2:
    raise SystemExit("Uso: python validar_csv.py caminho_do_arquivo.csv")

arquivo = pathlib.Path(sys.argv[1])

sha256 = hashlib.sha256()
with arquivo.open("rb") as bruto:
    for bloco in iter(lambda: bruto.read(1024 * 1024), b""):
        sha256.update(bloco)

sha256_hex = sha256.hexdigest()

try:
    with arquivo.open("r", encoding="utf-8-sig", newline="") as texto:
        amostra = texto.read(8192)
        texto.seek(0)

        dialeto = csv.Sniffer().sniff(
            amostra,
            delimiters=",;\t|",
        )
        leitor = csv.reader(texto, dialeto)
        cabecalho = next(leitor, None)

        if cabecalho is None:
            raise SystemExit("ERRO: arquivo vazio")

        total_colunas = len(cabecalho)
        linhas_dados = 0
        inconsistentes = []
        celulas_para_revisao = 0
        prefixos_formula = ("=", "+", "-", "@", "\t", "\r", "\n")

        for linha in leitor:
            numero_linha = leitor.line_num
            linhas_dados += 1

            if len(linha) != total_colunas and len(inconsistentes) < 20:
                inconsistentes.append(
                    (numero_linha, len(linha))
                )

            for valor in linha:
                if valor.lstrip(" ").startswith(prefixos_formula):
                    celulas_para_revisao += 1

except UnicodeDecodeError:
    raise SystemExit(
        "ERRO: o arquivo não pôde ser lido como UTF-8. "
        "Confirme a codificação na origem."
    )
except csv.Error as erro:
    raise SystemExit(
        f"ERRO: não foi possível detectar a estrutura CSV: {erro}"
    )

cabecalhos_vazios = [
    posicao + 1
    for posicao, nome in enumerate(cabecalho)
    if not nome.strip()
]

cabecalhos_duplicados = sorted({
    nome
    for nome in cabecalho
    if nome and cabecalho.count(nome) > 1
})

print(f"Arquivo: {arquivo}")
print(f"SHA-256: {sha256_hex}")
print(f"Delimitador: {repr(dialeto.delimiter)}")
print(f"Colunas: {total_colunas}")
print(f"Linhas de dados: {linhas_dados}")
print(f"Cabeçalhos: {cabecalho}")
print(f"Cabeçalhos vazios: {cabecalhos_vazios}")
print(f"Cabeçalhos duplicados: {cabecalhos_duplicados}")
print(f"Linhas inconsistentes, até 20: {inconsistentes}")
print(
    "Células iniciadas por prefixo de fórmula, "
    f"revisar: {celulas_para_revisao}"
)

Execute assim:

python .\validar_csv.py 'C:\Dados\clientes.csv'

Como interpretar o resultado

Delimitador: confira se corresponde ao que você viu nas primeiras linhas. A classe csv.Sniffer deduz o formato a partir de uma amostra, mas a própria documentação deixa claro que a detecção é heurística. Se o resultado não fizer sentido, especifique o delimitador com base na documentação do sistema de origem.

Colunas e cabeçalhos: compare a lista com o contrato da base. Um arquivo pode ser estruturalmente válido e ainda trazer uma coluna errada, ausente ou com nome inesperado.

Linhas inconsistentes: cada item mostra a linha física em que o registro terminou e a quantidade de campos encontrada. Volte à origem para corrigir aspas, separadores ou exportação. Não remende uma linha sem saber qual valor deveria ocupar cada coluna.

Células iniciadas por prefixo de fórmula: isso é um alerta, não uma acusação. Números negativos também começam com hífen e podem aparecer na contagem. Revise os casos antes de abrir a base em uma planilha. A OWASP descreve a injeção de fórmulas em CSV e explica por que valores iniciados por caracteres especiais podem ser interpretados como fórmulas por programas de planilha.

Passo 4: faça uma segunda leitura no PowerShell

Depois de confirmar o delimitador, importe a cópia no PowerShell. Para ponto e vírgula:

$dados = @(
  Import-Csv -LiteralPath $arquivoCsv -Delimiter ';' -Encoding UTF8
)

$dados.Count
@($dados[0].PSObject.Properties.Name)
$dados | Select-Object -First 5 | Format-Table -AutoSize

Troque ';' por ',' somente se o delimitador real for vírgula. A documentação oficial do Import-Csv alerta que um separador incorreto impede a divisão das colunas e pode produzir um objeto com uma única propriedade.

Esta segunda leitura serve como comparação entre dois parsers. Se Python e PowerShell mostrarem contagens ou colunas diferentes, não envie o arquivo ainda.

Passo 5: defina o que a IA pode receber

Mesmo um CSV estruturalmente limpo pode conter dados que não deveriam sair do ambiente local. Antes do envio:

  • remova colunas sem utilidade para a tarefa;
  • substitua identificadores diretos por códigos quando possível;
  • separe uma amostra pequena para testar o prompt;
  • registre quais filtros e transformações foram aplicados;
  • confirme as regras de retenção e uso de dados da ferramenta escolhida.

O guia Como separar arquivos e contextos de clientes antes de usar IA ajuda a organizar essa etapa sem misturar bases. Para revisar fórmulas e totais quando o arquivo de origem é uma planilha, consulte também Como revisar uma planilha criada com IA antes de usar.

Checklist antes do envio

  • o hash corresponde à cópia validada;
  • a codificação foi confirmada;
  • o delimitador detectado faz sentido;
  • os cabeçalhos foram comparados com a origem;
  • não há linhas com quantidade inesperada de campos;
  • células com possíveis fórmulas foram revisadas;
  • dados desnecessários ou sensíveis foram removidos;
  • uma amostra pequena foi usada para testar a instrução;
  • o resultado da IA será conferido contra registros reais.

Erros comuns

“Não foi possível detectar a estrutura”: o arquivo pode ter uma única coluna, ser pequeno demais, usar outro delimitador ou conter linhas irregulares. Inspecione a amostra e confirme a exportação na origem.

“Não pôde ser lido como UTF-8”: descubra a codificação correta antes de converter. Não escolha uma página de código apenas porque os primeiros acentos parecem melhorar.

Uma única coluna apareceu no PowerShell: o delimitador informado provavelmente não corresponde ao arquivo. Compare vírgula e ponto e vírgula, sem alterar o original.

O arquivo passou, mas a análise ficou errada: a estrutura estava legível, mas isso não garante conteúdo correto. Volte ao dicionário de dados, valide tipos, unidades, datas, chaves e regras do negócio.

O ganho real desse processo não é “preparar dados para a IA”. É criar uma evidência mínima de que a tabela enviada corresponde ao arquivo que você pretende analisar. Sem essa etapa, qualquer resposta convincente pode estar apoiada em colunas interpretadas da maneira errada.

RADAR BASTIDORES

IA muda rápido. Critério não.

Estamos preparando uma seleção editorial de novidades, ferramentas e guias que realmente merecem atenção.

Escolha apenas o canal pelo qual deseja receber novidades. Nome e demais campos são opcionais.

Os dados ficam privados no WordPress e não são vendidos. Informe ao menos e-mail, celular ou rede social.