LUIS から CLU(Conversational Language Understanding)へ移行するとき、「動いたはずのボットが突然 500 エラー」「ログを見ると Microsoft.CluRecognizer が見つからない」という状況にハマりがちです。本記事では、実際に遭遇しやすい 「Type Microsoft.CluRecognizer not registered in factory」エラー を題材に、Bot Framework Composer/SDK 双方での原因と解決手順を、設定ファイルとコード例つきで詳しく整理します。
LUIS → CLU 移行時に出る「Microsoft.CluRecognizer not registered in factory」とは
まず、問題のエラーメッセージを整理します。
エラーメッセージ:Type Microsoft.CluRecognizer not registered in factory
このメッセージが意味しているのは、次の 1 点だけです。
- ダイアログ内で指定された
$kind: "Microsoft.CluRecognizer"を実行時に解決できない(=その種類のコンポーネントが登録されていない)
つまり、C# コード側で using Microsoft.Bot.Components.Recognizers.CLURecognizer; と書いただけでは不十分で、Bot ランタイムに「この $kind のコンポーネントがここにあるよ」と教える仕組みが必要になります。
ここで押さえておきたいのが、Bot Framework の「宣言型コンポーネント」の仕組みです。
- .dialog ファイルでは、各アクションや認識器を
$kindという文字列で指定する - ランタイムは起動時にコンポーネント DLL を読み込み、
$kindと .NET の型をひも付けて「factory(工場)」に登録する - 登録されていない
$kindが出てくると、not registered in factoryという例外を投げる
このため、LUIS から CLU へ移行した際には、
- CLU 用コンポーネント DLL がそもそも読み込まれていない
- appsettings.json(settings.json)にコンポーネントの登録がない
$kindのスペル/大文字小文字が一致していない- 自作の認識器クラスに変えてしまい、宣言型登録を忘れている
といった理由で、今回のエラーが発生します。
ありがちな落とし穴を一覧で整理
| パターン | 典型的な原因 |
|---|---|
| Composer では動くが Azure VM にデプロイすると落ちる | VM 側ランタイムに CLU コンポーネント DLL がデプロイされていない/runtimeSettings.components がずれている |
NuGet と using を追加したのにエラーが続く | 実行プロジェクトではなく別プロジェクトにだけパッケージを追加している/コンポーネント登録がない |
CLURecognizer 型が見つからないコンパイルエラー | パッケージ内にその名前の型が存在しない、もしくは DI 登録のやり方がそもそも違う |
自作 $kind 名で使おうとして失敗 | カスタムクラスを declarative コンポーネントとして登録していない |
ここから先は、Composer を使っている場合と、.NET SDK で自前ホストしている場合の 2 パターンに分けて、正しい登録方法と設定例を順番に解説していきます。
Bot Framework Composer での解決手順
Composer を使っている場合は、基本的に「Package Manager から入れる」「settings でキーを設定する」の 2 ステップで解決できます。C# のコードを書き換える必要はほとんどありません。
Composer の Package Manager で CLU コンポーネントを追加
Composer の左ペインから Package Manager を開き、次の操作を行います。
- Browse タブを選択
Microsoft.Bot.Components.Recognizers.CLURecognizerを検索- 対象ボットのランタイムプロジェクトにインストール
この操作を行うと、プロジェクトの settings/appsettings.json(ローカルでは settings.development.json など)に次のような設定が自動的に追加されます。
{
"runtimeSettings": {
"components": [
{
"name": "Microsoft.Bot.Components.Recognizers.CLURecognizer"
}
]
}
}
この components 配列こそが「factory に登録する DLL 一覧」であり、ここに CLU コンポーネントのアセンブリ名が入っていないと、$kind: "Microsoft.CluRecognizer" を見つけられません。
CLU の接続情報を settings に定義する
次に、Azure Language リソースのエンドポイントとキー、CLU プロジェクト名とデプロイ名を設定します。Composer の設定画面、または settings/appsettings.json を直接編集して、次のような形で定義します。
{
"language": {
"clu": {
"endpoint": "https://<your-language-resource>.cognitiveservices.azure.com/",
"apiKey": "<your-api-key>",
"projectName": "YourCluProjectName",
"deploymentName": "production"
}
},
"runtimeSettings": {
"components": [
{ "name": "Microsoft.Bot.Components.Recognizers.CLURecognizer" }
]
}
}
ここで重要なのは認証方式です。
- CLU 認識器は基本的に API キー(endpoint + key)方式 を前提としている
clientId / clientSecret / tenantIdだけを設定しても、CLURuntime 側の期待と合わず認証に失敗する- Azure Portal の「言語リソース(Language)」→「キーとエンドポイント」で表示される キー をそのまま
apiKeyに設定する
設定値の意味を簡単に表にしておきます。
| キー | 例 | 意味 |
|---|---|---|
endpoint | https://xxx.cognitiveservices.azure.com/ | Azure Language リソースのエンドポイント URL |
apiKey | 英数字 32 文字程度 | 「キーとエンドポイント」に表示されるサブスクリプションキー |
projectName | MyCluProject | Language Studio で作成した CLU プロジェクト名 |
deploymentName | production / staging など | Language Studio で発行したデプロイメント名 |
.dialog 側の recognizer 設定($kind と設定値のひも付け)
次に、メインダイアログなどの .dialog ファイルで recognizer を CLU に切り替えます。推奨される設定例は次の通りです。
"recognizer": {
"$kind": "Microsoft.CluRecognizer",
"projectName": "=settings.language.clu.projectName",
"deploymentName": "=settings.language.clu.deploymentName",
"endpoint": "=settings.language.clu.endpoint",
"apiKey": "=settings.language.clu.apiKey"
}
ここでのポイントは 2 つです。
$kindの値を完全一致で"Microsoft.CluRecognizer"にすること(スペルや大文字小文字を変えない)- 設定は
=settings...の式でsettings.jsonの値を参照するようにしておくこと
もし既存の LUIS 設定からコピペしている場合は、$kind が Microsoft.LuisRecognizer のままになっていないか、endpointKey など LUIS 向けのプロパティ名が残っていないかもチェックしてください。
Composer 環境で確認しておきたいチェックリスト
- ✔ 実行しているボットのランタイムプロジェクトに
Microsoft.Bot.Components.Recognizers.CLURecognizerがインストールされている - ✔
settings/appsettings.jsonのruntimeSettings.componentsにコンポーネント名が入っている - ✔ .dialog の
$kindがMicrosoft.CluRecognizerになっている - ✔
endpoint / apiKey / projectName / deploymentNameがすべて設定されている - ✔ Language Studio 側で CLU プロジェクトをデプロイ済みで、
deploymentNameと一致している - ✔ 実行環境(ローカル/VM/App Service)ごとの
settings.*.jsonが正しいファイルに切り替わっている
ここまで揃えば、Composer 環境での「Microsoft.CluRecognizer not registered in factory」エラーはほぼ解消できるはずです。
.NET SDK(自前ホスト)での解決手順
次に、Bot Framework SDK を使って自前ホストしている場合の対処方法です。Adaptive Runtime(Composer ランタイム)をそのまま使うかどうかで若干手順が変わりますが、共通するポイントは次の 3 つです。
- 実行プロジェクトに CLU の NuGet パッケージを追加する
- ランタイムにコンポーネントを登録する(多くの場合
runtimeSettings.componentsで十分) Host.CreateDefaultBuilder(...)の Build / Run より前 に登録処理を行う
NuGet パッケージを「実行プロジェクト」に追加する
ソリューションを複数プロジェクト構成にしている場合、CLU パッケージを誤って共有ライブラリ側にだけインストールしてしまい、Web アプリ(実行プロジェクト)には入っていないケースがよくあります。
- ボットをホストしている ASP.NET Core プロジェクト(
Program.csがあるプロジェクト)を右クリック - 「NuGet パッケージの管理」から
Microsoft.Bot.Components.Recognizers.CLURecognizerを追加
これにより、ビルド出力フォルダ(bin/<Configuration>/<TargetFramework>/)に Microsoft.Bot.Components.Recognizers.CLURecognizer.dll がコピーされるようになります。デプロイ先でもこの DLL が存在するか、実際にファイルを確認しておくと安心です。
Adaptive Runtime を使う場合の Program.cs 例
Composer と同じ Adaptive Runtime を使う場合の典型的な Program.cs 例です。重要なのは、services.AddBotRuntime() やコンポーネント登録を Build() より前に行うことです。
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hosting, builder) =>
{
var root = AppDomain.CurrentDomain.BaseDirectory;
var env = hosting.HostingEnvironment.EnvironmentName;
// Composer 互換の設定読み込み
builder.AddBotRuntimeConfiguration(root, "settings", env);
builder.AddCommandLine(args);
})
.ConfigureServices((context, services) =>
{
// Adaptive Runtime を登録
services.AddBotRuntime();
// 通常、CLU 用コンポーネントは appsettings.json の
// "runtimeSettings.components" に登録しておけば、
// ここで個別に AddSingleton する必要はない
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
誤りやすいパターンとして、次のようなコードがあります。
CreateHostBuilder(args).Build().Run();の後ろにWebApplication.CreateBuilder()を書いてしまう- 旧来の
Startupパターンと .NET 6 以降の最小ホストパターンを混在させる
この場合、後段に書いたコードは実行されず、コンポーネント登録が一切行われないため、当然ながら Microsoft.CluRecognizer not registered in factory が発生します。ホストのスタイルは 1 つに統一し、登録処理は必ず Build の前に書くようにしてください。
services.AddSingleton<CLURecognizer>(); がうまくいかない理由
エラーに悩んだ結果、「とりあえずサービスコレクションに CLURecognizer を登録すればいいのでは?」と考え、次のようなコードを書いてしまうケースもあります。
public static void ConfigureServices(IServiceCollection services)
{
services.AddControllers().AddNewtonsoftJson();
// ❌ これでコンパイルエラー、あるいは実行時エラーになる
services.AddSingleton<CLURecognizer>();
}
これがうまくいかない理由は主に 2 つあります。
- パッケージ内にその名前の型が存在しない
コンポーネントパッケージは、「宣言型(Declarative)コンポーネント」を登録する BotComponent を内部に持っており、開発者が直接 new して使う前提ではないものがほとんどです。そのため、CLURecognizerというクラスが見つからず、コンパイルエラーになります。 - factory と DI コンテナは別物
not registered in factoryは「宣言型コンポーネントの factory に登録されていない」という意味であり、DI コンテナ(services.AddSingleton)の登録有無とは別です。DI にインスタンスを登録しても、$kindを解決する仕組みには何も影響しません。
正しいアプローチは、Composer と同様に runtimeSettings.components でコンポーネント DLL を読み込ませ、$kind: "Microsoft.CluRecognizer" を使うことです。C# コード側で個別の Recognizer 型を意識する必要は基本的にありません。
appsettings.json でコンポーネントを登録する
自前ホストでも、設定ファイルの構造は Composer とほぼ同じにできます。例えば次のような appsettings.json を用意し、先ほどの AddBotRuntimeConfiguration で読み込ませます。
{
"language": {
"clu": {
"endpoint": "https://<your-language-resource>.cognitiveservices.azure.com/",
"apiKey": "<your-api-key>",
"projectName": "YourCluProjectName",
"deploymentName": "production"
}
},
"runtimeSettings": {
"components": [
{ "name": "Microsoft.Bot.Components.Recognizers.CLURecognizer" }
]
}
}
これにより、Adaptive Runtime が起動時に CLU コンポーネントを自動的に読み込み、$kind: "Microsoft.CluRecognizer" を factory に登録してくれます。ダイアログファイルも Composer と同じ形式で記述できます。
SDK 環境でのチェックリスト
- ✔ 実行プロジェクトに CLU NuGet パッケージが追加されている
- ✔ ビルド出力フォルダに
Microsoft.Bot.Components.Recognizers.CLURecognizer.dllが存在する - ✔
Host.CreateDefaultBuilderなどのホストビルダーで、services.AddBotRuntime()をBuild()より前に呼んでいる - ✔
runtimeSettings.componentsにコンポーネント名が登録されている - ✔ .dialog ファイルから参照される設定キー(
settings.language.clu.*)がすべて存在する
カスタム認識器名(独自 $kind)を使う場合の注意点
エラーメッセージが次のような形式になっている場合もあります。
Type TreasuryBot.Custom_Recognizer.CustomCluRecognizer not registered in factory.
これは、.dialog ファイルの recognizer に独自の $kind 名を指定しているケースです。
"recognizer": {
"$kind": "TreasuryBot.Custom_Recognizer.CustomCluRecognizer",
...
}
このように $kind を自作クラス名に変えて使う場合は、次の条件を満たしていないと factory で解決できません。
- 自作認識器クラス(例:
CustomCluRecognizer)を作成している - そのクラスを宣言型コンポーネントとして登録する
BotComponentを実装している - 上記 BotComponent を含むアセンブリを
runtimeSettings.componentsに登録している
BotComponent の実装イメージは次のような形になります(概念図)。
public class CustomRecognizerComponent : BotComponent
{
public override void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
// 必要に応じてサービス登録
}
public override void ConfigureDeclarativeTypes(DeclarativeTypeCollection collection)
{
collection.Add(
new DeclarativeType<CustomCluRecognizer>(
"TreasuryBot.Custom_Recognizer.CustomCluRecognizer"));
}
}
そして、このコンポーネントを含むアセンブリ名を runtimeSettings.components に登録します。
"runtimeSettings": {
"components": [
{ "name": "TreasuryBot.Custom_Recognizer" }
]
}
ここまでして初めて、自作の $kind が factory で解決されるようになります。特別な理由がなければ、まずは既定の $kind: "Microsoft.CluRecognizer" をそのまま使う方がトラブルも少なく、移行検証もしやすくなります。
LUIS から CLU への移行時に確認しておきたいポイントまとめ
最後に、LUIS から CLU に切り替える際に見落としがちなポイントを、LUIS 時代の設定と対比しながら整理しておきます。
| 項目 | LUIS 時代 | CLU 移行後 |
|---|---|---|
| $kind | Microsoft.LuisRecognizer | Microsoft.CluRecognizer |
| 認証方式 | LUIS の endpointKey / authoringKey | Language リソースの endpoint + key(API キー) |
| 設定ファイル | settings.language.luis.* など | settings.language.clu.* など CLU 用に新規定義 |
| Azure ポータルのリソース | LUIS 専用リソース | 「言語」リソース+Language Studio の CLU プロジェクト |
| 移行時に出がちなエラー | 設定不足で LUIS への接続失敗 | Microsoft.CluRecognizer not registered in factory / 認証エラー/無効な project/deployment 名 |
特に、次のようなパターンは今回のエラーに直結します。
- LUIS 用のコンポーネント(Orchestrator など)は登録してあるが、CLU コンポーネントを追加していない
- ソリューションのどこかには CLU パッケージを入れたが、実行プロジェクトに入れていない
- ローカルの
settings.development.jsonを書き換えたが、VM 上のappsettings.jsonを更新し忘れている - カスタム
$kindを使っているのに BotComponent に declarative 登録を書いていない
トラブルシューティングのステップバイステップ
実際に「Microsoft.CluRecognizer not registered in factory」が出てしまったときに、どの順番で確認すればよいかを簡単な手順としてまとめます。
- ビルド出力に DLL があるか確認
デプロイ先(ローカル/VM/App Service)のbinフォルダを開き、Microsoft.Bot.Components.Recognizers.CLURecognizer.dllが存在するかを確認します。なければ NuGet の入れ先か、デプロイ設定を見直します。 - appsettings.json / settings.json の components セクションを確認
runtimeSettings.componentsに{ "name": "Microsoft.Bot.Components.Recognizers.CLURecognizer" }が入っているかを確認します。環境ごとの設定ファイル(development / production など)のずれにも注意します。 - .dialog の
$kindを確認
誤ってMicrosoft.CluRecogniserのようにスペルミスしていないか、Microsoft.LuisRecognizerのままになっていないかを確認します。 - 認証情報とプロジェクト名/デプロイ名を確認
「キーとエンドポイント」画面のキーを使っているか、Language Studio 上のプロジェクト名・デプロイ名と一致しているかを確認します。認証エラーの場合も、内部での初期化が失敗して似たような例外が見えることがあります。 - 自作
$kindの有無を確認$kindに自作の名前空間を使っている場合は、BotComponent の declarative 登録があるかを確認します。なければ、既定のMicrosoft.CluRecognizerに戻すか、登録コードを追加します。
この順に追っていけば、「どこで CLU が見えなくなっているのか」をかなりの確度で特定できます。
まとめ:エラーの本質と、最短での解消アプローチ
本記事では、LUIS から CLU へ移行した際に発生しがちな Type Microsoft.CluRecognizer not registered in factory エラーについて、Composer/SDK 両方の観点から原因と対処方法を整理しました。
- エラーの本質は 「
$kind: Microsoft.CluRecognizerを解決できるだけのコンポーネント登録がない」こと - Composer 環境では、Package Manager で CLU コンポーネントを追加し、
runtimeSettings.componentsに反映されていることを確認するだけで解消できるケースが多い - SDK/自前ホストでは、実行プロジェクトに NuGet を追加し、ホストの Build 前に Adaptive Runtime を初期化することが重要
- 認証は Language リソースの endpoint + API キー を使うのが基本で、
clientId / clientSecret / tenantIdだけでは動かないことが多い - カスタム
$kindを使う場合は、BotComponent による declarative 登録が必須 services.AddSingleton<CLURecognizer>();のような直接登録は、型名も仕組みも合わず、根本解決にならない
LUIS の終息に伴い、今後 CLU への移行はますます増えていきますが、「コンポーネント登録」「設定値」「ホスト初期化」の 3 つさえ押さえておけば、今回のようなエラーは比較的シンプルに切り分けられます。この記事をチェックリスト代わりにしながら、自身のボット環境の設定を一つずつ見直してみてください。

コメント