DelphiでGemini APIを使用してAIと会話を行う(TRESTClient)
DelphiでGemini APIを使用してAIと会話する方法をサンプルソースコードで解説します。
過去最大5往復分(10個)の会話履歴を与えて会話のキャッチボールが出来ます。
Gemini APIキーの取得
Googleのアカウントを取得しログインします。 次に Google AI Studio にアクセスします。
https://aistudio.google.com/
左下の「Get API key」をクリックし、右上の「API キーを作成」をクリックするとAPIキーを作成することができます。
取得したGemini APIキーは Gemini Free Tier(無料版)ですので1日の回数や1分間の回数制限などがあります。
また無料版は会話の内容を学習に使われる可能性がありますので注意が必要です。
お支払方法を設定すると有料版に切り替わるようです。
フォームデザイン
IDEから[ファイル]⇒[新規作成]⇒[VLC フォーム アプリケーション - Delphi]を選択して新規プロジェクトを作成します。
TMemo × 2個、TButton × 1個、TRESTClient × 1個、TRESTRequest × 1個、TRESTResponse × 1個をドラッグ&ドロップします。
ソースコード
以下ソースコードを貼り付けた後、デザインビューの左ペインのオブジェクトインスペクタのイベントから
Button1.OnClick に Button1Click を設定します。
RESTRequest1.OnAfterExecute に RESTRequest1AfterExecute を設定します。
Form1.OnCreate に FormCreate を設定します。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IPPeerClient, Vcl.StdCtrls, REST.Client,
Data.Bind.Components, Data.Bind.ObjectScope;
type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
RESTClient1: TRESTClient;
RESTRequest1: TRESTRequest;
RESTResponse1: TRESTResponse;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure RESTRequest1AfterExecute(Sender: TCustomRESTRequest);
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
//会話の履歴を保存する変数
ConvArr:Array of String;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
const
//API Key を設定する
ApiKey:String='ここに上記で取得したAPIキーを貼り付けます';
//過去の会話履歴を最大何往復分送るか(ユーザー+モデルで1往復分)
ConvNum:Integer=5;
implementation
{$R *.dfm}
uses Rest.Types, System.JSON, System.JSON.Readers, System.JSON.Builders;
procedure TForm1.Button1Click(Sender: TObject);
var
Body, ContentObj, PartsObj: TJSONObject;
ContentsArr, PartsArr: TJSONArray;
JsonStr: String;
i,j:Integer;
begin
if Trim(Memo1.Text)='' then Exit;
//https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-lite:generateContent?key=
//のURLを設定する
RESTClient1.BaseURL:=
'https://generativelanguage.googleapis.com';
RESTRequest1.Resource:='v1beta/models';
RESTRequest1.ResourceSuffix:='gemini-3.1-flash-lite:generateContent?key='+ApiKey;
RestClient1.ContentType:='application/json';
RESTRequest1.Timeout:=60000;
Body := TJSONObject.Create;
try
ContentsArr := TJSONArray.Create;
//過去の会話履歴最大5往復分(ユーザー5個、モデル5個)を与える
if Length(ConvArr)>(ConvNum*2) then
j:=Length(ConvArr)-(ConvNum*2)
else
j:=0;
for i := j to High(ConvArr) do
begin
ContentObj := TJSONObject.Create;
if (i mod 2)=0 then
ContentObj.AddPair('role', 'user')
else
ContentObj.AddPair('role', 'model');
PartsObj := TJSONObject.Create;
PartsObj.AddPair('text', ConvArr[i]);
PartsArr := TJSONArray.Create;
PartsArr.AddElement(PartsObj);
ContentObj.AddPair('parts', PartsArr);
ContentsArr.AddElement(ContentObj);
end;
//今回の会話を与える
ContentObj := TJSONObject.Create;
ContentObj.AddPair('role', 'user');
PartsObj := TJSONObject.Create;
PartsObj.AddPair('text', Memo1.Text);
PartsArr := TJSONArray.Create;
PartsArr.AddElement(PartsObj);
ContentObj.AddPair('parts', PartsArr);
ContentsArr.AddElement(ContentObj);
Body.AddPair('contents', ContentsArr);
Body.AddPair('system_instruction',
TJSONObject.Create.AddPair('parts',
TJSONArray.Create(
TJSONObject.Create.AddPair(
'text',
//応答の仕方を与える。「IT専門家のように答えて」「広島弁で答えて」など
'マークアップを使わずプレーンテキストで返答してください。')
)
)
);
JsonStr:=Trim(Body.ToJSON());
finally
Body.Free; //親オブジェクトが子オブジェクトを破棄するので親だけ破棄
end;
RESTRequest1.Params.Clear;
RESTRequest1.ClearBody;
RESTRequest1.AddBody(JsonStr, TRESTContentType.ctAPPLICATION_JSON);
RESTRequest1.Method:=TRESTRequestMethod.rmPOST;
RESTRequest1.Execute;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
Memo2.Clear;
end;
procedure TForm1.RESTRequest1AfterExecute(Sender: TCustomRESTRequest);
var sr:TStringReader;
JsonTr:TJsonTextReader;
JsonIt:TJSONIterator;
st:String;
begin
//jv1:=TJsonObject.ParseJSONValue(RESTResponse1.Content);
sr:=TStringReader.Create(RESTResponse1.Content);
JsonTr:=TJsonTextReader.Create(sr);
JsonIt:=TJsonIterator.Create(JsonTr);
try
JsonIt.Next('candidates');
JsonIt.Recurse;//配列の中に入る
JsonIt.Next;
JsonIt.Recurse;//連想配列の中に入る
JsonIt.Next('content');
JsonIt.Recurse;//連想配列の中に入る
JsonIt.Next('parts');
JsonIt.Recurse;//配列の中に入る
while JsonIt.Next do
begin
JsonIt.Recurse;//連想配列の中に入る
JsonIt.Next('text');
//Memo2.Lines.Add(StringReplace(JsonIt.AsString,#10,#13#10,[rfReplaceAll]));
st:=AdjustLineBreaks(JsonIt.AsString);
JsonIt.Return;
end;
JsonIt.Return;
JsonIt.Return;
JsonIt.Return;
JsonIt.Return;
finally
JsonIt.Free;
JsonTr.Free;
sr.Free;
end;
SetLength(ConvArr,length(ConvArr)+1);
ConvArr[High(ConvArr)]:=Memo1.Text;
Memo2.Lines.Add(StringOfChar('■', 50));
Memo2.Lines.Add(ConvArr[High(ConvArr)]);
Memo2.Lines.Add(StringOfChar('■', 50));
SetLength(ConvArr,length(ConvArr)+1);
ConvArr[High(ConvArr)]:=st;
Memo2.Lines.Add(st);
end;
end.
実行
IDEから[実行]⇒[実行]を選択するとコンパイルされて実行されます。
Memo1にAIへの会話や質問を入力しButton1をクリックするとMemo2にGemini AIから応答があります。
