RL RanceLee Tutorials
← Voltar aos tutoriais

Habilidades: O Que São e Como Usá-las

De Digitador a Super Assistente

Já aprendemos a usar o Claude Code para projetos e você pode ter experimentado o poder da programação com IA. Mas já notou um problema:

Toda vez que você faz algo parecido, precisa descrever os requisitos novamente.

Por exemplo, você quer que a IA ajude a:

  • Escrever mensagens de commit do Git
  • Revisar código
  • Gerar documentação do projeto
  • Sincronizar arquivos

Você pode fazer essas tarefas várias vezes ao dia, mas toda vez precisa digitar um longo parágrafo dizendo à IA o que fazer. É cansativo!

É como se toda vez que pedisse comida por delivery, você tivesse que dizer ao restaurante:

“Quero um bowl de macarrão com carne bovina, sem coentro, pimenta extra, macarrão al dente, menos caldo…”

Existe uma maneira de transformar essas operações comuns em comandos de um clique?

Sim, é sobre isso que vamos falar hoje: Habilidade.


O que é Habilidade?

Explicação em uma frase

Habilidade = comando de atalho da IA

Assim como o aplicativo Atalhos no seu celular, a Habilidade encapsula operações complexas em um comando simples.

Definição oficial

Habilidade se refere a um “módulo de capacidade” reutilizável que encapsula ferramentas/APIs/scripts e prompts em uma interface padrão, permitindo que a IA chame sob demanda para concluir tarefas específicas.

Ela enfatiza:

  • Entrada e saída claras
  • Gerenciamento de dependências e versões
  • Testável e atualizável
  • Transformar IA genérica em um assistente profissional orientado a negócios

Entendimento intuitivo

Sem Habilidade:

You: Please review this code and check the following:
1. Are there any performance issues?
2. Are there any security vulnerabilities?
3. Does the code style follow the conventions?
4. Is there any duplicate code?
5. Are variable names clear?
6. Are comments complete?
……(continue describing for 10 more lines)

Com Habilidade:

You: /review

A IA revisa automaticamente o código de acordo com padrões predefinidos e fornece um relatório detalhado.

Percebeu a diferença? De centenas de palavras para um único comando — esse é o poder da Habilidade.


Diferenças entre Habilidade, Prompt e MCP

Muitas pessoas perguntam: Quais são as diferenças entre Habilidade, Prompt e MCP?

Comparação conceitual

Aspecto Prompt Habilidade MCP
Essência Instrução textual Módulo de capacidade encapsulado Protocolo para conectar ferramentas externas
Reutilização Baixa, precisa redigitar toda vez Alta, define uma vez e reutiliza Alta, configura uma vez e usa continuamente
Complexidade Simples Média Complexa
Escopo de capacidade Apenas processamento de texto Texto + scripts simples Texto + interação com sistemas externos
Curva de aprendizado Mais baixa Média Relativamente alta

Usando analogias

Prompt = Instrução verbal

  • Você precisa dizer verbalmente à IA o que fazer toda vez
  • Adequado para tarefas únicas e sob demanda
  • Por exemplo: “Traduza este parágrafo”

Habilidade = Fluxo de trabalho

  • Solidifica instruções comuns em um fluxo de trabalho padrão
  • Adequado para tarefas repetitivas e padronizadas
  • Por exemplo: /commit gera automaticamente mensagens de commit do Git

MCP = Sistema externo

  • Permite que a IA se conecte a ferramentas e fontes de dados externas
  • Adequado para tarefas que precisam acessar sistemas externos
  • Por exemplo: conectar ao Obsidian para ler/escrever notas, conectar ao banco de dados para consultar dados

Relação entre os três

Prompt → The most basic interaction method
    ↓
Skill → Encapsulates prompt + simple logic
    ↓
MCP → Skill + external system capabilities

Metaforicamente falando:

  • Prompt = Você cozinha sozinho
  • Habilidade = Esquentar comida instantânea no micro-ondas
  • MCP = Plataforma de delivery de comida

