CommunityPesquisa e Análise de Dadosgithub.com

Yurieff/metrics-pack

Transforma dados de receita de uma startup em MRR (receita recorrente mensal), coortes, NRR (retenção de receita líquida) e um slide para investidores.

O que é metrics-pack?

O skill Metrics Pack é uma ferramenta especializada para analistas de startups e fundos de investimento que precisam extrair métricas financeiras padronizadas a partir de dados brutos de receita. Ele aceita três tipos de entrada: arquivos de atualização mensal, exportações de receita por cliente, ou um registro de contratos com detalhes como cliente, valor, mês de início e prazo. Todas as operações aritméticas são executadas por um helper Python testado (`metrics.py`), garantindo que nenhuma análise numérica seja feita manualmente pelo agente de IA. O skill separa meses faturados de meses contratados (assinados mas ainda não faturados), trata contratos com menos de três meses como não recorrentes, e produz uma nota em inglês claro, quatro arquivos CSV e um slide no formato 16:9. Indicado para plataformas como Claude Code, o usuário deve invocá-lo com frases como 'build the metrics pack for X', 'MRR, cohorts and NRR for X', ou '/metrics-pack X'. O resultado final inclui análises de MRR, coortes de receita, NRR (retenção de receita líquida) e um slide pronto para apresentação a investidores.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Yurieff/fundraising-skill-pack/tree/HEAD/skills/metrics-pack

Installed? Explore more Pesquisa e Análise de Dados skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Pacote de Métricas

O que você está fazendo

Você foi solicitado a transformar os dados de receita de uma startup nos números que um analista de fundos lê primeiro: MRR, coortes, NRR – em um único slide. Os números vêm de metrics.py, nunca da sua cabeça. Você escolhe a entrada, executa o helper, lê seus CSVs e escreve as palavras ao redor deles.

  ENTRADA                  HELPER (metrics.py)           VOCÊ
  ───────                  ───────────────────           ───
  updates/  (a)  ──┐
  exportação cliente (b) ──┼──►  mrr.csv  cohorts.csv  ──►  metrics.md   (inglês claro)
  registro contratos (c) ──┘    nrr.csv  excluded.csv      metrics-slide.png (um slide)

Entregáveis em <company-slug>/metrics-pack/, relativo ao diretório de trabalho atual:

  1. metrics.md – a nota. Abre com "In plain English."
  2. mrr.csv, cohorts.csv, nrr.csv (e excluded.csv para um registro de contratos) – escritos pelo helper, intocados por você.
  3. metrics-slide.png – um slide 16:9.

Abreviações usadas neste arquivo: MRR = receita recorrente mensal; NRR = retenção de receita líquida; CSV = arquivo de valores separados por vírgula; PNG = arquivo de imagem; ISO = o formato de data internacional (YYYY-MM-DD, ou YYYY-MM para um mês); EUR = euro; USD = dólar americano; --as-of = a opção do helper que nomeia o último mês faturado.

Entradas

De $ARGUMENTS ou da conversa: uma empresa, e opcionalmente um arquivo. Três tipos de entrada, nesta ordem de preferência:

EntradaO que éComo entra no helper
(b) exportação por clienteCSV customer_id,month,revenue, mês como YYYY-MM--revenue <csv>
(c) registro de contratosCSV com uma linha de cabeçalho Client, Contract value, Start month, Term (months); linhas acima do cabeçalho são ignoradas; meses como May-26; valores como "1,550,000"--contracts <csv>
(a) <company-slug>/updates/arquivos de atualização mensal com uma linha de receita, sem detalhe de clientelido como revenue-chart faz (Passo 2 lá), escreve customer_id,month,revenue com um cliente total, então --revenue

Com entrada (a) não há clientes. O helper então escreve cohorts.csv e nrr.csv com apenas um cabeçalho e deixa as células new, expansion, contraction e churned de mrr.csv vazias, porque com um cliente elas apenas reafirmariam o crescimento total. Ignore essas colunas, não mostre um mapa de calor, e imprima "12-month NRR: cannot compute yet" (motivo: nenhum detalhe de cliente). O mesmo vale para qualquer arquivo --revenue com um único id de cliente.

