Vertex AI は Google Cloud 上の Google の生成 AI プラットフォームです。gRPC の PredictionService を通じて Gemini モデルを公開しており、GenerateContent 呼び出しがプロンプトを送信してモデルの回答を返します。sgcWebSockets Enterprise には TsgcGRPCClient の上に配置される型付き Vertex AI gRPC クライアントが付属しているため、外部ランタイムなしで、Protocol Buffers を手作業で組み立てることもなく、Delphi や C++Builder から gRPC 経由で直接 Gemini を呼び出せます。
仕組み
gRPC は HTTP/2 上でフレーミングされた Protocol Buffers メッセージなので、Vertex AI 呼び出しはリージョンの aiplatform.googleapis.com エンドポイントへの HTTP/2 リクエストです。トランスポートは、ポート 443 で TLS を有効にしてリージョンホストに向けた TsgcHTTP2Client で、その上で TsgcGRPCClient がフレーミング、ヘッダー、タイムアウト、トレーラーを処理します。
Vertex AI ヘルパーは、sgcGRPC_Google_VertexAI 内の型付きメッセージクラスのセットです。コードで TsgcGRPCVertexAIGenerateContentRequest を構築し、ToBytes でシリアライズし、そのバイト列を gRPC クライアントに渡し、レスポンスのバイト列を TsgcGRPCVertexAIGenerateContentResponse に読み戻します。リクエストは Vertex AI のスキーマを反映しています。リクエストはモデルリソース名とコンテンツのリストを持ち、各コンテンツはロールと 1 つ以上のパートを持ち、パートはテキストかインラインのバイナリデータのいずれかを保持します。
Vertex AI は Google Cloud サービスアカウント認証を使用します。クライアントはサービスアカウント JWT に署名し、それを gRPC メタデータの authorization: Bearer ヘッダーとして送信するので、すべての呼び出しがリージョンの Vertex AI エンドポイントに対して認証されます。
サービスアカウントによる認証
Google Cloud クライアントは、サービスアカウント JSON キーから自己署名のサービスアカウント JWT に署名します。その JWT はオーディエンスにバインドされるため、リージョンの Vertex AI エンドポイントを対象にする必要があります。そうしないと aiplatform.googleapis.com が UNAUTHENTICATED で拒否します。トークンが取得されたら、それを gRPC クライアントの DefaultMetadata に追加すると、すべての呼び出しに付随します。
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);
トランスポートのセットアップ
リージョンホスト用の TsgcHTTP2Client を作成し、それを gRPC クライアントに割り当てます。Vertex AI は application/grpc+proto を話すので、チャネルのコンテンツタイプは 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;
プロンプトからのコンテンツ生成
型付きメッセージクラスからリクエストを構築します。モデルは完全なリソース名で、唯一のコンテンツは user ロールを持ち、プロンプトはテキストパートに入ります。Call はレスポンスが届くまでブロックし、生の Data バイト列を持つ TsgcGRPCResponse を返します。これを型付きレスポンスに読み込みます。
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;
レスポンスの読み取り
レスポンスのバイト列を TsgcGRPCVertexAIGenerateContentResponse に読み込みます。これは候補を公開し、各候補はそのコンテンツパートと終了理由を持ち、加えてプロンプト、候補、合計のトークン数を持つ UsageMetadata ブロックも公開します。
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;
生成設定と安全性設定
リクエストは、省略可能な GenerationConfig と安全性設定のリストも持ちます。サンプリングと長さを制御するには設定を使います。Temperature、TopP、TopK、CandidateCount、MaxOutputTokens、StopSequences です。各安全性設定は、危害の Category とブロックする 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;
ストリーミングレスポンス
Vertex AI は StreamGenerateContent も公開しています。これはサーバーストリーミングの対応版で、回答を 1 つのブロックではなく一連の部分チャンクとして返します。Vertex AI ヘルパーは TsgcGRPCClient の上に構築されているため、同じ型付きリクエストがクライアントのサーバーストリーミング API に供給されます。呼び出しを開始し、到着するたびに各チャンクを TsgcGRPCVertexAIGenerateContentResponse にデコードし、その候補からテキストを追記して、モデルが書き進めるにつれて UI を更新します。
提供状況
Vertex AI gRPC クライアントは sgcWebSockets Enterprise エディションの一部です。すぐに実行できるサンプルは Demos\21.GRPC\17.Vertex_AI にあります。サービスアカウント JSON キーを貼り付けるか読み込み、プロジェクト、リージョン、モデルを設定し、接続してから、Generate Content でプロンプトを送信します。完全なリファレンスは gRPC Client 製品ページにあります。
ご質問やご意見はありますか? お問い合わせください。コードを書いた本人から返信いたします。
