Claude Messages принимает PDF в блоке document с base64-источником с серверным промптом и без него. Для большого PDF выбирайте Opus/Sonnet с контекстом 1M и соблюдайте лимиты ниже. Chat Completions и Responses PDF не принимают.
python
import base64
import anthropic
with open("report.pdf", "rb") as f:
pdf_b64 = base64.standard_b64encode(f.read()).decode("utf-8")
client = anthropic.Anthropic(
api_key=KEY,
base_url="https://api.guardrelay.ai",
)
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{
"role": "user",
"content": [
{"type": "document", "source": {
"type": "base64",
"media_type": "application/pdf",
"data": pdf_b64,
}},
{"type": "text", "text": "Назови ключевые выводы отчёта"},
],
}],
)
print(message.content)- PDF должен быть стандартным и без пароля/шифрования.
- Весь HTTP-запрос вместе с base64 должен укладываться в 12 MiB.
- При применённом серверном промпте дополнительно действует общий media-бюджет: до 4 элементов, до 4 MiB декодированных данных на элемент и до 8 MiB суммарно.
- Без применённого серверного промпта допускается до 600 страниц только при 1M context window; при меньшем окне — максимум 100 страниц. При применённом серверном промпте независимо действует отдельный лимит media 4 MiB на элемент.
- Большой или плотный документ лучше разбить на несколько запросов.
- PDF, а также text/content document sources учитываются как input tokens. Некорректный или слишком большой PDF с применённым серверным промптом отклоняется до платной обработки.
При применённом серверном промпте тот же document block можно вложить в массив tool_result.content. Сохраняйте исходный tool_use_id; PDF должен иметь media_type: "application/pdf" и base64 source. Лимиты те же, что для обычного user message.
- Kimi. Документы работают по-другому: файл сначала загружается запросом
POST /v1/files, а затем упоминается в чат-запросе блокомinput_file. Форматы, лимиты, квота и срок жизни файла разобраны на странице Kimi · Chat Completions. - Composer и Grok. Документов нет. Блок документа или файла в
contentне распознаётся и даёт локальный400до списания. Нужный текст кладите в сообщение обычным текстом, помня про окно 200K у Composer и 500K у Grok.