Se a empresa for ambígua (duas empresas compartilham o nome), pergunte qual delas antes de ler qualquer coisa.


Passo 1 – Ficha da empresa e entrada

A ficha da empresa

<company-slug>/company-profile.md – leia-a primeiro. Se estiver faltando, crie-a. Se um campo estiver vazio e você aprender, preencha-o e atualize updated / updated_by. Nunca sobrescreva um campo preenchido: se encontrar um valor diferente, adicione uma linha em ## Conflicts com ambos os valores e fontes. A ficha termina com uma seção ## Conflicts (crie-a se faltar) cujo cabeçalho da tabela é exatamente | Field | Card value | Card source | New value | New source | Found by | Date |.

CampoValores permitidos
Trabalho feito para o clienteuma frase, nas próprias palavras da empresa, com URL
Quem pagatexto livre
Modelo de negócioB2B · B2C · B2G
Modelo de receitaassinatura · transação · anúncios · pontual · n.a.
Mercadoexatamente um: Fintech & seguros · Saúde & bio · Comércio & varejo · Logística & cadeia de suprimentos · IA & infraestrutura de dados · Software empresarial · Cibersegurança · Jurídico, compliance & governança · Vendas & marketing · RH & talentos · Educação · Mídia, jogos & entretenimento · Imobiliário & construção · Energia, clima & agricultura · Industrial & robótica · Estilo de vida do consumidor & serviços · Outros
Verticaltexto livre
Estágiopré-seed · seed · Série A · Série B+ · n.a.
Geografiapaís sede; países onde vende
Rodada sendo levantadavalor + moeda + instrumento, ou "não informado"
Métricas disponíveisonde (updates/, exportações), ou "nenhuma"

Frontmatter: company, slug, website, updated (data ISO), updated_by (nome do skill). A tabela da ficha tem uma terceira coluna, Source, preenchida para cada campo.

Pegue o nome da empresa, modelo de negócio, modelo de receita e geografia da ficha; geografia sugere a moeda esperada. Preencha "Metrics available" com o arquivo que você usar. Se o modelo de receita não for assinatura, diga na nota que MRR assume receita recorrente.

Encontre a entrada (tabela acima) e copie-a para <company-slug>/metrics-pack/input/ para que a execução seja auditável. Nunca publique ou envie um arquivo em nível de cliente a menos que o dono tenha dito que pode ser público. Moeda: pegue-a do arquivo; um registro de contratos frequentemente não informa nenhuma. Se nenhuma for informada, escreva "moeda não informada" em todos os lugares e nunca escolha uma.

Hoje e --as-of. --as-of é o último mês que foi realmente faturado – normalmente o mês atual, a partir da data de hoje (ISO). Meses após ele são contratados: assinados, ainda não faturados.


Passo 2 – Execute o helper

Use /usr/bin/python3 ou qualquer Python 3.9+; metrics.py precisa apenas da biblioteca padrão e não faz chamadas de rede. Ele fica ao lado deste arquivo (skills/metrics-pack/metrics.py; em um plugin instalado, ${CLAUDE_PLUGIN_ROOT}/skills/metrics-pack/metrics.py).

python3 <caminho>/metrics.py --contracts <register.csv> --out-dir <company-slug>/metrics-pack \
        --as-of 2026-11 --min-term 3
python3 <caminho>/metrics.py --revenue <export.csv>     --out-dir <company-slug>/metrics-pack \
        --as-of 2026-11

O que ele escreve:

ArquivoColunasSignificado
mrr.csvmonth, mrr, new, expansion, contraction, churned, statusuma linha por mês calendário; status é billed até --as-of, contracted após
cohorts.csvcohort, month_offset, revenuecoorte = primeiro mês de um cliente com receita; offset = meses desde então
nrr.csvstart_month, months, nrrNRR de 12 meses para cada mês inicial onde pode ser calculado a partir de meses faturados apenas (um mês após --as-of nunca conta); apenas cabeçalho se nenhum puder. Também apenas cabeçalho para uma exportação de único cliente, e para um registro de contratos sem renovação registrada; para um registro, apenas meses iniciais em que algum cliente tem uma renovação registrada (regra no Passo 2) são listados
excluded.csvclient, value, start, termcontratos mais curtos que --min-term meses (padrão 3)

