DifyでOllamaを使う(2) - 考えるエンジニア
FC2ブログ

DifyでOllamaを使う(2)

 今回は、OllamaでインストールしたローカルLLMをDifyのAPIを使う試みです。

以下の順でお話しします。
 1. Dify上でのAPI利用の準備
 2. PythonプログラムからのAPI利用
 3. curlコマンドからの利用
 4. .NET8(C#)プログラムからのAPI利用

 Ollama、Difyは前回のブログでお話ししたUbuntu Server(本体はRaspberry Pi 5)で実行しました。

1. Dify上でのAPI利用の準備
 APIはモデルプロバイダに登録したモデルのgemma2:2bを利用しました。Dify_API_setup1_241102.pnggemma2:2bを使ったチャットボットを作成した後に、スタジオの「公開する」から「APIリファレンスにアクセス」をクリックし、Dify_API_setup2_241102.png「APIキー」ボタンを押しました。ここで、APIがアクセスするBase URLが「http://192.168.11.11/v1」と表示されていることを確認。Dify_API_setup3_241102.png「+新しいシークレットキーを作成」をクリックすると、Dify_API_setup4_241102.pngAPIシークレットキーが作成されました。キーは紛失しないようにコピーして保管しました。「OK」ボタンを押すとDify_API_setup5_241102.png登録されていることが確認できました。Dify_API_setup6_241102.pngAPI実行に必要なBase URLとAPIシークレットキーが作成されたので、準備完了です。

2. PythonプログラムからのAPI利用
 1.で準備をしたBase URLとAPIシークレットキーを使って、PythonプログラムからAPIを利用しました。プログラムは以下の通りです。
import requests
import json

# APIキーとベースURLの設定
API_KEY = 'My-API-Key'
BASE_URL = 'http://192.168.11.11/v1'

# ヘッダーの設定
headers = {
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
}

# 質問を送信する関数
def send_question(query, user, conversation_id=None):
url = f'{BASE_URL}/chat-messages'

# リクエストボディの作成
data = {
'query': query,
'inputs': {},
'response_mode': 'blocking',
'user': user,
'auto_generate_name': True
}

if conversation_id:
data['conversation_id'] = conversation_id

# リクエストの送信
response = requests.post(url, headers=headers, json=data)
return response.json()

# 使用例
if __name__ == "__main__":
query = "日本の新幹線について教えてください。"
user = "DrBobT"

response = send_question(query, user)

print("Message ID: ", response.get('message_id'))
print("Conversation ID: ", response.get('conversation_id'))
print("Answer: ", response.get('answer'))
print("Retriever Resources: ", json.dumps(response.get('metadata', {}).get('retriever_resources'), indent=2, ensure_ascii=False))
実行結果は以下の通りです。正常に動作しました。Dify_API_run1_241102.png3. curlコマンドからの利用
 curlコマンドはMacMiniからUbuntu Server(本体はRaspberry Pi 5)に投げることで実行しました。response_modeとして、結果が全て取得できて表示をする「blocking」と、結果を逐次表示しながら表示する「streaming」があります。
 まずは「blocking」モードです。実行結果は以下の通り。Dify_API_run2_241102.png「{ "event": 」以降が回答です。分かりにくいので整頓すると、Dify_API_run3_241102.png赤枠の部分が回答の内容であることが分かります。Unicodeで返ってきているので、文字変換をすると正しく会話ができていることが分かりました。Dify_API_run4_241102.png 次に「streaming」モードです。実行させると、画面に文字が立て続けに出力されました。Dify_API_run5_241102.png詳細を見ると、赤枠部分が回答となりますが、細切れに入っていることが分かりました。Dify_API_run6_241102.pngこの回答もUnicodeなので、変換すると、結果は以下の通りで、問題ないことが分かりました。Dify_API_run7_241102.png
4. .NET8(C#)プログラムからのAPI利用
 2.のPythonプログラムをGPT-4oでC#にしてもらいました。プログラムは以下の通り。
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

class Program
{
private static readonly string ApiKey = "My-API-Key";
private static readonly string BaseUrl = "http://192.168.11.11/v1";

static async Task Main(string[] args)
{
string query = "こんにちは";
string user = "DrBobT";

var response = await SendQuestionAsync(query, user);

Console.WriteLine("Message ID: " + response["message_id"]);
Console.WriteLine("Conversation ID: " + response["conversation_id"]);
Console.WriteLine("Answer: " + response["answer"]);
Console.WriteLine("Retriever Resources: " + response["metadata"]?["retriever_resources"]?.ToString(Formatting.Indented) ?? "N/A");
}

public static async Task<JObject> SendQuestionAsync(string query, string user, string? conversationId = null)
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ApiKey);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

string url = $"{BaseUrl}/chat-messages";

var data = new
{
query = query,
inputs = new { },
response_mode = "blocking",
user = user,
auto_generate_name = true,
conversation_id = conversationId
};

string jsonData = JsonConvert.SerializeObject(data);
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");

HttpResponseMessage response = await client.PostAsync(url, content);

if (response.IsSuccessStatusCode)
{
string result = await response.Content.ReadAsStringAsync();
return JObject.Parse(result);
}
else
{
throw new Exception($"Error: {response.StatusCode}");
}
}
}
}
結果も問題なしでした。Dify_API_run8_241102.png
 今回、OllamaでインストールしたローカルLLMをDifyのAPIを使って利用できることが分かりました。WebAPIなのでPython、C#のどちらからも利用できるのが良いですね。何かに使っていこうと思います。

コメント

非公開コメント

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

Author: Dr.BobT
興味のおもむくままに生涯考え続けるエンジニアでありたい。

月別アーカイブ

メールフォーム

名前:
メール:
件名:
本文: