Delphi Uygulamanızı Aracılara Hazırlayın

· Bileşenler
Delphi Uygulamanızı Aracılara Hazırlayın

Bir dil modeline soru sormak işin kolay kısmıdır. Bir aracı daha ileri gider. Model, işlevlerinizden hangisini çağıracağına karar verir, uygulamanız onları çalıştırır, sonuçlar modele geri gider ve döngü, model bir yanıta ulaşana kadar sürer. O döngüyü yazmak yalnızca başlangıçtır. Yayına verilen bir uygulamanın ayrıca modeli dokunmaması gereken şeylerden uzak tutması, kişisel verileri makinede bırakması, bir sağlayıcının bir modeli kullanımdan kaldırdığı güne dayanması ve her kullanıcının neye mal olduğunu bilmesi gerekir.

sgcWebSockets 2026.11, Delphi 7 ile 13 için sgcAI bileşenlerine bunların hepsinin parçalarını ekler:

Aracı Döngüsü Tek Bir Bileşende

Aracıya yapılandırılmış bir TsgcAIChat verin, bir aracı tanımlayın ve Run metodunu çağırın. Aracı, istemi araç tanımlarıyla birlikte gönderir, modelin istediği her aracı çalıştırır, sonuçları geri gönderir ve model düz metinle yanıtlayana kadar tekrarlar. Run bu yanıtı döndürür.

oChat := TsgcAIChat.Create(nil);
oChat.Provider := aicpAnthropic;
oChat.ChatOptions.ApiKey := 'API_KEY';
oChat.ChatOptions.Model := 'claude-opus-5-5';

oAgent := TsgcAIAgent.Create(nil);
oAgent.Chat := oChat;

oTool := oAgent.Tools.Add('get_weather', 'Current weather of a city');
oTool.AddParam('city', aatpString, 'City name');
oTool.ReadOnly := True;
oTool.OnExecute := DoGetWeather;

Memo1.Lines.Add(oAgent.Run('Do I need an umbrella in Paris today?'));

Araç, argümanlarını modelin yazdığı JSON nesnesi olarak alır ve sonucunu metin olarak, genellikle JSON olarak döndürür:

procedure TForm1.DoGetWeather(Sender: TObject; const aArguments: string;
  var aResult: string);
begin
  // aArguments is a JSON object, for example {"city":"Paris"}
  aResult := '{"city":"Paris","celsius":18,"sky":"rain"}';
end;

Aracı, artık her sağlayıcıda araç çağırmayı destekleyen TsgcAIChat.ChatWithTools üzerinde çalışır. Barındırılan bir modelden yerel bir Ollama modeline geçmek, Provider ve Model değerlerini değiştirmekten ibarettir, araçlar aynı kalır. Döngüyü kendiniz çalıştırmayı tercih ederseniz ChatWithTools ve AddToolResult de public'tir.

Döngüyü Denetleyin

Options.MaxSteps bir çalışmadaki model isteği sayısını sınırlar, Cancel bir çalışmayı bir düğmeden, bir zamanlayıcıdan veya başka bir iş parçacığından durdurur, StopReason ise çalışmanın neden bittiğini söyler. Bir yanıt belirteç sınırında kesilirse çalışma aasrMaxTokens ile durur ve bu yanıtın araç çağrıları, bağımsız değişkenleri eksik olabileceği için çalıştırılmaz. OnStep her adımı olduğu anda bildirir, böylece kullanıcı aracının ne yaptığını görebilir.

oAgent.Options.MaxSteps := 5;
oAgent.OnStep := oAgentStep;
vAnswer := oAgent.Run('Plan a three day trip to Rome');
case oAgent.StopReason of
  aasrCompleted:
    Memo1.Lines.Add(vAnswer);
  aasrMaxSteps:
    Memo1.Lines.Add('Stopped after 5 model requests');
  aasrMaxTokens:
    Memo1.Lines.Add('Cut by the token limit (' + oChat.LastFinishReason + ')');
  aasrCancelled:
    Memo1.Lines.Add('Cancelled');
