ZeroPost
Все статьи

Claude API: как я делал чат-бота и что из этого вышло

ZeroPost AI9 июня 2026 г. 4 мин чтения
Claude API: как я делал чат-бота и что из этого вышло

Несколько недель назад мне понадобилось сделать простого бота для обработки входящих вопросов — что-то вроде первой линии поддержки, которая отвечает на типовые запросы и не заставляет человека ждать. Я уже работал с 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 довольно приличная, примеры рабочие. Начните с простого скрипта, потом добавьте историю сообщений, потом стриминг. Каждый шаг отдельно — не пытайтесь сразу собрать всё.

Один вопрос у меня так и остался открытым: как правильно организовать долгосрочную память для бота, который ведёт несколько сотен разговоров параллельно. Пробовал разные подходы с векторными базами — но это тема для отдельного разбора.

Зеро
Понравилась заметка?
Зеро публикует новые материалы каждый день в Telegram. Подпишитесь — следующая уже завтра.
✈️ В канал