Разработка AI API

Удобно использовать чат-инструменты ИИ в веб-интерфейсе, но чтобы по-настоящему интегрировать возможности ИИ в ваши собственные продукты, рабочие процессы и скрипты автоматизации, вам нужен API.

API (Application Programming Interface) — это мост для связи между приложениями. Через API ваш код может напрямую отправлять запросы к модели ИИ и получать ответы без необходимости вручную открывать веб-страницу и копировать-вставлять.

Представьте такие сценарии:

  • Ваш сайт электронной коммерции автоматически генерирует описательный текст для каждого товара.

  • Ваше приложение для заметок автоматически делает краткое изложение длинных текстов, введённых пользователями.

  • Ваша система поддержки клиентов автоматически классифицирует обращения пользователей и отвечает на них.

  • Все эти возможности можно реализовать через API ИИ.

Цель этого модуля — провести вас от «умения только общаться с ИИ» к «умению заставить ИИ работать в вашем коде».


Базовые концепции API

Прежде чем писать код, сначала разберитесь в нескольких ключевых концепциях.

Что такое API

API — это набор согласованных протоколов взаимодействия. Мы отправляем запросы в определённом формате, а другая сторона возвращает результаты в определённом формате.

Проведём аналогию с заказом еды:

  • Вы заходите в ресторан, получаете меню (документацию API) и понимаете, что можно заказать и как заказать (формат запроса).

  • Вы говорите официанту: «Одну курицу кунг-пао, поменьше острого» (отправка запроса к API).

  • Кухня готовит блюдо и приносит его вам (возврат ответа API).

В этом процессе вам не нужно заходить на кухню и не нужно знать, как готовится блюдо, — в этом и ценность API:инкапсулировать сложные детали, предоставляя только простой интерфейс。

Основы REST API

REST (Representational State Transfer) — в настоящее время самый популярный стиль проектирования API.

Проще говоря, для взаимодействия используется протокол HTTP:

HTTP-методНазначениеПример в API ИИ
POSTСоздание ресурсаОтправка чат-запросов, генерация изображений
GETПолучение ресурсаЗапрос списков моделей, получение информации о счетах
DELETEУдаление ресурсаУдаление истории диалога

Подавляющее большинство API ИИ используют POST-запросы, потому что нам нужно "отправлять контент ИИ для обработки".

Основы формата JSON

JSON (JavaScript Object Notation) — самый распространённый формат данных при взаимодействии с API.

Синтаксис JSON очень прост; это комбинация пар «ключ-значение».

Примеры

{
    "model": "gpt-4",
    "messages": [
        {
            "role": "user",
            "content": "Привет, пожалуйста, представь EXAMPLE"
        }
    ],
    "temperature": 0.7,
    "max_tokens": 1000
}

Это типичное тело запроса к API ИИ.

Несколько основных правил:

  • Для объектов используйте{ }чтобы обернуть, для массивов используйте[ ]чтобы обернуть.

  • В строках используются двойные кавычки", нельзя использовать одинарные кавычки.

  • Пары «ключ-значение» разделяются двоеточием:для разделения, ключи должны быть строками.

  • Несколько пар «ключ-значение» разделяются запятой,для разделения.

JSON очень похож на словари Python, но есть синтаксические различия; обращайте внимание при написании кода.


Настройка среды разработки

Чтобы хорошо выполнить работу, сначала нужно заточить инструменты.

Установка и настройка Python

Python — самый распространённый язык для вызова API ИИ, со зрелой экосистемой и богатыми библиотеками.

Сначала проверьте, установлен ли Python на вашем компьютере:

# 检查 Python 版本(Windows、macOS、Linux 通用)
python --version
# 或者
python3 --version

Рекомендуется использовать Python 3.9 или выше.

Если он не установлен, перейдите наpython.orgи скачайте последнюю стабильную версию.

Управление пакетами pip

pip — это менеджер пакетов Python, используемый для установки сторонних библиотек.

# 检查 pip 版本
pip --version
# 或者
pip3 --version

# 升级 pip 到最新版本
pip install --upgrade pip

# 配置国内镜像源(可选,提升下载速度)
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

Выбор редактора кода

Для написания кода для API ИИ мы рекомендуем один из следующих редакторов:

РедакторОсобенностиЦелевые пользователи
VS CodeБесплатный, богатая экосистема плагинов, легковесныйБольшинство разработчиков
CursorВстроенная помощь ИИ, может напрямую генерировать кодДля тех, кто хочет, чтобы ИИ помогал писать код
PyCharmСамый многофункциональный, лучшая поддержка PythonПрофессиональные Python-разработчики

Пример кода из этого руководства можно запустить в любом редакторе.


Основы OpenAI API

OpenAI API — это самый классический и устоявшийся API для ИИ, и многие другие поставщики совместимы с его форматом.

Регистрация и получение API-ключа

API-ключ — это ваш пропуск, подтверждающий вашу личность и фиксирующий ваше использование. Шаги для его получения:

  • 1. Посетитеplatform.openai.comЗарегистрируйте аккаунт

  • 2. Перейдите на страницу API-ключей

  • 3. Нажмите "Создать новый секретный ключ"

  • 4. Скопируйте и сохраните этот ключ (он показывается только один раз!)