Se o helper parar com error:, ele nomeia a coluna ou valor ruim. Corrija a entrada na fonte (ou pergunte ao dono) – nunca edite ao redor dela.

O que o helper assume (diga cada um na nota):

  • O valor do contrato é o total ao longo do prazo, distribuído uniformemente: valor ÷ prazo por mês, a partir do mês inicial. Se o dono disser que é por mês ou por ano, pare e pergunte – a resposta muda cada número.
  • Um contrato é recorrente apenas se seu prazo for de pelo menos --min-term meses. Mais curtos são não recorrentes: relatados em excluded.csv, não no MRR.
  • Nada renova a menos que uma nova linha diga. Quando o prazo de um contrato termina, o helper mostra a receita saindo como churned. Em um registro de contratos, isso é fim do contrato, não churn comprovado – diga isso para cada mês desse tipo.
  • Um registro de contratos registra contratos, não renovações. O fim do contrato é lido como perda de receita, então o helper calcula nrr.csv de um registro apenas para meses iniciais em que algum cliente tem uma renovação registrada. Regra: uma renovação é um contrato recorrente posterior (prazo pelo menos --min-term meses) do mesmo cliente cujo mês inicial é pelo menos um mês após o mês final de um contrato recorrente anterior (mês final = mês inicial + prazo - 1; então um contrato consecutivo iniciando no mês após o final conta, e uma lacuna é permitida). Um segundo contrato que sobrepõe o primeiro (um upsell ou complemento) não é uma renovação. Se nenhum cliente tiver uma renovação, nrr.csv tem apenas cabeçalho e a resposta é "cannot compute yet". Se alguns tiverem, o valor reflete apenas as renovações que o registro registra e a nota e o slide devem dizer isso.
  • Um cliente que para e depois retorna conta como new novamente.

Passo 3 – Leia as saídas

Leia os CSVs com o módulo csv. Cada número que você escreve vem deles. Não compute nada em prosa; se precisar de um número que os CSVs não tenham (por exemplo, uma proporção), compute-o com um comando e cite a saída do comando.

  1. MRR. O mrr do último mês faturado; o mês de pico e seu status; a divisão faturado-para-contratado. Nomeie o primeiro e o último mês nos dados.
  2. Execução. Meses após o último início de contrato apenas perdem receita, porque nada nos dados renova. Marque-os como execução de contratos sem renovação, nunca como churn.
  3. Coortes. Conte coortes com pelo menos dois meses de receita faturada. O mapa de calor no slide precisa de pelo menos duas dessas coortes; caso contrário, pule e diga por quê.
  4. NRR. Primeiro verifique a entrada. Para entrada (a) ou uma exportação de único cliente, ignore nrr.csv, cohorts.csv e as colunas de movimento: a resposta é "cannot compute yet". Caso contrário, se nrr.csv tiver linhas de dados, cite-as; para um registro de contratos adicione "conta apenas renovações registradas no registro". Se tiver apenas o cabeçalho, a resposta é "12-month NRR cannot be computed yet": nenhum cliente tem um mês de receita doze meses após seu início. Nunca estime, nunca preencha a partir de uma janela mais curta. Dê o motivo em uma linha (por exemplo "todo contrato no registro começa em 2026, então nenhum rodou doze meses e renovou").
  5. Excluídos. Número de contratos excluídos, seu valor total, e a regra que os excluiu.

Passo 4 – metrics-slide.png

Precisa de matplotlib e numpy (python3 -c "import matplotlib, numpy"). Se faltarem, pergunte antes de instalar qualquer coisa; a rota limpa é um ambiente virtual descartável. A base é o modelo de gráfico em revenue-chart (tema escuro, verificação de colisão de rótulos).

Um slide 16:9, neste layout:

 ┌─────────────────────────────────────────────────────────────┐
 │ <Company> – métricas de receita            a partir de <data ISO>       │
 ├──────────────────────────────┬──────────────────────────────┤
 │ Linha MRR: sólido = faturado, │ mapa de calor de coorte (meses │
 │ tracejado + sombreado = contratado │ faturdos apenas, % do mês 0) – ou o │
 │                              │ painel NRR se sem mapa de calor │
 ├──────────────────────────────┴──────────────────────────────┤
 │ NRR: <valor>  ou  "12-month NRR: cannot compute yet"         │
 │ três conclusões de uma linha                                   │
 └─────────────────────────────────────────────────────────────┘

