Delen via


Realtime Multimodale API's

De eerste realtime-API-integratie voor Semantic Kernel is toegevoegd, deze is momenteel alleen beschikbaar in Python en wordt beschouwd als experimenteel. Dit komt doordat de onderliggende services nog steeds worden ontwikkeld en onderhevig zijn aan wijzigingen en we moeten mogelijk belangrijke wijzigingen aanbrengen in de API in Semantic Kernel, omdat we van klanten leren hoe ze dit kunnen gebruiken en omdat we andere providers van dit soort modellen en API's toevoegen.

Realtime clientabstractie

Ter ondersteuning van verschillende realtime API's van verschillende leveranciers, met behulp van verschillende protocollen, is er een nieuwe clientabstractie toegevoegd aan de kernel. Deze client wordt gebruikt om verbinding te maken met de realtimeservice en berichten te verzenden en te ontvangen. De client is verantwoordelijk voor het afhandelen van de verbinding met de service, het verzenden van berichten en het ontvangen van berichten. De client is ook verantwoordelijk voor het afhandelen van eventuele fouten die optreden tijdens het verzenden/ontvangen van een verbinding of bericht. Gezien de manier waarop deze modellen werken, kunnen ze meer worden beschouwd als agenten dan als reguliere chatvoltooiingen. Ze kunnen instructies aannemen in plaats van een systeembericht en behouden hun eigen interne status. Bovendien kunnen ze namens ons worden aangeroepen om taken uit te voeren.

Realtime-API

Elke realtime-client implementeert de volgende methoden:

Methode Beschrijving
create_session Hiermee maakt u een nieuwe sessie
update_session Een bestaande sessie bijwerken
delete_session Hiermee verwijdert u een bestaande sessie
receive Dit is een asynchrone generatormethode die luistert naar berichten van de service en deze oplevert wanneer ze binnenkomen.
send Een bericht naar de service verzenden

Python-implementaties

De Python-versie van Semantic Kernel ondersteunt momenteel de volgende realtime-clients:

Klant Protocol Modaliteiten Functie aanroepen ingeschakeld Beschrijving
OpenAI Websocket Tekst & Audio Ja De OpenAI Realtime-API is een websocket-API waarmee u berichten in realtime kunt verzenden en ontvangen. Deze connector maakt gebruik van het OpenAI Python-pakket om verbinding te maken en berichten te ontvangen en te verzenden.
OpenAI WebRTC Tekst & Audio Ja De OpenAI Realtime-API is een WebRTC-API waarmee u berichten in realtime kunt verzenden en ontvangen. Er is een webRTC-compatibel audiospoor nodig tijdens het maken van sessies.
Azuur Websocket Tekst & Audio Ja De Azure Realtime-API is een websocket-API waarmee u berichten in realtime kunt verzenden en ontvangen. Hierbij wordt hetzelfde pakket gebruikt als de OpenAI-websocket-connector.

Aan de slag

Als u aan de slag wilt met de Realtime-API, moet u het semantic-kernel-pakket installeren met de realtime extra.

pip install semantic-kernel[realtime]

Afhankelijk van hoe u audio wilt verwerken, hebt u mogelijk extra pakketten nodig voor interface met luidsprekers en microfoons, zoals pyaudio of sounddevice.

Websocket clients

Vervolgens kunt u een kernel maken en de realtime-client eraan toevoegen. Dit laat zien hoe u dit doet met een AzureRealtimeWebsocket-verbinding. U kunt AzureRealtimeWebsocket vervangen door OpenAIRealtimeWebsocket zonder verdere wijzigingen.

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="")

Er zijn twee belangrijke dingen die u moet weten: de eerste is dat de realtime_client een asynchrone contextbeheerder is. Dit betekent dat u deze kunt gebruiken in een asynchrone functie en async with kunt gebruiken om de sessie te maken. De tweede is dat de methode receive een asynchrone generator is. Dit betekent dat u deze in een for-lus kunt gebruiken om berichten te ontvangen wanneer ze binnenkomen.

WebRTC-client

De installatie van een WebRTC-verbinding is iets complexer en daarom hebben we een extra parameter nodig bij het maken van de client. Deze parameter moet audio_track een object zijn dat het MediaStreamTrack protocol van het aiortc-pakket implementeert. Dit wordt ook gedemonstreerd in de voorbeelden die hieronder zijn gekoppeld.

Als u een client wilt maken die gebruikmaakt van WebRTC, doet u het volgende:

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="")

Beide voorbeelden ontvangen de audio als RealtimeAudioEvent en vervolgens geven ze dit door aan een niet-opgegeven audio_player-object.

Callback van audio-uitvoer

Naast deze hebben we een parameter met de naam audio_output_callback op de methode receive en bij het maken van de klasse. Deze callback wordt eerst aangeroepen voordat de audio verder wordt verwerkt en een numpy matrix van de audiogegevens krijgt, in plaats van dat deze wordt geparseerd in AudioContent en wordt geretourneerd als een RealtimeAudioEvent die u vervolgens kunt afhandelen, wat hierboven gebeurt. Dit heeft aangetoond dat het vloeiendere audio-uitvoer geeft, omdat er minder overhead is tussen de audiogegevens die binnenkomen en aan de speler worden gegeven.

In dit voorbeeld ziet u hoe u de audio_output_callbackdefinieert en gebruikt:

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="")

Voorbeelden

Er zijn vier voorbeelden in onze opslagplaats, ze hebben betrekking op de basisbeginselen met zowel websockets als WebRTC, evenals een complexere installatie, waaronder functieoproepen. Ten slotte is er een meer complexe demo- die gebruikmaakt van Azure Communication Services-, zodat u uw Semantische Kernel verbeterde realtime-API kunt aanroepen.