Udostępnij przez


API wielomodalne w czasie rzeczywistym

Dodano pierwszą integrację interfejsu API w czasie rzeczywistym dla jądra semantycznego, która jest obecnie dostępna tylko w języku Python i jest uznawana za eksperymentalną. To dlatego, że podstawowe usługi są nadal opracowywane i podlegają zmianom, co może wymagać wprowadzenia niekompatybilnych zmian w API w Semantic Kernel. Uczymy się od klientów, jak z tego korzystać, i dodajemy kolejnych dostawców tego rodzaju modeli i interfejsów API.

Abstrakcja klienta w czasie rzeczywistym

Aby obsługiwać różne interfejsy API w czasie rzeczywistym od różnych dostawców, używając różnych protokołów, do jądra dodano nową abstrakcję klienta. Ten klient służy do nawiązywania połączenia z usługą w czasie rzeczywistym i wysyłania i odbierania komunikatów. Klient jest odpowiedzialny za obsługę połączenia z usługą, wysyłanie komunikatów i odbieranie komunikatów. Klient jest również odpowiedzialny za obsługę wszelkich błędów występujących podczas połączenia lub wysyłania/odbierania komunikatów. Biorąc pod uwagę sposób działania tych modeli, można je traktować jako agenty bardziej niż zwykłe automatyczne odpowiedzi na czat; dlatego też realizują polecenia, zamiast reagować na komunikaty systemowe, zachowują swój własny stan wewnętrzny i mogą być wywoływane, aby wykonywać pracę w naszym imieniu.

Interfejs API czasu rzeczywistego

Każdy klient w czasie rzeczywistym implementuje następujące metody:

Metoda Opis
create_session Tworzy nową sesję
update_session Aktualizuje istniejącą sesję
delete_session Usuwa istniejącą sesję
receive Jest to metoda generatora asynchronicznego, która nasłuchuje komunikatów z usługi i przekazuje je w miarę ich otrzymywania.
send Wysyła komunikat do usługi

Implementacje języka Python

Wersja jądra semantycznego języka Python obsługuje obecnie następujących klientów w czasie rzeczywistym:

Klient Protokół Sposoby Wywoływanie funkcji jest włączone Opis
OpenAI Protokół Websocket Tekst i audio Tak Interfejs API OpenAI Realtime to API oparte na websocket, które umożliwia wymianę komunikatów w czasie rzeczywistym. To złącze używa pakietu OpenAI Python do łączenia się i wymiany komunikatów.
OpenAI WebRTC Tekst i audio Tak API OpenAI Realtime to interfejs oparty na protokole WebRTC, który umożliwia wysyłanie i odbieranie wiadomości w czasie rzeczywistym. Potrzebuje zgodnej z WebRTC ścieżki dźwiękowej podczas tworzenia sesji.
Azure Protokół WebSocket Tekst i audio Tak Interfejs API usługi Azure Realtime jest interfejsem API opartym na protokole websocket, który umożliwia wysyłanie i odbieranie komunikatów w czasie rzeczywistym. Korzysta to z tego samego pakietu co łącznik protokołu Websocket openAI.
Azure WebRTC Tekst i audio Tak Interfejs API usługi Azure Realtime jest interfejsem API opartym na protokole WebRTC, który umożliwia wysyłanie i odbieranie komunikatów w czasie rzeczywistym. Korzysta to z tego samego pakietu co łącznik OpenAI WebRTC.

Wprowadzenie

Aby rozpocząć pracę z interfejsem API czasu rzeczywistego, należy zainstalować semantic-kernel pakiet.

pip install semantic-kernel

W zależności od sposobu obsługi dźwięku może być konieczne użycie dodatkowych pakietów do interfejsu z głośnikami i mikrofonami, takimi jak pyaudio lub sounddevice.

Klienci protokołu Websocket

Następnie możesz utworzyć jądro i dodać do niego klienta czasu rzeczywistego. Pokazuje to, jak zrobić to za pomocą połączenia AzureRealtimeWebsocket, które można zastąpić na OpenAIRealtimeWebsocket bez konieczności żadnych dodatkowych zmian.

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

Istnieją dwie ważne kwestie, po pierwsze, że realtime_client jest menedżerem kontekstu asynchronicznego, oznacza to, że można go użyć w funkcji asynchronicznych i użyć async with do utworzenia sesji. Drugim jest to, że metoda receive jest generatorem asynchronicznym, co oznacza, że można jej użyć w pętli for do odbierania komunikatów, gdy nadejdą.

Klient WebRTC

Konfiguracja połączenia WebRTC jest nieco bardziej złożona i dlatego potrzebujemy dodatkowego parametru podczas tworzenia klienta. Ten parametr audio_track musi być obiektem implementujący protokół MediaStreamTrack pakietu aiortc. Przedstawiono to również w poniższych przykładach.

Aby utworzyć klienta korzystającego z usługi WebRTC, należy wykonać następujące czynności:

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

Obie próbki dźwiękowe odbierają dźwięk jako RealtimeAudioEvent, a następnie przekazują go do nieokreślonego obiektu audio_player.

Uwaga: Klient usługi Azure OpenAI WebRTC ma dodatkowy parametr: region, odnosi się to do regionu platformy Azure, w którym jest hostowana usługa OpenAI. Obecnie tylko eastus2 i swedencentral są obsługiwane.

Wywołanie zwrotne danych wyjściowych dźwięku

Obok tego mamy parametr o nazwie audio_output_callback w metodzie receive i podczas tworzenia klasy. Wywołanie zwrotne nastąpi jako pierwsze, przed dalszą obsługą dźwięku, i otrzyma tablicę danych audio numpy, zamiast być przetwarzane na AudioContent i zwracane jako RealtimeAudioEvent, które można następnie obsłużyć, co ma miejsce powyżej. To pokazało, że daje płynniejsze wyjście audio, ponieważ między danymi audio docierającymi i przekazywanymi do odtwarzacza jest mniejsze obciążenie.

W tym przykładzie pokazano, jak zdefiniować i użyć 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="")

Próbki

Istnieją cztery przykłady w repozytorium. Obejmują one zarówno podstawy korzystania z websockietów, jak i WebRTC, a także bardziej złożone ustawienia, w tym wywoływanie funkcji. Na koniec jest bardziej złożony pokaz, który korzysta z Azure Communication Services, aby umożliwić wywoływanie API czasu rzeczywistego wzbogaconego o jądro semantyczne.

Wkrótce

Więcej informacji można znaleźć wkrótce.

Wkrótce

Więcej informacji można znaleźć wkrótce.