Objetivo da Aula
Ao concluir esta aula, você será capaz de:
Calcular intervalo de confiança com t-distribution para estimativas de prazo
Implementar análise de incerteza com fatores de ajuste
Usar LLM para calibrar estimativas com analogia de projetos anteriores
Completar os 2 TODOs: analisarIncerteza e calcularIntervaloConfianca
Aplicar o cone de incerteza em fases diferentes do projeto
Por que isso importa
“Vai levar 2 semanas” não é uma estimativa — é um número sem contexto de incerteza. O mesmo projeto estimado no início tem incerteza de ±400%; no meio, ±25%. Intervalo de confiança transforma estimativas em probabilidades: “Com 80% de confiança, entregamos entre 4 e 7 semanas.”
LLMs não estimam bem (não têm sua velocidade de time). Mas são excelentes em identificar fatores de risco que inflam a incerteza — novidades tecnológicas, tamanho da codebase, integrações externas.
Conceitos Fundamentais
Cone de Incerteza
Fase de conceito: x0.25 a x4.0 (±300%)
Fase de definição: x0.5 a x2.0 (±100%)
Fase de design: x0.67 a x1.5 (±50%)
Fase de código: x0.8 a x1.25 (±25%)
Beta/UAT: x0.9 a x1.1 (±10%)Na fase de conceito, “2 semanas” pode ser de 3 dias a 8 semanas. Comunicar isso ao stakeholder é mais honesto do que a falsa precisão de “2 semanas”.
TODO 1: analisarIncerteza(estimativa, fatores)
def analisar_incerteza(estimativa_dias: float, fatores: dict) -> dict:
"""
fatores = {
'novidade_tecnologica': 0.0-1.0,
'tamanho_codebase': 0.0-1.0,
'integracoes_externas': int,
'requisitos_claros': 0.0-1.0,
'fase_projeto': str,
}
"""
CONE = {
'conceito': (0.25, 4.0),
'definicao': (0.5, 2.0),
'design': (0.67, 1.5),
'codigo': (0.8, 1.25),
'beta': (0.9, 1.1),
}
min_mult, max_mult = CONE.get(fatores.get('fase_projeto', 'definicao'), (0.5, 2.0))
# Ajustar multiplicadores por fatores de risco
risco_adicional = (
fatores.get('novidade_tecnologica', 0) * 0.5 +
fatores.get('tamanho_codebase', 0) * 0.3 +
fatores.get('integracoes_externas', 0) * 0.1 * max_mult +
(1 - fatores.get('requisitos_claros', 0.5)) * 0.4
)
max_ajustado = max_mult + risco_adicional
return {
'estimativa_base': estimativa_dias,
'minimo': round(estimativa_dias * min_mult, 1),
'maximo': round(estimativa_dias * max_ajustado, 1),
'mais_provavel': round(estimativa_dias * ((min_mult + max_ajustado) / 2 * 0.7 + 0.3), 1),
'fase': fatores.get('fase_projeto', 'definicao'),
}TODO 2: calcularIntervaloConfianca(amostras)
import math
def calcular_intervalo_confianca(amostras: list[float], nivel_confianca: float = 0.80) -> dict:
"""Intervalo de confiança com t-distribution para amostras pequenas."""
n = len(amostras)
if n < 2:
return {'erro': 'Precisa de pelo menos 2 amostras'}
media = sum(amostras) / n
variancia = sum((x - media) ** 2 for x in amostras) / (n - 1) # variância amostral
desvio = math.sqrt(variancia)
erro_padrao = desvio / math.sqrt(n)
# Valores críticos da t-distribution para graus de liberdade = n-1
# (valores aproximados para nível 80%)
t_critico_80 = {1: 3.08, 2: 1.89, 3: 1.64, 4: 1.53, 5: 1.48,
10: 1.37, 20: 1.33, 30: 1.31, 999: 1.28}
df = n - 1
t = next((t_critico_80[k] for k in sorted(t_critico_80.keys()) if k >= df), 1.28)
margem = t * erro_padrao
return {
'media': round(media, 1),
'desvio_padrao': round(desvio, 1),
'ic_inferior': round(max(0, media - margem), 1),
'ic_superior': round(media + margem, 1),
'nivel_confianca': nivel_confianca,
'n_amostras': n,
}Aprofundamento Técnico
Calibração com Analogia de Projetos
async def calibrar_por_analogia(descricao: str, historico: list[dict], client) -> dict:
historico_str = '\n'.join(
f'- {p["titulo"]}: estimado {p["estimado"]}d, real {p["real"]}d ({round(p["real"]/p["estimado"]*100-100, 0):+.0f}%)'
for p in historico
)
response = await client.messages.create(
model='claude-haiku-4-5-20251001',
max_tokens=300,
messages=[{
'role': 'user',
'content': f'''Dado este histórico de projetos e a nova tarefa, estime e identifique o fator de risco principal:
Histórico:
{historico_str}
Nova tarefa: {descricao}
Retorne JSON: {{"estimativa_dias": X, "fator_principal": "...", "similar_a": "..."}}''',
}],
)
texto = response.content[0].text
i, f = texto.index('{'), texto.rindex('}') + 1
return json.loads(texto[i:f])Times que usam analogia calibrada com LLM reduzem o erro médio de estimativa em ~30% segundo estudos de software estimation.
Exemplos Anotados
Exemplo 1: Análise de Incerteza
estimativa = 10 # dias estimados
fatores = {
'novidade_tecnologica': 0.8, # tecnologia nova para o time
'tamanho_codebase': 0.6, # codebase grande e pouco documentada
'integracoes_externas': 2, # 2 APIs externas
'requisitos_claros': 0.3, # requisitos vagos
'fase_projeto': 'definicao',
}
resultado = analisar_incerteza(10, fatores)
# → minimo: 5.0 dias
# → maximo: 24.0 dias ← risco alto inflou muito
# → mais_provavel: 12.3 diasExemplo 2: Intervalo de Confiança com Histórico
# Duração real de sprints similares (em dias)
amostras = [12, 15, 14, 18, 11, 16]
ic = calcular_intervalo_confianca(amostras, nivel_confianca=0.80)
# → media: 14.3 dias
# → ic_inferior: 11.9 dias
# → ic_superior: 16.8 dias
# Comunicação: "Com 80% de confiança, entregamos entre 12 e 17 dias"Padrões e Armadilhas
Padrões
Padrão 1: Sempre comunicar intervalo, nunca ponto único
f"Estimativa: {ic['ic_inferior']}-{ic['ic_superior']} dias (80% confiança)"
# Não: "Estimativa: 14 dias"Padrão 2: Cone de incerteza decresce com progresso
# Atualizar fase conforme o projeto avança
fatores['fase_projeto'] = 'codigo' # de 'definicao' para 'codigo' → IC menorArmadilhas
⚠️ Armadilha 1: IC com n<5 amostras é muito largo Com 3 amostras, o IC 80% pode ser tão amplo quanto o cone de incerteza da fase de conceito. Precisa de pelo menos 8-10 amostras históricas para IC significativo.
⚠️ Armadilha 2: Usar variância populacional em vez de amostral
# ERRADO: divide por n (variância populacional)
variancia = sum((x - media)**2 for x in amostras) / n
# CORRETO: divide por n-1 (variância amostral de Bessel)
variancia = sum((x - media)**2 for x in amostras) / (n - 1)Se não for realizar o laboratório, pule para o próximo capítulo.
Ponte para o Lab
TODO 1 — analisar_incerteza(estimativa, fatores): aplique o cone de incerteza por fase e ajuste por fatores de risco.
TODO 2 — calcular_intervalo_confianca(amostras): implemente com variância amostral (n-1) e valores t críticos aproximados.
Agora você está pronto para o lab.