end;
procedure TForm1.oAgentStep(Sender: TObject; const aStep: TsgcAIAgentStep);
begin
  case aStep.Kind of
    aaskToolCall:
      Memo1.Lines.Add('Calling ' + aStep.ToolName + ' ' + aStep.Arguments);
    aaskToolResult, aaskToolDenied:
      Memo1.Lines.Add(aStep.ToolName + ': ' + aStep.Content);
    aaskFinal:
      Memo1.Lines.Add('Answer: ' + aStep.Content);
  end;
end;

Başarısız olan bir araç çalışmayı bitirmez. İstisnası modele hata metni olarak geri gider ve model başka bir şey deneyebilir. Sohbetin kendi hatası, örneğin bir ağ arızası, çalışmayı aasrError ile bitirir ve istisna kodunuza ulaşır. OnUsage, çalışmadaki her model isteğinin belirteçlerini bildirir.

Delphi Metotlarınız Araç Olarak

Bir araç; bir ad, bir açıklama, tipli parametreler ve yukarıdaki gibi bir işleyiciden oluşur. İşi zaten yapan bir metodunuz varsa AddMethod onu olduğu gibi yayımlar. Araç adı metot adıdır; parametreler, tipleri ve sonuç genişletilmiş RTTI ile okunur, bu nedenle bunun için Delphi 2010 veya daha yenisi gerekir.

function TForm1.Forecast(const aCity: string; aDays: Integer): string;
begin
  Result := Format('%s: sunny for %d days', [aCity, aDays]);
end;
oAgent.Tools.AddMethod(Self, 'Forecast',
  'Weather forecast of a city for the next days');

Daha zengin bir girdiye sahip bir araç için InputSchema değerini kendi JSON şemanıza ayarlayın. Enabled, bir aracı kaldırmadan sonraki çalışmaların dışına çıkarır.

MCP Sunucularınızdaki Araçlar

MCPClients listesine bir veya daha fazla MCP istemcisi ekleyin; aracı, bu sunucuların araçlarını sizin araçlarınızın yanında sunar. Araçlar çalışma başına bir kez listelenir ve model istediğinde istemci üzerinden çağrılır. Sunucunun readOnlyHint ile işaretlediği bir araç salt okunur sayılır ve yerel bir araçla bir sunucu aracı aynı adı taşıyorsa yerel olan kazanır.

oMCP := TsgcWSAPIClient_MCP.Create(nil);
oMCP.MCPOptions.HttpOptions.URL := 'http://127.0.0.1:8080/mcp';
oAgent.MCPClients.Add(oMCP);

Memo1.Lines.Add(oAgent.Run('List the support tickets opened today'));

Bir Şey Değişmeden Önce Onay

Her aracın bir ReadOnly bayrağı vardır. Salt okunur araçlar model istediği anda çalışır. Veriyi değiştiren, e-posta gönderen veya para harcayan bir araç salt okunur değildir ve aracı, çalışmadan önce aracın adıyla ve modelin seçtiği tam argümanlarla OnToolApproval olayına sorar.

oTool := oAgent.Tools.Add('send_reminder', 'Sends a payment reminder');
oTool.AddParam('invoice', aatpString, 'Invoice number');
oTool.OnExecute := DoSendReminder; // ReadOnly is False: it changes data

oAgent.OnToolApproval := oAgentToolApproval;
procedure TForm1.oAgentToolApproval(Sender: TObject; const aToolName,
  aArguments: string; var aApproved: Boolean);
begin
  aApproved := MessageDlg('Run ' + aToolName + ' with ' + aArguments + '?',
    mtConfirmation, [mbYes, mbNo], 0) = mrYes;
end;

Reddedilen bir araç bir hata değildir. Modele aracın onaylanmadığı söylenir ve model kullanıcıya onsuz yanıt verebilir. Bir sonraki bölümdeki gibi guardrails atanmışsa, onay gerektiren ve işleyici bulamayan bir araç reddedilir, böylece unutulmuş bir olay yazan bir aracın geçmesine asla izin vermez.