Quando usar cada um?

Use Prompt se:

  • A tarefa é simples e única
  • Os requisitos são flexíveis e mutáveis
  • Não precisa de reutilização

Use Habilidade se:

  • A tarefa é altamente repetitiva
  • Tem um fluxo de trabalho padronizado
  • Quer melhorar a eficiência

Use MCP se:

  • Precisa acessar dados externos (banco de dados, API, sistema de arquivos, etc.)
  • Precisa interagir com outros softwares (Obsidian, navegador, etc.)
  • Precisa obter informações em tempo real

Comparação de casos práticos:

Cenário 1: Traduzir um parágrafo

  • Use Prompt: “Traduza este parágrafo” (mais simples)

Cenário 2: Traduzir muitos documentos diariamente

  • Use Habilidade: /translate (fluxo de trabalho de tradução padronizado)

Cenário 3: Traduzir automaticamente notas do Obsidian e salvar

  • Use MCP: Conecte ao Obsidian, leia, traduza e salve automaticamente (mais poderoso)

Uso Básico da Habilidade

Como visualizar as Habilidades existentes?

No Claude Code ou Codex, digite:

/skill

Ele listará todas as Habilidades disponíveis.

Como usar uma Habilidade?

Método 1: Execução direta

Digite /skill, depois use Tab para selecionar a Habilidade desejada e pressione Enter para executar.

Método 2: Executar com parâmetros

Após selecionar uma Habilidade, continue digitando sua solicitação específica:

/translate translate the comments in this code to English

Habilidades integradas comuns

A maioria das ferramentas de programação com IA vem com algumas Habilidades integradas comuns:

Habilidade Função Exemplo
/commit Gerar automaticamente mensagem de commit do Git /commit
/review Revisar qualidade do código /review
/fix Corrigir erros de código /fix
/test Gerar casos de teste /test
/doc Gerar documentação /doc
/refactor Refatorar código /refactor

Essas Habilidades integradas já resolvem 80% das necessidades diárias.


Criando Sua Própria Habilidade

Se as Habilidades integradas não forem suficientes, você pode criar sua própria Habilidade.

Dois métodos de criação

Método 1: Deixe a IA criar para você (recomendado)

O Codex vem com uma Habilidade para criar Habilidades (parece confuso, mas é poderoso).

Passos:

  1. Digite /skill
  2. Encontre a opção relacionada a “Criar Habilidade”
  3. Após selecionar, diga à IA qual Habilidade você deseja

Exemplo:

/create-skill

I want a translation Skill with the following features:
1. Automatically detect Chinese comments in code
2. Translate them into English
3. Keep the code format unchanged

A IA criará automaticamente o arquivo da Habilidade e o colocará no local correto.

Método 2: Criação manual

Se você quiser entender mais profundamente a estrutura da Habilidade, pode criá-la manualmente.

Estrutura do arquivo de Habilidade:

Cada Habilidade é uma pasta que deve conter um arquivo SKILL.md:

my-skill/
  ├── SKILL.md          # Skill description and configuration
  └── scripts/          # Optional: helper scripts
      └── helper.py

Formato básico do SKILL.md:

---
name: Skill name
description: Skill description
---

# Detailed description

Write detailed usage instructions and implementation logic here.

## Parameters

- `--param1`: Description of parameter 1
- `--param2`: Description of parameter 2

## Example

Example usage code

A seção “Caso Prático” mais adiante neste capítulo detalhará como criar uma Habilidade completa.


Instalando Habilidades de Outros

Existem muitas Habilidades prontas no GitHub que você pode baixar e usar diretamente.

Encontrando a pasta de Habilidades

Localização das Habilidades do Codex:

  • Mac/Linux: ~/.codex/skills/
  • Windows: %USERPROFILE%\.codex\skills\