Важно:Никогда не коммитьте свой API-ключ в публичный репозиторий кода. Если он утечёт, другие могут использовать вашу квоту, и вам выставят счёт.

Первый вызов API

Сначала установите официальный OpenAI SDK:

pip install openai

Теперь напишите вашу первую программу вызова API:

Примеры

# Путь к файлу: first_api_call.py
# Пример первого вызова OpenAI API

from openai import OpenAI

# Инициализация клиента
# Примечание: рекомендуется читать API Key из переменных окружения; не встраивайте его жёстко в код
# Для демонстрационных целей он записан прямо здесь. В реальных проектах используйте переменные окружения.
client = OpenAI(
    api_key="your-api-key-here"  # Замените на ваш API Key
)

# Отправьте запрос к чату
response = client.chat.completions.create(
    model="gpt-3.5-turbo",  # Выберите модель
    messages=[
        {
            "role": "user",  # Роль: user обозначает пользователя
            "content": "Пожалуйста, расскажите в одном предложении о Rookie Tutorial от EXAMPLE."  # Содержимое, введённое пользователем
        }
    ]
)

# Выведите полный ответ (посмотрите, что было возвращено)
print("Полный ответ:")
print(response)
print("\n" + "="*50 + "\n")

# Извлечь ответ ИИ
ai_reply = response.choices[0].message.content
print("Ответ ИИ:")
print(ai_reply)

Если у вас нет OpenAI api_key, вы также можете использовать альтернативы от местных провайдеров. Многие местные модели совместимы с OpenAI, например DeepSeek. Вы можете перейти наhttps://platform.deepseek.com/api_keysПодайте заявку на api_key, а затем замените свои значения на следующий кодapi_keyиmodel, DeepSeek поддерживает модели deepseek-v4-flash и deepseek-v4-pro (режим мышления), и вы можете использовать API для вызова больших моделей:

Примеры

from openai import OpenAI

# Инициализация клиента
# Примечание: рекомендуется читать API Key из переменной окружения, не прописывайте его жёстко в коде
# Для демонстрации он указан здесь напрямую. В реальных проектах используйте переменные окружения
client = OpenAI(
    api_key="sk-xxxx",  # Задайте api_key
    base_url="https://api.deepseek.com")  # Укажите адрес запроса


# Отправьте запрос к чату
response = client.chat.completions.create(
    model="deepseek-v4-flash",  # Выберите модель
    messages=[
        {
            "role": "user",  # Роль: user обозначает пользователя
            "content": "Пожалуйста, расскажите в одном предложении о Rookie Tutorial от EXAMPLE."  # Содержимое, введённое пользователем
        }
    ]
)

# Выведите полный ответ (посмотрите, что было возвращено)
print("Полный ответ:")
print(response)
print("\n" + "="*50 + "\n")

# Извлечь ответ ИИ
ai_reply = response.choices[0].message.content
print("Ответ ИИ:")
print(ai_reply)

Запустите эту программу:

python first_api_call.py

Если всё работает нормально, вы увидите примерно такой вывод:

完整响应:
ChatCompletion(
  id='chatcmpl-xxx',
  choices=[Choice(finish_reason='stop', index=0, message=ChatMessage(content='Example是一个专注于提供编程技术教程的学习平台...', role='assistant'))],
  model='gpt-3.5-turbo',
  usage=CompletionUsage(completion_tokens=30, prompt_tokens=18, total_tokens=48)
)

==================================================

AI 回复:
Example是一个专注于提供编程技术教程的学习平台,涵盖多种编程语言和技术领域。

Поздравляем! Вы успешно вызвали AI API.

Пояснение параметров запроса

У OpenAI API есть много параметров, которые можно настроить. Вот наиболее часто используемые из них:

Название параметраTypeОбязательныйОписаниеЗначение по умолчанию
modelstringДаID модели для использования, например gpt-3.5-turbo, gpt-4Отсутствует
messagesarrayДаСписок сообщений истории диалогаОтсутствует
temperatureчислонетТемпература сэмплирования, от 0 до 2. Чем выше она, тем более случайный результат; чем ниже, тем более детерминированный.1.0
max_tokensцелое числонетМаксимальное количество токенов для генерацииБезлимитный
top_pчислонетПараметр ядерной выборки, между 0-11.0
stopстрока/массивнетСтоп-последовательность; остановить генерацию при обнаружении этих символовnull

Сосредоточимся на temperature — наиболее часто используемом параметре настройки:

Примеры

# Путь к файлу: temperature_demo.py
# Демонстрация влияния параметра temperature на вывод

from openai import OpenAI

client = OpenAI(api_key="your-api-key-here")

def ask_ai(temperature_value: float, question: str) -> str:
    """Укажите temperature для вопроса"""
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": question}],
        temperature=temperature_value,
        max_tokens=200
    )
    return response.choices[0].message.content

# Задайте один и тот же вопрос три раза с разной температурой
question = "Придумайте слоган для EXAMPLE"