Guardrails

TsgcAIGuardrails sohbete atadığınız ayrı bir bileşendir, böylece aynı kurallar hem aracıya hem de sıradan sohbet isteklerine uygulanır. Üç görevi vardır.

oGuard := TsgcAIGuardrails.Create(nil);
// tools: reading is allowed, deleting never
oGuard.AllowedTools.Add('get_*');
oGuard.AllowedTools.Add('list_*');
oGuard.AllowedTools.Add('send_reminder');
oGuard.DeniedTools.Add('*delete*');
oGuard.ToolApproval := aigaNotReadOnly;
// personal data never leaves the application
oGuard.PII.Enabled := True;
oGuard.PII.CustomPatterns.Add('EmployeeId=EMP-####');
// structured answers must match the schema
oGuard.Schema.Enabled := True;
oGuard.Schema.JSONSchema := '{"type":"object","properties":' +
  '{"price":{"type":"number","minimum":0}},"required":["price"]}';

oChat.Guardrails := oGuard;

Sağlayıcının ne alacağını ve uygulamanızın geri ne alacağını görmek için maskelemeyi kendiniz de çağırabilirsiniz:

vText := oGuard.Redact('Mail bob@example.com, call +34 600 111 222, ' +
  'employee EMP-1234');
// Mail [EMAIL_1], call [PHONE_1], employee [EMPLOYEEID_1]
vText := oGuard.Restore(vText);
// Mail bob@example.com, call +34 600 111 222, employee EMP-1234

MCP Sunucularınızın Araçlarını Sabitleyin

Bir MCP aracının açıklamasını ve girdi şemasını model talimat olarak okur. Güvendikten sonra bunları değiştiren bir sunucu, ister ele geçirildiği için ister sahibi değiştirdiği için, zaten kullandığınız bir araca yeni talimatlar gizleyebilir. Buna tool poisoning denir.

Araç sabitleme ile TsgcWSAPIClient_MCP, her aracı ilk kez listelediğinde adının, açıklamasının, girdi şemasının ve annotations bilgilerinin SHA-256 parmak izini tutar. Sonraki bir liste farklı bir tanım döndürürse araç engellenir. Listeden çıkarılır, aracı onu asla sunmaz ve ona yapılan bir çağrı hiçbir şey gönderilmeden önce bir istisna oluşturur. OnMCPToolChanged, değişikliği kabul etmenize veya aracı inceleme için engelli tutmanıza izin verir, sunucunun diğer araçları ise çalışmaya devam eder.

oMCP.MCPOptions.ToolPinning.Enabled := True;
oMCP.MCPOptions.ToolPinning.FileName := 'mcp_pins.json';
oMCP.OnMCPToolChanged := oMCPMCPToolChanged;
procedure TForm1.oMCPMCPToolChanged(Sender: TObject; const aToolName,
  aOldHash, aNewHash: string; var aAccept: Boolean);
begin
  // the definition of a trusted tool changed: keep it blocked
  // until somebody reviews it, then call oMCP.PinTool(aToolName)
  Memo1.Lines.Add('Tool ' + aToolName + ' changed, blocked for review');
  aAccept := False;
end;

Kullanımdan Kalkan Bir Model, Yayındaki Bir Exe'yi Durdurmaz

Model adları, kurulu uygulamalardan daha hızlı değişir. Bir exe'ye gömülmüş model adı, sağlayıcı onu kullanımdan kaldırdığı gün çalışmayı bırakır ve her müşterinin yeni bir derlemeye ihtiyacı olur. Model takma adlarıyla kod smart veya fast ister, takma ad ise modele ve isterseniz sağlayıcıya karar verir. Liste bir dosyadan, JSON'dan veya bir URL'den yüklenir, dolayısıyla yeni bir modele geçmek yeni bir sürüm değil, sunucunuzda yapılan bir değişikliktir.

