Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 47 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Fujitsu Cloud Service Genearative AI Platform の API を利用するための C

---
# 使い方
## 起動
## 1. 起動
1. SampleCSharpUI.exe をクリックして起動
2. 【初回起動時のみ】
自動的にテナント名とクライアントIDを入力する [ 設定 ] 画面を表示します。
Expand All @@ -29,7 +29,7 @@ Fujitsu Cloud Service Genearative AI Platform の API を利用するための C
| 非対話認証 | 秘密キーによる非対話が可能な契約時に選択 |
| ClientSecret | 契約時に通知された秘密キーを設定 |

## 会話関連の操作
## 2. 会話関連の操作
### 会話入力
- 画面下の [ 入力 ] 欄に質問を入力し、 Enter を押すことで送信されます。
- 改行を入力したいときは、 Shift+Enter で改行ができます。
Expand All @@ -50,13 +50,13 @@ Generative AI Platform は、プロンプトパターンとして会話履歴プ
そのため、ルームに過去の会話が残っていると、その履歴に影響を受けた回答となります。そのため、新しい会話を始めたいときは過去の会話履歴を削除する必要があります。
過去の会話履歴の削除は、 [ ルーム ]-[ 会話をクリア ] メニューをクリックすることで実現できます。

## ルーム関連の操作
## 2. ルーム関連の操作
### ルームの選択
- メニューに表示されているルーム名をクリックすると作成済ルーム一覧がリスト表示されるので、そこから移動したいルームを選択してください。

### ルームの新規作成
[ ルーム ]-[ 新規作成 ] メニューをクリックして、ルームの新規作成画面を表示します。
1. [ ルーム名 ] 欄に識別名を入力し、利用するRAGを [ リトリーバー ] 選択から選択します。なお、RAG不要時は「 none 」を選択します。
1. [ ルーム名 ] 欄に識別名を入力し、利用するRAGを [ RAG指定 ] 選択から選択します。なお、RAG不要時は「 none 」を選択します。
1. [OK] をクリックしルームを作成します。作成が成功したときは自動的に作成したルームに移動します。

### ルームを管理
Expand All @@ -73,7 +73,42 @@ Generative AI Platform は、プロンプトパターンとして会話履歴プ
[ ルーム管理 ] 画面で [ 削除 ] をクリックすると該当行のルームを削除できます。
- 削除前に確認ダイアログが表示されるので、誤操作でクリックしてしまった時は [ いいえ ] をクリックすると削除を中止できます。

## RAG関連の操作
## 4. ルームなし推論

ルーム不要でTakaneに対してプロンプトを入力し回答を得るだけでよい場合には、ルームの設定や管理などの事前実行が必要なWebAPI呼び出しは煩雑に感じてしまいます。
そのようなユースケースに対するサンプルコードとして「ルームなし会話」モードを実装しています。

### ルームなしの選択
ルームの選択で「(none)」を選択するとチャットルームなしでの利用となります。
サンプルコード内で画面に表示されている過去履歴を渡しているので、過去履歴を踏まえたやりとりが可能となっておりますが、過去履歴を渡さずに API コールをすれば、必ず入力したプロンプトだけを踏まえた回答となります。

### APIの選択
ルームとして「 (none) 」を選択すると、右横に使用する API を選択する機能を表示します。
「Cohere v2 chat 互換 API」または「Cohere OpenAI Chat Completions 互換 API」が選択できます。

### ルームなしの設定
しているときに、左下の歯車アイコンをクリックすると、推論パラメタの編集が可能です。
1. [ ルーム名 ] は、「 (none) 」固定です。
2. [ ランダム性 ] は、Temperature と呼ばれるもので、0.0~1.0の範囲で0.1刻みで指定可能です。0.0を指定すると毎回同じ回答になり、1.0に近づくにつれてLLMはより様々な探索を行う可能性が高くなります。
3. [ システムプロンプト ] は、推論時のシステムプロンプトを指定します。
4. [ RAG 指定 ] は、推論時に利用する RAG を指定します。なお、RAG不要時は「 none 」を選択します。
5. [OK] をクリックすると変更した内容でルームを更新します。