print("--- temperature=0 (наиболее детерминированный, результаты похожи каждый раз) ---")
print(ask_ai(0.0, question))
print("\n--- temperature=0.7 (сбалансированный, рекомендуется для повседневного использования) ---")
print(ask_ai(0.7, question))
print("\n--- temperature=1.8 (наиболее случайный, результаты сильно различаются каждый раз) ---")
print(ask_ai(1.8, question))

Практическое правило:

  • temperature=0: фактологические ответы, генерация кода, сценарии, требующие точных результатов

  • temperature=0.7: повседневное общение, общие задачи

  • temperature>1.0: творческое письмо, мозговой штурм


Anthropic Claude API

Claude — большая языковая модель от Anthropic, известная своей безопасностью и возможностями обработки длинных текстов.

Сходства и различия с OpenAI API

Оба могут генерировать текст, но есть некоторые различия в философии проектирования:

Пункт сравненияOpenAI APIClaude API
Структура сообщенийsystem, user, assistant чередуютсяsystem задаётся отдельно, user и assistant чередуются
Длина контекста16k-128k варьируетсяСерия Claude 3 поддерживает 200k
Проектирование параметровtemperature, top_p и т. д.temperature, top_p и т. д., схожие концепции

Структура Claude Messages API

Сначала установите Claude SDK:

pip install anthropic

Базовые вызовы Claude API:

Примеры

# Путь к файлу: claude_first_call.py
# Пример базового вызова Claude API

import anthropic

# Инициализация клиента
client = anthropic.Anthropic(
    api_key="your-api-key-here"  # Замените на ваш ключ API Claude
)

# Отправить запрос сообщения
response = client.messages.create(
    model="claude-3-sonnet-20240229",  # Выберите модель Claude
    max_tokens=1024,  # Claude требует установки max_tokens
    messages=[
        {
            "role": "user",
            "content": "Пожалуйста, расскажите о EXAMPLE Rookie Tutorial в трёх предложениях"
        }
    ]
)

# Вывести ответ
print("Полный ответ:")
print(response)
print("\n" + "="*50 + "\n")

# Извлечь ответ
print("Ответ Claude:")
print(response.content[0].text)

Аналогично мы можем заменить его на совместимую отечественную большую модель, например DeepSeek, указавapi_key 、 base_url、modelЭти три параметра:

Примеры

import anthropic

# Инициализировать клиент
client = anthropic.Anthropic(
    api_key="sk-xxx",  # Замените на свой API-ключ
    base_url="https://api.deepseek.com/anthropic"  # Базовый URL для Claude API
)

# Отправить запрос сообщения
response = client.messages.create(
    model="deepseek-v4-flash",  # Выберите модель Claude
    max_tokens=1024,  # Claude требует установки max_tokens
    messages=[
        {
            "role": "user",
            "content": "Пожалуйста, представьте учебник EXAMPLE в трёх предложениях."
        }
    ]
)

# Вывести ответ
print("Полный ответ:")
print(response)
print("\n" + "="*50 + "\n")

# Извлечь ответ
print("Ответ Claude:")
print(response.content[0].thinking)

Настройки системного промпта

В Claude API System Prompt — независимый параметр, он не помещается в массив messages:

Примеры

# Путь к файлу: claude_system_prompt.py
# Пример использования Claude System Prompt

import anthropic

client = anthropic.Anthropic(api_key="your-api-key-here")

response = client.messages.create(
    model="claude-3-sonnet-20240229",
    max_tokens=1024,
    # Здесь задаётся системный промпт
    system="Вы профессиональный редактор технической документации. Отвечайте кратко и точно, при необходимости используйте списки.",
    messages=[
        {
            "role": "user",
            "content": "Какие ключевые знания нужно освоить при изучении Python?"
        }
    ]
)

print(response.content[0].text)

Управление многоходовым диалогом

Одноходовые диалоги просты, но действительно полезным приложениям нужно "помнить контекст".

Способы ведения истории диалога

Подход прост:Сохраняйте все предыдущие диалоги и отправляйте их ИИ с каждым запросом。

Примеры

# Путь к файлу: multi_turn_chat.py
# Пример управления многоходовым диалогом

from openai import OpenAI

client = OpenAI(api_key="your-api-key-here")

class ChatBot:
    """Простой бот для многоходового диалога"""

    def __init__(self, system_prompt: str = "Вы полезный ассистент"):
        self.messages = []  # Используйте список для хранения истории диалога
        # Сначала добавьте системный промпт
        self.messages.append({
            "role": "system",
            "content": system_prompt
        })

    def chat(self, user_input: str) -> str:
        """Отправьте сообщение и получите ответ"""
        # Добавьте сообщение пользователя в историю
        self.messages.append({
            "role": "user",
            "content": user_input
        })

        # Вызовите API
        response = client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=self.messages
        )

        # Получите ответ ИИ
        ai_reply = response.choices[0].message.content

        # Также добавьте ответ ИИ в историю
        self.messages.append({
            "role": "assistant",
            "content": ai_reply
        })

        return ai_reply

    def get_history(self) -> list:
        """Получить историю разговора"""
        return self.messages


