
Cansei de copiar resposta da telinha do chat e colar no editor. O que resolve isso é um ia.php de vinte linhas: curl_init apontando para o endpoint de mensagens, três headers e o payload em json_encode. Roda com php ia.php no terminal e a resposta volta em JSON, pronta pra entrar em qualquer rotina sua.
<?php
$payload = [
'model' => 'claude-opus-5',
'max_tokens' => 16000,
'messages' => [
['role' => 'user', 'content' => 'Explique indice composto no MySQL 8 em 3 linhas.'],
],
];
$ch = curl_init('https://api.anthropic.com/v1/messages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_TIMEOUT => 120,
CURLOPT_HTTPHEADER => [
'content-type: application/json',
'x-api-key: ' . getenv('ANTHROPIC_API_KEY'),
'anthropic-version: 2023-06-01',
],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
]);
$corpo = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http !== 200) {
fwrite(STDERR, "HTTP $http: $corpon");
exit(1);
}
foreach (json_decode($corpo, true)['content'] as $bloco) {
if ($bloco['type'] === 'text') {
echo $bloco['text'], "n";
}
} Antes de rodar, exporte a chave no shell: export ANTHROPIC_API_KEY='sua-chave'. Chave escrita dentro do arquivo vaza no primeiro commit distraído; getenv custa a mesma linha e não vai pro Git.
O primeiro é o header de autenticação. Muita API usa Authorization: Bearer, e essa aqui não: a chave vai em x-api-key e o anthropic-version é obrigatório. Errou um dos dois e volta 401 com authentication_error no corpo — por isso o script joga $corpo no STDERR e sai com código 1, em vez de morrer calado.
O segundo é achar que content[0] é sempre o texto. É um array de blocos, e nos modelos atuais o bloco de raciocínio vem antes do text. Filtrar pelo type, como no foreach, evita o resultado vazio que parece bug da API e é só leitura errada do JSON. Pelo mesmo motivo não economize no max_tokens: esse raciocínio conta no mesmo teto, e um valor apertado corta a saída no meio, com stop_reason voltando max_tokens.
Com isso no terminal, o passo seguinte é mover o bloco pra dentro de uma classe e trocar o echo por um retorno. O CURLOPT_TIMEOUT generoso fica: resposta longa demora mesmo.
Seu banner de consentimento está certo, mas o vídeo incorporado grava cookie de terceiro no primeiro carregamento. Troque o domínio…
A listagem do custom post type abre e o single dá 404 no WordPress 6.9. Entenda o cache das rewrite…
Um par .service e .timer substitui a linha do crontab com log no journal, execução perdida recuperada no boot e…
400 produtos importados do fornecedor com a aba Descrição vazia. Um wp eval-file percorre os SKUs sem texto, grava pelo…
Some com PAC e SEDEX da lista quando o frete grátis está disponível, usando woocommerce_package_rates, e limpe o cache de…
A barra de upload chega no fim e o WordPress devolve só "Erro HTTP". Separe as três causas: Imagick barrado…