Localização das Habilidades do Claude Code:

  • Mac/Linux: ~/.claude/skills/
  • Windows: %USERPROFILE%\.claude\skills\

Passos para instalação

  1. Abra a pasta de Habilidades

Se a pasta não existir, você pode criá-la manualmente:

# Mac/Linux
mkdir -p ~/.codex/skills

# Windows (PowerShell)
New-Item -Path "$env:USERPROFILE\.codex\skills" -ItemType Directory -Force

  1. Baixe o arquivo da Habilidade

Baixe a pasta da Habilidade do GitHub ou de outras fontes.

  1. Copie para o diretório de Habilidades

Copie a pasta inteira da Habilidade para o diretório skills correspondente.

  1. Reinicie a ferramenta

Nota: O Codex atualmente não suporta recarregamento a quente; você precisa sair e reiniciar para ver a nova Habilidade. O Claude Code geralmente reconhece automaticamente.

Verifique a instalação

Após reiniciar, digite /skill para visualizar a lista e confirmar se a nova Habilidade apareceu.


Caso Prático: Criando uma Habilidade de Sincronização

Cenário do problema

Se você usa tanto o Codex quanto o Claude Code (muitas pessoas fazem isso), encontrará um problema:

As Habilidades das duas ferramentas precisam ser gerenciadas separadamente, o que é muito inconveniente.

  • Habilidades do Codex estão em ~/.codex/skills/
  • Habilidades do Claude Code estão em ~/.claude/skills/

Toda vez que você cria uma Habilidade útil no Codex, precisa copiá-la manualmente para a pasta do Claude. Muito tedioso!

Nesse ponto, podemos criar uma Habilidade para sincronizar automaticamente o conteúdo das duas pastas — usar uma Habilidade para gerenciar Habilidades.

Esta Habilidade irá:

  1. Verificar as diferenças entre as duas pastas de Habilidades
  2. Relatar quais Habilidades precisam ser sincronizadas
  3. Após sua confirmação, sincronizar automaticamente

Basta dizer os requisitos para a IA.

Abaixo está o que a IA faz para você. Observe que essas etapas são todas automáticas; você não precisa fazer nada! É mostrado aqui apenas para demonstração.

Passo 1: Criar a pasta da Habilidade

No diretório de skills do Codex ou Claude Code, crie uma nova pasta:

mkdir ~/.codex/skills/codex-claude-skill-sync

Passo 2: Criar SKILL.md

Crie um arquivo SKILL.md na pasta:

name: codex-claude-skill-sync
description: Sync Codex and Claude Skills
---

# Codex/Claude Skill Sync

## Overview

Used to check and sync the Skill directories of Codex and Claude, keeping both sides consistent. By default, only reports differences; executes sync after user confirmation.

## Workflow

1. Run difference report (no modification):

   `python3 scripts/sync_skills.py`

2. Report differences to the user in English and wait for explicit consent before proceeding.
3. After consent, execute sync:

   `python3 scripts/sync_skills.py --apply`

4. When encountering a conflict (same modification time but different content), pause and ask the user which side to keep.

## Rules

- Default directories:
  - Codex: `/Users/yourusername/.codex/skills`
  - Claude: `/Users/yourusername/.claude/skills`
- Only process top-level directories that contain `SKILL.md`, skip hidden directories and `.system`
- Determine which side is newer based on the latest modification time in the directory
- When syncing, delete the target Skill directory first, then copy the entire source directory

## Parameters

- `--apply` Execute sync (default is report only)
- `--codex <path>` Override Codex directory
- `--claude <path>` Override Claude directory
- `--prefer codex|claude` When modification time is the same but content differs, use the specified side to overwrite (requires explicit user authorization)

Importante: Altere os caminhos acima para seus caminhos reais!

Passo 3: Criar o arquivo de script

Crie um diretório scripts sob a pasta da Habilidade e, em seguida, crie sync_skills.py:

mkdir ~/.codex/skills/codex-claude-skill-sync/scripts