# Пример использования
if __name__ == "__main__":
    bot = ChatBot(system_prompt="Вы — помощник по программированию, специализирующийся на ответах на вопросы об EXAMPLE и Python")

    print("=== Демонстрация многоходового диалога ===")

    # Первый раунд
    r1 = bot.chat("Что такое Python?")
    print(Пользователь: Что такое Python?)
    print("ИИ:", r1)
    print()

    # Второй раунд (ИИ может помнить предыдущую тему)
    r2 = bot.chat(Каковы его возможности?)
    print(Пользователь: Каковы его возможности?)
    print("ИИ:", r2)
    print()

    # Третий раунд
    r3 = bot.chat(Есть ли руководства по Python на EXAMPLE?)
    print(Пользователь: Есть ли руководства по Python на EXAMPLE?)
    print("ИИ:", r3)

Ключевой момент: история диалога представляет собой упорядоченный список, строго чередующийся между пользователем и ассистентом: пользователь-ассистент-пользователь-ассистент. Каждый запрос должен отправлять полную историю, чтобы ИИ мог понимать контекст. История расходует токены, поэтому её нужно регулярно очищать.

Обработка переполнения контекстного окна

У каждой модели есть ограничение контекстного окна, например, gpt-3.5-turbo — 16k, gpt-4 — 8k или 32k.

Когда история диалога слишком длинная, возникает ошибка.

Несколько распространённых стратегий обработки:

Примеры

# Путь к файлу: context_management.py
# Пример стратегий управления контекстным окном

from openai import OpenAI

client = OpenAI(api_key="your-api-key-here")


class ChatBotWithContextLimit:
    """Чат-бот с ограничением контекста"""

    def __init__(self, system_prompt: str, max_messages: int = 10):
        self.system_prompt = system_prompt
        self.max_messages = max_messages  # Сколько сообщений хранить максимум
        self.messages = []

    def _trim_messages(self):
        """Обрезать список сообщений, оставить самые последние сообщения"""
        # Всегда сохранять системный промпт, затем оставлять только последние max_messages
        if len(self.messages) > self.max_messages:
            # Оставлять N самых последних сообщений
            self.messages = self.messages[-self.max_messages:]

    def chat(self, user_input: str) -> str:
        # Добавить сообщение пользователя
        self.messages.append({
            "role": "user",
            "content": user_input
        })

        # Сократить историю
        self._trim_messages()

        # Сформировать полный запрос (системный промпт + история)
        full_messages = [
            {"role": "system", "content": self.system_prompt}
        ] + self.messages

        try:
            response = client.chat.completions.create(
                model="gpt-3.5-turbo",
                messages=full_messages
            )
            ai_reply = response.choices[0].message.content

            self.messages.append({
                "role": "assistant",
                "content": ai_reply
            })

            return ai_reply

        except Exception as e:
            # Если всё ещё возникают ошибки, может потребоваться более агрессивное сокращение
            return f"Ошибка: {str(e)}"


# Стратегия 2: использовать ИИ для суммирования истории разговора
def summarize_conversation(messages: list) -> str:
    """Использовать ИИ для суммирования истории разговора, заменяя исходную историю"""
    history_text = "\n".join([
        f"{m['role']}: {m['content']}"
        for m in messages
    ])

    prompt = f"""Пожалуйста, суммируйте следующий разговор в краткое резюме, сохранив ключевую информацию:

{history_text}

Резюме: """


    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}],
        temperature=0
    )

    return response.choices[0].message.content


# Использовать стратегию суммаризации
print("--- Пример резюме истории разговора ---")
sample_history = [
    {"role": "user", "content": "Как меня зовут?"},
    {"role": "assistant", "content": "Извините, я не знаю вашего имени. Вы можете мне сказать."},
    {"role": "user", "content": "Меня зовут Сяо Мин, я изучаю Python на EXAMPLE."},
    {"role": "assistant", "content": "Привет, Сяо Мин! Приятно познакомиться. EXAMPLE — отличная обучающая платформа."},
    {"role": "user", "content": "Я хочу узнать о списках, можешь меня научить?"},
    {"role": "assistant", "content": "Конечно! Списки Python — это..."},
]

summary = summarize_conversation(sample_history)
print("Сводка диалога:", summary)

Обобщите методы управления контекстом:

СтратегияПреимуществаНедостаткиПрименимые сценарии
Оставлять только последние N записейПросто, быстроМожет привести к потере важной информацииКороткие разговоры, сценарии непринуждённого общения
Использовать ИИ для обобщения историиСохраняет семантическую информациюТребует дополнительных вызовов APIДлинные диалоги, много важной информации
Скользящее окноСочетает простоту и полнотуНемного сложнее в реализацииОбщего назначения для типичных сценариев

Потоковый вывод

Когда вы общаетесь с ИИ на веб-странице, текст появляется слово за словом — это потоковый вывод.

Что такое потоковый вывод

  • Обычный режим: ИИ возвращает полный ответ сразу после его генерации; возможно, придётся подождать несколько секунд или даже десятки секунд.

  • Потоковый режим: ИИ отправляет каждый токен сразу после его генерации, обеспечивая лучший пользовательский опыт.

Технически потоковый вывод использует протокол SSE (Server-Sent Events), при котором сервер непрерывно отправляет данные.

Реализация эффекта печатной машинки

Примеры

