# Semantic Kernel:Chatチャットサービス


生成系AIが人気を博しているのは、ChatGPTを通じて引き起こされたものです。このインテリジェントなチャット式のインタラクションは、人々の対話認識と理解を一変させました。人間のように文脈をつなげ、全体的な理解と応答ができるのです。

もちろん、SKは初期のバージョンからこれを適応させており、SKではChatHistoryを通じてチャットのコンテキストを保持しています。現在の1.15.0のパッケージには、システム、アシスタント、ユーザー、ツールの4つの役割があります。以下でこれらの役割の機能と作用を説明します。

1. **System (システム)**: この役割はアシスタントの行動を指示または設定します。システム内では、権限の管理、フローの制御、システムレベルのタスクの実行などが役割となります。
2. **Assistant (アシスタント)**: この役割はシステム指令やユーザーの入力に対する応答を提供します。対話の中で、アシスタント役割はユーザーに対して支援を提供し、質問に回答し、タスクを実行します。
3. **User (ユーザー)**: この役割はチャット完了に必要な入力を提供します。対話において、ユーザー役割はシステムと対話する実際の人間のユーザーを代表し、質問や情報を求めます。
4. **Tool (ツール)**: この役割はチャット完了に必要な追加情報や参考資料を提供します。対話において、ツール役割はサポート機能、データクエリ、その他の補助的なタスクを提供します。

以下にチャットのシナリオを示します。systemで役割と特性を設定し、userが入力し、assistantが応答します。

```csharp
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using System.Runtime.CompilerServices;
using System.Text;

var chatModelId = "gpt-4o";
var geminiModelId = "gemini-1.5-flash-latest";
var geminiKey = File.ReadAllText(@"C:\GPT\gemini.txt");
var key = File.ReadAllText(@"C:\GPT\key.txt");

#pragma warning disable SKEXP0070
var kernel = Kernel.CreateBuilder()
   .AddOpenAIChatCompletion(chatModelId, key)
   //.AddGoogleAIGeminiChatCompletion(geminiModelId, geminiKey)
   .Build();

var chatHistory = new ChatHistory(systemMessage: "あなたは.NETの上級講師です。回答は簡潔に行ってください。");
var chat = kernel.GetRequiredService<IChatCompletionService>();

var settings = new PromptExecutionSettings
{
    ExtensionData = new Dictionary<string, object>
    {
        ["max_tokens"] = 1000,
        ["temperature"] = 0.2,
        ["top_p"] = 0.8,
        ["presence_penalty"] = 0.0,
        ["frequency_penalty"] = 0.0
    }
};

while (true)
{
    // 提問
    Console.ResetColor();
    Console.WriteLine("----------学生提问：----------");
    chatHistory.AddUserMessage(Console.ReadLine());
    Console.WriteLine();

    // 回答
    var reply = await chat.GetChatMessageContentAsync(chatHistory, settings);
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine("==========講師回答：==========");
    Console.WriteLine(reply.Content);
    chatHistory.AddMessage(reply.Role, reply.Content);
    Console.WriteLine();
}
```

上記の応答は内容が多い場合、待機する必要があります。以下はストリーミング応答でユーザーエクスペリエンスを向上させます。ストリーミングかどうかは応答の内容とは関係ありません。

```csharp
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("==========講師回答：==========");
AuthorRole? role = AuthorRole.Assistant;
var contentBuilder = new StringBuilder();

await foreach (var reply in chat.GetStreamingChatMessageContentsAsync(chatHistory, settings))
{
    if (reply.Role.HasValue && role != reply.Role)
    {
        role = reply.Role;
    }
    Console.Write(reply.Content);
    contentBuilder.Append(reply.Content);
}

chatHistory.AddMessage(role.Value, contentBuilder.ToString());
Console.WriteLine();
```

以下は二問二答です。二番目の問答では、GPTの「賢さ」が明らかに見て取れ、文脈を理解しています。

また、前述のように、同一サービス内で異なるLLMをサポートしています。上記の例ではGPTとGeminiです。Kernelの利点は、異なるLLMサービスを注入できることです。一つのサービスで問題が発生したり、料金体系が変更された場合に柔軟に切り替えることができます。

以下に二種類のLLMの結果を示します（ここでは比較はしません）。

![GPT問答](https://mmbiz.qpic.cn/sz_mmbiz_png/4CAA63nvHRBlib0B57PzIzoOyKD2PX6gwaiaNqHTfxTibHMRBurvnMGGlic80pAdY75M2WVQ2xTkZy1cpZ30KWdukA/640?wx_fmt=png&from=appmsg)
（GPT問答）
<br>

![Gemini問答](https://mmbiz.qpic.cn/sz_mmbiz_png/4CAA63nvHRBlib0B57PzIzoOyKD2PX6gwVWTFau0bn53kZfwMP8SAG1Uw31gQu4Gicv1IsdAMyEjdz9xEZKqYbOg/640?wx_fmt=png&from=appmsg)
（Gemini問答）

(Translated by GPT)

元のリンク：https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247488236&idx=1&sn=074c51ba590f2d6bd8233887174aa905&chksm=9f004dc6a877c4d0c41b986d263978900874c1aa1cbf63e7033f1644d7f17039e818e559cd77&token=1614195268&lang=zh_CN#rd&wt.mc_id=MVP_325642