Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Informazioni su come usare modelli di ragionamento come DeepSeek in Azure OpenAI con OpenAI SDK per Python.
Questo articolo illustra diverse procedure consigliate per l'integrazione dei modelli di ragionamento:
- Autenticazione senza chiave: usare identità gestite o credenziali per sviluppatori anziché chiavi API.
- Operazioni asincrone: usare le funzionalità asincrone per migliorare le prestazioni.
- Risposte in streaming: fornire feedback immediato agli utenti.
- Separazione dei motivi: separare i passaggi di ragionamento dall'output finale.
- Gestione risorse: pulire le risorse dopo l'uso.
Il blocco di costruzione DeepSeek
Esplora l'esempio del blocco di costruzione DeepSeek. Illustra come usare la libreria client OpenAI per chiamare il modello di DeepSeek-R1 e generare risposte ai messaggi utente.
Panoramica dell'architettura
Il diagramma seguente illustra la semplice architettura dell'app di esempio:
L'app di chat viene eseguita come un'app contenitore di Azure. L'app usa l'identità gestita con Microsoft Entra ID per l'autenticazione con Azure OpenAI anziché con una chiave API. L'app usa Azure OpenAI per generare risposte ai messaggi utente.
L'app si basa su questi servizi e componenti:
- Un'app Python Quart che usa la libreria client OpenAI per generare risposte ai messaggi utente
- Front-end HTML/JS di base che trasmette le risposte dal back-end usando righe JSON su un flusso leggibile
- File Bicep per il provisioning di risorse Azure, inclusi strumenti Foundry, Azure Container Apps, Azure Container Registry, Azure Log Analytics e ruoli RBAC.
Costo
Per ridurre i costi, questo esempio usa piani tariffari di base o a consumo per la maggior parte delle risorse. Modificare il livello in base alle esigenze ed eliminare le risorse al termine per evitare addebiti.
Per ulteriori informazioni sul costo nello repository di esempio.
Prerequisiti
Un contenitore di sviluppo include tutte le dipendenze necessarie per questo articolo. È possibile eseguirlo in GitHub Codespaces (in un browser) o in locale usando Visual Studio Code.
Per seguire questo articolo, assicurarsi di soddisfare questi prerequisiti:
- Una sottoscrizione Azure: Crearne una gratuitamente
- Azure autorizzazioni dell'account: l'account Azure deve avere autorizzazioni
Microsoft.Authorization/roleAssignments/write, ad esempio Role Based Access Control Administrator, User Access Administrator o Owner. Se non si dispone delle autorizzazioni a livello di sottoscrizione, è necessario ricevere RBAC per un gruppo di risorse esistente e distribuire le risorse in tale gruppo.- L'account Azure richiede anche autorizzazioni
Microsoft.Resources/deployments/writea livello di sottoscrizione.
- L'account Azure richiede anche autorizzazioni
- account su GitHub
Ambiente di sviluppo aperto
Seguire questa procedura per configurare un ambiente di sviluppo preconfigurato con tutte le dipendenze necessarie.
GitHub Codespaces esegue un contenitore di sviluppo gestito da GitHub con Visual Studio Code per web come interfaccia. Usare GitHub Codespaces per la configurazione più semplice, perché include gli strumenti e le dipendenze necessari preinstallati per questo articolo.
Importante
Tutti gli account GitHub possono usare Codespaces per un massimo di 60 ore gratuite ogni mese con due istanze principali. Per altre informazioni, vedere l'archiviazione e le ore di base mensili incluse di GitHub Codespaces.
Usare la procedura seguente per creare un nuovo GitHub Codespace nel ramo main del repository Azure-Samples/deepseek-python GitHub.
Fare clic con il pulsante destro del mouse sul pulsante seguente e scegliere Apri collegamento nella nuova finestra. Questa azione consente di avere l'ambiente di sviluppo e la documentazione aperta side-by-side.
Nella pagina Crea spazio codici esaminare e quindi selezionare Crea nuovo spazio di codice
Attendere l'avvio dello spazio di codice. Potrebbe richiedere alcuni minuti.
Accedi ad Azure con l'interfaccia della riga di comando Azure Developer nel terminale nella parte inferiore dello schermo.
azd auth loginCopiare il codice dal terminale e incollarlo in un browser. Seguire le istruzioni per eseguire l'autenticazione con l'account Azure.
Si eseguono le altre attività in questo contenitore di sviluppo.
Distribuire ed eseguire
Il repository di esempio include tutti i file di codice e configurazione necessari per distribuire l'app di chat in Azure. Seguire questa procedura per distribuire l'app di chat in Azure.
Distribuire l'applicazione di chat su Azure
Importante
Le risorse di Azure create in questa sezione iniziano a generare costi immediatamente. Queste risorse potrebbero comunque comportare costi anche se si arresta il comando prima del completamento.
Eseguire il seguente comando della CLI sviluppatore di Azure per il provisioning delle risorse di Azure e la distribuzione del codice sorgente.
azd upUsare la tabella seguente per rispondere alle richieste:
Rapido Risposta Nome dell'ambiente Tienila breve e minuscola. Aggiungere il nome o l'alias. Ad esempio: chat-app. Viene usato come parte del nome del gruppo di risorse.Abbonamento Selezionare la sottoscrizione in cui creare le risorse. Località (per l'hosting) Seleziona una località vicino a te dall'elenco. Posizione del modello DeepSeek Seleziona una località vicino a te dall'elenco. Se la stessa località è disponibile come prima località, selezionare questa posizione. Attendere che l'app venga distribuita. La distribuzione richiede in genere da 5 a 10 minuti.
Usare l'app chat per porre domande al modello linguistico di grandi dimensioni
Dopo la distribuzione, il terminale visualizza un URL.
Selezionare l'URL etichettato
Deploying service webper aprire l'app di chat nel browser.Nel browser, porre una domanda sull'immagine caricata, ad esempio "Chi ha dipinto la Mona Lisa?"
Azure OpenAI fornisce la risposta tramite l'inferenza del modello e il risultato viene visualizzato nell'app.
Esplorazione del codice di esempio
OpenAI e Azure OpenAI Service usano entrambi la comune libreria client Python, ma è necessario apportare alcune lievi modifiche al codice per gli endpoint di Azure OpenAI. Questo esempio usa un modello di ragionamento DeepSeek-R1 per generare risposte in una semplice app di chat.
Installazione e autenticazione
Il src\quartapp\chat.py file inizia con l'installazione e la configurazione dell'autenticazione senza chiave.
Configurazione dell'infrastruttura
Lo script usa Quart, un framework Web asincrono, per creare un Blueprint oggetto denominato chat. Questo Blueprint definisce le route dell'app e gestisce i relativi hook del ciclo di vita.
bp = Blueprint("chat", __name__, template_folder="templates", static_folder="static")
Definisce le route Blueprint e / e gli hook del ciclo di vita /chat/stream e @bp.before_app_serving.
Inizializzazione con autenticazione senza chiave
Il frammento di codice seguente gestisce l'autenticazione.
Annotazioni
L'hook @bp.before_app_serving inizializza il client OpenAI e gestisce l'autenticazione. Questo approccio è fondamentale per accedere in modo sicuro ai modelli di DeepSeek-R1 ospitati Azure.
La strategia di autenticazione si adatta all'ambiente:
- In production: usa Managed Identity Credential con un ID client Azure per evitare di archiviare chiavi sensibili. Questo metodo è sicuro e scalabile per le app native del cloud.
- In development: usa Azure Developer CLI Credential con un ID tenant Azure per semplificare i test locali usando la sessione di accesso Azure CLI dello sviluppatore.
@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)
Questo approccio di autenticazione senza chiave offre:
- Maggiore sicurezza: nessuna chiave API archiviata nel codice o nelle variabili di ambiente.
- Gestione più semplice: non è necessario ruotare le chiavi o gestire i segreti.
- Transizioni uniformi: lo stesso codice funziona sia nello sviluppo che nell'ambiente di produzione.
Configurazione del provider di token
Nel frammento di codice seguente il provider di token crea un token di connessione per autenticare le richieste ai servizi OpenAI Azure. Genera e aggiorna automaticamente questi token usando le credenziali configurate.
bp.openai_token_provider = get_bearer_token_provider(
bp.azure_credential, "https://cognitiveservices.azure.com/.default"
)
Configurazione del client Azure OpenAI
Esistono due possibili client, AzureOpenAI e AsyncAzureOpenAI. Il frammento di codice seguente usa AsyncAzureOpenAI insieme al framework asincrono Quart per migliorare le prestazioni con gli utenti simultanei:
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: si riferisce all'endpoint di inferenza DeepSeek ospitato su Azure
- api_key: usa una chiave API generata dinamicamente dal provider di token.
- api-version: specifica la versione dell'API che supporta i modelli DeepSeek
Configurazione del nome della distribuzione del modello
Il frammento di codice seguente imposta la versione del modello DeepSeek recuperando il nome della distribuzione dalla configurazione dell'ambiente. Assegna il nome alla bp.model_deployment_name variabile, rendendolo accessibile in tutta l'app. Questo approccio consente di modificare la distribuzione del modello senza aggiornare il codice.
bp.model_deployment_name = os.getenv("AZURE_DEEPSEEK_DEPLOYMENT")
Annotazioni
In Azure OpenAI non si usano direttamente nomi di modello come gpt-4o o deepseek-r1. È invece possibile creare deployments, ovvero istanze denominate di modelli nella risorsa Azure OpenAI. Questo approccio offre i vantaggi seguenti:
- Astrazione: mantiene i nomi di distribuzione fuori dal codice usando le variabili di ambiente.
- Flessibilità: consente di passare da distribuzioni DeepSeek diverse senza modificare il codice.
- Configurazione specifica dell'ambiente: consente l'uso di distribuzioni diverse per sviluppo, test e produzione.
- Gestione delle risorse: ogni distribuzione Azure ha una propria quota, limitazione e monitoraggio.
Gestione del ciclo di vita
Il frammento di codice seguente impedisce perdite di risorse chiudendo la Azure client OpenAI asincrona quando l'applicazione viene arrestata. L'hook @bp.after_app_serving garantisce una corretta pulizia delle risorse.
@bp.after_app_serving
async def shutdown_openai():
await bp.openai_client.close()
Funzione di streaming del gestore chat
La chat_handler() funzione gestisce le interazioni utente con il DeepSeek-R1 modello attraverso la chat/stream route. Trasmette le risposte al client in tempo reale ed elabora le risposte. La funzione estrae messaggi dal payload JSON.
Implementazione di streaming
La
response_streamfunzione inizia accettando messaggi dal client.- request_messages: la route prevede un payload JSON contenente i messaggi utente.
@bp.post("/chat/stream") async def chat_handler(): request_messages = (await request.get_json())["messages"]Successivamente, la funzione trasmette le risposte dall'API OpenAI. Combina messaggi di sistema come "Sei un assistente utile" con i messaggi forniti dall'utente.
@stream_with_context async def response_stream(): all_messages = [ {"role": "system", "content": "You are a helpful assistant."}, ] + request_messagesSuccessivamente, la funzione crea una richiesta di completamento della chat in streaming.
Il
chat.completions.createmetodo invia i messaggi alDeepSeek-R1modello. Ilstream=Trueparametro abilita lo streaming delle risposte in tempo reale.chat_coroutine = bp.openai_client.chat.completions.create( model=bp.openai_model, messages=all_messages, stream=True, )Il frammento di codice seguente elabora le risposte in streaming dal
DeepSeek-R1modello e gestisce gli errori. Scorre gli aggiornamenti, verifica la disponibilità di scelte valide e invia ogni blocco di risposta come righe JSON. Se si verifica un errore, registra l'errore e invia un messaggio di errore JSON al client durante la continuazione del flusso.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())
Ragionamento della gestione dei contenuti
Mentre i modelli linguistici tradizionali forniscono solo output finali, i modelli di ragionamento come DeepSeek-R1 mostrano i passaggi intermedi di ragionamento. Questi passaggi li rendono utili per:
- Risoluzione di problemi complessi
- Esecuzione di calcoli matematici
- Gestione del ragionamento logico in più passaggi
- Prendere decisioni trasparenti
Il submit gestore eventi in index.html elabora la risposta di streaming nel front-end. Questo approccio consente di accedere e visualizzare i passaggi di ragionamento del modello insieme all'output finale.
Il frontend utilizza un ReadableStream per elaborare le risposte in streaming dal backend. Separa il contenuto di ragionamento dal contenuto normale, mostrando il ragionamento in una sezione espandibile e la risposta finale nell'area principale della chat.
Suddivisione dettagliata
Avviare la richiesta di streaming
Questo frammento di codice crea una connessione tra il front-end JavaScript e il back-end Python, abilitando l'integrazione di DeepSeek-R1 Azure OpenAI con l'autenticazione senza chiave.
const response = await fetch("/chat/stream", { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify({messages: messages}) });Inizializzare le variabili
Il frammento di codice seguente inizializza le variabili per archiviare separatamente le risposte e i pensieri. Questa separazione consente di gestire in modo efficace il contenuto di ragionamento.
let answer = ""; let thoughts = "";Elaborare ogni aggiornamento
Il frammento di codice seguente itera in modo asincrono su porzioni della risposta del modello.
for await (const event of readNDJSONStream(response.body)) {Identificare e indirizzare il tipo di contenuto
Lo script controlla se l'evento contiene un
deltacampo. Se sì, elabora il contenuto in base al fatto che sia contenuto di ragionamento o contenuto normale.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); }- Se il tipo di contenuto è
reasoning_content, il contenuto viene aggiunto athoughtse visualizzato nella.thoughts-contentsezione . - Se il tipo di contenuto è
content, il contenuto viene aggiunto aanswere visualizzato nella.answer-contentsezione . - L'oggetto
.loading-barviene nascosto una volta che il contenuto inizia a essere trasmesso in streaming, e la sezione.thoughtsviene visualizzata se ci sono pensieri.
- Se il tipo di contenuto è
Gestione degli errori:
Gli errori vengono registrati nel back-end e restituiti al client in formato JSON.
except Exception as e: current_app.logger.error(e) yield json.dumps({"error": str(e)}, ensure_ascii=False) + "\n"Questo frammento di codice front-end visualizza il messaggio di errore nell'interfaccia della chat.
messageDiv.scrollIntoView(); if (event.error) { messageDiv.innerHTML = "Error: " + event.error; }
Pulire GitHub Codespaces
Per ottimizzare le ore gratuite per singolo core, elimina l'ambiente Codespaces di GitHub.
Importante
Per ulteriori informazioni sull'archiviazione gratuita e sulle ore core incluse nel tuo account GitHub, consulta Archiviazione e ore core mensili incluse in GitHub Codespaces.
Accedere al dashboard GitHub Codespaces.
Trova il tuo spazio di codice attivo creato dal repository
Azure-Samples//deepseek-pythonGitHub.Aprire il menu di scelta rapida per lo spazio di codice e selezionare Elimina.
Ottenere assistenza
Registrare il tuo problema nel repository Issues.