# Путь к файлу: streaming_demo.py
# Демонстрация потокового вывода (эффект печатной машинки)

from openai import OpenAI

client = OpenAI(api_key="your-api-key-here")

print("=== Демонстрация потокового вывода ===")
print("Вопрос: Напишите введение к EXAMPLE\n")
print("A:", end="", flush=True)

# Ключевой параметр: stream=True
response = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "user", "content": "Пожалуйста, напишите введение к руководству EXAMPLE"}
    ],
    stream=True  # Включить потоковый вывод
)

collected_reply = []

for chunk in response:
    # Извлечь содержимое текущего фрагмента
    if chunk.choices[0].delta.content:
        content = chunk.choices[0].delta.content
        print(content, end="", flush=True)  # Печать в реальном времени без переносов строк
        collected_reply.append(content)

print()  # Вывести перевод строки в конце
print("\n" + "="*50)
print("Полный ответ:", "".join(collected_reply))

Запустите эту программу, и вы увидите, как текст появляется слово за словом.

Использование потокового вывода Claude аналогично:

Примеры

# Путь к файлу: claude_streaming.py
# Пример потокового вывода Claude

import anthropic

client = anthropic.Anthropic(api_key="your-api-key-here")

print("=== Потоковый вывод Claude ===")
print("Вопрос: Как научиться программировать?"\n")
print("A:", end="", flush=True)

with client.messages.stream(
    model="claude-3-sonnet-20240229",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Как системно изучать программирование?"}]
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

print()

Совет по пользовательскому опыту: если сценарий не требует "обязательно дожидаться полного результата", отдавайте приоритет потоковому выводу. Когда пользователи видят прогресс, это может значительно улучшить опыт.


Расчёт и оптимизация затрат на API

API ИИ тарифицируются по использованию; чем больше вы используете, тем больше платите.

Принципы тарификации токенов

API ИИ тарифицируется не по количеству слов или числу разговоров, а потокену,Токенявляется базовой единицей обработки текста ИИ.

Один токен приблизительно равен:

  • Английский: 0.75 слова (или 4 буквы)

  • Китайский: 1-2 китайских иероглифа

Например:

  • "Hello, World" — приблизительно 3-4 токена

  • "EXAMPLE Rookie Tutorial is great" — приблизительно 6-8 токенов

Способ оплаты:

Prompt tokens(你发给 AI 的) + Completion tokens(AI 返回给你的)= 总 tokens

У разных моделей разные цены, например gpt-3.5-turbo стоит $0.0015/1k токенов промпта, $0.002/1k токенов ответа.

Как контролировать затраты на API

Примеры

# Путь к файлу: cost_tracking.py
# Пример отслеживания и контроля затрат API

from openai import OpenAI

client = OpenAI(api_key="your-api-key-here")

# Список цен моделей (пример, актуальные цены смотрите в официальной документации)
# Единица измерения: USD / 1k токенов
MODEL_PRICES = {
    "gpt-3.5-turbo": {
        "prompt": 0.0015,
        "completion": 0.002
    },
    "gpt-4": {
        "prompt": 0.03,
        "completion": 0.06
    }
}


def chat_with_cost_tracking(model: str, messages: list):
    """Чат со статистикой затрат"""
    response = client.chat.completions.create(
        model=model,
        messages=messages
    )

    # Получаем использование токенов из ответа
    usage = response.usage
    prompt_tokens = usage.prompt_tokens
    completion_tokens = usage.completion_tokens
    total_tokens = usage.total_tokens

    # Вычисляем стоимость
    price = MODEL_PRICES.get(model, {"prompt": 0, "completion": 0})
    prompt_cost = (prompt_tokens / 1000) * price["prompt"]
    completion_cost = (completion_tokens / 1000) * price["completion"]
    total_cost = prompt_cost + completion_cost

    return {
        "reply": response.choices[0].message.content,
        "usage": {
            "prompt_tokens": prompt_tokens,
            "completion_tokens": completion_tokens,
            "total_tokens": total_tokens
        },
        "cost": {
            "prompt_cost": prompt_cost,
            "completion_cost": completion_cost,
            "total_cost": total_cost
        }
    }


# Пример использования
if __name__ == "__main__":
    result = chat_with_cost_tracking(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": "Расскажи о Python"}]
    )

    print("Ответ ИИ:", result["reply"])
    print()
    print("Статистика использования:")
    print(f" Токены промпта: {result['usage']['prompt_tokens']}")
    print(f" Токены ответа: {result['usage']['completion_tokens']}")
    print(f" Всего токенов: {result['usage']['total_tokens']}")
    print()
    print("Статистика стоимости (USD):")
    print(f" Стоимость промпта: ${result['cost']['prompt_cost']:.6f}")
    print(f" Стоимость ответа: ${result['cost']['completion_cost']:.6f}")
    print(f" Общая стоимость: ${result['cost']['total_cost']:.6f}")

Несколько практических советов по оптимизации затрат:

СоветКак это сделатьКоэффициент экономии
Выбирайте подходящую модельИспользуйте gpt-3.5-turbo для простых задач, а не gpt-490%+
Ограничьте max_tokensУстановите разумный верхний предел, чтобы ИИ не говорил слишком многоЗависит от ситуации
Сокращайте контекстСохраняйте только необходимую историю переписки50%+
Делайте промпты краткимиНе делайте системный промпт слишком длиннымЗависит от ситуации
Кэширование результатовВозвращайте кэшированные результаты сразу для идентичных вопросовЗависит от ситуации

Стратегии кэширования

Для повторяющихся вопросов кеширование результатов может сэкономить много денег:

Примеры

# Путь к файлу: response_cache.py
# Простая реализация кеша ответов

import hashlib
import json
from openai import OpenAI

client = OpenAI(api_key="your-api-key-here")


class SimpleCache:
    """Простой кеш в памяти"""

    def __init__(self):
        self.cache = {}

    def _make_key(self, model: str, messages: list) -> str:
        """Сгенерировать ключ кеша на основе содержимого запроса"""
        # Сериализовать информацию о ключе и вычислить хеш
        key_data = {
            "model": model,
            "messages": messages
        }
        key_str = json.dumps(key_data, sort_keys=True)
        return hashlib.md5(key_str.encode()).hexdigest()

    def get(self, model: str, messages: list):
        """Получить кэш"""
        key = self._make_key(model, messages)
        return self.cache.get(key)

    def set(self, model: str, messages: list, value: str):
        """Установить кэш"""
        key = self._make_key(model, messages)
        self.cache[key] = value


# Функция чата с кэшем
cache = SimpleCache()

def chat_with_cache(model: str, messages: list):
    # Сначала проверить кэш
    cached = cache.get(model, messages)
    if cached:
        print("(Попадание в кэш, возвращаем сразу)")
        return cached

    # Промах кэша, вызываем API
    response = client.chat.completions.create(
        model=model,
        messages=messages
    )
    reply = response.choices[0].message.content

    # Сохраняем в кэш
    cache.set(model, messages, reply)

    return reply


#
if __name__ == "__main__":
    messages = [{"role": "user", "content": "Что это за сайт EXAMPLE?"}]

    print("Первый вызов...")
    r1 = chat_with_cache("gpt-3.5-turbo", messages)
    print(r1)
    print()

    print("Второй вызов (тот же вопрос)...")
    r2 = chat_with_cache("gpt-3.5-turbo", messages)
    print(r2)

Обработка ошибок и механизмы повторных попыток

Сетевые запросы всегда могут завершиться ошибкой, и API не исключение. Надёжный код должен обрабатывать различные сценарии исключений.

Распространённые типы ошибок

Тип ошибкиКод состояния HTTPПричинаСпособ обработки
Ошибка аутентификации401Неверный или истёкший API-ключПроверьте API-ключ
Недостаточная квота402На счёте нет средствПополните баланс или смените аккаунт
Превышен лимит429Слишком частые запросы или исчерпана квотаПодождите немного и попробуйте снова
Ошибка сервера5xxПроблема на стороне сервера ИИПовторить

Повтор с экспоненциальной задержкой

При возникновении временных ошибок (например, 429, 5xx) наиболее распространённая стратегия — повтор с экспоненциальной задержкой:

  • Первая ошибка → подождать 1 секунду → повторить

  • Вторая ошибка → подождать 2 секунды → повторить

  • Третий сбой → подождать 4 секунды → повторить

  • Четвёртый сбой → подождать 8 секунд → повторить

Время ожидания каждый раз удваивается, что даёт сервису шанс восстановиться.

Примеры

# Путь к файлу: error_handling.py
# Обработка ошибок и повторные попытки с экспоненциальной задержкой

import time
from openai import OpenAI, APIError, RateLimitError, APIConnectionError

client = OpenAI(api_key="your-api-key-here")


def chat_with_retry(
    model: str,
    messages: list,
    max_retries: int = 3,
    initial_wait: float = 1.0
):
    """Функция чата с механизмом повторных попыток"""

    retries = 0

    while retries <= max_retries:
        try:
            response = client.chat.completions.create(
                model=model,
                messages=messages
            )
            return {
                "success": True,
                "reply": response.choices[0].message.content
            }

        except RateLimitError as e:
            # Ошибка ограничения скорости: подождите немного и повторите попытку
            retries += 1
            if retries > max_retries:
                return {
                    "success": False,
                    "error": f"Попытки повтора исчерпаны: {str(e)}"
                }
            wait_time = initial_wait * (2 ** (retries - 1))
            print(f"Сработало ограничение скорости, ожидание {wait_time} секунд перед повторной попыткой...")
            time.sleep(wait_time)

        except APIConnectionError as e:
            # Ошибка сетевого подключения: повторить
            retries += 1
            if retries > max_retries:
                return {
                    "success": False,
                    "error": f"Сбой сетевого подключения: {str(e)}"
                }
            wait_time = initial_wait * (2 ** (retries - 1))
            print(f"Сетевая ошибка, ожидание {wait_time} секунд перед повторной попыткой...")
            time.sleep(wait_time)

        except APIError as e:
            # Ошибка API: повтор в зависимости от ситуации
            if e.status_code and 500 <= e.status_code < 600:
                retries += 1
                if retries > max_retries:
                    return {
                        "success": False,
                        "error": f"Ошибка сервера: {str(e)}"
                    }
                wait_time = initial_wait * (2 ** (retries - 1))
                print(f"Ошибка сервера, ожидание {wait_time} секунд перед повторной попыткой...")
                time.sleep(wait_time)
            else:
                # Ошибки, не связанные с 5xx, не повторять
                return {
                    "success": False,
                    "error": fОшибка API: {str(e)}
                }

        except Exception as e:
            # Прочие ошибки, не повторять
            return {
                "success": False,
                "error": fНеизвестная ошибка: {str(e)}
            }


# Пример использования
if __name__ == "__main__":
    result = chat_with_retry(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": "Привет, EXAMPLE"}]
    )

    if result["success"]:
        print(Успех:, result["ответ"])
    else:
        print(Ошибка:, result["ошибка"])

Вы также можете использовать существующую библиотеку для упрощения логики повторных попыток, например tenacity, установите её с помощью следующей команды:

pip install tenacity

Примеры

# Путь к файлу: tenacity_demo.py
# Используйте библиотеку tenacity для упрощения логики повторных попыток

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
from openai import OpenAI, RateLimitError, APIError

client = OpenAI(api_key="your-api-key-here")


@retry(
    stop=stop_after_attempt(3),  # Повторять до 3 раз
    wait=wait_exponential(multiplier=1, min=1, max=10),  # Экспоненциальная задержка: 1, 2, 4... до 10 секунд
    retry=retry_if_exception_type((RateLimitError, APIError))  # Повторять только при определённых исключениях
)
def chat_with_tenacity(model: str, messages: list):
    """Использование декоратора tenacity для реализации повторных попыток"""
    response = client.chat.completions.create(
        model=model,
        messages=messages
    )
    return response.choices[0].message.content


# Использование
try:
    reply = chat_with_tenacity(
        "gpt-3.5-turbo",
        [{"role": "user", "content": "Расскажи о Python"}]
    )
    print(reply)
except Exception as e:
    print(fОкончательная ошибка: {e})

Практический проект: инструмент чата с ИИ в командной строке

Теперь давайте объединим то, что мы изучили ранее, и создадим полноценный инструмент чата в командной строке.

Примеры

# Путь к файлу: example_chatbot.py
# ПРИМЕР ИИ-чат-бота — Полноценный инструмент командной строки

import sys
import json
import os
from datetime import datetime
from openai import OpenAI


class ExampleChatBot:
    """Полнофункциональный чат-бот для командной строки"""

    def __init__(self, config_file: str = "config.json"):
        # Загрузить конфигурацию
        self.config = self._load_config(config_file)
        self.client = OpenAI(api_key=self.config["api_key"])

        # Состояние диалога
        self.messages = []
        self.total_tokens = 0
        self.total_cost = 0.0

        # Инициализировать системную подсказку
        self._init_system_prompt()

    def _load_config(self, config_file: str) -> dict:
        """Загрузить файл конфигурации"""
        default_config = {
            "api_key": "ваш-api-ключ-здесь",
            "model": "gpt-3.5-turbo",
            "system_prompt": "Вы — полезный ИИ-ассистент, работающий на EXAMPLE.",
            "max_history": 20,
            "stream": True,
            "temperature": 0.7
        }

        if os.path.exists(config_file):
            with open(config_file, "r", encoding="utf-8") as f:
                user_config = json.load(f)
                default_config.update(user_config)

        return default_config

    def _save_config(self, config_file: str = "config.json"):
        """Сохранить файл конфигурации"""
        with open(config_file, "w", encoding="utf-8") as f:
            json.dump(self.config, f, indent=2, ensure_ascii=False)

    def _init_system_prompt(self):
        """Инициализировать системный промпт"""
        self.messages = [
            {
                "role": "system",
                "content": self.config["system_prompt"]
            }
        ]

    def _trim_history(self):
        """Обрезать историю диалога"""
        # Оставить системный промпт + самые последние N диалогов
        max_messages = self.config["max_history"]
        if len(self.messages) > max_messages + 1:
            self.messages = [self.messages[0]] + self.messages[-max_messages:]

    def chat(self, user_input: str) -> str:
        """Отправить сообщение и получить ответ"""
        # Добавить сообщение пользователя
        self.messages.append({
            "role": "user",
            "content": user_input
        })

        # Сократить историю
        self._trim_history()

        if self.config["stream"]:
            return self._chat_stream()
        else:
            return self._chat_normal()

    def _chat_normal(self) -> str:
        """Обычный режим (без потоковой передачи)"""
        response = self.client.chat.completions.create(
            model=self.config["model"],
            messages=self.messages,
            temperature=self.config["temperature"]
        )

        ai_reply = response.choices[0].message.content

        # Подсчитать использование
        if hasattr(response, "usage"):
            self.total_tokens += response.usage.total_tokens
            # Приблизительно оценить стоимость (цена gpt-3.5-turbo)
            self.total_cost += (response.usage.total_tokens / 1000) * 0.002

        self.messages.append({
            "role": "assistant",
            "content": ai_reply
        })

        return ai_reply

    def _chat_stream(self) -> str:
        """Режим потоковой передачи"""
        response = self.client.chat.completions.create(
            model=self.config["model"],
            messages=self.messages,
            temperature=self.config["temperature"],
            stream=True
        )

        collected_chunks = []
        print("ИИ:", end="", flush=True)

        for chunk in response:
            if chunk.choices[0].delta.content:
                content = chunk.choices[0].delta.content
                print(content, end="", flush=True)
                collected_chunks.append(content)

        print()

        ai_reply = "".join(collected_chunks)

        self.messages.append({
            "role": "assistant",
            "content": ai_reply
        })

        # Подсчёт токенов в потоковом режиме требует дополнительной обработки, здесь упрощено
        # В реальных проектах можно вызвать API использования или оценить
        self.total_tokens += len(ai_reply) // 2  # Приблизительная оценка

        return ai_reply

    def save_conversation(self, filename: str = None):
        """Сохранить историю беседы"""
        if not filename:
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            filename = f"conversation_{timestamp}.json"

        data = {
            "model": self.config["model"],
            "total_tokens": self.total_tokens,
            "estimated_cost": self.total_cost,
            "messages": self.messages,
            "saved_at": datetime.now().isoformat()
        }

        with open(filename, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2, ensure_ascii=False)

        return filename

    def clear_history(self):
        """Очистить историю разговора"""
        self._init_system_prompt()
        self.total_tokens = 0
        self.total_cost = 0.0

    def show_stats(self):
        """Показать статистику"""
        print("\n" + "="*40)
        print(Статистика диалога)
        print("="*40)
        print(fМодель: {self.config['model']})
        print(fКоличество сообщений: {len(self.messages) - 1})
        print(fВсего токенов: {self.total_tokens})
        print(fПримерная стоимость: ${self.total_cost:.4f})
        print("="*40 + "\n")


def print_help():
    """Вывести справочную информацию"""
    print("\n" + "="*40)
    print(ПРИМЕР AI Chat Tool - Список команд)
    print("="*40)
    print(/help - Показать справку)
    print(/clear - Очистить историю диалога)
    print(/stats - Показать статистику)
    print(/save - Сохранить историю беседы)
    print(/model - Переключить модель)
    print(/temp - Настроить температуру)
    print(/system - Изменить системный промпт)
    print(/quit - Выйти из программы)
    print("="*40 + "\n")


def main():
    print("="*40)
    print(ПРИМЕР Инструмент чата с ИИ)
    print("="*40)
    print(Введите /help для просмотра команд или введите текст напрямую, чтобы начать чат\n")

    bot = ExampleChatBot()

    while True:
        try:
            user_input = input(Вы:).strip()

            if not user_input:
                continue

            # Обработка команд
            if user_input.startswith("/"):
                cmd = user_input.lower()

                if cmd in ["/quit", "/exit", "/q"]:
                    print(До свидания!)
                    break

                elif cmd == "/help":
                    print_help()

                elif cmd == "/clear":
                    bot.clear_history()
                    print(История переписки очищена)

                elif cmd == "/stats":
                    bot.show_stats()

                elif cmd == "/save":
                    filename = bot.save_conversation()
                    print(fРазговор сохранён в: {filename})

                elif cmd.startswith("/model "):
                    model = user_input[7:].strip()
                    bot.config["model"] = model
                    bot._save_config()
                    print(fМодель переключена на: {model})

                elif cmd.startswith("/temp "):
                    try:
                        temp = float(user_input[6:].strip())
                        if 0 <= temp <= 2:
                            bot.config["temperature"] = temp
                            bot._save_config()
                            print(fТемпература установлена на: {temp})
                        else:
                            print(Температура должна быть в диапазоне 0-2)
                    except ValueError:
                        print(Пожалуйста, введите корректное число)

                elif cmd.startswith("/system "):
                    system_prompt = user_input[8:].strip()
                    bot.config["system_prompt"] = system_prompt
                    bot.clear_history()
                    bot._save_config()
                    print(Системный промпт обновлён, диалог сброшен)

                else:
                    print(Неизвестная команда, введите /help для справки)

            else:
                # Обычный чат
                if not bot.config["stream"]:
                    print("ИИ:", end="")

                bot.chat(user_input)
                print()

        except KeyboardInterrupt:
            print("\nВведите /quit для выхода или продолжайте общаться)

        except Exception as e:
            print(fОшибка: {e})


if __name__ == "__main__":
    main()

Создайте файл конфигурации:

{
    "api_key": "your-api-key-here",
    "model": "gpt-3.5-turbo",
    "system_prompt": "你是一个乐于助人的 AI 助手,由 EXAMPLE 提供技术支持。",
    "max_history": 20,
    "stream": true,
    "temperature": 0.7
}

Теперь вы можете запустить этот инструмент чата:

python example_chatbot.py

Вы увидите:

========================================
  EXAMPLE AI 聊天工具
========================================
输入 /help 查看命令,直接输入文字开始聊天

你:你好
AI:你好!很高兴见到你。我是由 EXAMPLE 提供技术支持的 AI 助手,有什么可以帮你的吗?

你:/stats

========================================
对话统计
========================================
模型:gpt-3.5-turbo
消息数:2
总 tokens:50
估算费用:$0.0001
========================================

你:/quit
再见!
Другие расширения