Dela via


API:er för multi-modala realtidsfunktioner

Den första API-integreringen i realtid för semantisk kernel har lagts till, den är för närvarande endast tillgänglig i Python och anses vara experimentell. Det beror på att de underliggande tjänsterna fortfarande utvecklas och kan komma att ändras och vi kan behöva göra icke-bakåtkompatibla ändringar i API:et i Semantic Kernel när vi lär oss av kunderna hur de ska använda detta och när vi lägger till andra leverantörer av den här typen av modeller och API:er.

Abstraktion av realtidsklient

För att stödja olika realtids-API:er från olika leverantörer har en ny klientabstraktion lagts till i kerneln med hjälp av olika protokoll. Den här klienten används för att ansluta till realtidstjänsten och skicka och ta emot meddelanden. Klienten ansvarar för att hantera anslutningen till tjänsten, skicka meddelanden och ta emot meddelanden. Klienten ansvarar också för att hantera eventuella fel som uppstår under anslutningen eller processen för att skicka/ta emot meddelanden. Med tanke på hur dessa modeller fungerar kan de betraktas som agenter mer än vanliga chattavslut, därför tar de också instruktioner, snarare än ett systemmeddelande, de behåller sitt eget interna tillstånd och kan anropas för att utföra arbete för vår räkning.

Realtids API

Alla realtidsklienter implementerar följande metoder:

Metod Beskrivning
create_session Skapar en ny session
update_session Uppdaterar en befintlig session
delete_session Tar bort en befintlig session
receive Det här är en asynkron generatormetod som lyssnar efter meddelanden från tjänsten och returnerar dem när de tas emot.
send Skickar ett meddelande till tjänsten

Python-implementeringar

Python-versionen av Semantic Kernel stöder för närvarande följande realtidsklienter:

Klient Protokoll Modaliteter Funktionsanrop aktiverat Beskrivning
OpenAI Websocket Text & ljud Ja OpenAI Realtime API är ett websocket-baserat API som gör att du kan skicka och ta emot meddelanden i realtid. Den här anslutningsappen använder OpenAI Python-paketet för att ansluta och ta emot och skicka meddelanden.
OpenAI WebRTC Text & ljud Ja OpenAI Realtime API är ett WebRTC-baserat API som gör att du kan skicka och ta emot meddelanden i realtid, det behöver ett webRTC-kompatibelt ljudspår när sessionen skapas.
Blått Websocket Text & ljud Ja Azure Realtime API är ett websocket-baserat API som gör att du kan skicka och ta emot meddelanden i realtid. Detta använder samma paket som OpenAI websocket connector.

Komma igång

För att komma igång med Realtime-API:et måste du installera semantic-kernel-paketet med realtime extra.

pip install semantic-kernel[realtime]

Beroende på hur du vill hantera ljud kan du behöva ytterligare paket för att interagera med högtalare och mikrofoner, till exempel pyaudio eller sounddevice.

Websocket-klienter

Sedan kan du skapa en kernel och lägga till realtidsklienten i den. Detta visar hur du gör det med en AzureRealtimeWebsocket-anslutning. Du kan ersätta AzureRealtimeWebsocket med OpenAIRealtimeWebsocket utan ytterligare ändringar.

from semantic_kernel.connectors.ai.open_ai import (
    AzureRealtimeWebsocket,
    AzureRealtimeExecutionSettings,
    ListenEvents,
)
from semantic_kernel.contents import RealtimeAudioEvent, RealtimeTextEvent

# this will use environment variables to get the api key, endpoint, api version and deployment name.
realtime_client = AzureRealtimeWebsocket()
settings = AzureRealtimeExecutionSettings(voice='alloy')
async with realtime_client(settings=settings, create_response=True):
    async for event in realtime_client.receive():
        match event:
            # receiving a piece of audio (and send it to a undefined audio player)
            case RealtimeAudioEvent():
                await audio_player.add_audio(event.audio)
            # receiving a piece of audio transcript
            case RealtimeTextEvent():
                # Semantic Kernel parses the transcript to a TextContent object captured in a RealtimeTextEvent
                print(event.text.text, end="")
            case _:
                # OpenAI Specific events
                if event.service_type == ListenEvents.SESSION_UPDATED:
                    print("Session updated")
                if event.service_type == ListenEvents.RESPONSE_CREATED:
                    print("\nMosscap (transcript): ", end="")

