Eine Frage tippen und die Antwort lesen, so sprechen die meisten Anwendungen heute mit einem Sprachmodell. Die Realtime-APIs ändern das. OpenAI Realtime und Gemini Live nehmen die Stimme des Nutzers auf, während er spricht, und antworten mit einer eigenen Stimme, schnell genug, um ein Gespräch zu führen. Das von Hand zu bauen bedeutet, Audio in beide Richtungen zu streamen, zu entscheiden, wann der Nutzer fertig ist, den Agenten zu stoppen, wenn er unterbrochen wird, und mittendrin Tools auszuführen.
sgcWebSockets 2026.10 fügt TsgcAIVoiceAgent hinzu, eine einzige Komponente, die all das übernimmt. Sie hört zu, erkennt, wann der Nutzer einen Gesprächswechsel abgeschlossen hat, antwortet und ruft Ihre Tools auf. Sie ist für Delphi 7 bis 13 und für .NET verfügbar.
TsgcAIVoiceAgent in Aktion: Erkennung von Gesprächswechseln, Barge-in, Live-Transkripte und Tool-Aufrufe. Auch auf YouTube.
Schnellstart
Wählen Sie den Anbieter, setzen Sie den API-Schlüssel, eine Stimme und die Anweisungen, behandeln Sie OnTranscript und rufen Sie Start auf. Das ist bereits ein funktionierender Sprachassistent.
oVoice := TsgcAIVoiceAgent.Create(nil);
oVoice.Provider := vapOpenAI;
oVoice.OpenAIOptions.ApiKey := 'API_KEY';
oVoice.OpenAIOptions.Voice := 'alloy';
oVoice.Instructions := 'You are a friendly assistant. Answer briefly.';
oVoice.OnTranscript := oVoiceTranscript;
oVoice.OnError := oVoiceError;
oVoice.Start;
OnTranscript liefert Live-Transkripte beider Seiten des Gesprächs, des Nutzers und des Agenten, sodass der Bildschirm mitverfolgen kann, was gesagt wird:
procedure TForm1.oVoiceTranscript(Sender: TObject;
aRole: TsgcAIVoiceAgentRole; const aText: string; aFinal: Boolean);
begin
if aFinal then
begin
if aRole = varUser then
Memo1.Lines.Add('You: ' + aText)
else
Memo1.Lines.Add('Agent: ' + aText);
end;
end;
OpenAI Realtime oder Gemini Live, WebSocket oder WebRTC
Zwei Anbieter werden unterstützt, OpenAI Realtime und Gemini Live. Der Wechsel ist eine Eigenschaft und die passenden Optionen:
oVoice.Provider := vapGemini;
oVoice.GeminiOptions.ApiKey := 'GEMINI_API_KEY';
oVoice.Start;
Die Sitzung läuft über WebSocket. Mit OpenAI kann sie auch über WebRTC laufen:
oVoice.Provider := vapOpenAI;
oVoice.Transport := vatWebRTC;
oVoice.OpenAIOptions.ApiKey := 'API_KEY';
oVoice.Start;
Eingebautes Audio oder Ihr eigenes
Unter Windows, Android und iOS sind Mikrofon und Lautsprecher eingebaut, sodass der Schnellstart oben bereits alles ist, was Sie brauchen. Auf jeder anderen Plattform, oder wenn das Audio von woanders kommt, schalten Sie das Gerät ab. Ihre Anwendung liefert Audio mit SendAudio und empfängt die Antwort in OnAudioOutput.
oVoice.Audio.UseDevice := False;
oVoice.Audio.Format := vafPCM16;
oVoice.Audio.SampleRate := 16000;
oVoice.Start;
// ... 20 ms of PCM16 mono at 16 kHz = 640 bytes
SetLength(vChunk, 640);
FillChar(vChunk[0], Length(vChunk), 0);
oVoice.SendAudio(vChunk);
Den Anruf entgegennehmen
Die Telefonie spricht G.711, und der Sprachagent spricht es ebenfalls. Setzen Sie das Audioformat auf mu-law oder A-law bei 8 kHz, und die Bytes eines Anrufs gehen direkt hinein und direkt hinaus, ohne jede Umwandlung in Ihrem Code.
oVoice.Provider := vapOpenAI;
oVoice.OpenAIOptions.ApiKey := 'API_KEY';
oVoice.Instructions := 'You answer the phone of a restaurant and take bookings.';
oVoice.Audio.UseDevice := False;
oVoice.Audio.Format := vafG711ULaw;
oVoice.OnAudioOutput := oVoicePhoneAudioOutput;
oVoice.Start;
procedure TForm1.DoPhoneAudioReceived(const aData: TBytes);
begin
// ... G.711 mu-law, 8 kHz, as it arrives from the RTP stream of the call
oVoice.SendAudio(aData);
end;
procedure TForm1.oVoicePhoneAudioOutput(Sender: TObject;
const aData: TBytes);
begin
// ... already G.711 mu-law at 8 kHz: send it back to the caller
SendToPhone(aData);
end;
Erkennung von Gesprächswechseln
Die Erkennung von Gesprächswechseln entscheidet, wann der Nutzer zu sprechen aufgehört hat und der Agent antworten soll. Es gibt vier Modi.
- Server VAD lässt den Anbieter das Ende des Gesprächswechsels per Sprachaktivitätserkennung feststellen.
- Semantic VAD hört auf das, was gesagt wird, nicht nur auf Stille, sodass eine Pause mitten im Satz den Nutzer nicht abschneidet.
- Client VAD erkennt den Gesprächswechsel auf dem Client.
- Manual ist Push-to-Talk: Ihre Anwendung entscheidet, wo der Gesprächswechsel endet.
oVoice.TurnDetection.Mode := vtdServerVAD;
oVoice.TurnDetection.Threshold := 0.6;
oVoice.TurnDetection.PrefixPaddingMs := 300;
oVoice.TurnDetection.SilenceDurationMs := 700;
oVoice.TurnDetection.Mode := vtdSemanticVAD;
oVoice.TurnDetection.Eagerness := 'low';
Bei Push-to-Talk übergeben Sie das Audio und fordern eine Antwort an, sobald der Nutzer die Taste loslässt:
procedure TForm1.btnTalkMouseUp(Sender: TObject);
begin
// ... TurnDetection.Mode is vtdManual
oVoice.CommitAudio;
oVoice.CreateResponse;
end;
Barge-in
Menschen unterbrechen, und ein guter Sprachagent lässt sie das tun. Mit Barge-in stoppt der Agent das Sprechen, sobald der Nutzer zu sprechen beginnt, und die Antwort wird abgebrochen. Die Antwort wird zudem auf das gekürzt, was der Nutzer tatsächlich gehört hat, sodass der Gesprächsverlauf nicht behauptet, der Agent habe Worte gesagt, die nie abgespielt wurden.
oVoice.BargeIn := True;
oVoice.OnTurnStarted := oVoiceTurnStarted;
oVoice.OnTurnEnded := oVoiceTurnEnded;
oVoice.OnBargeIn := oVoiceBargeIn;
procedure TForm1.oVoiceBargeIn(Sender: TObject);
begin
Memo1.Lines.Add('The user interrupted the agent.');
end;
Tools
Ein Sprachagent wird nützlich, wenn er Dinge erledigen kann. Deklarieren Sie ein Tool mit einem Namen, einer Beschreibung und einem JSON-Schema für seine Parameter, und beantworten Sie es in OnToolCall.
procedure TForm1.StartWeatherAssistant;
var
oTool: TsgcAIVoiceAgentTool;
begin
oVoice.Provider := vapOpenAI;
oVoice.OpenAIOptions.ApiKey := 'API_KEY';
oVoice.Instructions := 'You are a weather assistant. ' +
'Call get_weather to know the weather of a city before answering.';
oVoice.Tools.Clear;
oTool := oVoice.Tools.Add;
oTool.Name := 'get_weather';
oTool.Description := 'Returns the current weather of a city.';
oTool.Parameters := '{"type":"object","properties":' +
'{"city":{"type":"string","description":"Name of the city"}},' +
'"required":["city"]}';
oVoice.OnToolCall := oVoiceWeatherToolCall;
oVoice.OnTranscript := oVoiceTranscript;
oVoice.Start;
end;
procedure TForm1.oVoiceWeatherToolCall(Sender: TObject;
const aCallId, aName, aArguments: string; var aResult: string;
var aHandled: Boolean);
var
oJSON: TsgcJSON;
vCity: string;
begin
if aName <> 'get_weather' then
Exit; // ... not mine: the MCP client, if any, gets the call
oJSON := TsgcJSON.Create(nil);
Try
oJSON.Read(aArguments);
vCity := '';
if Assigned(oJSON.Node['city']) then
vCity := oJSON.Node['city'].Value;
Finally
oJSON.Free;
End;
// ... replace with a call to your weather service
aResult := '{"city":"' + vCity + '","temperature":21,"sky":"clear"}';
aHandled := True;
end;
Tools können auch von einem MCP-Server kommen. Weisen Sie einen MCP-Client zu, und seine Tools werden dem Agenten automatisch angeboten:
oMCP := TsgcWSAPIClient_MCP.Create(nil);
oMCP.MCPOptions.HttpOptions.URL := 'https://localhost:5001/mcp';
oVoice.MCPClient := oMCP;
oVoice.Start;
Die Demo: ein Sprachassistent für einen Shop
Die Delphi-Demo in Demos\15.AI\02.Applications\09.VoiceAgent ist ein Shop-Assistent, mit dem Sie sprechen. Sie arbeitet mit einem Produktkatalog, der in einem TDataSet gehalten wird, und gibt dem Agenten vier Tools: find_products zum Durchsuchen des Katalogs, get_product zum Lesen eines Produkts, update_stock zum Ändern des Lagerbestands und count_low_stock zum Auflisten der Produkte, die nachbestellt werden müssen. Fragen Sie, was knapp wird, sagen Sie dann, ein Produkt soll nachbestellt werden, und beobachten Sie, wie sich das Raster ändert, während der Assistent antwortet.
Verfügbarkeit
TsgcAIVoiceAgent erscheint in sgcWebSockets 2026.10, für Delphi 7 bis 13 und für .NET, in der Edition Enterprise. Was sonst noch neu im Release ist, steht im Beitrag zu sgcWebSockets 2026.10, und die übrigen AI-Komponenten finden Sie auf der AI-Produktseite.
Weiterlesen
- KI-Dokumentenextraktion für Delphi und .NET, ebenfalls neu in 2026.10
- Ein Server-Sent-Events-Client für Delphi und .NET
Fragen oder Feedback? Nehmen Sie Kontakt auf. Sie erhalten eine Antwort von den Leuten, die den Code geschrieben haben.
