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.