.NET 用 Azure Cognitive Language Services Conversations クライアント ライブラリ - バージョン 1.1.0

会話型Language Understanding (略して CLU とも呼ばれる) は、次のような多くの言語理解機能を提供するクラウドベースの会話型 AI サービスです。

  • 会話アプリ: 会話内の意図とエンティティを抽出する場合に使用されます
  • ワークフロー アプリ: オーケストレーターのように機能し、会話を分析するための最適な候補を選択して、Qna、Luis、Conversation App などのアプリから最適な応答を得ます。

ソースコード | パッケージ (NuGet) | API リファレンス ドキュメント | サンプル | 製品ドキュメント | 分析 REST API のドキュメント | REST API ドキュメントの作成

作業の開始

パッケージをインストールする

NuGet を使用して .NET 用の Azure Cognitive Language Services Conversations クライアント ライブラリをインストールします。

dotnet add package Azure.AI.Language.Conversations

前提条件

この SDK を使用して会話プロジェクトを作成およびインポートすることはできますが、 Language Studio はプロジェクトを作成するための推奨される方法です。

クライアントを認証する

Conversations サービスを操作するには、 クラスの ConversationAnalysisClient インスタンスを作成する必要があります。 クライアント オブジェクトをインスタンス化するには、 エンドポイントAPI キー が必要です。 Cognitive Services での認証の詳細については、「 Azure Cognitive Services への要求を認証する」を参照してください。

API キーを取得する

エンドポイントAPI キーは、Azure Portal の Cognitive Services リソースから取得できます。

または、次に示す Azure CLI コマンドを使用して、Cognitive Service リソースから API キーを取得します。

az cognitiveservices account keys list --resource-group <resource-group-name> --name <resource-name>

名前空間

まず、 および 関連クラスの名前空間を ConversationAnalysisClient インポートします。

using Azure.Core;
using Azure.AI.Language.Conversations;

ConversationAnalysisClient を作成する

エンドポイントAPI キーを決定したら、 をConversationAnalysisClientインスタンス化できます。

Uri endpoint = new Uri("https://myaccount.cognitiveservices.azure.com");
AzureKeyCredential credential = new AzureKeyCredential("{api-key}");

ConversationAnalysisClient client = new ConversationAnalysisClient(endpoint, credential);

ConversationAuthoringClient を作成する

ConversationAuthoringClient使用するには、必要に応じて、上記の名前空間に加えて次の名前空間を使用します。

using Azure.AI.Language.Conversations.Authoring;

エンドポイントAPI キーを使用すると、 をConversationAuthoringClientインスタンス化できます。

Uri endpoint = new Uri("https://myaccount.cognitiveservices.azure.com");
AzureKeyCredential credential = new AzureKeyCredential("{api-key}");

ConversationAuthoringClient client = new ConversationAuthoringClient(endpoint, credential);

Azure Active Directory 認証を使用してクライアントを作成する

Azure Active Directory (AAD) 認証を ConversationAnalysisClient 作成したり、使用したり ConversationAuthoringClient することもできます。 ユーザーまたはサービス プリンシパルには、"Cognitive Services 言語閲覧者" ロールが割り当てられている必要があります。 DefaultAzureCredential を使用すると、マネージド ID またはサービス プリンシパルを使用してサービスを認証したり、アプリケーションに取り組む開発者として認証したり、コードを変更せずに認証したりすることができます。

Azure.Identity から 、、または任意のDefaultAzureCredential資格情報の種類を使用する前に、まず Azure.Identity パッケージをインストールする必要があります。

クライアント ID とシークレットで を使用DefaultAzureCredentialするには、、AZURE_CLIENT_ID、および AZURE_CLIENT_SECRET 環境変数をAZURE_TENANT_ID設定する必要があります。または、それらの値を ClientSecretCredential Azure.Identity の にも渡すことができます。

ソース ファイルの先頭にある に適切 DefaultAzureCredential な名前空間を使用していることを確認します。

using Azure.Identity;

その後、 の DefaultAzureCredential インスタンスを作成し、それをクライアントの新しいインスタンスに渡すことができます。

Uri endpoint = new Uri("https://myaccount.cognitiveservices.azure.com");
DefaultAzureCredential credential = new DefaultAzureCredential();

