← 返回列表

Entrevista Série AI 16: Como deve ser um bom Spec Coding?

Um bom Spec Coding (Programação Orientada por Especificações) tem como núcleo transformar "ideias vagas" em "contratos precisos, verificáveis e executáveis". Não se trata apenas de escrever um documento, mas de estabelecer uma linguagem de comunicação inequívoca entre humanos e AI (ou entre humanos). A seguir, apresento as características de um bom spec a partir de quatro dimensões: estrutura de conteúdo da especificação, princípios de escrita, fluxo de colaboração com AI e verificação de qualidade.


1. Estrutura padrão de um documento de especificação (exemplo com módulo funcional)

Seção Conteúdo obrigatório Exemplo
1. Objetivo e Escopo Descrever em uma frase o que fazer e claramente o que não fazer "Implementar API de registo de utilizador, sem incluir verificação de email"
2. Contrato de Entrada/Saída Estrutura de dados, tipos, campos obrigatórios/opcionais, valores de exemplo Corpo do pedido POST /register {email: string, password: string}, resposta 201 ou 400 com código de erro
3. Comportamento e Lógica Regras de negócio, condições de fronteira, transições de estado "A password deve ter 8-20 caracteres, incluindo pelo menos um número; se o email já existir, retornar 409"
4. Tratamento de Erros Todos os cenários de exceção possíveis e respetivos códigos/mensagens de erro "Falha de conexão à base de dados → retornar 503, não expor stacktrace"
5. Requisitos Não Funcionais Desempenho (tempo de resposta < 200ms), segurança (consultas parametrizadas), logs, observabilidade "Todas as SQL devem usar pré-compilação; registar email mas não registar password"
6. Casos de Teste (cruciais) Pelo menos 3 entradas típicas + 2 entradas de fronteira/exceção, com saídas esperadas Ver tabela abaixo
7. Dependências e Restrições Bibliotecas, versões, variáveis de ambiente "Python 3.10+, FastAPI, variável de ambiente DB_URL"

Exemplo de casos de teste (incorporados no spec)

Cenário Entrada Saída Esperada
Registo normal email: a@b.com, pwd: Pass1234 201, retornar user_id
Password demasiado curta pwd: Ab1 400, código de erro WEAK_PASSWORD
Email já existe mesmo email acima 409, código de erro EMAIL_EXISTS

Um bom Spec deve primeiro escrever os casos de teste, pois a AI pode gerar testes unitários diretamente a partir deles e, após a conclusão, verificar automaticamente.


2. Princípios fundamentais para escrever Spec (variante SMART)

Princípio Explicação Contraexemplo
Preciso (Precise) Usar números concretos, tipos, condições booleanas; evitar "possivelmente", "geralmente" ❌ "A password deve ser suficientemente segura" → ✅ "A password deve ter pelo menos 8 caracteres, incluindo maiúsculas, minúsculas e números"
Verificável (Verifiable) Cada requisito deve poder ser avaliado como aprovado/reprovado por teste automático ou inspeção manual ❌ "O código deve ser elegante" → ✅ "Complexidade ciclomática da função ≤ 10, sem blocos de código duplicados"
Inequívoco (Unambiguous) O mesmo termo deve ter o mesmo significado em todo o texto; fornecer glossário se necessário ❌ "Se o utilizador não existir, retornar erro" → ✅ "Utilizador não existe → retornar 404 com {code: 'USER_NOT_FOUND'}"
Completo (Complete) Cobrir caminho feliz, todos os caminhos de exceção e requisitos não funcionais ❌ Apenas escrever cenário de sucesso → ✅ Incluir timeout de base de dados, permissões insuficientes, etc.
Atómico (Atomic) Um spec descreve apenas um ponto funcional que pode ser entregue de forma independente (facilita a AI completar de uma vez) ❌ Usar um spec para escrever "todo o sistema de pagamento" → ✅ Dividir em "gerar ordem de pagamento", "verificar assinatura de callback", "reembolso"

3. Fluxo de Spec Coding na colaboração com AI

  1. Humano escreve o spec (estrutura acima, especialmente casos de teste e assinaturas de funções).
  2. Alimentar o spec de uma vez à AI (não adicionar requisitos de forma dialogal, para evitar poluição de vibração).
  3. AI produz código + testes unitários (a AI deve gerar testes executáveis de acordo com os casos de teste no spec).
  4. Executar os testes: se todos passarem, prosseguir; se não, modificar o spec ou corrigir diretamente o código (pode entrar num pequeno ciclo, mas registar as alterações).
  5. Revisão humana: verificar se há funcionalidades fora do spec (scope creep) e questões de segurança/desempenho.
  6. Consolidar: submeter o documento spec e o código final juntos no repositório como documentação permanente.

Prática chave: Spec como código — usar spec.md + test_spec.py, onde o ficheiro de teste provém diretamente dos exemplos do spec, de modo que futuras modificações no código apenas exijam executar os testes para verificar se o spec foi quebrado.


4. Efeitos de um bom Spec (podem servir como critérios de aceitação)

  • Determinismo: o mesmo spec produz implementações semelhantes quando dado a diferentes AIs (ou pessoas).
  • Testabilidade: após escrever o código, é possível verificar automaticamente 90% da correção.
  • Manutenibilidade: passados seis meses, qualquer pessoa que leia o spec consegue entender a intenção do design original.
  • Baixo custo de comunicação: a equipa discute apenas o spec, não as linhas de código específicas.
  • Segurança/qualidade integradas: requisitos de segurança (como consultas parametrizadas) e condições de fronteira são escritos no spec, e a AI deve cumpri-los.

5. Exemplo de um bom Spec (versão minimalista)

# Spec: API de Registo de Utilizador

## Escopo
- Receber email, password
- Não enviar email de verificação, não verificar autenticidade do email

## Contrato
POST /register
Content-Type: application/json
Request: { "email": string, "password": string }
Response 201: { "user_id": string }
Response 400: { "code": "INVALID_PASSWORD" | "INVALID_EMAIL" }
Response 409: { "code": "EMAIL_ALREADY_EXISTS" }

## Comportamento
- email deve estar em formato básico RFC 5322 (ex: a@b.c)
- password: comprimento 8-20, pelo menos um número e uma letra maiúscula
- Armazenar usando bcrypt com custo de salt 10
- Se antes de guardar na base de dados se detetar que o email já existe → 409

## Casos de Teste (entrada -> código de estado esperado + campos da resposta)
| Input email | password | Esperado |
|------------|----------|------|
| test@x.com | Pass1234  | 201, user_id existe |
| test@x.com | pass      | 400, INVALID_PASSWORD |
| bad        | Pass1234  | 400, INVALID_EMAIL |
| (email já existente) | Pass1234 | 409, EMAIL_ALREADY_EXISTS |

## Não Funcional
- SQL deve usar consultas parametrizadas (para prevenção de injeção)
- Registar IP de origem do pedido, não registar password
- Tempo de resposta: 95% dos pedidos < 100ms (excluindo bcrypt)

## Dependências
- Python 3.10+, FastAPI, bcrypt, asyncpg

Bom Spec Coding = transformar as "decisões de design" humanas em "casos de teste + assinaturas de tipo + restrições de comportamento" da máquina, deixando a AI apenas preencher a implementação, enquanto o humano mantém sempre o controlo da qualidade e direção.

评论

暂无已展示的评论。

发表评论(匿名)