Érvelési alkalmazások fejlesztése DeepSeek-modellekkel a Microsoft Foundryben az OpenAI SDK használatával

Ismerje meg, hogyan használhat érvelési modelleket, például a DeepSeeket az Azure OpenAI-ben, az OpenAI SDK for Python használatával.

Ez a cikk számos ajánlott eljárást mutat be az érvelési modellek integrálásához:

  • Kulcs nélküli hitelesítés: API-kulcsok helyett használjon felügyelt identitásokat vagy fejlesztői hitelesítő adatokat.
  • Aszinkron műveletek: Aszinkron funkciók használata a jobb teljesítmény érdekében.
  • Streamelési válaszok: Azonnali visszajelzés küldése a felhasználóknak.
  • Érvelési elkülönítés: Az érvelés lépéseinek elkülönítése a végső kimenettől.
  • Erőforrás-kezelés: Erőforrások törlése használat után.

A DeepSeek építőeleme

Ismerkedjen meg a DeepSeek építőelem példával. Bemutatja, hogyan hívhatja meg a DeepSeek-R1 modellt az OpenAI ügyfélkódtár használatával, és hogyan hozhat létre válaszokat a felhasználói üzenetekre.

Architekturális áttekintés

Az alábbi diagram a mintaalkalmazás egyszerű architektúráját mutatja be: Az architektúrát ábrázoló ábra az ügyféltől a háttéralkalmazásig.

A csevegőalkalmazás Azure tárolóalkalmazásként fut. Az alkalmazás Microsoft Entra ID felügyelt identitást használ a Azure OpenAI-val való hitelesítéshez API-kulcs helyett. Az alkalmazás Azure OpenAI használatával hoz létre válaszokat a felhasználói üzenetekre.

Az alkalmazás a következő szolgáltatásokra és összetevőkre támaszkodik:

  • Egy Python Quart alkalmazás, amely a OpenAI ügyfélkódtárat csomagot használja a felhasználói üzenetekre adott válaszok létrehozásához
  • Egy egyszerű HTML/JS-előtér, amely JSON-vonalak használatával streameli a válaszokat a háttérrendszerből egy olvasható adatfolyamon keresztül
  • Bicep fájlok Azure erőforrások kiépítéséhez, beleértve a Foundry Tools, az Azure Container-alkalmazások, az Azure Container Registry, az Azure Log Analytics és az RBAC-szerepköröket.

Költség

A költségek alacsony szinten tartása érdekében ez a minta alapszintű vagy fogyasztási tarifacsomagokat használ a legtöbb erőforráshoz. Igény szerint állítsa be a szintet, és törölje az erőforrásokat, ha elkészült a díjak elkerülése érdekében.

További információ a costról a mintaadattárban.

Előfeltételek

A fejlesztői tároló tartalmazza a cikkhez szükséges összes függőséget. Futtathatja a GitHub Codespaces-ben (böngészőben) vagy helyben a Visual Studio Code használatával.

A cikk követéséhez győződjön meg arról, hogy megfelel az alábbi előfeltételeknek:

Nyílt fejlesztési környezet

Az alábbi lépésekkel előre konfigurált fejlesztői környezetet állíthat be az összes szükséges függőséggel együtt.

GitHub Codespaces egy GitHub által felügyelt fejlesztési tárolót futtat a webes Visual Studio Code felülettel. A legegyszerűbb beállításhoz használja GitHub codespace-eket, mivel a cikkhez előre telepített szükséges eszközökkel és függőségekkel rendelkezik.

Fontos

Minden GitHub-fiók legfeljebb 60 órán át használhatja a Codespace-eket havonta két alapvető példánnyal. További információkért tekintse meg a GitHub Codespaces havi tárhelyét és alapóra-kiosztását.

Az alábbi lépésekkel hozzon létre egy új GitHub codespace-t a main GitHub adattár Azure-Samples/deepseek-python ágán.

  1. Kattintson a jobb gombbal az alábbi gombra, és válassza a Hivatkozás megnyitása az új ablakban lehetőséget. Ez a művelet lehetővé teszi, hogy a fejlesztési környezet és a dokumentáció egymás mellett legyen megnyitva.

    Open in GitHub Codespaces

  2. A Kódtér létrehozása lapon tekintse át, majd válassza az Új kódtér létrehozása lehetőséget

  3. Várja meg, amíg a kódolási környezet elindul. Eltarthat néhány percig.

  4. Jelentkezzen be a Azure a Azure fejlesztői parancssori felülettel a képernyő alján lévő terminálban.

    azd auth login
    
  5. Másolja ki a kódot a terminálból, majd illessze be egy böngészőbe. Kövesse az utasításokat a Azure-fiókjával való hitelesítéshez.