ConversationAnalysisClient client = new ConversationAnalysisClient(endpoint, credential);

リージョン エンドポイントでは AAD 認証がサポートされないことに注意してください。 代わりに、AAD 認証を使用するリソースの カスタム ドメイン 名を作成します。

主要な概念

ConversationAnalysisClient

ConversationAnalysisClientは、デプロイされた Conversations モデルを使用して予測を行う主なインターフェイスです。 クエリを送信するための同期 API と非同期 API の両方が提供されます。

スレッド セーフ

すべてのクライアント インスタンス メソッドがスレッド セーフであり、相互に独立していることを保証します (ガイドライン)。 これにより、クライアント インスタンスの再利用に関する推奨事項は、スレッド間でも常に安全になります。

その他の概念

クライアント オプション | 応答 | へのアクセス実行時間の長い操作 | エラーの | 処理診断 | あざける | クライアントの有効期間

Azure.AI.Language.Conversations クライアント ライブラリには、同期 API と非同期 API の両方が用意されています。

次の例は、上記で作成した を使用した一般的なシナリオをclient示しています。

会話を分析する

会話を分析するには、 メソッドを AnalyzeConversation() 呼び出します。

string projectName = "Menu";
string deploymentName = "production";

var data = new
{
    analysisInput = new
    {
        conversationItem = new
        {
            text = "Send an email to Carol about tomorrow's demo",
            id = "1",
            participantId = "1",
        }
    },
    parameters = new
    {
        projectName,
        deploymentName,

        // Use Utf16CodeUnit for strings in .NET.
        stringIndexType = "Utf16CodeUnit",
    },
    kind = "Conversation",
};

Response response = client.AnalyzeConversation(RequestContent.Create(data));

using JsonDocument result = JsonDocument.Parse(response.ContentStream);
JsonElement conversationalTaskResult = result.RootElement;
JsonElement conversationPrediction = conversationalTaskResult.GetProperty("result").GetProperty("prediction");

Console.WriteLine($"Top intent: {conversationPrediction.GetProperty("topIntent").GetString()}");

Console.WriteLine("Intents:");
foreach (JsonElement intent in conversationPrediction.GetProperty("intents").EnumerateArray())
{
    Console.WriteLine($"Category: {intent.GetProperty("category").GetString()}");
    Console.WriteLine($"Confidence: {intent.GetProperty("confidenceScore").GetSingle()}");
    Console.WriteLine();
}

Console.WriteLine("Entities:");
foreach (JsonElement entity in conversationPrediction.GetProperty("entities").EnumerateArray())
{
    Console.WriteLine($"Category: {entity.GetProperty("category").GetString()}");
    Console.WriteLine($"Text: {entity.GetProperty("text").GetString()}");
    Console.WriteLine($"Offset: {entity.GetProperty("offset").GetInt32()}");
    Console.WriteLine($"Length: {entity.GetProperty("length").GetInt32()}");
    Console.WriteLine($"Confidence: {entity.GetProperty("confidenceScore").GetSingle()}");
    Console.WriteLine();

    if (entity.TryGetProperty("resolutions", out JsonElement resolutions))
    {
        foreach (JsonElement resolution in resolutions.EnumerateArray())
        {
            if (resolution.GetProperty("resolutionKind").GetString() == "DateTimeResolution")
            {
                Console.WriteLine($"Datetime Sub Kind: {resolution.GetProperty("dateTimeSubKind").GetString()}");
                Console.WriteLine($"Timex: {resolution.GetProperty("timex").GetString()}");
                Console.WriteLine($"Value: {resolution.GetProperty("value").GetString()}");
                Console.WriteLine();
            }
        }
    }
}

より詳細な出力を有効にするように、追加のオプションを に AnalyzeConversation 渡すことができます。

string projectName = "Menu";
string deploymentName = "production";

var data = new
{
    analysisInput = new
    {
        conversationItem = new
        {
            text = "Send an email to Carol about tomorrow's demo",
            id = "1",
            participantId = "1",
        }
    },
    parameters = new
    {
        projectName,
        deploymentName,
        verbose = true,

        // Use Utf16CodeUnit for strings in .NET.
        stringIndexType = "Utf16CodeUnit",
    },
    kind = "Conversation",
};