Regras para o slide:

  • Contratado nunca é estilizado como faturado. Meses após --as-of usam uma linha tracejada, marcadores ocos e uma faixa sombreada rotulada "contratado, ainda não faturado".
  • Para um registro de contratos, um valor NRR mostrado traz a ressalva "conta apenas renovações registradas no registro" (o script adiciona quando source = "register").
  • A linha NRR mostra o valor de nrr.csv, ou as palavras exatas "12-month NRR: cannot compute yet".
  • Mapa de calor apenas se pelo menos duas coortes tiverem pelo menos dois meses faturados.
  • Três conclusões de uma linha, cada uma rastreável a uma linha CSV, nenhuma uma recomendação ou previsão.
  • Moeda no título do eixo; "moeda não informada" se a fonte não deu nenhuma.
  • Todos os valores no slide são lidos dos CSVs pelo script, não digitados. As conclusões são o único texto digitado: verifique cada número nelas contra os CSVs após desenhar.
import csv, os
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np

# CONFIGURE ---------------------------------------------------------------
company  = "Company"
folder   = "<company-slug>/metrics-pack"
currency = "currency not stated"      # ou "EUR", "USD" ...
as_of    = "2026-11"                  # mesmo valor de --as-of
source   = "register"                 # "register" (--contracts) ou "export" (--revenue)
takeaways = [                         # três conclusões de uma linha, cada uma verificada contra os CSVs
    "Takeaway 1",
    "Takeaway 2",
    "Takeaway 3",
]
# -------------------------------------------------------------------------

def read(name):
    with open(os.path.join(folder, name), newline="", encoding="utf-8") as fh:
        return list(csv.DictReader(fh))

mrr, coh, nrr_rows = read("mrr.csv"), read("cohorts.csv"), read("nrr.csv")
months = [r["month"] for r in mrr]
vals = [float(r["mrr"]) for r in mrr]
billed = [r["status"] == "billed" for r in mrr]
x = np.arange(len(months))
nb = sum(billed)                                   # meses faturados vêm primeiro

BG, FG, MUTED = '#0f1117', '#e0e0e0', '#9aa0b4'
BILLED, CONTR = '#4fc3f7', '#f2b84b'

fig = plt.figure(figsize=(13.333, 7.5), facecolor=BG)         # 16:9
gs = fig.add_gridspec(3, 2, height_ratios=[0.5, 5.2, 1.9], width_ratios=[1.35, 1],
                      hspace=0.35, wspace=0.18, left=0.06, right=0.97, top=0.97, bottom=0.04)
ax_t = fig.add_subplot(gs[0, :]); ax_t.axis('off')
ax_t.text(0, 0.5, f"{company} – métricas de receita", color='#fff', fontsize=20,
          fontweight='bold', va='center')
ax_t.text(1, 0.5, f"faturado através de {as_of}", color=MUTED, fontsize=11, ha='right', va='center')

# --- Linha MRR ---
ax = fig.add_subplot(gs[1, 0]); ax.set_facecolor(BG)
if nb < len(months):
    ax.axvspan(nb - 0.5, len(months) - 0.5, color=CONTR, alpha=0.10, zorder=0)
    ax.text(nb - 0.35, 0.97, "contratado,\
ainda não faturado", color=CONTR, fontsize=9,
            transform=ax.get_xaxis_transform(), va='top')
ax.plot(x[:nb], vals[:nb], color=BILLED, lw=2.6, marker='o', ms=5, label='MRR faturado', zorder=3)
if nb < len(months):
    j = max(nb - 1, 0)                                         # une os dois segmentos
    ax.plot(x[j:], vals[j:], color=CONTR, lw=2.2, ls='--',
            label='MRR contratado (não faturado)', zorder=3)
    ax.scatter(x

…

[truncado para tradução]

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Habilidades Relacionadas