A többi feladatot ebben a fejlesztési tárolóban hajtja végre.

Üzembe helyezés és futtatás

A mintatároló tartalmazza az összes kódot és konfigurációs fájlt, amely szükséges a csevegőalkalmazás üzembe helyezéséhez az Azure-ra. Az alábbi lépéseket követve üzembe helyezheti a csevegőalkalmazást a Azure.

Az Azure-ra történő csevegőalkalmazás üzembe helyezése

Fontos

Azure ebben a szakaszban létrehozott erőforrások azonnal pénzbe kerülnek. Ezek az erőforrások még akkor is költségekkel járhatnak, ha megszakítja a parancsot, mielőtt befejeződne.

  1. Futtassa a következő Azure Fejlesztői parancssori felület parancsot Azure erőforrás-kiépítéshez és a forráskód üzembe helyezéséhez:

    azd up
    
  2. Az alábbi táblázat segítségével válaszolhat a kérdésekre:

    Haladéktalan Válasz
    Környezet neve Legyen rövid és kisbetűs. Adja hozzá a nevét vagy aliasát. Például: chat-app. Az erőforráscsoport nevének részeként használják.
    Előfizetés Válassza ki az előfizetést az erőforrások létrehozásához.
    Hely (üzemeltetéshez) Válasszon ki egy Önhöz közeli helyet a listából.
    A DeepSeek-modell helye Válasszon ki egy Önhöz közeli helyet a listából. Ha ugyanaz a hely érhető el, mint az első hely, válassza ezt.
  3. Várja meg az alkalmazás üzembe helyezését. Az üzembe helyezés általában 5–10 percet vesz igénybe.

A csevegőalkalmazással kérdéseket tehet fel a nagy nyelvi modellnek

  1. Az üzembe helyezés után a terminál egy URL-címet jelenít meg.

  2. Válassza ki a címkézett URL-címet Deploying service web a csevegőalkalmazás böngészőben való megnyitásához.

    Képernyőkép a csevegőalkalmazásról a böngészőben, a válasz mellett a csevegő szövegmezőben lévő kérdésről.

  3. A böngészőben tegyen fel egy kérdést a feltöltött képről, például: "Ki festette a Mona Lisa-t?"

  4. Azure OpenAI modellkövetkeztetéssel adja meg a választ, és az eredmény megjelenik az alkalmazásban.

A mintakód felfedezése

Az OpenAI és a Azure OpenAI Service egyaránt a common Python ügyfélkódtárat használják, de néhány kisebb kódmódosítást kell végrehajtania Azure OpenAI-végpontok esetében. Ez a minta egy DeepSeek-R1 érvelési modellt használ a válaszok egyszerű csevegőalkalmazásban való létrehozásához.

Beállítás és hitelesítés

A src\quartapp\chat.py fájl a kulcs nélküli hitelesítés beállításával és konfigurálásával kezdődik.

Infrastruktúra beállítása

A szkript a Quart, egy aszinkron webes keretrendszer használatával létrehoz egy Blueprint, amit így neveznek: chat. Ez Blueprint határozza meg az alkalmazás útvonalait, és kezeli annak életciklus-függvényeit.

bp = Blueprint("chat", __name__, template_folder="templates", static_folder="static")

A Blueprint meghatározza az / és /chat/stream útvonalakat, valamint a @bp.before_app_serving és @bp.after_app_serving életciklus-horgokat.

Inicializálás kulcs nélküli hitelesítéssel

Az alábbi kódrészlet kezeli a hitelesítést.

Megjegyzés:

A @bp.before_app_serving horog inicializálja az OpenAI-ügyfelet, és kezeli a hitelesítést. Ez a megközelítés kritikus fontosságú a Azure üzemeltetett DeepSeek-R1 modellek biztonságos eléréséhez.

A hitelesítési stratégia alkalmazkodik a környezethez:

  • Az éles környezetben: A bizalmas kulcsok tárolásának elkerülése érdekében az Azure kliensazonosítóval rendelkező Managed Identity Credential kerül használatra. Ez a módszer biztonságos és méretezhető a natív felhőbeli alkalmazásokhoz.
  • Fejlesztés alatt: Az Azure Developer CLI hitelesítő adatainak és egy Azure bérlőazonosító segítségével egyszerűsíti a helyi tesztelést a fejlesztő Azure CLI bejelentkezési munkamenetének használatával.
