Google Vertex AI über gRPC in Delphi

· Komponenten

Vertex AI ist die generative KI-Plattform von Google auf Google Cloud. Sie stellt die Gemini-Modelle über einen gRPC-PredictionService bereit, bei dem ein GenerateContent-Aufruf Ihren Prompt sendet und die Antwort des Modells zurückgibt. sgcWebSockets Enterprise liefert einen typisierten Vertex-AI-gRPC-Client, der auf TsgcGRPCClient aufsetzt, sodass Sie Gemini aus Delphi und C++Builder direkt über gRPC aufrufen können, ohne externe Laufzeitumgebung und ohne Protocol Buffers von Hand zusammenzustellen.

Wie es funktioniert

gRPC sind Protocol-Buffers-Nachrichten, die über HTTP/2 gerahmt werden, daher ist ein Vertex-AI-Aufruf ein HTTP/2-Request an den regionalen aiplatform.googleapis.com-Endpunkt. Der Transport ist ein TsgcHTTP2Client, der auf den Regions-Host an Port 443 mit aktiviertem TLS verweist, und TsgcGRPCClient übernimmt darauf das Framing, die Header, die Timeouts und die Trailer.

Der Vertex-AI-Helfer ist ein Satz typisierter Nachrichtenklassen in sgcGRPC_Google_VertexAI. Sie erstellen einen TsgcGRPCVertexAIGenerateContentRequest im Code, serialisieren ihn mit ToBytes, übergeben die Bytes dem gRPC-Client und laden dann die Antwort-Bytes zurück in einen TsgcGRPCVertexAIGenerateContentResponse. Der Request spiegelt das Vertex-AI-Schema wider: ein Request trägt einen Modell-Ressourcennamen und eine Liste von Contents, jeder Content hat eine Rolle und einen oder mehrere Parts, und ein Part hält entweder Text oder eingebettete Binärdaten.

Vertex AI verwendet die Google-Cloud-Dienstkonto-Authentifizierung. Der Client signiert ein Dienstkonto-JWT und sendet es als authorization: Bearer-Header in den gRPC-Metadaten, sodass jeder Aufruf gegen den regionalen Vertex-AI-Endpunkt authentifiziert wird.

Authentifizierung mit einem Dienstkonto

Der Google-Cloud-Client signiert ein selbstsigniertes Dienstkonto-JWT aus Ihrem Dienstkonto-JSON-Schlüssel. Dieses JWT ist audience-gebunden, es muss also auf den regionalen Vertex-AI-Endpunkt ausgerichtet sein, andernfalls weist aiplatform.googleapis.com es mit UNAUTHENTICATED ab. Sobald ein Token bezogen ist, fügen Sie es den DefaultMetadata des gRPC-Clients hinzu, sodass es bei jedem Aufruf mitreist.

uses
  sgcHTTP_Google_Cloud, sgcGRPC_Client;

// CloudClient is a TsgcHTTPGoogleCloud_PubSub_Client used here only to sign the JWT
CloudClient.GoogleCloudOptions.Authentication := gcaJWT;
CloudClient.GoogleCloudOptions.JWT.ClientEmail   := ClientEmail;
CloudClient.GoogleCloudOptions.JWT.PrivateKeyId  := PrivateKeyId;
CloudClient.GoogleCloudOptions.JWT.PrivateKey.Text := PrivateKey;
CloudClient.GoogleCloudOptions.JWT.ProjectId     := ProjectId;
CloudClient.GoogleCloudOptions.JWT.API_Endpoint  :=
  'https://' + Region + '-aiplatform.googleapis.com/';

// after the token arrives in OnAuthToken
GRPC.DefaultMetadata.Clear;
GRPC.DefaultMetadata.Add('authorization', 'Bearer ' + Token);

Den Transport einrichten

Erstellen Sie einen TsgcHTTP2Client für den regionalen Host und weisen Sie ihn dem gRPC-Client zu. Vertex AI spricht application/grpc+proto, belassen Sie den Channel-Content-Type also bei grpcProto.

uses
  sgcHTTP2_Client, sgcGRPC_Client, sgcGRPC_Types;

HTTP2 := TsgcHTTP2Client.Create(nil);
HTTP2.Host := Region + '-aiplatform.googleapis.com';   // e.g. us-central1-...
HTTP2.Port := 443;
HTTP2.TLS  := True;

GRPC := TsgcGRPCClient.Create(nil);
GRPC.Client := HTTP2;
GRPC.ChannelOptions.ContentType := grpcProto;
GRPC.ChannelOptions.Compression := grpcNoCompression;

HTTP2.Active := True;

Inhalt aus einem Prompt generieren