### マルチモーダル対応
<img src="./images/snapshot_01.png" alt="マルチモーダル対応" width="600">

ルームなし会話では、マルチモーダル対応として、添付画像に対する質問を入力することができます。
添付できる画像ファイル形式は、png、jpeg、webp、非アニメーションgif形式の5MB以下となります。
1. 画像の添付方法は、入力欄下の [+] ボタンをクリックしてファイル選択
2. 画像の添付解除は、画像横の [-] ボタンをクリックして解除

マルチモーダル対応は、Cohere v2 Chat 互換 API (/v2/chat)、または、Cohere OpenAI Chat Completions 互換 API (/compatibility/v1/chat/completions) を呼び出すことで実現可能です。

### RAG 参照
ルームなしの設定で RAG を指定したとき、「Cohere v2 chat 互換 API」を選択している場合は、 documents オプションを使って、RAG の検索結果を参照情報として設定して推論します。
「Cohere OpenAI Chat Completions 互換 API」を選択している場合は、 documents オプションがないため、入力プロンプトの先頭に追加して推論します。

## 5. RAG関連の操作

### RAGの新規作成
[ ファイル ]-[RAG]-[ 新規作成 ] メニューをクリックして、ルームの新規作成画面を表示します。
Expand Down Expand Up @@ -106,35 +141,6 @@ RAG自体を削除したり、RAGに格納されているデータを変更し
[ RAG管理 ] 画面で [ 削除 ] をクリックすると該当行のRAGを削除できます。
- 削除前に確認ダイアログが表示されるので、誤操作でクリックしてしまった時は [ いいえ ] をクリックすると削除を中止できます。

## ルームなし会話
ルームを作成することで下記のような機能をWebAPIとして提供しています。
- 過去履歴を踏まえたプロンプトパターンの実現
- ルームへ会話を記録することによる後日閲覧の実現
- 各種トークン数の設定
しかしながら、ルーム不要でTakaneに対してプロンプトを入力し回答を得るだけでよい場合には、ルームの設定や管理などの事前実行が必要なWebAPI呼び出しは煩雑に感じてしまいます。
そのようなユースケースでは「ルームなし会話」モードがあります。

### 本サンプル画面での使い方
ルームの選択で「(none)」を選択するとチャットルームなしでの利用となります。
サンプルコード内で画面に表示されている過去履歴を渡しているので、過去履歴を踏まえたやりとりが可能となっておりますが、過去履歴を渡さずにAPIコールをすれば、必ず入力したプロンプトだけを踏まえた回答となります。

#### 制限事項
ルームを「(none)」に選択してる場合は、ルーム編集や新規作成の機能はご利用になれません。
ルーム編集やルーム新規作成が必要な場合は、他のルームを選択してから実行してください。

### マルチモーダル対応
<img src="images/snapshot_01.png" alt="マルチモーダル対応" width="600">

ルームなし会話では、マルチモーダル対応として、添付画像に対する質問を入力することができます。
添付できる画像ファイル形式は、png、jpeg、webp、非アニメーションgif形式の5MB以下となります。
1. 画像の添付方法は、入力欄下の [+] ボタンをクリックしてファイル選択
2. 画像の添付解除は、画像横の [-] ボタンをクリックして解除

マルチモーダル対応は、Cohere v2 Chat 互換 API (/v2/chat)、または、Cohere OpenAI Chat Completions 互換 API (/compatibility/v1/chat/completions) を呼び出すことで実現可能です。
サンプルコードでは、Cohere v2 Chat 互換 API を使用しています。

OpenAI 互換 API、または、Cohere V2 Chat 互換 API を呼び出すことで実現可能です。