@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)

Ez a kulcs nélküli hitelesítési módszer a következőt nyújtja:

  • Nagyobb biztonság: Nincsenek kód- vagy környezeti változókban tárolt API-kulcsok.
  • Egyszerűbb kezelés: Nincs szükség kulcsok elforgatására vagy titkos kulcsok kezelésére.
  • Zökkenőmentes átmenetek: Ugyanaz a kód fejlesztési és éles környezetben is működik.

Token-szolgáltató beállítása

A következő kódrészletben a token-szolgáltató létrehoz egy bearer tokent az Azure OpenAI szolgáltatásokra irányuló kérelmek hitelesítéséhez. Automatikusan létrehozza és frissíti ezeket a jogkivonatokat a konfigurált hitelesítő adatok használatával.

bp.openai_token_provider = get_bearer_token_provider(
    bp.azure_credential, "https://cognitiveservices.azure.com/.default"
)

Azure OpenAI-ügyfélkonfiguráció

Két lehetséges ügyfél van, AzureOpenAI és AsyncAzureOpenAI. Az alábbi kódrészlet az aszinkron AsyncAzureOpenAI keretrendszerrel együtt az egyidejű felhasználók jobb teljesítményét biztosítjaQuart:

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: A Azure által üzemeltetett DeepSeek következtetési végpontra mutat
  • api_key: Dinamikusan generált API-kulcsot használ a jogkivonat-szolgáltatótól.
  • api-version: A DeepSeek-modelleket támogató API-verziót adja meg

Modell telepítési nevének konfigurációja

Az alábbi kódrészlet a DeepSeek-modell verzióját állítja be úgy, hogy lekérte az üzembe helyezés nevét a környezet konfigurációjából. Hozzárendeli a nevet a bp.model_deployment_name változóhoz, így az az alkalmazás teljes területén elérhető lesz. Ez a módszer lehetővé teszi a modell üzembe helyezésének módosítását a kód frissítése nélkül.

bp.model_deployment_name = os.getenv("AZURE_DEEPSEEK_DEPLOYMENT")

Megjegyzés:

Az OpenAI Azure nem használ közvetlenül modellneveket, például gpt-4o vagy deepseek-r1. Ehelyett létrehozhat deployments, amelyek az Azure OpenAI-erőforrásban lévő modellek nevesített példányai. Ez a megközelítés a következő előnyöket kínálja:

  • Absztrakció: Környezeti változók használatával távol tartja az üzembehelyezési neveket a kódtól.
  • Rugalmasság: Lehetővé teszi a különböző DeepSeek-környezetek közötti váltást a kód módosítása nélkül.
  • Környezetspecifikus konfiguráció: Lehetővé teszi a fejlesztéshez, teszteléshez és éles környezethez szükséges különböző telepítések használatát.
  • Forráskezelés: Minden Azure telepítés saját kvótával, sebességkorlátozással és monitorozással rendelkezik.

Életciklus-kezelés

Az alábbi kódrészlet megakadályozza az erőforrások kiszivárgását az aszinkron Azure OpenAI-ügyfél bezárásával, amikor az alkalmazás leáll. A @bp.after_app_serving horog biztosítja az erőforrások megfelelő tisztítását.

@bp.after_app_serving
async def shutdown_openai():
    await bp.openai_client.close()

Csevegéskezelő streamelési függvénye

A chat_handler() függvény a DeepSeek-R1 útvonalon keresztül kezeli a felhasználói interakciókat a chat/stream modellel. Valós időben streameli a válaszokat az ügyfélnek, és feldolgozza őket. A függvény kinyeri az üzeneteket a JSON hasznos adataiból.

Streamelés implementálása

  1. A response_stream függvény az ügyfél üzeneteinek elfogadásával kezdődik.

    • request_messages: Az útvonal felhasználói üzeneteket tartalmazó JSON-hasznos adatra számít.
    @bp.post("/chat/stream")
    async def chat_handler():
       request_messages = (await request.get_json())["messages"]
    
  2. Ezután a függvény az OpenAI API-ból streameli a válaszokat. Egyesíti a rendszerüzeneteket, például a "Hasznos asszisztens" szöveget a felhasználó által megadott üzenetekkel.

    @stream_with_context
    async def response_stream():
        all_messages = [
            {"role": "system", "content": "You are a helpful assistant."},
        ] + request_messages
    
  3. Ezután a függvény létrehoz egy streamelési csevegés befejezési kérését.

    A chat.completions.create metódus elküldi az üzeneteket a DeepSeek-R1 modellnek. A stream=True paraméter valós idejű válaszstreamelést tesz lehetővé.

      chat_coroutine = bp.openai_client.chat.completions.create(
          model=bp.openai_model,
          messages=all_messages,
          stream=True,
      )
    
  4. Az alábbi kódrészlet feldolgozza a modellből érkező streamelési válaszokat, és kezeli a DeepSeek-R1 hibákat. Iterálja a frissítéseket, ellenőrzi az érvényes választási lehetőségeket, és minden választömbet JSON-sorokként küld el. Ha hiba történik, naplózza a hibát, és JSON-hibaüzenetet küld az ügyfélnek a stream folytatása közben.

    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())
    

