ルールエンジン

2009年1月7日

ルールエンジンを使うべきか?

ルールエンジンは、代替の計算モデルを提供することに尽きます。条件分岐やループを含むシーケンスによる命令という通常の命令型モデルではなく、ルールエンジンはプロダクションルールシステムに基づいています。これは、それぞれに条件とアクションを持つ一連のプロダクションルールであり、単純化すると、if-then文の集まりと考えることができます。

微妙な点は、ルールは任意の順序で記述でき、エンジンがその意味のある順序を使用していつ評価するかを決定することです。それを考える良い方法は、システムがすべてのルールを走査し、条件が真であるルールを選択し、対応するアクションを評価することです。これの良い点は、多くの問題がこのモデルに自然に適合することです。

  if car.owner.hasCellPhone then premium += 100;
  if car.model.theftRating > 4 then premium += 200;
  if car.owner.livesInDodgyArea && car.model.theftRating > 2 
     then premium += 300;

ルールエンジンは、この計算モデルを使用してプログラミングを容易にするツールです。完全な開発環境である場合もあれば、従来のプラットフォームで動作するフレームワークである場合もあります。近年私が見たもののほとんどは、既存のプラットフォームに適合するように設計されたツールです。かつては、このようなツールを使用してシステム全体を構築するという概念がありましたが、現在では(賢明にも)人々はシステムの一部にのみルールエンジンを使用する傾向があります。プロダクションルールの計算モデルは、計算問題のサブセットにのみ最適であるため、ルールエンジンはより大きなシステムに組み込まれる方が適しています。

シンプルなルールエンジンを自分で構築することができます。必要なのは、条件とアクションを持つオブジェクトをいくつか作成し、それらをコレクションに格納し、それらを走査して条件を評価し、アクションを実行することだけです。しかし、ほとんどの場合、「ルールエンジン」という用語は、ルールエンジンの構築と実行を支援するために特別に構築された製品を意味します。ルールの指定方法は、人がJavaオブジェクトとしてルールを記述するためのAPI、ルールを表すDSL、または人がルールを入力できるGUIなど、さまざまです。より効率的な実行エンジンは、特殊なアルゴリズム(Reteアルゴリズムなど)を使用して、数百のルールに関する条件を迅速に評価するのに役立ちます。

ルールエンジンの重要な特性は、連鎖です。これは、あるルールの処理部分がシステムの状態を変更し、他のルールの条件部分の値を変更する方法です。連鎖は、より複雑な動作をサポートするため魅力的に聞こえますが、簡単に推論とデバッグが非常に困難になる可能性があります。

ルールエンジン製品を使用した人々の事例をいくつか目にしましたが、毎回うまくいかなかったようです(免責事項:私は統計的に有効なサンプルではありません)。ルールエンジンの主な売り込みは、ビジネス担当者が自分でルールを指定できるようにし、プログラマーを巻き込まずにルールを構築できることです。多くの場合、これはもっともらしいように聞こえますが、実際にはめったにうまくいきません。

それでも、ビジネスで読みやすいDSLには依然として価値があり、実際、この計算モデルで価値を見出している分野でもあります。しかし、ここにも危険が潜んでいます。ルールのリストを見て、各ルールが意味をなすことを確認することは理にかなっている場合がありますが、特に連鎖がある場合、ルールの相互作用は非常に複雑になることがよくあります。そのため、ルールシステムの設定は簡単だったが、この暗黙的なプログラムフローを誰も理解できないため、保守が非常に困難だったという話をよく聞きます。これは、命令型計算モデルを放棄することの暗い側面です。命令型コードのすべての欠点にもかかわらず、それがどのように機能するかを理解することは比較的簡単です。プロダクションルールシステムでは、ある場所で単純な変更を行うと、多くの意図しない結果が生じ、めったにうまくいかないという点に簡単に到達する可能性があります。

この暗黙的な動作を制御するためのヒューリスティックを理解するには、これらのシステムを十分に時間をかけて調べていません。

  • ルール数を制限することが重要であるように思われます。実際、優れたパフォーマンスを得るために高度なアルゴリズムを必要とするだけの数のルールがあるシステムは、おそらく理解するには多すぎる数のルールを持っています。
  • 連鎖の使用方法には十分注意してください。多くの場合、ルールを整理して連鎖を制限したり、排除したりするのが最適です。
  • 多くの場合と同様に、テストはここで過小評価されることがよくありますが、暗黙的な動作によりテストがより重要になり、本番データを使用して行う必要があります。
  • ルールシステムを構築する際には、ルールベースの変更によって早期の問題が発生するようなことを行うことを検討してください。

これらすべてから、ルールエンジン製品を避けることには多くの利点があると考えるようになりました。プロダクションルールの基本的な考え方は非常に単純です。暗黙的な動作を制御するには、ルール数を制限して、ルールを狭いコンテキスト内に維持する必要があります。これは、チームがその狭いコンテキスト内でのみ動作するように設計された限定的なルールエンジンを構築する、よりドメイン固有のアプローチを支持するでしょう。ルールエンジンの使用を検討している場合は、製品と手動で作成されたドメイン固有のアプローチの両方でプロトタイプを作成して、それらの比較方法を把握することをお勧めします。

独自のシンプルなルールエンジンの構築方法の詳細(いくつかの玩具例を含む)については、プロダクションルールシステムの章を参照してください。私のDSLに関する書籍