Несколько недель назад мне понадобилось сделать простого бота для обработки входящих вопросов — что-то вроде первой линии поддержки, которая отвечает на типовые запросы и не заставляет человека ждать. Я уже работал с OpenAI API, поэтому думал, что всё будет привычно. Оказалось — почти так, но с несколькими сюрпризами, о которых стоит знать заранее.
Вот что я понял за это время.
Начало: ключ, библиотека, первый запрос
Первый шаг стандартный — регистрация на console.anthropic.com, получение API-ключа. Anthropic даёт небольшой бесплатный кредит на старте, так что потестировать можно без карточки.
Я работал на Python. Официальная библиотека ставится одной командой:
pip install anthropic
Первый рабочий запрос выглядит примерно так:
import anthropic
client = anthropic.Anthropic(api_key="ваш_ключ")
message = client.messages.create(
model="claude-opus-4-5",
max_tokens=1024,
messages=[
{"role": "user", "content": "Привет! Как дела?"}
]
)
print(message.content[0].text)
Запустил — ответил. Ничего неожиданного. Но дальше начинается то, ради чего вообще стоит разбираться с этим API.
System prompt — это не мелочь
Главная штука, которую я сначала недооценил — системный промпт. Именно он определяет, кем будет ваш бот: вежливым менеджером, строгим аналитиком или параноидальным юристом, который на каждый вопрос отвечает "проконсультируйтесь со специалистом".
В API Anthropic системный промпт передаётся отдельным параметром, не внутри массива messages:
message = client.messages.create(
model="claude-opus-4-5",
max_tokens=1024,
system="Ты — помощник интернет-магазина электроники. Отвечаешь кратко и по делу. Если вопрос не связан с товарами или заказами — вежливо объясняешь, что можешь помочь только по теме магазина.",
messages=[
{"role": "user", "content": "Какой ноутбук посоветуешь до 80 тысяч?"}
]
)
Я потратил примерно час, пока не нашёл правильный баланс. Слишком жёсткий — бот отказывается от половины нормальных вопросов. Слишком мягкий — уходит в сторону и болтает о чём попало. Пришлось итерировать.
Память разговора: делаем нормальный диалог
Вот где я споткнулся первым делом. Claude — как и любая языковая модель через API — не помнит предыдущие сообщения сама по себе. Каждый запрос для неё чистый лист. Чтобы бот помнил контекст, историю нужно передавать вручную при каждом обращении.
На практике это выглядит так:
conversation_history = []
def chat(user_message):
conversation_history.append({
"role": "user",
"content": user_message
})
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=1024,
system="Ты — помощник интернет-магазина электроники.",
messages=conversation_history
)
assistant_reply = response.content[0].text
conversation_history.append({
"role": "assistant",
"content": assistant_reply
})
return assistant_reply
print(chat("Что у вас есть из наушников?"))
print(chat("А что из этого подойдёт для спорта?"))
Второй вопрос про "из этого" работает правильно — бот понимает контекст, потому что вся переписка уже в массиве messages.
Проблема появляется, когда разговор становится длинным. Контекстное окно у Claude большое — до 200 тысяч токенов у некоторых версий — но за токены платишь. Я ограничился хранением последних 20 сообщений. Для большинства сценариев хватает.
Стриминг: когда важно не заставлять ждать
По умолчанию API отдаёт ответ целиком — сначала думает, потом выдаёт текст. Для коротких ответов это нормально. Но если бот генерирует что-то объёмное, пользователь смотрит на пустой экран и не понимает, работает ли вообще что-то.
Стриминг решает это — текст появляется по мере генерации, как в веб-интерфейсе Claude:
with client.messages.stream(
model="claude-opus-4-5",
max_tokens=1024,
system="Ты — помощник интернет-магазина.",
messages=conversation_history
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Мелочь, но ощущение от интерфейса меняется сильно. Пользователь видит, что бот "думает", а не завис.
Грабли, на которые я налетел
Первое — обработка ошибок. Я поначалу писал код без try/except и несколько раз ловил падение бота из-за превышения лимита или временной недоступности API. Anthropic возвращает понятные коды ошибок — rate_limit_error, overloaded_error, authentication_error. Их стоит обрабатывать явно и, где нужно, делать retry с паузой.
Второе — стоимость. Claude Opus 4-5 — мощная модель, но и дорогая. Для простых задач вроде FAQ или первичной сортировки запросов отлично подходит Haiku 4-5 — раз в десять дешевле и отвечает быстрее. Я переключился на него для рутинных диалогов, а Opus оставил для сложных случаев.
Третье — тестирование промптов. Каждый раз запускать код ради проверки формулировки — неудобно. Перешёл на Anthropic Workbench в консоли — там можно итерировать системный промпт прямо в браузере, без единой строчки кода.
Что дальше
Базовый бот заработал за вечер. Остальное время ушло на шлифовку: правильный промпт, граничные случаи, интеграция с базой данных товаров через инструменты — это уже отдельная история, про tool use в API.
Если хотите попробовать — документация у Anthropic довольно приличная, примеры рабочие. Начните с простого скрипта, потом добавьте историю сообщений, потом стриминг. Каждый шаг отдельно — не пытайтесь сразу собрать всё.
Один вопрос у меня так и остался открытым: как правильно организовать долгосрочную память для бота, который ведёт несколько сотен разговоров параллельно. Пробовал разные подходы с векторными базами — но это тема для отдельного разбора.