Tartalomkezelés indoklása

Míg a hagyományos nyelvi modellek csak végső kimeneteket biztosítanak, az érvelési modellek, például a DeepSeek-R1, megjelenítik a köztes érvelési lépéseiket. Ezek a lépések a következőkhöz teszik hasznossá őket:

  • Összetett problémák megoldása
  • Matematikai számítások végrehajtása
  • Többlépéses logikai érvelés kezelése
  • Transzparens döntések meghozatala

Az submit eseménykezelő a index.html-ben dolgozza fel a streamelési választ a frontend oldalon. Ez a megközelítés lehetővé teszi a modell érvelési lépéseinek elérését és megjelenítését a végső kimenet mellett.

A felület a ReadableStream a háttérrendszerből érkező streaming válaszok feldolgozására használja. Elválasztja az érvelési tartalmakat a normál tartalomtól, és egy bővíthető szakaszban jeleníti meg az érvelést, és a fő csevegési területen a végső választ.

Részletes részletezés

  1. Streamelési kérés kezdeményezése

    Ez a kódrészlet kapcsolatot hoz létre a JavaScript előtér és a Python háttérrendszer között, lehetővé téve a DeepSeek-R1 Azure OpenAI-integrációját kulcs nélküli hitelesítéssel.

    const response = await fetch("/chat/stream", {
        method: "POST",
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify({messages: messages})
    });
    
  2. Változók inicializálása

    Az alábbi kódrészlet inicializálja a változókat a válasz és a gondolatok külön tárolásához. Ez az elkülönítés segít hatékonyan kezelni az érvelési tartalmakat.

    let answer = "";
    let thoughts = "";    
    
  3. Az egyes frissítések feldolgozása

    Az alábbi kódrészlet aszinkron módon iterál a modell válaszának darabjai között.

    for await (const event of readNDJSONStream(response.body)) {
    
  4. Tartalomtípus észlelése és átirányítása

    A szkript ellenőrzi, hogy az esemény tartalmaz-e delta mezőt. Ha igen, akkor a tartalmat attól függően dolgozza fel, hogy az érvelési tartalmat vagy a szokásos tartalmat tartalmazza.

    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);
     }
    
    • Ha a tartalomtípus az reasoning_content, akkor a rendszer hozzáadja thoughts a tartalmat, és megjelenik a .thoughts-content szakaszban.
    • Ha a tartalomtípus az content, akkor a rendszer hozzáadja answer a tartalmat, és megjelenik a .answer-content szakaszban.
    • A .loading-bar rejtve marad, amint a tartalom elkezd streamelni, és a .thoughts szakasz megjelenik, ha vannak gondolatok.
  5. Hibakezelés:

    A rendszer naplózza a hibákat a háttérrendszerben, és JSON formátumban adja vissza az ügyfélnek.

    except Exception as e:
        current_app.logger.error(e)
        yield json.dumps({"error": str(e)}, ensure_ascii=False) + "\n"
    

    Ez az előtérbeli kódrészlet a csevegőfelületen jeleníti meg a hibaüzenetet.

    messageDiv.scrollIntoView();
    if (event.error) {
        messageDiv.innerHTML = "Error: " + event.error;
    }
    

GitHub kódterek takarítása

Törölje a GitHub Codespaces környezetet, hogy maximálisan kihasználhassa a magonkénti ingyenes órákat.

Fontos

GitHub-fiókjának ingyenes tárhelyéről és magóráiról további információt a GitHub Codespaces által havonta biztosított tárhely és magórák című témakörben talál.

  1. Jelentkezzen be a GitHub Codespaces felületére.

  2. Keresse meg a Azure-Samples//deepseek-python GitHub adattárból létrehozott aktív kódtereket.

  3. Nyissa meg a kódtér helyi menüjét, és válassza a Törléslehetőséget.

Segítség kérése

Rögzítse a problémát a tároló Issues lapján.

Következő lépések