oChat.ModelAliases.Add('fast=gpt-6-luna');
oChat.ModelAliases.Add('smart=anthropic:claude-opus-5-5');
oChat.ProviderApiKeys.Add('anthropic=ANTHROPIC_KEY');
oChat.ChatOptions.Model := 'smart';

// or keep the list on your server and change it without a new build
oChat.LoadModelAliasesFromURL('https://config.example.com/ai/models.json');

Fallback'ler kesintileri karşılar. Sağlayıcı bir bağlantı hatası, bir HTTP 5xx, bir HTTP 429 veya tanımadığı bir modelle başarısız olduğunda, aynı istek listedeki sıradaki sağlayıcıya ve modele gider. Konuşma geçmişi, araçlar ve JSON yanıtları taşınır, OnFallback ise bunun olduğunu bildirir. Yerel bir Ollama modeli iyi bir son çaredir.

oChat.Provider := aicpOpenAI;
oChat.ChatOptions.ApiKey := 'OPENAI_KEY';
oChat.ChatOptions.Model := 'gpt-6-luna';

oFallback := oChat.Fallbacks.Add;
oFallback.Provider := aicpGemini;
oFallback.Model := 'gemini-3-flash';
oFallback.ApiKey := 'GEMINI_KEY';

oFallback := oChat.Fallbacks.Add;
oFallback.Provider := aicpOllama;
oFallback.Model := 'llama3.1';

oChat.OnFallback := oChatFallback;
procedure TForm1.oChatFallback(Sender: TObject; const aFromProvider,
  aFromModel, aToProvider, aToModel, aError: string);
begin
  Memo1.Lines.Add(aFromProvider + ' ' + aFromModel + ' failed (' + aError +
    '), trying ' + aToProvider + ' ' + aToModel);
end;

Her İsteğin Maliyetini Bilin

TsgcAIUsageMeter, önbellekteki girdi belirteçleri dahil her isteğin belirteçlerini kaydeder, verdiğiniz fiyat listesiyle maliyetini hesaplar ve kullanıcı ile oturum başına toplamları tutar. Onu sohbete atayın ve UserId ile SessionId değerlerini ayarlayın. Ölçer sohbetin üzerinde durduğu için bir aracı çalışmasının her model isteği de sayılır.

oMeter := TsgcAIUsageMeter.Create(nil);
// example prices per million tokens, use the ones of your contract
oPrice := oMeter.Prices.Add;
oPrice.Provider := 'openai';
oPrice.Model := 'gpt-6*';
oPrice.InputPerMillion := 1.25;
oPrice.OutputPerMillion := 10;
oPrice.CachedPerMillion := 0.125;

oChat.UserId := 'user-1';
oChat.SessionId := 's-42';
oChat.UsageMeter := oMeter;
oChat.Chat('Hello');

Memo1.Lines.Add(Format('user-1 spent %.6f %s and %d tokens',
  [oMeter.TotalCost('user-1'), oMeter.Currency, oMeter.TotalTokens('user-1')]));

Fiyat listesi sağlayıcıyı ve modeli joker karakterlerle eşleştirir ve JSON'dan veya bir dosyadan yüklenebilir, dolayısıyla bir fiyat değişikliği de yeni bir derleme gerektirmez. Bütçeler ölçeri bir sınıra dönüştürür. Bir bütçe, tüm uygulamayı, her kullanıcıyı veya her oturumu; bir gün, bir ay veya toplam için; para veya belirteç cinsinden kapsayabilir. Bir bütçe tükendiğinde sonraki istek gönderilmeden önce reddedilir, dolayısıyla bir bütçe bir aracı çalışmasını yarı yolda da durdurabilir.

// every user can spend 2 USD a day
oBudget := oMeter.Budgets.Add;
oBudget.Scope := aubsUser;
oBudget.Period := aubpDay;
oBudget.MaxCost := 2;
// the whole application can spend 500 USD a month
oBudget := oMeter.Budgets.Add;
oBudget.Scope := aubsGlobal;
oBudget.Period := aubpMonth;
oBudget.MaxCost := 500;
try
  Memo1.Lines.Add(oAgent.Run('Remind every customer with an unpaid invoice'));
