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_callback
definieert 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.