Slash Commands no SDK
Aprenda como usar slash commands para controlar sessões do Claude Code através do SDK
Slash commands fornecem uma maneira de controlar sessões do Claude Code com comandos especiais que começam com /. Esses comandos podem ser enviados através do SDK para executar ações como compactar contexto, listar uso de contexto ou invocar comandos personalizados. Apenas comandos que funcionam sem um terminal interativo são despachados através do SDK; a mensagem system/init lista os disponíveis em sua sessão.
Descobrindo Slash Commands Disponíveis
O Claude Agent SDK fornece informações sobre slash commands disponíveis na mensagem de inicialização do sistema. Acesse essas informações quando sua sessão começar:
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Hello Claude",
options: { maxTurns: 1 }
})) {
if (message.type === "system" && message.subtype === "init") {
console.log("Available slash commands:", message.slash_commands);
// Inclui comandos integrados mais skills agrupados, por exemplo:
// ["clear", "compact", "context", "usage", "code-review", "verify", ...]
}
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage
async def main():
async for message in query(prompt="Hello Claude", options=ClaudeAgentOptions(max_turns=1)):
if isinstance(message, SystemMessage) and message.subtype == "init":
print("Available slash commands:", message.data["slash_commands"])
# Inclui comandos integrados mais skills agrupados, por exemplo:
# ["clear", "compact", "context", "usage", "code-review", "verify", ...]
asyncio.run(main())
Enviando Slash Commands
Envie slash commands incluindo-os em sua string de prompt, assim como texto regular. Comandos que atuam no histórico de conversas, como /compact, precisam de mensagens anteriores para funcionar, então os exemplos abaixo fazem uma pergunta primeiro e depois enviam o comando como um acompanhamento para a mesma conversa:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Construir histórico de conversa primeiro
try {
for await (const message of query({
prompt: "What does the README in this directory cover?",
options: { maxTurns: 2 }
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}
} catch (error) {
// Uma query() de um único disparo lança após produzir um resultado de erro,
// então a query de acompanhamento abaixo ainda é executada.
console.error(`Session ended with an error: ${error}`);
}
// Enviar um slash command como acompanhamento para a mesma conversa
for await (const message of query({
prompt: "/compact",
options: { continue: true, maxTurns: 1 }
})) {
if (message.type === "result") {
console.log("Command executed, result subtype:", message.subtype);
// Exemplo de saída: Command executed, result subtype: success
}
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async def main():
# Construir histórico de conversa primeiro
try:
async for message in query(
prompt="What does the README in this directory cover?",
options=ClaudeAgentOptions(max_turns=2),
):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
except Exception as error:
# Uma query() de um único disparo lança após produzir um resultado de erro,
# então a query de acompanhamento abaixo ainda é executada.
print(f"Session ended with an error: {error}")
# Enviar um slash command como acompanhamento para a mesma conversa
async for message in query(
prompt="/compact",
options=ClaudeAgentOptions(continue_conversation=True, max_turns=1),
):
if isinstance(message, ResultMessage):
print("Command executed, result subtype:", message.subtype)
# Exemplo de saída: Command executed, result subtype: success
asyncio.run(main())
Uma query pode terminar com um resultado de erro, por exemplo quando o limite maxTurns / max_turns é atingido antes do trabalho ser concluído. A mensagem de resultado final então tem is_error: true e um subtipo de erro como error_max_turns em vez de success.
Após produzir essa mensagem de resultado final, o SDK lança um erro, porque o processo CLI sai com um código diferente de zero.
Envolva o loop em um try/catch em TypeScript ou try/except em Python se seu comando puder atingir o limite, como mostrado em Single Message Input, ou defina maxTurns alto o suficiente para o trabalho ser concluído. Em Python, capture Exception: o SDK apresenta resultados de erro como uma Exception simples.
Slash Commands Comuns
`/compact` - Compactar histórico de conversa
O comando /compact reduz o tamanho do seu histórico de conversa resumindo mensagens antigas enquanto preserva contexto importante. A compactação precisa de uma conversa existente com pelo menos duas trocas anteriores para resumir. Este exemplo tem uma conversa primeiro, depois a compacta e lê a mensagem do sistema compact_boundary que relata o resultado:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Compaction needs existing history, so have a conversation first
try {
for await (const message of query({
prompt: "Explain what this project does",
options: { maxTurns: 2 }
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}
} catch (error) {
// A single-shot query() throws after yielding an error result,
// so the follow-up query below still runs.
console.error(`Session ended with an error: ${error}`);
}
// Compact the same conversation
for await (const message of query({
prompt: "/compact",
options: { continue: true, maxTurns: 1 }
})) {
if (message.type === "system" && message.subtype === "compact_boundary") {
console.log("Compaction completed");
console.log("Pre-compaction tokens:", message.compact_metadata.pre_tokens);
console.log("Trigger:", message.compact_metadata.trigger);
// Example output:
// Compaction completed
// Pre-compaction tokens: 1842
// Trigger: manual
}
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage, SystemMessage
async def main():
# Compaction needs existing history, so have a conversation first
try:
async for message in query(
prompt="Explain what this project does",
options=ClaudeAgentOptions(max_turns=2),
):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)
except Exception as error:
# A single-shot query() raises after yielding an error result,
# so the follow-up query below still runs.
print(f"Session ended with an error: {error}")
# Compact the same conversation
async for message in query(
prompt="/compact",
options=ClaudeAgentOptions(continue_conversation=True, max_turns=1),
):
if isinstance(message, SystemMessage) and message.subtype == "compact_boundary":
print("Compaction completed")
print("Pre-compaction tokens:", message.data["compact_metadata"]["pre_tokens"])
print("Trigger:", message.data["compact_metadata"]["trigger"])
# Example output:
# Compaction completed
# Pre-compaction tokens: 1842
# Trigger: manual
asyncio.run(main())
Uma mensagem compact_boundary só chega quando a compactação foi executada. Sem nada para resumir, /compact relata o motivo em vez de gerar um erro: a execução ainda termina com um resultado success, nenhuma mensagem compact_boundary é emitida, e o texto do resultado carrega a mensagem, por exemplo Not enough messages to compact. após uma única troca curta. Uma chamada query() única e nova começa com contexto vazio, então use este padrão em uma sessão com turnos anteriores, por exemplo no modo de entrada em streaming ou ao retomar uma sessão.
`/clear` - Redefinir contexto de conversa
O comando /clear redefine a conversa para um contexto vazio, para que os prompts subsequentes comecem sem nenhum histórico de conversa anterior. A conversa anterior permanece no disco e pode ser retomada passando seu ID de sessão para a opção resume.
Isso é útil no modo de entrada em streaming, onde você envia múltiplos prompts em uma única conexão. Para chamadas query() únicas, cada chamada já começa com contexto vazio, então enviar /clear não tem efeito prático; inicie uma nova query() em vez disso.
/clear no SDK requer Claude Code v2.1.117 ou posterior. Em versões anteriores, ele é omitido de slash_commands.
Criando Slash Commands Personalizados
Além de usar slash commands integrados, você pode criar seus próprios comandos personalizados que estão disponíveis através do SDK. Comandos personalizados são definidos como arquivos markdown em diretórios específicos, similar a como subagentes são configurados.
O diretório .claude/commands/ é o formato legado. O formato recomendado é .claude/skills/<name>/SKILL.md, que suporta a mesma invocação de slash command (/name) mais invocação autônoma pelo Claude. Veja Skills para o formato atual. O CLI continua suportando ambos os formatos, e os exemplos abaixo permanecem precisos para .claude/commands/.
Localizações de Arquivo
Slash commands personalizados são armazenados em diretórios designados baseado em seu escopo:
- Comandos de projeto:
.claude/commands/- Disponíveis apenas no projeto atual (legado; prefira.claude/skills/) - Comandos pessoais:
~/.claude/commands/- Disponíveis em todos seus projetos (legado; prefira~/.claude/skills/)
Formato de Arquivo
Cada comando personalizado é um arquivo markdown onde:
- O nome do arquivo (sem extensão
.md) se torna o nome do comando - O conteúdo do arquivo define o que o comando faz
- Frontmatter YAML opcional fornece configuração
Exemplo Básico
Crie o diretório .claude/commands em seu projeto se ele não existir, então crie .claude/commands/refactor.md:
Refactor the selected code to improve readability and maintainability.
Focus on clean code principles and best practices.
Isso cria o comando /refactor que você pode usar através do SDK.
Com Frontmatter
Crie .claude/commands/security-check.md:
---
allowed-tools: Read, Grep, Glob
description: Run security vulnerability scan
model: claude-opus-4-8
---
Analyze the codebase for security vulnerabilities including:
- SQL injection risks
- XSS vulnerabilities
- Exposed credentials
- Insecure configurations
Usando Slash Commands Personalizados no SDK
Uma vez definidos no sistema de arquivos, comandos personalizados estão automaticamente disponíveis através do SDK:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Use a custom command
try {
for await (const message of query({
prompt: "/refactor src/auth/login.ts",
options: { maxTurns: 3 }
})) {
if (message.type === "assistant") {
console.log("Refactoring suggestions:", message.message);
}
}
} catch (error) {
// A single-shot query() throws after yielding an error result,
// so the second query below still runs.
console.error(`Session ended with an error: ${error}`);
}
// Custom commands appear in the slash_commands list
for await (const message of query({
prompt: "Hello",
options: { maxTurns: 1 }
})) {
if (message.type === "system" && message.subtype === "init") {
console.log("Available commands:", message.slash_commands);
// Includes built-in commands plus bundled skills and your custom commands, for example:
// ["clear", "compact", "context", "usage", "code-review", "verify", "refactor", "security-check", ...]
}
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, SystemMessage
async def main():
# Use a custom command
try:
async for message in query(
prompt="/refactor src/auth/login.py", options=ClaudeAgentOptions(max_turns=3)
):
if isinstance(message, AssistantMessage):
for block in message.content:
if hasattr(block, "text"):
print("Refactoring suggestions:", block.text)
except Exception as error:
# A single-shot query() raises after yielding an error result,
# so the second query below still runs.
print(f"Session ended with an error: {error}")
# Custom commands appear in the slash_commands list
async for message in query(prompt="Hello", options=ClaudeAgentOptions(max_turns=1)):
if isinstance(message, SystemMessage) and message.subtype == "init":
print("Available commands:", message.data["slash_commands"])
# Includes built-in commands plus bundled skills and your custom commands, for example:
# ["clear", "compact", "context", "usage", "code-review", "verify", "refactor", "security-check", ...]
asyncio.run(main())
Recursos Avançados
Argumentos e Placeholders
Comandos personalizados suportam argumentos dinâmicos usando placeholders:
Crie .claude/commands/fix-issue.md:
---
argument-hint: [issue-number] [priority]
description: Fix a GitHub issue
---
Fix issue #$0 with priority $1.
Check the issue description and implement the necessary changes.
Use no SDK:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Pass arguments to custom command
for await (const message of query({
prompt: "/fix-issue 123 high",
options: { maxTurns: 5 }
})) {
// Command will process with $0="123" and $1="high"
if (message.type === "result" && message.subtype === "success") {
console.log("Issue fixed:", message.result);
}
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
async def main():
# Pass arguments to custom command
async for message in query(prompt="/fix-issue 123 high", options=ClaudeAgentOptions(max_turns=5)):
# Command will process with $0="123" and $1="high"
if isinstance(message, ResultMessage):
print("Issue fixed:", message.result)
asyncio.run(main())
Execução de Comando Bash
Comandos personalizados podem executar comandos bash e incluir sua saída:
Crie .claude/commands/git-commit.md:
---
allowed-tools: Bash(git add *), Bash(git status *), Bash(git commit *)
description: Create a git commit
---
## Context
- Current status: !`git status`
- Current diff: !`git diff HEAD`
## Task
Create a git commit with appropriate message based on the changes.
Referências de Arquivo
Inclua conteúdos de arquivo usando o prefixo @:
Crie .claude/commands/review-config.md:
---
description: Review configuration files
---
Review the following configuration files for issues:
- Package config: @package.json
- TypeScript config: @tsconfig.json
- Environment config: @.env
Check for security issues, outdated dependencies, and misconfigurations.
Organização com Namespacing
Organize comandos em subdiretórios para melhor estrutura:
.claude/commands/
├── frontend/
│ ├── component.md # Creates /component (project:frontend)
│ └── style-check.md # Creates /style-check (project:frontend)
├── backend/
│ ├── api-test.md # Creates /api-test (project:backend)
│ └── db-migrate.md # Creates /db-migrate (project:backend)
└── review.md # Creates /review (project)
O subdiretório aparece na descrição do comando mas não afeta o nome do comando em si.
Exemplos Práticos
Comando de Revisão de Pull Request
Crie .claude/commands/review-pr.md:
---
allowed-tools: Read, Grep, Glob, Bash(git diff *)
description: Comprehensive code review
---
## Changed Files
!`git diff --name-only HEAD~1`
## Detailed Changes
!`git diff HEAD~1`
## Review Checklist
Review the above changes for:
1. Code quality and readability
2. Security vulnerabilities
3. Performance implications
4. Test coverage
5. Documentation completeness
Provide specific, actionable feedback organized by priority.
Claude Code inclui skills code-review e verify agrupados. Se você nomear um comando personalizado após um deles, por exemplo .claude/commands/code-review.md, seu comando sobrescreve o skill agrupado e slash_commands lista o nome uma vez.
Comando Test Runner
Crie .claude/commands/test.md:
---
allowed-tools: Bash, Read, Edit
argument-hint: [test-pattern]
description: Run tests with optional pattern
---
Run tests matching pattern: $ARGUMENTS
1. Detect the test framework (Jest, pytest, etc.)
2. Run tests with the provided pattern
3. If tests fail, analyze and fix them
4. Re-run to verify fixes
Use esses comandos através do SDK:
import { query } from "@anthropic-ai/claude-agent-sdk";
// Run code review
try {
for await (const message of query({
prompt: "/review-pr",
options: { maxTurns: 3 }
})) {
// Process review feedback
}
} catch (error) {
// A single-shot query() throws after yielding an error result,
// so the second query below still runs.
console.error(`Session ended with an error: ${error}`);
}
// Run specific tests
for await (const message of query({
prompt: "/test auth",
options: { maxTurns: 5 }
})) {
// Handle test results
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
# Run code review
try:
async for message in query(prompt="/review-pr", options=ClaudeAgentOptions(max_turns=3)):
# Process review feedback
pass
except Exception as error:
# A single-shot query() raises after yielding an error result,
# so the second query below still runs.
print(f"Session ended with an error: {error}")
# Run specific tests
async for message in query(prompt="/test auth", options=ClaudeAgentOptions(max_turns=5)):
# Handle test results
pass
asyncio.run(main())
Veja Também
- Slash Commands - Documentação completa de slash commands
- Subagentes no SDK - Configuração similar baseada em sistema de arquivos para subagentes
- Referência TypeScript SDK - Documentação completa da API
- Visão geral do SDK - Conceitos gerais do SDK
- Referência CLI - Interface de linha de comando