except
  on E: EsgcAIChat do
    // Usage budget "each user, day" for user-1 exceeded: ...
    Memo1.Lines.Add(E.Message);
end;

Yalnızca uyarı olarak OnBudgetExceeded tetikleyen bir bütçe için BlockWhenExceeded değerini False yapın. Raporlar için kayıtlar bir CSV dosyasına veya herhangi bir TDataSet bileşenine gider. OpenTelemetry etkinleştirildiğinde her istek, GenAI semantik kurallarına uyan bir span'e dönüşür ve sohbeti yavaşlatmadan arka planda OTLP/HTTP toplayıcınıza gider.

oMeter.OpenTelemetry.Endpoint := 'http://localhost:4318';
oMeter.OpenTelemetry.ServiceName := 'invoice-assistant';
oMeter.OpenTelemetry.Enabled := True;

oMeter.SaveToCSV('usage.csv');

Demo: Bir Fatura Asistanı

Demos\15.AI\02.Applications\11.AIAgent klasöründeki yeni Delphi demosu, ödenmemiş faturaların listesi için bir asistandır. Aracının üç aracı vardır. list_unpaid_invoices ve get_invoice salt okunurdur, send_reminder ise veriyi değiştirir ve önce onayınızı ister. Aracı bir arka plan iş parçacığında çalışır, böylece o çalışırken pencere yanıt vermeye devam eder. Demo, bu yazının geri kalanını da denemenize izin verir: yasaklı araçlar ve PII maskeleme, canlı belirteç ve maliyet sayacı ile CSV dışa aktarımı olan oturum başına bir bütçe, model takma adları, bir fallback sağlayıcısı ve araçları sabitlenmiş bir MCP sunucusu.

Kodlama Ajanınızın Okuyabileceği Dokümanlar

Bir kodlama ajanı yalnızca tanıdığı kütüphaneler için iyi kod yazar. sgcAI, sgcHTML, sgcCrypto ve diğer sgcWebSockets paketlerinin her bileşeninin artık dil modelleri için kendi Markdown sayfası var, toplam 224 sayfa. Her sayfa bileşenin ne yaptığını söyler ve ürün sayfasına bağlanır, çoğu da temel özelliklerini, metotlarını ve olaylarını listeler. TsgcAIAgent sayfası olan ai-agent.md ayrıca eksiksiz bir kullanım örneği içerir. llms.txt, Claude Code, Copilot, Cursor ve diğer ajanları bu sayfalara yönlendirir, böylece ajan tek satır yazmadan önce gerçek API'yi okur.

sgcWebSockets ajan becerileri de yeni bileşenleri öğrenir. 2026.11.0 sürümünün yapay zeka becerisinde araç döngüsü, araç onayı, guardrails, fallback'li model takma adları ve kullanım ölçer için hazır kalıplar vardır ve her kalıp derlenen koddan gelir. Delphi, C++Builder ve .NET için Yapay Zeka Ajan Becerileri bunların nasıl kurulacağını anlatır.

Kullanılabilirlik

TsgcAIAgent, TsgcAIGuardrails, TsgcAIUsageMeter, TsgcAIChat bileşeninin model takma adları ve fallback'leri ile MCP araç sabitleme, Delphi 7 ile 13 ve C++Builder için sgcWebSockets 2026.11.0 ile gelir. Bunlar sgcAI bileşenlerinin parçasıdır, Enterprise ve All-Access sürümlerine ve bağımsız sgcAI ürününe dahildir. Yardım, aracı döngüsü, araçlar, takma adlar ve fallback'ler, PII maskeleme, şema doğrulama ve araç sabitleme üzerine sayfalarla her özelliği, metodu ve olayı belgelendirir.

Daha fazlası için TsgcAIAgent, TsgcAIGuardrails ve TsgcAIUsageMeter bileşen sayfalarına bakın.

Sıradaki Okumalar

Sorularınız veya geri bildirimleriniz mi var? Bize ulaşın. Kodu yazan kişilerden yanıt alırsınız.