Bir soru yazıp cevabı okumak, bugün çoğu uygulamanın bir dil modeliyle konuşma şeklidir. Gerçek zamanlı API'ler bunu değiştiriyor. OpenAI Realtime ve Gemini Live, kullanıcının sesini söylendiği anda alır ve bir sohbeti sürdürecek kadar hızlı, kendi sesleriyle cevap verir. Bunu elle yapmak, sesi her iki yönde de akıtmak, kullanıcının ne zaman bitirdiğine karar vermek, aracı yarıda kesildiğinde durdurmak ve bütün bunların ortasında araçları çalıştırmak anlamına gelir.
sgcWebSockets 2026.10, tüm bunları yapan tek bir bileşen olan TsgcAIVoiceAgent'ı ekliyor. Dinler, kullanıcının bir turu bitirdiğini algılar, cevap verir ve araçlarınızı çağırır. Delphi 7'den 13'e ve .NET için mevcuttur.
TsgcAIVoiceAgent iş başında: tur algılama, barge-in, canlı transkriptler ve araç çağrıları. YouTube'da da izleyin.
Hızlı Başlangıç
Sağlayıcıyı seçin, bir API anahtarı, bir ses ve talimatları ayarlayın, OnTranscript'i işleyin ve Start'ı çağırın. Bu, çalışan bir sesli asistan demektir.
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, sohbetin her iki tarafının, kullanıcının ve aracının, canlı transkriptlerini iletir, böylece ekran söylenenleri takip edebilir:
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 veya Gemini Live, WebSocket veya WebRTC
İki sağlayıcı destekleniyor, OpenAI Realtime ve Gemini Live. Geçiş, tek bir özellik ve karşılık gelen seçeneklerden ibarettir:
oVoice.Provider := vapGemini;
oVoice.GeminiOptions.ApiKey := 'GEMINI_API_KEY';
oVoice.Start;
Oturum WebSocket üzerinden çalışır. OpenAI ile WebRTC üzerinden de çalışabilir:
oVoice.Provider := vapOpenAI;
oVoice.Transport := vatWebRTC;
oVoice.OpenAIOptions.ApiKey := 'API_KEY';
oVoice.Start;
Yerleşik Ses veya Kendi Sesiniz
Windows, Android ve iOS'ta mikrofon ve hoparlör yerleşiktir, bu yüzden yukarıdaki hızlı başlangıç tek ihtiyacınız olandır. Başka herhangi bir platformda, ya da ses başka bir yerden geldiğinde, cihazı kapatın. Uygulamanız SendAudio ile ses gönderir ve cevabı OnAudioOutput içinde alır.
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);
Telefona Cevap Vermek
Telefon hatları G.711 konuşur, sesli aracı da öyle. Ses formatını 8 kHz'de mu-law veya A-law olarak ayarlayın, bir aramanın baytları kodunuzda hiçbir dönüşüm olmadan doğrudan girer ve doğrudan çıkar.
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;
Tur Algılama
Tur algılama, kullanıcının konuşmayı bitirdiği ve aracının cevap vermesi gereken anı belirler. Dört mod vardır.
- Server VAD, sağlayıcının turun sonunu ses etkinliği algılamasıyla tespit etmesini sağlar.
- Semantic VAD, yalnızca sessizliği değil, söylenenleri dinler, böylece bir cümlenin ortasındaki bir duraklama kullanıcının sözünü kesmez.
- Client VAD, turu istemci tarafında algılar.
- Manual, bas-konuş yöntemidir: uygulamanız turun nerede bittiğine karar verir.
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';
Bas-konuş yönteminde, kullanıcı düğmeyi bıraktığında sesi commit edin ve bir cevap isteyin:
procedure TForm1.btnTalkMouseUp(Sender: TObject);
begin
// ... TurnDetection.Mode is vtdManual
oVoice.CommitAudio;
oVoice.CreateResponse;
end;
Barge-in
İnsanlar sözü keser, iyi bir sesli aracı da buna izin verir. Barge-in ile, kullanıcı konuşmaya başladığında aracı konuşmayı durdurur ve cevap iptal edilir. Cevap ayrıca kullanıcının gerçekten duyduğu kısma kadar kısaltılır, böylece konuşma geçmişi, aracının hiç çalınmamış sözler söylediğini iddia etmez.
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;
Araçlar
Bir sesli aracı, bir şeyler yapabildiğinde faydalı hale gelir. Bir isim, bir açıklama ve parametreleri için bir JSON şeması ile bir araç tanımlayın ve OnToolCall içinde cevaplayın.
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;
Araçlar bir MCP sunucusundan da gelebilir. Bir MCP istemcisi atayın, araçları otomatik olarak aracıya sunulur:
oMCP := TsgcWSAPIClient_MCP.Create(nil);
oMCP.MCPOptions.HttpOptions.URL := 'https://localhost:5001/mcp';
oVoice.MCPClient := oMCP;
oVoice.Start;
Demo: Bir Sesli Mağaza Asistanı
Demos\15.AI\02.Applications\09.VoiceAgent içindeki Delphi demosu, konuştuğunuz bir mağaza asistanıdır. Bir TDataSet içinde tutulan bir ürün kataloğu üzerinde çalışır ve aracıya dört araç verir: kataloğu aramak için find_products, bir ürünü okumak için get_product, stoğu değiştirmek için update_stock ve yeniden stoklanması gereken ürünleri listelemek için count_low_stock. Neyin azaldığını sorun, ardından bir ürünü yeniden stoklamasını söyleyin ve cevap verirken tablonun nasıl değiştiğini izleyin.
Kullanılabilirlik
TsgcAIVoiceAgent, Delphi 7'den 13'e ve .NET için, sgcWebSockets 2026.10 ile Enterprise sürümünde geliyor. Bu sürümdeki diğer yenilikler sgcWebSockets 2026.10 yazısında, yapay zeka bileşenlerinin geri kalanı ise Yapay Zeka ürün sayfasında.
Devamını Okuyun
- Delphi ve .NET için Yapay Zeka ile Belge Çıkarma, 2026.10'da da yeni
- Delphi ve .NET İçin Bir Server-Sent Events İstemcisi
Sorularınız veya geri bildiriminiz mi var? Bizimle iletişime geçin. Kodu yazan kişilerden bir yanıt alacaksınız.