Código completo para sync_skills.py:

#!/usr/bin/env python3
"""
Compare and sync skill folders between Codex and Claude.

Default behavior is report-only. Use --apply to perform sync.
"""

from __future__ import annotations

import argparse
import hashlib
import os
from datetime import datetime
from pathlib import Path
import shutil
import sys

DEFAULT_CODEX = Path("/Users/yourusername/.codex/skills")
DEFAULT_CLAUDE = Path("/Users/yourusername/.claude/skills")

IGNORE_DIR_NAMES = {".git", ".idea", ".vscode", "__pycache__", ".pytest_cache", ".mypy_cache"}
IGNORE_FILE_NAMES = {".DS_Store"}
TIME_EPSILON = 1.0


def format_time(timestamp: float) -> str:
    return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")


def list_skill_dirs(root: Path) -> tuple[dict[str, Path], list[str]]:
    if not root.exists():
        raise FileNotFoundError(f"Root path does not exist: {root}")
    if not root.is_dir():
        raise NotADirectoryError(f"Root path is not a directory: {root}")

    skills: dict[str, Path] = {}
    ignored: list[str] = []
    for entry in sorted(root.iterdir(), key=lambda p: p.name):
        if not entry.is_dir():
            continue
        if entry.name.startswith("."):
            ignored.append(entry.name)
            continue
        if not (entry / "SKILL.md").is_file():
            continue
        skills[entry.name] = entry
    return skills, ignored


def dir_state(path: Path) -> tuple[str, float, int]:
    hasher = hashlib.sha256()
    latest_mtime = path.stat().st_mtime
    file_count = 0

    for root, dirs, files in os.walk(path):
        dirs[:] = [d for d in dirs if d not in IGNORE_DIR_NAMES]
        dirs.sort()
        files = sorted(f for f in files if f not in IGNORE_FILE_NAMES)

        rel_dir = os.path.relpath(root, path)
        if rel_dir == ".":
            rel_dir = ""
        hasher.update(f"D|{rel_dir}\n".encode())

        try:
            latest_mtime = max(latest_mtime, os.stat(root).st_mtime)
        except FileNotFoundError:
            continue

        for name in files:
            file_path = Path(root) / name
            rel_path = os.path.relpath(file_path, path)

            if file_path.is_symlink():
                try:
                    target = os.readlink(file_path)
                except OSError:
                    target = ""
                hasher.update(f"L|{rel_path}\n{target}\n".encode())
                try:
                    latest_mtime = max(latest_mtime, file_path.lstat().st_mtime)
                except FileNotFoundError:
                    pass
                continue

            if not file_path.is_file():
                continue

            stat = file_path.stat()
            latest_mtime = max(latest_mtime, stat.st_mtime)
            file_count += 1
            hasher.update(f"F|{rel_path}\n{stat.st_size}\n".encode())

            with open(file_path, "rb") as handle:
                for chunk in iter(lambda: handle.read(1024 * 1024), b""):
                    hasher.update(chunk)

    return hasher.hexdigest(), latest_mtime, file_count


