◇ OpenCyber Academy
Engenharia · Capítulo 9 · Português

Capítulo 9 — Programação II

Ensino gratuito e aberto para quem deseja proteger pessoas e tecnologias. Não é preciso criar uma conta para estudar ou consultar as respostas.

Capítulo 9 — Programação II

Mapa da aula

Aula 09 publicada. Mapa, exemplo, EX025.

flowchart TD
  N0["9.1 Módulos e interfaces"]
  N1["9.2 Dependências e cadeia de suprimentos"]
  N2["9.3 Testes além de exemplos"]
  N3["9.4 Um harness de avaliação"]
  N4["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4
  N4 --> EX["Exemplo resolvido"]
  EX --> Q["Exercício EX025"]

Desenho lógico

flowchart LR
  N0["9.1 Módulos e interfaces"]
  N1["9.2 Dependências e cadeia de suprimentos"]
  N2["9.3 Testes além de exemplos"]
  N3["9.4 Um harness de avaliação"]
  N4["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX025"]
[9.1 Módulos e interfaces]
    |
    v
[9.2 Dependências e cadeia de suprimentos]
    |
    v
[9.3 Testes além de exemplos]
    |
    v
[9.4 Um harness de avaliação]
    |
    v
[Síntese]
    |
    v
[Exemplo resolvido] --> [Exercício EX025]

Objetivos de aprendizagem

Você vai (1) estruturar programas maiores em módulos com interfaces claras; (2) gerenciar dependências e seus riscos de cadeia de suprimentos; (3) escrever testes, inclusive testes baseados em propriedades e de regressão; e (4) construir um pequeno harness de avaliação para um componente de IA.

9.1 Módulos e interfaces

Programas grandes são divididos em módulos com interfaces estreitas. Em sistemas de IA, separe carregamento de dados, inferência do modelo, aplicação de políticas e execução de ferramentas. O módulo de políticas deve ser pequeno, revisável e independente do modelo: ele decide o que é permitido independentemente do que o modelo diga. Essa é a forma em software do menor privilégio. Se a política depender do julgamento do próprio modelo, uma injeção de prompt bem-sucedida também derrota a política. Mantê-la em código separado significa que ela aplica as mesmas regras, seja qual for a forma como o modelo foi persuadido. Interfaces estreitas também tornam as revisões possíveis: um revisor consegue ler com cuidado um módulo de 80 linhas, mas não um sistema em que as verificações estão espalhadas por prompts e scripts.

9.2 Dependências e cadeia de suprimentos

Projetos de IA puxam muitas bibliotecas e arquivos de modelo. Fixe versões, verifique hashes e prefira serialização segura: carregar arquivos pickle não confiáveis em Python pode executar código arbitrário, e é por isso que formatos feitos para guardar apenas tensores são preferidos para os pesos dos modelos. O OWASP LLM 2025 lista cadeia de suprimentos (LLM03) e envenenamento de dados e de modelos (LLM04). Gu et al. (arXiv:1708.06733) mostraram que um modelo com backdoor obtido de terceiros pode se comportar normalmente em entradas limpas. Fixar versões impede que uma atualização mude o comportamento em silêncio, e as verificações de hash impedem que um arquivo trocado seja carregado. Um modelo com backdoor é mais difícil: pode passar em todos os testes comuns, porque seu comportamento nocivo só aparece com um gatilho específico. Engenheiros reduzem esse risco preferindo fontes com proveniência publicada, registrando de onde veio cada modelo e testando comportamentos inesperados em entradas fora da distribuição habitual.

9.3 Testes além de exemplos

Testes de regressão congelam um comportamento sabidamente bom, para que mudanças não possam quebrá-lo em silêncio. Testes baseados em propriedades geram muitas entradas e conferem invariantes ("a política nunca permite create_work_order sem um indicador de confirmação"). Em componentes de IA, um conjunto de referência (golden set) de entradas com saídas esperadas detecta deriva de comportamento quando um modelo ou um prompt muda. Cada tipo pega algo diferente. Testes de regressão impedem que bugs antigos voltem, testes de propriedades encontram entradas em que ninguém pensou e conjuntos de referência mostram quando uma edição de prompt ou uma atualização do modelo muda respostas que antes estavam certas. Conjuntos de referência exigem cuidado, porque as saídas dos modelos variam; Sam confere propriedades das respostas, como qual ferramenta foi proposta, e não a redação exata.

9.4 Um harness de avaliação

Um harness carrega um conjunto de teste, executa o componente, registra as saídas e calcula métricas com intervalos. Ele deve ser determinístico dada uma semente, registrar versões (hash do modelo, versão do prompt, commit do código) e manter os dados de teste separados dos dados de desenvolvimento. Sem versões registradas, um resultado não pode ser vinculado ao sistema que descreve, e uma regressão posterior não pode ser rastreada. O determinismo torna as reexecuções comparáveis, de modo que uma mudança nas métricas reflita uma mudança no sistema e não na amostragem aleatória. Manter teste e desenvolvimento separados impede que o sistema seja ajustado com os próprios exemplos usados para julgá-lo, o que faria os resultados parecerem melhores do que são.

9.5 Exemplo resolvido (caso sintético da NRS)

Sam reestruturou o Wrench em quatro módulos. O módulo policy (80 linhas) confere cada chamada de ferramenta proposta contra o papel do usuário e exige um token de confirmação para ordens de serviço. Um teste baseado em propriedades gerou 10,000 requisições aleatórias de chamada de ferramenta e confirmou que nenhuma passou sem token. A revisão de dependências encontrou um script de conversão de modelos que carregava arquivos pickle de uma pasta compartilhada; Sam o substituiu por um carregador de formato só de tensores e acrescentou verificação de hash. O teste de propriedades amostra o espaço de chamadas de ferramenta de forma muito mais ampla do que casos escritos à mão conseguiriam, embora não prove que não existe nenhuma chamada insegura.

9.6 Erros e limites

Três erros são comuns: lógica de política embutida em prompts em vez de código; dependências sem versão fixada e arquivos de modelo não verificados; e conjuntos de referência reutilizados para ajuste (eles deixam de detectar deriva). Uma política escrita num prompt pode ser contornada pela entrada do modelo, enquanto uma política em código não pode. Dependências sem versão fixada tornam sem sentido hoje os resultados dos testes de ontem. Um conjunto de referência usado durante o ajuste deixa aos poucos de ser uma verificação independente, porque o sistema foi adaptado a ele. Sam mantém um segundo conjunto, intocado, para as decisões de liberação e o renova quando o uso do sistema muda.

Exercícios

Síntese

Uma boa estrutura coloca as decisões de segurança em código pequeno e testável fora do modelo; dependências e testes disciplinados mantêm essa estrutura confiável à medida que o sistema cresce.

Continue estudando — capítulo 09 de 50

← Capítulo 08 (rascunho) · Índice de capítulos do curso · Capítulo 10 (rascunho) →