Response response = client.AnalyzeConversation(RequestContent.Create(data));

別の言語で会話を分析する

プロパティは language 、会話の言語を指定するように設定できます。

string projectName = "Menu";
string deploymentName = "production";

var data = new
{
    analysisInput = new
    {
        conversationItem = new
        {
            text = "Enviar un email a Carol acerca de la presentación de mañana",
            language = "es",
            id = "1",
            participantId = "1",
        }
    },
    parameters = new
    {
        projectName,
        deploymentName,
        verbose = true,

        // Use Utf16CodeUnit for strings in .NET.
        stringIndexType = "Utf16CodeUnit",
    },
    kind = "Conversation",
};

Response response = client.AnalyzeConversation(RequestContent.Create(data));

オーケストレーション プロジェクトを使用して会話を分析する

オーケストレーション プロジェクトを使用して会話を分析するには、会話プロジェクトと同様に AnalyzeConversation() メソッドを呼び出すことができます。

string projectName = "DomainOrchestrator";
string deploymentName = "production";

var data = new
{
    analysisInput = new
    {
        conversationItem = new
        {
            text = "How are you?",
            id = "1",
            participantId = "1",
        }
    },
    parameters = new
    {
        projectName,
        deploymentName,

        // Use Utf16CodeUnit for strings in .NET.
        stringIndexType = "Utf16CodeUnit",
    },
    kind = "Conversation",
};

Response response = client.AnalyzeConversation(RequestContent.Create(data));

using JsonDocument result = JsonDocument.Parse(response.ContentStream);
JsonElement conversationalTaskResult = result.RootElement;
JsonElement orchestrationPrediction = conversationalTaskResult.GetProperty("result").GetProperty("prediction");

質問応答予測

質問応答によって会話が分析された場合は、回答を取得できる意図 (おそらく最上位の意図) が含まれます。

string respondingProjectName = orchestrationPrediction.GetProperty("topIntent").GetString();
JsonElement targetIntentResult = orchestrationPrediction.GetProperty("intents").GetProperty(respondingProjectName);

if (targetIntentResult.GetProperty("targetProjectKind").GetString() == "QuestionAnswering")
{
    Console.WriteLine($"Top intent: {respondingProjectName}");

    JsonElement questionAnsweringResponse = targetIntentResult.GetProperty("result");
    Console.WriteLine($"Question Answering Response:");
    foreach (JsonElement answer in questionAnsweringResponse.GetProperty("answers").EnumerateArray())
    {
        Console.WriteLine(answer.GetProperty("answer").GetString());
    }
}

会話の要約

会話を要約するために、 を AnalyzeConversation 返すメソッド オーバーロードを Operation<BinaryData>使用できます。

var data = new
{
    analysisInput = new
    {
        conversations = new[]
        {
            new
            {
                conversationItems = new[]
                {
                    new
                    {
                        text = "Hello, how can I help you?",
                        id = "1",
                        role = "Agent",
                        participantId = "Agent_1",
                    },
                    new
                    {
                        text = "How to upgrade Office? I am getting error messages the whole day.",
                        id = "2",
                        role = "Customer",
                        participantId = "Customer_1",
                    },
                    new
                    {
                        text = "Press the upgrade button please. Then sign in and follow the instructions.",
                        id = "3",
                        role = "Agent",
                        participantId = "Agent_1",
                    },
                },
                id = "1",
                language = "en",
                modality = "text",
            },
        }
    },
    tasks = new[]
    {
        new
        {
            taskName = "Issue task",
            kind = "ConversationalSummarizationTask",
            parameters = new
            {
                summaryAspects = new[]
                {
                    "issue",
                }
            },
        },
        new
        {
            taskName = "Resolution task",
            kind = "ConversationalSummarizationTask",
            parameters = new
            {
                summaryAspects = new[]
                {
                    "resolution",
                }
            },
        },
    },
};

Operation<BinaryData> analyzeConversationOperation = client.AnalyzeConversations(WaitUntil.Completed, RequestContent.Create(data));

