🤖 Claude Agent SDK

Aprende a criar agentes poderosos com a API da Anthropic e o Claude Agent SDK, incluindo subagentes, hooks e integração com Model Context Protocol.

🚀 Introdução ao Claude Agent SDK

O Claude Agent SDK (anteriormente Claude Code SDK) é a ferramenta oficial da Anthropic para construir agentes AI autónomos. Diferente da API tradicional onde implementas o ciclo de agentes manualmente, o Agent SDK gere automaticamente o ciclo de observação, pensamento e ação.

ℹ️ Claude vs Claude Code vs Agent SDK
  • Claude (claude.ai): Interface web para conversas com Claude
  • Claude Code: CLI e IDE extension para programação com Claude
  • Claude Agent SDK: Framework para construir agentes programaticamente

Características Principais

🛠️

Ferramentas Integradas

Read, Write, Edit, Bash, Glob, Grep, WebSearch, WebFetch prontos a usar.

🔄

Subagentes

Spawn workers especializados para tarefas paralelas com contexto isolado.

⚡

Hooks

Executa código em eventos do ciclo de vida (PreToolUse, PostToolUse, etc).

🔌

MCP Support

Integração com Model Context Protocol para conectar ferramentas externas.

📦 Instalação e Configuração

bash
# Instalar Claude Agent SDK (Python)
pip install claude-agent-sdk

# Instalar Claude Agent SDK (TypeScript)
npm install @anthropic-ai/claude-agent-sdk

# Configurar API Key
export ANTHROPIC_API_KEY=sk-ant-api03-xxxxx

Exemplo Básico

python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions

async def main():
    async for message in query(
        prompt="Analisa o ficheiro app.py e encontra bugs potenciais",
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Bash"],
            permission_mode="acceptEdits"
        )
    ):
        if hasattr(message, "result"):
            print(message.result)

asyncio.run(main())

Agente com Ferramentas Customizadas

python
from claude_agent_sdk import query, ClaudeAgentOptions, Tool

# Definir ferramenta customizada
def pesquisar_jira(ticket_id: str) -> str:
    """Pesquisa informações de um ticket no Jira."""
    # Implementação real conectaria à API do Jira
    return f"Ticket {ticket_id}: Bug na autenticação, prioridade alta"

ferramenta_jira = Tool(
    name="pesquisar_jira",
    description="Pesquisa tickets no Jira. Input: ID do ticket.",
    func=pesquisar_jira
)

async def agente_com_ferramenta():
    async for message in query(
        prompt="Pesquisa o ticket PROJ-1234 e resume o problema",
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "pesquisar_jira"],
            custom_tools=[ferramenta_jira]
        )
    ):
        if hasattr(message, "result"):
            print(message.result)

asyncio.run(agente_com_ferramenta())

🛠️ Ferramentas Integradas

O Claude Agent SDK vem com um conjunto de ferramentas integradas que permitem ao agente interagir com o sistema de ficheiros, executar comandos e pesquisar na web.

Ferramentas Disponíveis
┌──────────────┬────────────────────────────────────────────┐
│   Ferramenta │                  Descrição                  │
├──────────────┼────────────────────────────────────────────┤
│ Read         │ Ler ficheiros do sistema                   │
│ Write        │ Criar novos ficheiros                      │
│ Edit         │ Editar ficheiros existentes                │
│ Bash         │ Executar comandos no terminal              │
│ Glob         │ Encontrar ficheiros por padrão             │
│ Grep         │ Pesquisar conteúdo em ficheiros            │
│ WebSearch    │ Pesquisar na web                          │
│ WebFetch     │ Obter conteúdo de URLs                     │
└──────────────┴────────────────────────────────────────────┘
python
from claude_agent_sdk import query, ClaudeAgentOptions

async def agente_dev():
    async for message in query(
        prompt="""
        1. Lê o ficheiro src/app.py
        2. Encontra todos os TODOs usando Grep
        3. Cria um ficheiro TODO.md com a lista
        4. Executa os testes com pytest
        """,
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Write", "Grep", "Bash"],
            permission_mode="interactive"  # Pede confirmação para cada ação
        )
    ):
        if hasattr(message, "tool_use"):
            print(f"A executar: {message.tool_use.name}")
        elif hasattr(message, "result"):
            print(message.result)

asyncio.run(agente_dev())