Det finns två viktiga saker att notera, den första är att realtime_client är en asynkron kontexthanterare, vilket innebär att du kan använda den i en asynkron funktion och använda async with för att skapa sessionen. Den andra är att metoden receive är en asynkron generator, vilket innebär att du kan använda den i en for-loop för att ta emot meddelanden när de tas emot.

WebRTC-klient

Installationen av en WebRTC-anslutning är lite mer komplex och därför behöver vi en extra parameter när du skapar klienten. Den här parametern audio_track måste vara ett objekt som implementerar MediaStreamTrack-protokollet för aiortc-paketet. Detta visas också i exemplen som är länkade nedan.

Om du vill skapa en klient som använder WebRTC gör du följande:

from semantic_kernel.connectors.ai.open_ai import (
    ListenEvents,
    OpenAIRealtimeExecutionSettings,
    OpenAIRealtimeWebRTC,
)
from aiortc.mediastreams import MediaStreamTrack

class AudioRecorderWebRTC(MediaStreamTrack):
    # implement the MediaStreamTrack methods.

realtime_client = OpenAIRealtimeWebRTC(audio_track=AudioRecorderWebRTC())
# Create the settings for the session
settings = OpenAIRealtimeExecutionSettings(
    instructions="""
You are a chat bot. Your name is Mosscap and
you have one goal: figure out what people need.
Your full name, should you need to know it, is
Splendid Speckled Mosscap. You communicate
effectively, but you tend to answer with long
flowery prose.
""",
    voice="shimmer",
)
audio_player = AudioPlayer
async with realtime_client(settings=settings, create_response=True):
    async for event in realtime_client.receive():
        match event.event_type:
            # receiving a piece of audio (and send it to a undefined audio player)
            case "audio":
                await audio_player.add_audio(event.audio)
            case "text":
                # the model returns both audio and transcript of the audio, which we will print
                print(event.text.text, end="")
            case "service":
                # OpenAI Specific events
                if event.service_type == ListenEvents.SESSION_UPDATED:
                    print("Session updated")
                if event.service_type == ListenEvents.RESPONSE_CREATED:
                    print("\nMosscap (transcript): ", end="")

Båda dessa exempel får ljudet som RealtimeAudioEvent och skickar sedan det till ett ospecificerat audio_player objekt.

Återanrop till ljudutdata

Bredvid detta har vi en parameter som heter audio_output_callback på metoden receive och när klassen skapas. Det här återanropet anropas först innan ytterligare hantering av ljudet och får en numpy matris med ljuddata, i stället för att den parsas till AudioContent och returneras som en RealtimeAudioEvent som du sedan kan hantera, vilket är vad som händer ovan. Detta har visat sig ge jämnare ljudutdata eftersom det är mindre overhead mellan ljuddata som tas emot och levereras till spelaren.

Det här exemplet visar hur du definierar och använder audio_output_callback:

from semantic_kernel.connectors.ai.open_ai import (
    ListenEvents,
    OpenAIRealtimeExecutionSettings,
    OpenAIRealtimeWebRTC,
)
from aiortc.mediastreams import MediaStreamTrack

class AudioRecorderWebRTC(MediaStreamTrack):
    # implement the MediaStreamTrack methods.

class AudioPlayer:
    async def play_audio(self, content: np.ndarray):
        # implement the audio player

realtime_client = OpenAIRealtimeWebRTC(audio_track=AudioRecorderWebRTC())
# Create the settings for the session
settings = OpenAIRealtimeExecutionSettings(
    instructions="""
You are a chat bot. Your name is Mosscap and
you have one goal: figure out what people need.
Your full name, should you need to know it, is
Splendid Speckled Mosscap. You communicate
effectively, but you tend to answer with long
flowery prose.
""",
    voice="shimmer",
)
audio_player = AudioPlayer
async with realtime_client(settings=settings, create_response=True):
    async for event in realtime_client.receive(audio_output_callback=audio_player.play_audio):
        match event.event_type:
            # no need to handle case: "audio"
            case "text":
                # the model returns both audio and transcript of the audio, which we will print
                print(event.text.text, end="")
            case "service":
                # OpenAI Specific events
                if event.service_type == ListenEvents.SESSION_UPDATED:
                    print("Session updated")
                if event.service_type == ListenEvents.RESPONSE_CREATED:
                    print("\nMosscap (transcript): ", end="")

Prover

Det finns fyra exempel i vår lagringsplats, de täcker både grunderna med både websockets och WebRTC, samt en mer komplex konfiguration, inklusive funktionsanrop. Slutligen finns det en mer komplex demo som använder Azure Communication Services så att du kan anropa ditt semantiska kernel-förbättrade realtids-API.