2024/11/02
今回は、
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を利用しました。
gemma2:2bを使ったチャットボットを作成した後に、スタジオの「公開する」から「APIリファレンスにアクセス」をクリックし、
「APIキー」ボタンを押しました。ここで、APIがアクセスするBase URLが「http://192.168.11.11/v1」と表示されていることを確認。
「+新しいシークレットキーを作成」をクリックすると、
APIシークレットキーが作成されました。キーは紛失しないようにコピーして保管しました。「OK」ボタンを押すと
登録されていることが確認できました。
API実行に必要な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))
実行結果は以下の通りです。正常に動作しました。
3. curlコマンドからの利用 curlコマンドはMacMiniからUbuntu Server(本体はRaspberry Pi 5)に投げることで実行しました。response_modeとして、結果が全て取得できて表示をする「blocking」と、結果を逐次表示しながら表示する「streaming」があります。
まずは「blocking」モードです。実行結果は以下の通り。
「{ "event": 」以降が回答です。分かりにくいので整頓すると、
赤枠の部分が回答の内容であることが分かります。Unicodeで返ってきているので、文字変換をすると正しく会話ができていることが分かりました。
次に「streaming」モードです。実行させると、画面に文字が立て続けに出力されました。
詳細を見ると、赤枠部分が回答となりますが、細切れに入っていることが分かりました。
この回答もUnicodeなので、変換すると、結果は以下の通りで、問題ないことが分かりました。
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}");
}
}
}
}
結果も問題なしでした。
今回、OllamaでインストールしたローカルLLMをDifyのAPIを使って利用できることが分かりました。WebAPIなのでPython、C#のどちらからも利用できるのが良いですね。何かに使っていこうと思います。