🔄 Subagentes

Subagentes são workers especializados que podem ser spawnados para executar tarefas em paralelo ou com contexto isolado. Cada subagente tem o seu próprio contexto e pode trabalhar independentemente.

python
from claude_agent_sdk import query, ClaudeAgentOptions, Subagent

async def main():
    # O Claude pode spawnar subagentes automaticamente
    # ou podes configurá-los explicitamente

    async for message in query(
        prompt="""
        Preciso que faças 3 tarefas em paralelo:
        1. Analisa o código em src/ e encontra bugs
        2. Verifica a documentação em docs/
        3. Executa os testes e reporta falhas
        """,
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Bash", "Glob"],
            subagents=[
                Subagent(
                    name="analisador_codigo",
                    instructions="Especializado em encontrar bugs e code smells",
                    allowed_tools=["Read", "Glob"]
                ),
                Subagent(
                    name="verificador_docs",
                    instructions="Especializado em verificar documentação",
                    allowed_tools=["Read", "Glob"]
                ),
                Subagent(
                    name="runner_testes",
                    instructions="Especializado em executar e analisar testes",
                    allowed_tools=["Bash"]
                )
            ]
        )
    ):
        print(message)

asyncio.run(main())
💡 Quando Usar Subagentes?
  • Pesquisa profunda em múltiplas localizações
  • Análise de código em paralelo
  • Tarefas que requerem contexto isolado
  • Delegação de subtarefas especializadas

⚡ Sistema de Hooks

Hooks permitem executar código personalizado em pontos específicos do ciclo de vida do agente. São determinísticos - executam 100% das vezes, ao contrário das instruções no CLAUDE.md que são apenas sugestões.

Tipos de Hooks

Tipos de Hooks
┌─────────────────────┬────────────────────────────────────────┐
│       Hook          │              Quando Executa             │
├─────────────────────┼────────────────────────────────────────┤
│ PreToolUse          │ Antes de executar uma ferramenta       │
│ PostToolUse         │ Depois de executar uma ferramenta      │
│ Notification        │ Quando o agente envia uma notificação  │
│ Stop                │ Quando o agente termina                │
└─────────────────────┴────────────────────────────────────────┘

Configurar Hooks

json
// settings.json ou .claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/format-code.sh"
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/validate-command.sh"
          }
        ]
      }
    ]
  }
}

Exemplo de Hook Script

bash
#!/bin/bash
# .claude/hooks/format-code.sh
# Executa após Edit ou Write para formatar o código

# Obter o ficheiro modificado do stdin
FILE_PATH=$(cat | jq -r '.tool_input.file_path')

# Executar prettier/eslint se for JS/TS
if [[ "$FILE_PATH" == *.js ]] || [[ "$FILE_PATH" == *.ts ]]; then
    npx prettier --write "$FILE_PATH"
    npx eslint --fix "$FILE_PATH"
fi

# Executar black se for Python
if [[ "$FILE_PATH" == *.py ]]; then
    black "$FILE_PATH"
fi

🔌 Integração MCP

O Model Context Protocol (MCP) é um protocolo padrão para conectar agentes a fontes de dados e ferramentas externas. O Claude Agent SDK suporta MCP nativamente.

Exemplo com Supabase MCP

python
from claude_agent_sdk import query, ClaudeAgentOptions

async def agente_com_mcp():
    async for message in query(
        prompt="Mostra-me todos os utilizadores registados na base de dados",
        options=ClaudeAgentOptions(
            allowed_tools=["Read"],
            mcp_servers=[
                {
                    "name": "supabase",
                    "type": "stdio",
                    "command": "npx",
                    "args": ["-y", "@anthropic/mcp-server-supabase"],
                    "env": {
                        "SUPABASE_URL": "https://xxx.supabase.co",
                        "SUPABASE_KEY": "xxx"
                    }
                }
            ]
        )
    ):
        if hasattr(message, "result"):
            print(message.result)

asyncio.run(agente_com_mcp())
ℹ️ Servidores MCP Populares
  • @modelcontextprotocol/server-filesystem: Acesso ao sistema de ficheiros
  • @modelcontextprotocol/server-postgres: Base de dados PostgreSQL
  • @anthropic/mcp-server-supabase: Integração com Supabase
  • mcp-server-slack: Integração com Slack
  • mcp-server-github: Integração com GitHub