using JsonDocument result = JsonDocument.Parse(analyzeConversationOperation.Value.ToStream());
JsonElement jobResults = result.RootElement;
foreach (JsonElement task in jobResults.GetProperty("tasks").GetProperty("items").EnumerateArray())
{
    Console.WriteLine($"Task name: {task.GetProperty("taskName").GetString()}");
    JsonElement results = task.GetProperty("results");
    foreach (JsonElement conversation in results.GetProperty("conversations").EnumerateArray())
    {
        Console.WriteLine($"Conversation: #{conversation.GetProperty("id").GetString()}");
        Console.WriteLine("Summaries:");
        foreach (JsonElement summary in conversation.GetProperty("summaries").EnumerateArray())
        {
            Console.WriteLine($"Text: {summary.GetProperty("text").GetString()}");
            Console.WriteLine($"Aspect: {summary.GetProperty("aspect").GetString()}");
        }
        Console.WriteLine();
    }
}

その他のサンプル

会話を分析する方法のその他の例については、 ブラウザーでサンプル を参照してください。

トラブルシューティング

全般

.NET SDK を使用して Cognitive Language Services Conversations クライアント ライブラリと対話すると、サービスによって返されるエラーは、REST API 要求に返されるのと同じ HTTP 状態コードに対応します。

たとえば、存在しないプロジェクトに発話を送信すると、 400 "Bad Request" を示すエラーが返されます。

try
{
    var data = new
    {
        analysisInput = new
        {
            conversationItem = new
            {
                text = "Send an email to Carol about tomorrow's demo",
                id = "1",
                participantId = "1",
            }
        },
        parameters = new
        {
            projectName = "invalid-project",
            deploymentName = "production",

            // Use Utf16CodeUnit for strings in .NET.
            stringIndexType = "Utf16CodeUnit",
        },
        kind = "Conversation",
    };

    Response response = client.AnalyzeConversation(RequestContent.Create(data));
}
catch (RequestFailedException ex)
{
    Console.WriteLine(ex.ToString());
}

操作のクライアント要求 ID など、追加情報がログに記録されていることがわかります。

Azure.RequestFailedException: The input parameter is invalid.
Status: 400 (Bad Request)
ErrorCode: InvalidArgument

Content:
{
  "error": {
    "code": "InvalidArgument",
    "message": "The input parameter is invalid.",
    "innerError": {
      "code": "InvalidArgument",
      "message": "The input parameter \"payload\" cannot be null or empty."
    }
  }
}

Headers:
Transfer-Encoding: chunked
pragma: no-cache
request-id: 0303b4d0-0954-459f-8a3d-1be6819745b5
apim-request-id: 0303b4d0-0954-459f-8a3d-1be6819745b5
x-envoy-upstream-service-time: 15
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
x-content-type-options: nosniff
Cache-Control: no-store, proxy-revalidate, no-cache, max-age=0, private
Content-Type: application/json

コンソール ログの設定

ログを表示する最も簡単な方法は、コンソール ログを有効にすることです。 コンソールにメッセージを出力する Azure SDK ログ リスナーを作成するには、 メソッドを AzureEventSourceListener.CreateConsoleLogger 使用します。

// Setup a listener to monitor logged events.
using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

その他のログメカニズムの詳細については、 こちらを参照してください

次のステップ

共同作成

このライブラリのビルド、テスト、および投稿の詳細については、 CONTRIBUTING.md を参照してください。

このプロジェクトでは、共同作成と提案を歓迎しています。 ほとんどの共同作成では、共同作成者使用許諾契約書 (CLA) にご同意いただき、ご自身の共同作成内容を使用する権利を Microsoft に供与する権利をお持ちであり、かつ実際に供与することを宣言していただく必要があります。 詳細については、「 cla.microsoft.com」を参照してください。

pull request を送信すると、CLA を提供して PR (ラベル、コメントなど) を適宜装飾する必要があるかどうかを CLA ボットが自動的に決定します。 ボットによって提供される手順にそのまま従ってください。 この操作は、Microsoft の CLA を使用するすべてのリポジトリについて、1 回だけ行う必要があります。

このプロジェクトでは、Microsoft オープン ソースの倫理規定を採用しています。 詳しくは、「Code of Conduct FAQ (倫理規定についてよくある質問)」を参照するか、opencode@microsoft.com 宛てに質問またはコメントをお送りください。