---
# サンプルコードの利用 API
サンプルコードでは、Fujitsu Cloud Service Genearative AI Platform が提供する次の API を使用しています。
Expand All @@ -153,7 +159,9 @@ OpenAI 互換 API、または、Cohere V2 Chat 互換 API を呼び出すこと
| POST | /api/v1/chats/{id}/messages/createNextAiMessage | LLM から回答受信 |
| GET | /api/v1/chats/{id} | チャットルーム履歴取得 |
| POST | /api/v1/action/defined/text:simple_chat/call | チャットルームなし推論 |
| POST | /api/v1/pass-through/takane/v2/chat | Cohere v2 Chat 互換 API (画像付き入力推論) |
| POST | /api/v1/pass-through/takane/v2/chat | Cohere v2 Chat 互換 API |
| POST | /api/v1/pass-through/takane/compatibility/v1/chat/completions | Cohere OpenAI Chat Completions 互換 API |
| POST | /api/v1/retrievers/search | 入力プロンプトからRAG検索 |

## チャットルーム関連
チャットルームの作成・更新・削除は、 MVVM デザインパターンに基づき、 Models\ChatRoomModel.cs に記載しています。
Expand All @@ -169,14 +177,14 @@ RAG 関連については、 MVVM デザインパターンに基づき、 Models

| 操作 | エンドポイント | 用途 |
| ---- | ---- | ---- |
| GET | /api/v1/retrievers | リトリーバー一覧取得 |
| PUT | /api/v1/retrievers/{id} | リトリーバー取得 |
| POST | /api/v1/retrievers | リトリーバー追加 |
| POST | /api/v1/files/from-url | URL からのファイルアップロード |
| POST | /api/v1/files | ローカルファイルのアップロード |
| DELETE | /api/v1/files/{id} | ファイル削除 |
| GET | /api/v1/retrievers | リトリーバー一覧取得 |
| POST | /api/v1/retrievers | リトリーバー追加 |
| POST | /api/v1/retrievers/{id}/process/embeddings | RAGデータ作成 |
| GET | /api/v1/retrievers/{id} | RAGデータ作成完了確認 |
| DELETE | /api/v1/retrievers/{id} | リトリーバー削除 |
| PUT | /api/v1/retrievers/{id} | リトリーバー取得 |
| DELETE | /api/v1/retrievers/{id} | リトリーバー削除 |

---
Expand Down
123 changes: 120 additions & 3 deletions SampleCSharpUI/Commons/APIData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ public class TCohereV2ChatRequest
public float temperature { get; set; }
[DataMember]
public uint max_tokens { get; set; }

[DataMember(EmitDefaultValue = false)]
public TDocument[] documents { get; set; }
}

[DataContract]
Expand All @@ -230,6 +231,8 @@ public class TCohereV2ChatMessage
public string role { get; set; }
[DataMember]
public TContent[] content { get; set; }
[DataMember(EmitDefaultValue = false)]
public TCitation[] citations { get; set; }
}

[DataContract]
Expand All @@ -239,17 +242,37 @@ public class TContent
public string type { get; set; }
[DataMember]
public string text { get; set; }
[DataMember]
[DataMember(EmitDefaultValue = false)]
public TImageUrl image_url { get; set; }
}

[DataContract]
public class TImageUrl
{
[DataMember]
[DataMember(EmitDefaultValue = false)]
public string url { get; set; }
}

[DataContract]
public class TCitation
{
[DataMember(EmitDefaultValue = false)]
public string text { get; set; }
[DataMember(EmitDefaultValue = false)]
public TSource[] sources { get; set; }
}

[DataContract]
public class TSource
{
[DataMember(EmitDefaultValue = false)]
public string id { get; set; }
[DataMember(EmitDefaultValue = false)]
public string type { get; set; }
[DataMember(EmitDefaultValue = false)]
public TData document { get; set; }
}

[DataContract]
public class TCohereV2ChatResponse
{
Expand All @@ -259,7 +282,101 @@ public class TCohereV2ChatResponse
public TCohereV2ChatMessage message { get; set; }
[DataMember]
public string finish_reason { get; set; }
}

[DataContract]
public class TDocument
{
[DataMember(EmitDefaultValue = false)]
public TData data { get; set; }
}