def build_plan(
    codex_skills: dict[str, Path],
    claude_skills: dict[str, Path],
    codex_root: Path,
    claude_root: Path,
    prefer: str | None,
) -> tuple[list[dict], list[str], list[dict]]:
    actions: list[dict] = []
    identical: list[str] = []
    conflicts: list[dict] = []

    all_names = sorted(set(codex_skills) | set(claude_skills))
    for name in all_names:
        codex_path = codex_skills.get(name)
        claude_path = claude_skills.get(name)

        if codex_path and not claude_path:
            actions.append(
                {
                    "name": name,
                    "src": codex_path,
                    "dst": claude_root / name,
                    "reason": "only in codex",
                    "direction": "codex -> claude",
                }
            )
            continue
        if claude_path and not codex_path:
            actions.append(
                {
                    "name": name,
                    "src": claude_path,
                    "dst": codex_root / name,
                    "reason": "only in claude",
                    "direction": "claude -> codex",
                }
            )
            continue

        if not codex_path or not claude_path:
            continue

        codex_hash, codex_mtime, _ = dir_state(codex_path)
        claude_hash, claude_mtime, _ = dir_state(claude_path)

        if codex_hash == claude_hash:
            identical.append(name)
            continue

        time_delta = codex_mtime - claude_mtime
        if abs(time_delta) <= TIME_EPSILON:
            if prefer == "codex":
                actions.append(
                    {
                        "name": name,
                        "src": codex_path,
                        "dst": claude_path,
                        "reason": "same mtime, prefer codex",
                        "direction": "codex -> claude",
                        "codex_mtime": codex_mtime,
                        "claude_mtime": claude_mtime,
                    }
                )
            elif prefer == "claude":
                actions.append(
                    {
                        "name": name,
                        "src": claude_path,
                        "dst": codex_path,
                        "reason": "same mtime, prefer claude",
                        "direction": "claude -> codex",
                        "codex_mtime": codex_mtime,
                        "claude_mtime": claude_mtime,
                    }
                )
            else:
                conflicts.append(
                    {
                        "name": name,
                        "codex_mtime": codex_mtime,
                        "claude_mtime": claude_mtime,
                    }
                )
            continue

        if time_delta > 0:
            actions.append(
                {
                    "name": name,
                    "src": codex_path,
                    "dst": claude_path,
                    "reason": "codex newer",
                    "direction": "codex -> claude",
                    "codex_mtime": codex_mtime,
                    "claude_mtime": claude_mtime,
                }
            )
        else:
            actions.append(
                {
                    "name": name,
                    "src": claude_path,
                    "dst": codex_path,
                    "reason": "claude newer",
                    "direction": "claude -> codex",
                    "codex_mtime": codex_mtime,
                    "claude_mtime": claude_mtime,
                }
            )

    return actions, identical, conflicts


def print_report(
    actions: list[dict],
    identical: list[str],
    conflicts: list[dict],
    codex_root: Path,
    claude_root: Path,
    apply: bool,
    ignored_codex: list[str],
    ignored_claude: list[str],
) -> None:
    print("Skill sync report")
    print(f"Codex: {codex_root}")
    print(f"Claude: {claude_root}")

    if ignored_codex:
        print(f"Ignored in Codex: {', '.join(sorted(ignored_codex))}")
    if ignored_claude:
        print(f"Ignored in Claude: {', '.join(sorted(ignored_claude))}")

    print("\nPlanned sync actions:")
    if not actions:
        print("- none")
    else:
        for item in actions:
            codex_mtime = item.get("codex_mtime")
            claude_mtime = item.get("claude_mtime")
            details = []
            if codex_mtime is not None:
                details.append(f"codex mtime: {format_time(codex_mtime)}")
            if claude_mtime is not None:
                details.append(f"claude mtime: {format_time(claude_mtime)}")
            detail_text = f" ({', '.join(details)})" if details else ""
            print(f"- {item['name']}: {item['direction']} [{item['reason']}]" + detail_text)

    print("\nConflicts:")
    if not conflicts:
        print("- none")
    else:
        for item in conflicts:
            print(
                f"- {item['name']}: same mtime but different content "
                f"(codex {format_time(item['codex_mtime'])}, claude {format_time(item['claude_mtime'])})"
            )

    print(f"\nUp-to-date skills: {len(identical)}")

    if not apply:
        print("\nDry run only. Re-run with --apply to sync.")


