Anthropic Messages
Подключение Anthropic SDK и Claude Code к Veda AI Gateway. Потоковая передача, инструменты, расширенное мышление и изображения в формате Anthropic.
Veda AI Gateway реализует формат Anthropic Messages. Anthropic SDK и Claude Code подключаются сменой адреса и токена, а модели из каталога Veda вызываются в привычном формате Anthropic, включая модели других авторов.
Адрес и аутентификация
| Параметр | Значение |
|---|---|
| Базовый адрес для SDK | $VEDA_BASE_URL (без /v1) |
| Маршрут | POST /v1/messages |
| Аутентификация | Authorization: Bearer $VEDA_API_KEY |
Ключ передаётся как токен
Veda принимает ключ только в заголовке Authorization: Bearer. В Anthropic SDK передавайте его в authToken
(auth_token в Python). Параметр apiKey отправляет заголовок x-api-key, и такой запрос получит ошибку 401.
Заголовки anthropic-version и anthropic-beta передаются модели без изменений. Anthropic SDK выставляет anthropic-version сам.
Первый запрос
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
authToken: process.env.VEDA_API_KEY,
baseURL: process.env.VEDA_BASE_URL,
});
const message = await client.messages.create({
model: "anthropic/claude-sonnet-5.5",
max_tokens: 1024,
system: "Отвечай кратко.",
messages: [{ role: "user", content: "Почему небо голубое?" }],
});
console.log(message.content);В формате Messages max_tokens обязателен. Ответ содержит массив блоков content; текст находится в блоках типа text.
Потоковая передача
С "stream": true ответ приходит событиями Server-Sent Events формата Anthropic: message_start, content_block_start, content_block_delta, content_block_stop, message_delta и message_stop. SDK собирает их за вас:
const stream = client.messages.stream({
model: "anthropic/claude-sonnet-5.5",
max_tokens: 1024,
messages: [{ role: "user", content: "Напиши короткое стихотворение о море." }],
});
stream.on("text", (text) => process.stdout.write(text));
const final = await stream.finalMessage();
console.log(final.usage);Вызов инструментов
Инструмент описывается полями name, description и input_schema. Когда модель вызывает инструмент, ответ приходит с stop_reason: "tool_use" и блоком tool_use. Результат отправляется в следующем сообщении пользователя блоком tool_result с тем же tool_use_id.
const tools: Anthropic.Tool[] = [
{
name: "getWeather",
description: "Текущая погода в городе",
input_schema: {
type: "object",
properties: { location: { type: "string", description: "Город и страна" } },
required: ["location"],
},
},
];
const messages: Anthropic.MessageParam[] = [{ role: "user", content: "Какая погода в Казани?" }];
const first = await client.messages.create({
model: "anthropic/claude-sonnet-5.5",
max_tokens: 1024,
messages,
tools,
});
messages.push({ role: "assistant", content: first.content });
const results: Anthropic.ToolResultBlockParam[] = [];
for (const block of first.content) {
if (block.type !== "tool_use") continue;
const { location } = block.input as { location: string };
const result = { location, temperatureC: 18 }; // здесь ваш код
results.push({ type: "tool_result", tool_use_id: block.id, content: JSON.stringify(result) });
}
messages.push({ role: "user", content: results });
const second = await client.messages.create({
model: "anthropic/claude-sonnet-5.5",
max_tokens: 1024,
messages,
tools,
});Расширенное мышление
Мышление включается параметром thinking. Модели с адаптивным мышлением принимают { "type": "adaptive" }, глубина задаётся в output_config.effort. Для бюджета в токенах используйте { "type": "enabled", "budget_tokens": 2048 }; бюджет должен быть меньше max_tokens.
curl "$VEDA_BASE_URL/v1/messages" \
-H "Authorization: Bearer $VEDA_API_KEY" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "anthropic/claude-sonnet-5.5",
"max_tokens": 8192,
"thinking": { "type": "adaptive" },
"output_config": { "effort": "high" },
"messages": [{ "role": "user", "content": "Объясни парадокс Монти Холла по шагам." }]
}'Рассуждение возвращается блоками thinking перед блоками text, если модель его отдаёт. Какой вариант параметров поддерживает модель, показано в примере на её странице в каталоге.
Изображения на входе
Изображение передаётся блоком image с источником url или base64:
const message = await client.messages.create({
model: "anthropic/claude-sonnet-5.5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{ type: "text", text: "Опиши это изображение." },
{ type: "image", source: { type: "url", url: "https://example.com/photo.jpg" } },
],
},
],
});В журнале запросов встроенные данные base64 заменяются пометкой с размером.
Claude Code
Claude Code использует формат Messages. Задайте переменные окружения, например в ~/.zshrc или ~/.bashrc:
export ANTHROPIC_BASE_URL="http://localhost:3002"
export ANTHROPIC_AUTH_TOKEN="your-veda-api-key"
export ANTHROPIC_API_KEY=""ANTHROPIC_BASE_URL получает VEDA_BASE_URL вашей установки без /v1. ANTHROPIC_API_KEY оставьте пустым: иначе Claude Code отправит ключ в x-api-key вместо Bearer-токена. Затем запустите Claude Code с моделью из каталога:
claude --model 'anthropic/claude-sonnet-5.5'Параметры
Veda передаёт тело запроса модели без изменений. Поддержку необязательных параметров определяет модель.
| Параметр | Тип | Описание |
|---|---|---|
model | string | Обязательный. Идентификатор модели |
max_tokens | integer | Обязательный. Ограничение длины ответа |
messages | array | Обязательный. Сообщения с ролями user и assistant |
system | string или array | Системная инструкция |
stream | boolean | Потоковая передача. По умолчанию false |
temperature, top_p, top_k | number | Параметры выборки |
stop_sequences | array | Последовательности остановки |
tools, tool_choice | array, object | Вызов инструментов |
thinking, output_config | object | Расширенное мышление и его глубина |
metadata | object | Метаданные запроса, например user_id |
Ошибки
На этом маршруте ошибки проверки ключа и лимитов приходят в формате Anthropic, поэтому SDK выбрасывает для них штатные исключения:
{
"type": "error",
"error": { "type": "rate_limit_error", "message": "Rate limit exceeded" },
"request_id": "0b8e5c9e-3f5c-4a57-9d4e-7f2a1c6d8e10"
}| Код | error.type | Когда |
|---|---|---|
400 | invalid_request_error | Тело запроса не является JSON-объектом |
401 | authentication_error | Ключ неверен, отключён, удалён или истёк |
402 | billing_error | Достигнут лимит расходов ключа |
429 | rate_limit_error | Больше 60 запросов в минуту на один ключ |
502, 503 | api_error | Модель или учёт лимитов временно недоступны |
Ошибки самой модели передаются с исходным кодом и телом.