Erstellen Sie den Request aus den typisierten Nachrichtenklassen. Das Modell ist der vollständige Ressourcenname, der einzelne Content hat die user-Rolle, und der Prompt geht in einen Text-Part. Call blockiert, bis die Antwort eintrifft, und gibt ein TsgcGRPCResponse mit den rohen Data-Bytes zurück, die Sie in eine typisierte Response laden.

uses
  sgcGRPC_Client, sgcGRPC_Types, sgcGRPC_Google_VertexAI;

var
  oRequest: TsgcGRPCVertexAIGenerateContentRequest;
  oContent: TsgcGRPCVertexAIContent;
  oPart: TsgcGRPCVertexAIPart;
  oResponse: TsgcGRPCResponse;
begin
  oRequest := TsgcGRPCVertexAIGenerateContentRequest.Create;
  try
    oRequest.Model := 'projects/' + ProjectId + '/locations/' + Region +
      '/publishers/google/models/' + Model;   // e.g. gemini-2.0-flash

    oContent := oRequest.AddContent;
    oContent.Role := 'user';
    oPart := oContent.AddPart;
    oPart.Text := 'Explain gRPC in one sentence.';

    oResponse := GRPC.Call(
      'google.cloud.aiplatform.v1.PredictionService', 'GenerateContent',
      oRequest.ToBytes);

    if oResponse.StatusCode = grpcOK then
      ParseResponse(oResponse.Data)
    else
      ShowMessage('gRPC error: ' + oResponse.StatusMessage);
  finally
    oRequest.Free;
  end;
end;

Die Response auslesen

Laden Sie die Antwort-Bytes in einen TsgcGRPCVertexAIGenerateContentResponse. Er stellt die Candidates bereit, jeder mit seinen Content-Parts und einem Finish-Reason, sowie einen UsageMetadata-Block mit den Token-Zählungen für Prompt, Candidate und Gesamt.

procedure ParseResponse(const aData: TBytes);
var
  oResponse: TsgcGRPCVertexAIGenerateContentResponse;
  oCandidate: TsgcGRPCVertexAICandidate;
  i, j: Integer;
begin
  oResponse := TsgcGRPCVertexAIGenerateContentResponse.Create;
  try
    oResponse.LoadFromBytes(aData);
    for i := 0 to oResponse.CandidateCount - 1 do
    begin
      oCandidate := oResponse.Candidate(i);
      for j := 0 to oCandidate.Content.PartCount - 1 do
        Memo1.Lines.Add(oCandidate.Content.Part(j).Text);
    end;
    Memo1.Lines.Add('Total tokens: ' +
      IntToStr(oResponse.UsageMetadata.TotalTokenCount));
  finally
    oResponse.Free;
  end;
end;

Generierungskonfiguration und Sicherheitseinstellungen

Der Request trägt außerdem eine optionale GenerationConfig und eine Liste von Sicherheitseinstellungen. Verwenden Sie die Config, um Sampling und Länge zu steuern: Temperature, TopP, TopK, CandidateCount, MaxOutputTokens und StopSequences. Jede Sicherheitseinstellung paart eine Schadens-Category mit einem blockierenden Threshold.

oRequest.GenerationConfig.Temperature     := 0.7;
oRequest.GenerationConfig.MaxOutputTokens := 1024;
oRequest.GenerationConfig.StopSequences.Add('END');

with oRequest.AddSafetySetting do
begin
  Category  := 7;   // HARM_CATEGORY_DANGEROUS_CONTENT
  Threshold := 2;   // BLOCK_MEDIUM_AND_ABOVE
end;

Streaming-Responses

Vertex AI stellt außerdem StreamGenerateContent bereit, das Server-Streaming-Gegenstück, das die Antwort als Folge partieller Chunks statt als einen Block zurückgibt. Da der Vertex-AI-Helfer auf TsgcGRPCClient aufbaut, speist derselbe typisierte Request die Server-Streaming-API des Clients: Starten Sie den Aufruf, dekodieren Sie jeden Chunk in einen TsgcGRPCVertexAIGenerateContentResponse, sobald er eintrifft, und hängen Sie den Text aus dessen Candidates an, um die Benutzeroberfläche zu aktualisieren, während das Modell schreibt.

Verfügbarkeit

Der Vertex-AI-gRPC-Client ist Teil der sgcWebSockets Enterprise Edition. Ein sofort lauffähiges Beispiel befindet sich in Demos\21.GRPC\17.Vertex_AI: fügen Sie Ihren Dienstkonto-JSON-Schlüssel ein oder laden Sie ihn, setzen Sie Projekt, Region und Modell, verbinden Sie sich und senden Sie dann einen Prompt mit Generate Content. Die vollständige Referenz finden Sie auf der gRPC-Client-Produktseite.

Fragen oder Feedback? Nehmen Sie Kontakt auf. Sie erhalten eine Antwort von den Leuten, die den Code geschrieben haben.