def apply_actions(actions: list[dict]) -> None:
    for item in actions:
        src = Path(item["src"])
        dst = Path(item["dst"])

        if dst.exists():
            if dst.is_dir():
                shutil.rmtree(dst)
            else:
                dst.unlink()

        shutil.copytree(src, dst, symlinks=True)


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="Sync Codex and Claude skill folders")
    parser.add_argument("--codex", type=Path, default=DEFAULT_CODEX, help="Codex skill root")
    parser.add_argument("--claude", type=Path, default=DEFAULT_CLAUDE, help="Claude skill root")
    parser.add_argument("--apply", action="store_true", help="Apply sync actions")
    parser.add_argument(
        "--prefer",
        choices=["codex", "claude"],
        help="Break ties when mtimes are equal",
    )
    return parser.parse_args()


def main() -> int:
    args = parse_args()

    try:
        codex_skills, ignored_codex = list_skill_dirs(args.codex)
        claude_skills, ignored_claude = list_skill_dirs(args.claude)
    except (FileNotFoundError, NotADirectoryError) as exc:
        print(str(exc), file=sys.stderr)
        return 2

    actions, identical, conflicts = build_plan(
        codex_skills,
        claude_skills,
        args.codex,
        args.claude,
        args.prefer,
    )
    print_report(
        actions,
        identical,
        conflicts,
        args.codex,
        args.claude,
        args.apply,
        ignored_codex,
        ignored_claude,
    )

    if args.apply and actions:
        apply_actions(actions)
        print("\nSync complete.")
    elif args.apply and not actions:
        print("\nNo changes to apply.")

    if conflicts and not args.prefer:
        return 1
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

Importante: Lembre-se de modificar os caminhos no início:

DEFAULT_CODEX = Path("/Users/yourusername/.codex/skills")
DEFAULT_CLAUDE = Path("/Users/yourusername/.claude/skills")

Altere-os para seus caminhos reais.

Usando a Habilidade de Sincronização

Passo 1: Visualizar diferenças

No Claude Code ou Codex, digite:

/codex-claude-skill-sync

A IA executará automaticamente o script e relatará as diferenças entre as duas pastas de Habilidades.

Passo 2: Confirmar sincronização

Se você concordar em sincronizar, diga à IA:

Agreed, please execute sync.

A IA executará python3 scripts/sync_skills.py --apply para concluir a sincronização.

Pronto! A partir de agora, sempre que você criar ou modificar uma Habilidade em qualquer um dos lados, basta executar esta Habilidade de sincronização uma vez e ambos os lados permanecerão consistentes.


Dicas Avançadas de Habilidade

Dica 1: Combinar Habilidades

Várias Habilidades podem ser usadas em sequência:

/review then /fix to fix the issues found

A IA primeiro revisará o código e, em seguida, corrigirá automaticamente com base nos resultados da revisão.

Dica 2: Personalizar parâmetros da Habilidade

Muitas Habilidades suportam parâmetros:

/commit --type feat --scope api

Isso gerará uma mensagem de commit em um formato específico.

Dica 3: Modelos de Habilidade

Você pode criar modelos de Habilidade para gerar rapidamente novas Habilidades:

  1. Copie uma pasta de Habilidade existente
  2. Modifique o SKILL.md
  3. Salve

Dica 4: Compartilhar Habilidades com a equipe

Coloque a pasta de Habilidades em um repositório Git para que os membros da equipe possam compartilhar:

git clone https://github.com/your-team/skills.git ~/.codex/skills/team-skills

Resumo

O que aprendemos hoje:

  1. O que é Habilidade: Um módulo de capacidade reutilizável que transforma operações complexas em comandos simples
  2. Habilidade vs Prompt vs MCP: Diferenças e cenários de aplicação
  3. Como usar Habilidade: /skill para visualizar e invocar
  4. Como criar Habilidade: Deixe a IA ajudar ou crie manualmente
  5. Como instalar Habilidade: Copie para a pasta correspondente
  6. Caso prático: Criar uma Habilidade de sincronização para resolver o gerenciamento de múltiplas ferramentas

Pontos-chave:

  • Habilidade eleva a IA de um “digitador” a um “assistente profissional”
  • Operações comuns devem ser encapsuladas em Habilidades
  • Uma boa Habilidade pode economizar 90% do tempo