[DataContract]
public class TData
{
[DataMember(EmitDefaultValue = false)]
public string id { get; set; }
[DataMember(EmitDefaultValue = false)]
public string title { get; set; }
[DataMember(EmitDefaultValue = false)]
public string text { get; set; }
}

[DataContract]
public class TOpenAIChatRequest
{
[DataMember]
public string model { get; set; }
[DataMember]
public TOpenAIChatMessage[] messages { get; set; }
[DataMember]
public float temperature { get; set; }
[DataMember]
public uint max_tokens { get; set; }
}
[DataContract]
public class TOpenAIChatMessage
{
[DataMember]
public string role { get; set; }
[DataMember]
public string content { get; set; }
}

[DataContract]
public class TOpenAIChatResponse
{
[DataMember]
public string id { get; set; }
[DataMember]
public TChoice[] choices { get; set; }
[DataMember]
public int created { get; set; }
}
[DataContract]
public class TChoice
{
[DataMember]
public string finish_reason { get; set; }
[DataMember]
public int index { get; set; }
[DataMember]
public TOpenAIChatMessage message { get; set; }
}

[DataContract]
public class TRetrieverSearchRequest
{
[DataMember]
public string search_type { get; set; }
[DataMember]
public string search_text { get; set; }
[DataMember]
public int limit { get; set; }
[DataMember]
public TRetrieverFilter filter { get; set; }
}

[DataContract]
public class TRetrieverFilter
{
[DataMember]
public TRetrieverFilterQuery retriever_id { get; set; }
}

[DataContract]
public class TRetrieverFilterQuery
{
[DataMember(Name = "in")]
public string[] ids { get; set; }
}


[DataContract]
public class TRetrieverSearchResponse
{
[DataMember]
public TRefChunks[] results { get; set; }
}
}
}
9 changes: 1 addition & 8 deletions SampleCSharpUI/Commons/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@

namespace SampleCSharpUI.Commons
{
internal class Config
internal partial class Config
{
internal static string ClientId { get; set; }
internal static string TenantName { get; set; }
internal static string SelectedChatRoomID { get; set; }

internal static bool IsUseOSWebView { get; set; }
internal static bool IsPromptAuthentication { get; set; }
internal static string ClientSecret { get; set; }
Expand Down Expand Up @@ -49,7 +47,6 @@ internal static void LoadProperties()

Config.ClientId = recvData.ClientId;
Config.TenantName = recvData.TenantName;
Config.SelectedChatRoomID = recvData.SelectedChatRoomID;
Config.IsUseOSWebView = recvData.IsUseOSWebView;
Config.IsPromptAuthentication = !recvData.IsNotPromptAuthentication;
Config.ClientSecret = CryptographyHelper.DecryptStringe(recvData.ClientSecret);
Expand All @@ -62,7 +59,6 @@ internal static void LoadProperties()
{
Config.ClientId = string.Empty;
Config.TenantName = string.Empty;
Config.SelectedChatRoomID = string.Empty;
Config.IsUseOSWebView = false;
Config.IsPromptAuthentication = true;
Config.ClientSecret = string.Empty;
Expand Down Expand Up @@ -113,7 +109,6 @@ internal static void SaveProperties()
// Loadがはしらないように内部変数から取得する
st.ClientId = Config.ClientId;
st.TenantName = Config.TenantName;
st.SelectedChatRoomID = Config.SelectedChatRoomID;
st.IsUseOSWebView = Config.IsUseOSWebView;
st.IsNotPromptAuthentication = !Config.IsPromptAuthentication;
st.ClientSecret = CryptographyHelper.EncryptString(Config.ClientSecret);
Expand Down Expand Up @@ -148,8 +143,6 @@ private class TPropertiesData
[DataMember]
public string TenantName { get; set; }
[DataMember]
public string SelectedChatRoomID { get; set; }
[DataMember]
public bool IsUseOSWebView { get; set; }
[DataMember]
public bool IsNotPromptAuthentication { get; set; }
Expand Down
Loading
Loading