5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DelphiからOllamaを使う

Last updated at Posted at 2024-12-06

Ollamaは,Hugging Faceなどで公開されている,大規模言語モデルをローカルのPCで動かすことができるツールです。MITライセンスで公開されています。

Delphi 12.2から追加されたスマート支援機能で,OllamaにCodellamaを導入して利用できるようになりました。
Ollamaの導入のしかたと,Delphiのスマート支援機能で利用するする方法については以下の記事でご確認いただければと思います。

OllamaはREST APIでロードした大規模言語モデルを利用できるので,Delphiのアプリで利用しようと思います。

OllamaにLlama3.2を導入

開発環境と同じPCにOllamaをインストールします。
OllamaをWindowsにインストールするには,https://ollama.com/よりOllamaSetup.exeをダウンロードして実行します。
Ollamaのインストール後,以下をコマンドプロンプトより実行し,大規模言語モデルLlama3.2をインストールします。

コマンドプロンプト
> ollama run llama3.2

OllamaのAPIを調べる

OllamaのAPIのドキュメントから大規模言語モデルに質問するAPIを調べます。

これによると,ストリーミングしないリクエストは

curl http://localhost:11434/api/generate -d '{
  "model": "llama3.2",
  "prompt": "Why is the sky blue?",
  "stream": false
}'

で,結果は以下のように返ってくると書かれています。
ポート番号は11434で,modelにolammaへ導入した大規模言語モデル名を,promptに質問内容を書けば良いようです。

{
  "model": "llama3.2",
  "created_at": "2023-08-04T19:22:45.499127Z",
  "response": "The sky is blue because it is the color of the sky.",
  "done": true,
  "context": [1, 2, 3],
  "total_duration": 5043500667,
  "load_duration": 5025959,
  "prompt_eval_count": 26,
  "prompt_eval_duration": 325953000,
  "eval_count": 290,
  "eval_duration": 4709213000
}

responseに返答があるのでそれを取り出せればよいようです。

RAD Studio の RESTデバッガ を利用する

Delphiを起動して メインメニューーツールーRESTデバッガ を選択します。
Snap0000.png

要求の入力

Snap0001.png
上記の要求ペインの要求タブで,上記の情報を以下のように入力します。

メソッド: POST
URL: http://localhost:11434/api/generate
コンテンツタイプ: applicaiton/json
カスタム本体

{
  "model": "llama3.2",
  "prompt": "Why is the sky blue?",
  "stream": false
}

要求を送信

「要求の送信」 ボタンをクリックすると,Ollamaに送信され,以下のように結果が返ってきます。

{
    "model": "llama3.2",
    "created_at": "2024-12-01T07:16:24.9383655Z",
    "response": "The sky appears blue because of a phenomenon called Rayleigh scattering, named after the British physicist Lord Rayleigh, who first described it in the late 19th century.\n\nHere's what happens:\n\n1. **Sunlight enters Earth's atmosphere**: When sunlight enters our atmosphere, it consists of a spectrum of colors, including all the colors of the visible light spectrum (red, orange, yellow, green, blue, indigo, and violet).\n2. **Light scatters off tiny molecules**: The shorter wavelengths of light (like blue and violet) are more easily scattered by the tiny molecules of gases in the atmosphere, such as nitrogen and oxygen.\n3. **Blue light is scattered in all directions**: As a result of this scattering, the blue light is distributed throughout the atmosphere, reaching our eyes from all parts of the sky.\n4. **Other colors continue straight**: The longer wavelengths of light (like red and orange) are less affected by the scattering and continue to travel in a straight line, reaching our eyes from the direction of the sun.\n\nSince we're typically looking at the sky in the daytime when the sun is overhead, the blue light is scattered all around us, making the sky appear blue. The exact shade of blue can vary depending on factors like atmospheric conditions, pollution levels, and time of day.\n\nIn summary, the sky appears blue because of the scattering of shorter wavelengths (blue light) by tiny molecules in the atmosphere, while longer wavelengths (other colors) continue straight to our eyes from the direction of the sun.",
    "done": true,
    "done_reason": "stop",
    "context": [
        128006,
・・・中略・・・
        7160,
        13
    ],
    "total_duration": 2398489800,
    "load_duration": 29612900,
    "prompt_eval_count": 31,
    "prompt_eval_duration": 2000000,
    "eval_count": 310,
    "eval_duration": 2361000000
}

「コンポーネントのコピー」ボタンをクリックします。

なお,RESTデバッガツールの詳しい使い方については以下で確認できます。

DelphiでRESTクライアントを作成する

RESTデバッガ でコピーしたコンポーネントを,Delphiで利用しましょう。
Delphiを起動してVCLの新規プロジェクトを作成し,以下のようにフォームに Edit1(TEdit),Memo1(TMemo),Button1(TButton)を配置して,コピーしたコンポーネントをペーストします。
Snap0016.png

コードタブを表示して,JSONのシリアライズとデシリアライズをする関数を作成します。

Unit1.pas
uses
  System.JSON.Types, System.JSON.Serializers; // JsonSerializer に必要
  
function OllamaGenerateRequestJSON(AModel,APrompt:string):string;
// generateでリクエストするJSONのテキストを出力する
type
  TOllamaGenerateRequest=record
    model:string;
    prompt:string;
    stream:boolean;
  end;
var
  OllamaGenerateRequest: TOllamaGenerateRequest;
begin
  OllamaGenerateRequest.model  := AModel;
  OllamaGenerateRequest.prompt := APrompt;
  OllamaGenerateRequest.stream := False;
  var JsonSerializer := TJsonSerializer.Create;
  try
    JsonSerializer.Formatting := TJsonFormatting.Indented;
    Result := 
      JsonSerializer.Serialize<TOllamaGenerateRequest>(OllamaGenerateRequest);
  finally
    JsonSerializer.Free;
  end;
end;

function OllamaGenerateResponseJSON(AContent:string):string;
// generateでリクエストするJSONのテキストを出力する
type
  TOllamaGenerateResponse=record
    response:string;
  end;
begin
  var JsonSerializer := TJsonSerializer.Create;
  var JSONResponse   := 
    JsonSerializer.Deserialize<TOllamaGenerateResponse>(AContent);
  Result := JSONResponse.response;
  JsonSerializer.Free;
end;

フォームデザイナに戻し,Button1をクリックして,OnClickイベントを以下のように記述します。

Unit1.pas
procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    RESTRequest1.Params[0].Value:=
      OllamaGenerateRequestJSON('llama3.2:latest',Edit1.Text);
    RESTRequest1.Execute;
    Memo1.Text:=OllamaGenerateResponseJSON(RESTResponse1.Content);
  finally
  end;
end;

完成したプログラムを実行し,Edit1に質問を入力してButton1をクリックすると,Ollamaを介してLlama3.2が返事をしてくれます。
Snap0017.png

補足

RESTデバッガからコピーされるコンポーネントの情報はそれほど多くないので,手順を自前で書いたり,スレッド化すれば,より使いやすくなると思います。

また,OllamaのAPIにはオプションを使って返事を同じにするためSeedを指定したり,コンテキストウインドウをどのくらい利用したかなどの情報も取得できます。履歴をもって会話するAPI(Chat)もありますので,これらを使えばもっと便利なRESTクライアントが作れるのではないかと思います。

謝辞

この記事を書くにあたって,@ht_deko
(Hideaki Tominaga)さんの記事や,@pik(Jun HOSOKAWA)さんの記事が大変参考になりました。感謝します。

また,コードに問題があるようでしたらご指摘いただけるとありがたいです。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?