Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Узнайте, как использовать модели рассуждений, такие как DeepSeek в Azure OpenAI, с помощью пакета SDK OpenAI для Python.
В этой статье показано несколько рекомендаций по интеграции моделей причин:
- Аутентификация без ключей: используйте управляемые удостоверения или учетные данные разработчика вместо ключей API.
- Асинхронные операции: используйте асинхронные функции для повышения производительности.
- Ответы потоковой передачи: предоставляют немедленную обратную связь пользователям.
- Разделение рассуждений: Отделите шаги рассуждений от окончательных результатов.
- Управление ресурсами: очистка ресурсов после использования.
Базовый блок DeepSeek
Изучите пример базового блока DeepSeek. В нем показано, как использовать клиентская библиотека OpenAI для вызова модели DeepSeek-R1 и создания ответов на сообщения пользователей.
Обзор архитектуры
На следующей схеме показана простая архитектура примера приложения:
Приложение чата запускается как приложение контейнера Azure. Приложение использует управляемое удостоверение с Microsoft Entra ID для проверки подлинности с помощью Azure OpenAI вместо ключа API. Приложение использует Azure OpenAI для создания ответов на сообщения пользователей.
Приложение использует следующие службы и компоненты:
- Приложение Python Quart, использующее пакет клиентской библиотеки OpenAI для создания ответов на сообщения пользователей
- Базовый интерфейс HTML/JS, который передает ответы из серверной части с помощью строк JSON через readableStream
- Файлы Bicep для предоставления ресурсов Azure, включая средства Foundry, Azure Container Apps, Azure Container Registry, Azure Log Analytics и роли RBAC.
Себестоимость
Чтобы снизить затраты, в этом примере используются базовые или ценовые категории потребления для большинства ресурсов. Настройте уровень по мере необходимости и удалите ресурсы, чтобы избежать расходов.
Дополнительные сведения о стоимости см. в образце репозитория.
Предпосылки
Контейнер разработки включает все зависимости, необходимые для этой статьи. Его можно запустить в GitHub Codespaces (в браузере) или локально с помощью Visual Studio Code.
Чтобы следовать этой статье, убедитесь, что выполнены следующие предварительные требования:
- Подписка Azure — Создайте бесплатно
- разрешения учетной записи Azure — у учетной записи Azure должны быть разрешения
Microsoft.Authorization/roleAssignments/write, например Администратор управления доступом на основе ролей, Администратор доступа пользователя или Владелец. Если у вас нет разрешений на уровне подписки, необходимо предоставить RBAC для существующей группы ресурсов и развернуть в этой группе.- Для учетной записи Azure также требуются разрешения
Microsoft.Resources/deployments/writeна уровне подписки.
- Для учетной записи Azure также требуются разрешения
- учетная запись GitHub
Открытие среды разработки
Выполните следующие действия, чтобы настроить предварительно настроенную среду разработки со всеми необходимыми зависимостями.
GitHub Codespaces запускает контейнер разработки, управляемый GitHub, с Visual Studio Code для веб в качестве интерфейса. Используйте GitHub Codespaces для простейшей настройки, так как она поставляется с необходимыми средствами и зависимостями, предварительно установленными для этой статьи.
Это важно
Все учетные записи GitHub могут использовать Codespaces до 60 часов бесплатно каждый месяц с двумя основными экземплярами. Дополнительные сведения см. в разделе GitHub Codespaces: ежемесячные включенные объемы хранилища и основные часы.
Выполните следующие действия, чтобы создать новое пространство кода GitHub в ветви main репозитория Azure-Samples/deepseek-python GitHub.
Щелкните правой кнопкой мыши следующую кнопку и нажмите кнопку "Открыть ссылку" в новом окне. Это действие позволяет иметь среду разработки и документацию, открытую параллельно.
На странице "Создание пространства кода" просмотрите и выберите "Создать новое пространство кода"
Дождитесь запуска рабочего пространства кода. Это может занять несколько минут.
Войдите в Azure с помощью интерфейса командной строки разработчика Azure в терминале в нижней части экрана.
azd auth loginСкопируйте код из терминала и вставьте его в браузер. Следуйте инструкциям по проверке подлинности с помощью учетной записи Azure.
Вы выполняете остальные задачи в этом контейнере разработки.
Развертывание и запуск
В примере репозитория есть все файлы кода и конфигурации, необходимые для развертывания приложения чата в Azure. Выполните следующие действия, чтобы развернуть приложение чата в Azure.
Развертывание приложения чата в Azure
Это важно
Ресурсы Azure, созданные в этом разделе, начинают сразу же приносить расходы. Эти ресурсы могут по-прежнему влечь за собой затраты, даже если вы остановите команду, прежде чем она завершится.
Выполните следующую команду командной строки разработчика Azure Azure для подготовки ресурсов и развертывания исходного кода:
azd upИспользуйте следующую таблицу, чтобы ответить на запросы:
Подсказка Ответ Имя среды Сохраните его коротким и в нижнем регистре. Добавьте имя или псевдоним. Например: chat-app. Он используется в качестве части имени группы ресурсов.Подписка Выберите подписку, в которой вы хотите создать ресурсы. Расположение (для размещения) Выберите место рядом с вами из списка. Расположение модели DeepSeek Выберите место рядом с вами из списка. Если то же местоположение доступно в качестве вашего первого выбора, выберите его. Дождитесь развертывания приложения. Развертывание обычно занимает от 5 до 10 минут.
Используйте приложение чата, чтобы задавать вопросы большой языковой модели.
После развертывания терминал отображает URL-адрес.
Выберите URL-адрес, помеченный
Deploying service webдля открытия приложения чата в браузере.В браузере задайте вопрос о отправленном изображении, например "Кто нарисовал Мону Лизу?"
Azure OpenAI предоставляет ответ через вывод модели, а результат отображается в приложении.
Изучение примера кода
OpenAI и Azure OpenAI Service используют общую клиентскую библиотеку Python, но необходимо внести несколько небольших изменений в код для конечных точек Azure OpenAI. В этом примере используется модель логического вывода DeepSeek-R1 для генерации ответов в простом чате.
Настройка и проверка подлинности
Файл src\quartapp\chat.py начинается с установки и настройки проверки подлинности без ключей.
Настройка инфраструктуры
Сценарий использует Quart, асинхронный веб-фреймворк, чтобы создать Blueprint под названием chat. Это Blueprint определяет маршруты приложения и управляет его хуками жизненного цикла.
bp = Blueprint("chat", __name__, template_folder="templates", static_folder="static")
Blueprint определяет маршруты / и /chat/stream, а также перехватчики жизненного цикла @bp.before_app_serving и @bp.after_app_serving.
Инициализация с помощью проверки подлинности без ключа
Следующий фрагмент кода обрабатывает проверку подлинности.
Замечание
Хук @bp.before_app_serving инициализирует клиент OpenAI и обрабатывает проверку подлинности. Этот подход крайне важен для безопасного доступа к Azure размещенным DeepSeek-R1 моделям.
Стратегия проверки подлинности адаптируется к среде:
- In production: использовать Управляемое удостоверение с идентификатором клиента Azure, чтобы избежать хранения конфиденциальных ключей. Этот метод является безопасным и масштабируемым для облачных приложений.
- На стадии разработки: использует учетные данные Azure Developer CLI с идентификатором клиента Azure для упрощения локального тестирования, используя сеанс входа разработчика в Azure CLI.
@bp.before_app_serving
async def configure_openai():
if os.getenv("RUNNING_IN_PRODUCTION"):
client_id = os.environ["AZURE_CLIENT_ID"]
bp.azure_credential = ManagedIdentityCredential(client_id=client_id)
else:
tenant_id = os.environ["AZURE_TENANT_ID"]
bp.azure_credential = AzureDeveloperCliCredential(tenant_id=tenant_id)
Этот подход к проверке подлинности без ключей обеспечивает следующее:
- Улучшена безопасность: ключи API не хранятся в переменных кода или среды.
- Упрощение управления. Нет необходимости сменить ключи или управлять секретами.
- Плавные переходы: один и тот же код работает как в среде разработки, так и в производственной среде.
Настройка поставщика токенов
В следующем фрагменте кода поставщик токенов создает токен предъявителя для аутентификации запросов к службам Azure OpenAI. Он автоматически создает и обновляет эти маркеры с помощью настроенных учетных данных.
bp.openai_token_provider = get_bearer_token_provider(
bp.azure_credential, "https://cognitiveservices.azure.com/.default"
)
Конфигурация клиента Azure OpenAI
Есть два возможных клиента: AzureOpenAI и AsyncAzureOpenAI. Следующий фрагмент кода использует AsyncAzureOpenAI вместе с асинхронным Quart фреймворком для улучшения производительности в условиях конкурентного использования.
bp.openai_client = AsyncAzureOpenAI(
azure_endpoint=os.environ["AZURE_INFERENCE_ENDPOINT"],
azure_ad_token_provider=openai_token_provider,
api_version="2024-10-21",
- base_url: указывает на конечную точку инференса DeepSeek с Azure
- api_key. Использует динамически созданный ключ API от поставщика токенов.
- API-версия: указывает версию API, поддерживающую модели DeepSeek
Конфигурация имени развертывания модели
Следующий фрагмент кода задает версию модели DeepSeek, получив имя развертывания из конфигурации среды. Он назначает имя переменной bp.model_deployment_name , что делает его доступным во всем приложении. Такой подход позволяет изменить развертывание модели без обновления кода.
bp.model_deployment_name = os.getenv("AZURE_DEEPSEEK_DEPLOYMENT")
Замечание
В OpenAI Azure имена моделей напрямую не используются, например gpt-4o или deepseek-r1. Вместо этого вы создаете deployments, которые называются экземплярами моделей в ресурсе OpenAI Azure. Этот подход обеспечивает следующие преимущества:
- Абстракция: Сохраняет имена развертываний вне кода, используя переменные среды.
- Гибкость. Позволяет переключаться между различными развертываниями DeepSeek, не изменяя код.
- Конфигурация для конкретной среды: позволяет использовать различные развертывания для разработки, тестирования и рабочей среды.
- Управление ресурсами: Каждое развертывание Azure имеет собственные квоты, ограничения и мониторинг.
Управление жизненным циклом
Следующий фрагмент кода предотвращает утечку ресурсов, закрывая асинхронный Azure клиент OpenAI при завершении работы приложения. Хук @bp.after_app_serving обеспечивает правильную очистку ресурсов.
@bp.after_app_serving
async def shutdown_openai():
await bp.openai_client.close()
Функция стриминга обработчика чата
Функция chat_handler() управляет взаимодействием с моделью DeepSeek-R1 через маршрут chat/stream. Он передает ответы клиенту в режиме реального времени и обрабатывает их. Функция извлекает сообщения из полезных данных JSON.
Реализация потоковой передачи
Функция
response_streamначинается с приема сообщений от клиента.- request_messages: маршрут ожидает нагрузку JSON, содержащую сообщения пользователя.
@bp.post("/chat/stream") async def chat_handler(): request_messages = (await request.get_json())["messages"]Затем функция передает ответы из API OpenAI. Он объединяет системные сообщения, такие как "Вы полезный помощник" с предоставленными пользователем сообщениями.
@stream_with_context async def response_stream(): all_messages = [ {"role": "system", "content": "You are a helpful assistant."}, ] + request_messagesЗатем функция создает запрос завершения потокового чата.
Метод
chat.completions.createотправляет сообщения вDeepSeek-R1модель. Параметрstream=Trueвключает потоковую передачу ответов в режиме реального времени.chat_coroutine = bp.openai_client.chat.completions.create( model=bp.openai_model, messages=all_messages, stream=True, )Следующий фрагмент кода обрабатывает ответы потоковой передачи из
DeepSeek-R1модели и обрабатывает ошибки. Он выполняет итерацию по обновлениям, проверяет допустимые варианты и отправляет каждый фрагмент ответа в виде строк JSON. Если возникает ошибка, он регистрирует ошибку и отправляет клиенту сообщение об ошибке JSON при продолжении потока.try: async for update in await chat_coroutine: if update.choices: yield update.choices[0].model_dump_json() + "\n" except Exception as e: current_app.logger.error(e) yield json.dumps({"error": str(e)}, ensure_ascii=False) + "\n" return Response(response_stream())
Обработка содержимого на основе рассуждений
В то время как традиционные языковые модели предоставляют только окончательные выходные данные, модели рассуждений, такие как DeepSeek-R1, показывают свои промежуточные этапы рассуждений. Эти шаги делают их полезными для:
- Решение сложных проблем
- Выполнение математических вычислений
- Обработка многошагового логического рассуждения
- Принятие прозрачных решений
Обработчик событий submit, расположенный в index.html, обрабатывает потоковый ответ на стороне интерфейса. Этот подход позволяет получать доступ к инструкциям модели и отображать их наряду с окончательными выходными данными.
Фронтенд использует ReadableStream для обработки потоковых ответов из бэкенда. Он отделяет содержимое рассуждений от обычного содержимого, показывая рассуждение в расширяемом разделе, а окончательный ответ — в основной области чата.
Пошаговый разбор
Запуск потокового запроса
Этот фрагмент кода создает соединение между интерфейсом JavaScript и серверной частью Python, что позволяет интегрировать DeepSeek-R1 Azure OpenAI с проверкой подлинности без ключей.
const response = await fetch("/chat/stream", { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify({messages: messages}) });Инициализация переменных
Следующий фрагмент кода инициализирует переменные для хранения ответов и мыслей отдельно. Это разделение помогает эффективно обрабатывать содержимое рассуждений.
let answer = ""; let thoughts = "";Обработка каждого обновления
Следующий фрагмент кода асинхронно итерирует фрагменты ответа модели.
for await (const event of readNDJSONStream(response.body)) {Определение и маршрутизация типа контента
Скрипт проверяет, содержит
deltaли событие поле. Если это так, он обрабатывает содержимое в зависимости от того, является ли оно обоснованным или обычным.if (!event.delta) { continue; } if (event.delta.reasoning_content) { thoughts += event.delta.reasoning_content; if (thoughts.trim().length > 0) { // Only show thoughts if they are more than just whitespace messageDiv.querySelector(".loading-bar").style.display = "none"; messageDiv.querySelector(".thoughts").style.display = "block"; messageDiv.querySelector(".thoughts-content").innerHTML = converter.makeHtml(thoughts); } } else if (event.delta.content) { messageDiv.querySelector(".loading-bar").style.display = "none"; answer += event.delta.content; messageDiv.querySelector(".answer-content").innerHTML = converter.makeHtml(answer); }- Если тип контента имеет значение
reasoning_content, содержимое добавляетсяthoughtsи отображается в.thoughts-contentразделе. - Если тип контента имеет значение
content, содержимое добавляетсяanswerи отображается в.answer-contentразделе. - Элемент
.loading-barскрывается, как только начинается потоковая передача содержимого, и раздел.thoughtsотображается, если есть какие-либо мысли.
- Если тип контента имеет значение
Обработка ошибок:
Ошибки регистрируются в серверной части и возвращаются клиенту в формате JSON.
except Exception as e: current_app.logger.error(e) yield json.dumps({"error": str(e)}, ensure_ascii=False) + "\n"Этот фрагмент кода внешнего интерфейса отображает сообщение об ошибке в интерфейсе чата.
messageDiv.scrollIntoView(); if (event.error) { messageDiv.innerHTML = "Error: " + event.error; }
Очистка GitHub пространства кода
Удалите среду GitHub Codespaces, чтобы максимально увеличить бесплатные часы на ядро.
Это важно
Дополнительные сведения о бесплатном хранилище и основных часах учетной записи GitHub см. в разделе GitHub Codespaces: ежемесячные включенные в хранилище и основные часы.
Войдите на панель мониторинга GitHub Codespaces.
Найдите свои активные Кодспейсы, созданные из репозитория
Azure-Samples//deepseek-pythonGitHub.Откройте контекстное меню для пространства кода и выберите Удалить.
Получите помощь
Зарегистрируйте вашу проблему в Issues репозитория.