Prolog Reasoner について
Prolog Reasonerは、形式論理や探索を必要とするLLMワークフロー向けに、SWI-Prologの実行機能をMCPサーバーとPythonライブラリで提供します。再利用可能なルールベースに対応し、Prologコードを確認してデバッグできます。
主な機能
- 01SWI-Prologコードとクエリの実行
- 02名前付きルールベースの保存と再利用
- 03CLP(FD)制約のサポート
- 04Prologコードの確認とデバッグ
- 05自然言語からPrologへの変換を行うPythonライブラリ
活用シーン
- 01制約充足問題の解決
- 02複数段階の論理推論の実行
- 03クエリ間で安定したドメインルールを再利用
MCP 対応
MCPサーバーは`execute_prolog`と、名前付きルールベースの一覧表示、取得、保存、削除を行う4つのツールを公開します。接続クライアントが渡したPrologコードを実行し、外部のLLM APIは呼び出しません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
5掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| query | string | はい | 実行する Prolog クエリ(例:"mortal(X)")。 |
| trace | boolean | いいえ | True の場合、各解について構造化された証明木を metadata.proof_trace に含めます。メタインタープリターのオーバーヘッドが増加します。オプトイン機能です。 |
| rule_bases | any | いいえ | 含める、以前に保存したルールベースの名前。ルールは 指定した順序で ``prolog_code`` の先頭に追加されます。クエリ間で再利用する必要がある ドメイン固有のルール(ゲームの仕組み、法律上の ルールなど)に使用します。 |
| max_results | integer | いいえ | 結果の最大数(無限ループを防止します)。 |
| prolog_code | string | はい | Prolog コード(事実とルール)。 |
詳細
prolog-reasoner
LLM 向けの「論理計算機」としての SWI-Prolog — MCP サーバーおよび Python ライブラリとして利用できます。LLM の論理的推論におけるブラックボックスを解消します。
LLM は自然言語を得意としますが、形式論理には苦戦します。Prolog は論理的推論を得意としますが、自然言語を処理できません。prolog-reasoner は、LLM に SWI-Prolog の実行機能を提供することで、このギャップを埋めます。
役に立ちますか?
組み込みの 30 問の論理ベンチマークでは、次の結果が得られました。
| パイプライン | 正解率 |
|---|---|
LLM のみ(claude-sonnet-4-6) | 22/30(73.3%) |
| LLM + prolog-reasoner | 27/30(90.0%) |
差が生じるのは、制約充足や複数段階の推論に集中しています。これは、LLM が苦手で Prolog が得意とする組み合わせ論的な領域です。詳細な内訳はこちらをご覧ください。
効果の理由
LLM はパターンマッチングを行いますが、Prolog は実際に探索して解を求めます。LLM が問題を Prolog で記述すると、同時に次の 2 つのことが起こります。
- Prolog が、LLM の苦手とする組み合わせ論的な処理(制約充足、複数段階の推論、網羅的な探索)を担います。
- 推論が、読んで再実行やデバッグができるコードとして残ります。うまくいかない場合は、失敗した Prolog とその理由を正確に確認できます。
2 つの使い方
- MCP サーバー — Claude(または任意の MCP クライアント)が、会話中に論理ソルバーとして呼び出します。ルールベースを使うと、LLM は安定したドメインルールを一度保存し、呼び出しごとに名前で参照できます。
- Python ライブラリ — 自己修正機能を備えた、自然言語から Prolog への完全なパイプラインです。OpenAI または Anthropic が必要です。
機能
- MCP ツール:任意の SWI-Prolog 実行に使う
execute_prologと、再利用可能な名前付きルールベースを管理するlist_rule_bases/get_rule_base/save_rule_base/delete_rule_base(v14) - ルールベース:安定した Prolog ルール(チェスの移動ルールや法律上の公理など)を一度保存し、
execute_prologから名前で参照できます。これにより、LLM は呼び出しごとに状況固有の事実だけを記述できます。 - 透明性の高い中間表現:Prolog コードが監査記録となり、実行前に確認、変更、検証できます。
- CLP(FD) のサポート:スケジューリングや最適化のための制約論理プログラミング
- 失敗による否定、再帰、SWI-Prolog の標準機能すべて
- ライブラリモード:自己修正ループを備えた自然言語から Prolog への変換(OpenAI / Anthropic)
要件
- Python ≥ 3.10
- SWI-Prolog がインストールされ、PATH に設定されていること(≥ 9.0)
- OpenAI または Anthropic の API キー — ライブラリモードでのみ必要。MCP サーバーでは不要です。
インストール
# MCP server only (no LLM dependencies)
pip install prolog-reasoner
# Library with OpenAI
pip install prolog-reasoner[openai]
# Library with Anthropic
pip install prolog-reasoner[anthropic]
# Both providers
pip install prolog-reasoner[all]
MCP サーバーのセットアップ
MCP サーバーは 5 つのツールを公開します。execute_prolog は接続された LLM が記述した Prolog コードを実行し、4 つのルールベース用ツールは名前付きの再利用可能な Prolog モジュールを管理します。外部の LLM API は呼び出さないため、API キーは不要です。
Claude Desktop / Claude Code
{
"mcpServers": {
"prolog-reasoner": {
"command": "uvx",
"args": ["prolog-reasoner"]
}
}
}
または、prolog-reasoner を直接インストールしている場合:
{
"mcpServers": {
"prolog-reasoner": {
"command": "prolog-reasoner"
}
}
}
Docker(SWI-Prolog 同梱)
SWI-Prolog をローカルにインストールしたくない場合は、Docker を使用してください。
docker build -f docker/Dockerfile -t prolog-reasoner .
{
"mcpServers": {
"prolog-reasoner": {
"command": "docker",
"args": ["run", "-i", "--rm", "prolog-reasoner"]
}
}
}
ツールのリファレンス
execute_prolog(prolog_code, query, rule_bases=None, max_results=100, trace=False)
prolog_code— Prolog の事実とルール(文字列)query— 実行する Prolog クエリ。例:"mortal(X)"(文字列)rule_bases—prolog_codeの前に追加する、保存済みルールベース名の任意のリスト(指定順)。呼び出しのたびに再送信せずに、安定したドメインルールを再利用する場合に使用しますmax_results— 返される解の最大数(デフォルトは 100)trace—Trueの場合、各解の構造化された証明木をmetadata.proof_traceに追加します。任意で有効にできるサブ機能です。パフォーマンスへの影響があり、CLP(FD)、高階述語、assert/retract はサポートしていません。
success、output、query、error、metadata を含む JSON オブジェクトを返します。
成功時、metadata には execution_time_ms、result_count、truncated、rule_bases_used が含まれます。ルールベースが指定されていた場合は、rule_base_load_ms(ディスク I/O の所要時間)も追加されます。失敗時、metadata には error_category(syntax_error、undefined_predicate、unbound_variable、type_error、domain_error、evaluation_error、permission_error、timeout、trace_mechanism_error、unknown のいずれか)と、接続された LLM(または人間)が Prolog コードの修正方法を判断するための自然言語によるヒント error_explanation も含まれます。
ルールベース用ツール — PROLOG_REASONER_RULES_DIR(デフォルトは ~/.prolog-reasoner/rules/)以下に、名前付きの再利用可能な Prolog モジュールを管理します。名前には [a-z0-9_-] のみ使用でき、長さは 1~64 文字です。
save_rule_base(name, content)— ルールベースを書き込み、または上書きします。書き込み前に内容の構文を検証します(解析のみ)。検証に失敗するとRULEBASE_003が返されます。{"success": true, "name": ..., "created": bool}を返します。初回の書き込みではcreatedがtrue、上書きではfalseになります。max_rule_sizeを超えるファイルはRULEBASE_005で拒否されます。list_rule_bases()— 保存済みのすべてのルールベースを、name、description、tagsとともに返します。メタデータは、各ファイルの先頭にある% description:/% tags:コメントから抽出されます。get_rule_base(name)— 保存済みルールベースの Prolog ソースをそのまま返します。delete_rule_base(name)— 保存済みルールベースを削除します。
名前、サイズ、存在に関するエラーが発生した場合、ツールは例外を発生させるのではなく、{"success": false, "error": "...", "error_code": "RULEBASE_001"|"RULEBASE_002"|"RULEBASE_003"|"RULEBASE_005"} を返します。I/O エラー(RULEBASE_004)はインフラストラクチャエラーとして伝播します。
ルールベースの規約 — 各ルールベースファイルの先頭に、list_rule_bases のメタデータとしても機能するコメントを記述します。
% description: Chess piece movement rules
% tags: chess, games
piece_move(knight, (X1,Y1), (X2,Y2)) :- ...
次に、execute_prolog から参照します。
{
"rule_bases": ["chess_moves"],
"prolog_code": "position(knight, (4,4)).",
"query": "piece_move(knight, (4,4), Target)"
}
ルールベースは、ドメインに特化したフォークの基盤としても機能します。法律上の公理、ゲームルール、税務シナリオなどを厳選したセットとして BUNDLED_RULES_DIR に同梱し、すぐに使える推論パッケージとして提供できます。
ライブラリの使用方法
ライブラリは、PrologExecutor(Prolog 専用、LLM 不要)と PrologReasoner(自然言語から Prolog へのパイプライン。LLM API キーが必要)を公開しています。
Prolog を直接実行する(LLM 不要)
import asyncio
from prolog_reasoner.config import Settings
from prolog_reasoner.executor import PrologExecutor
async def main():
settings = Settings() # no API key needed
executor = PrologExecutor(settings)
result = await executor.execute(
prolog_code="human(socrates). mortal(X) :- human(X).",
query="mortal(X)",
)
print(result.output) # mortal(socrates)
asyncio.run(main())
完全な自然言語から Prolog へのパイプライン(LLM API キーが必要)
import asyncio
from prolog_reasoner import PrologReasoner, TranslationRequest, ExecutionRequest
from prolog_reasoner.config import Settings
from prolog_reasoner.executor import PrologExecutor
from prolog_reasoner.translator import PrologTranslator
from prolog_reasoner.llm_client import LLMClient
async def main():
settings = Settings(llm_api_key="sk-...") # from env or explicit
llm = LLMClient(
provider=settings.llm_provider,
api_key=settings.llm_api_key,
model=settings.llm_model,
timeout_seconds=settings.llm_timeout_seconds,
)
reasoner = PrologReasoner(
translator=PrologTranslator(llm, settings),
executor=PrologExecutor(settings),
)
translation = await reasoner.translate(
TranslationRequest(query="Socrates is human. All humans are mortal. Is Socrates mortal?")
)
print(translation.prolog_code)
result = await reasoner.execute(
ExecutionRequest(prolog_code=translation.prolog_code, query=translation.suggested_query)
)
print(result.output)
asyncio.run(main())
設定
すべての設定は環境変数で行います(プレフィックスは PROLOG_REASONER_)。
| 変数 | デフォルト値 | 必要な対象 |
|---|---|---|
LLM_PROVIDER | openai | ライブラリ(openai または anthropic) |
LLM_API_KEY | "" | ライブラリのみ — MCP では設定しないでください |
LLM_MODEL | gpt-5.4-mini | ライブラリ |
LLM_TEMPERATURE | 0.0 | ライブラリ |
LLM_TIMEOUT_SECONDS | 30.0 | ライブラリ |
SWIPL_PATH | swipl | 両方 |
EXECUTION_TIMEOUT_SECONDS | 10.0 | 両方 |
RULES_DIR | ~/.prolog-reasoner/rules | 両方(ユーザーが保存したルールベースの格納先) |
BUNDLED_RULES_DIR | 未設定 | 両方(任意 — フォークにデフォルトのルールを同梱するため、初回起動時に RULES_DIR に同期されます) |
MAX_RULE_SIZE | 1048576(1 MiB) | 両方(ファイルごとの保存上限。save_rule_base は上限を超える内容を RULEBASE_005 で拒否します) |
MAX_RULE_PROMPT_BYTES | 65536(64 KiB) | ライブラリのみ(「利用可能なルールベース」プロンプトセクション全体の上限。超過した場合はマーカーを付けて切り詰められます) |
LOG_LEVEL | INFO | 両方 |
ベンチマーク
benchmarks/ には、LLM のみの推論と LLM + Prolog の推論を比較するための、5 つのカテゴリ(演繹、推移関係、制約、矛盾、複数ステップ)にわたる 30 個の論理問題が含まれています。このベンチマークでは、NL→Prolog の変換ステップが必要なため、ライブラリの経路(変換器 + 実行器)をテストします。
結果
anthropic/claude-sonnet-4-6 で、30 問を 1 回実行して測定しました。
| パイプライン | 正答率 | 平均レイテンシ |
|---|---|---|
| LLM のみ | 22/30(73.3%) | 1.7s |
| LLM + Prolog | 27/30(90.0%) | 3.8s |
カテゴリ別の内訳:
| カテゴリ | LLM のみ | LLM + Prolog |
|---|---|---|
| 演繹 | 6/6 | 6/6 |
| 推移関係 | 6/6 | 5/6 |
| 制約 | 3/7 | 6/7 |
| 矛盾 | 4/4 | 3/4 |
| 複数ステップ | 3/7 | 7/7 |
差が顕著なのは、制約(SEND+MORE、6 クイーン、ナップサック問題、K4 の彩色、Einstein-lite)と複数ステップ(ニムのゲーム理論、3 人の騎士と悪漢、TSP-4、シマウマパズル)です。これらは、記号ソルバーがパターン補完を上回る組合せ探索中心の領域そのものです。純粋な演繹や推移関係の問題では LLM はすでに高い性能を発揮しており、Prolog を使っても精度は上がらず、レイテンシだけが増加します。
LLM + Prolog の失敗 3 件はすべて、推論ミスではなく、LLM が生成したコードの不備(述語定義の欠落、束縛されていない CLP(FD) 変数)による Prolog 実行エラーでした。これらはプロンプトの調整で対処できます。特筆すべき点として、失敗はすべて検証可能です。説明のない誤った自然言語の回答ではなく、失敗した Prolog コードそのものと失敗理由を確認できます。
自分で実行する
docker run --rm -e PROLOG_REASONER_LLM_API_KEY=sk-... \
prolog-reasoner-dev python benchmarks/run_benchmark.py
結果は benchmarks/results.json に保存されます。
他の Prolog MCP との比較
Prolog MCP サーバーはいくつか存在し、それぞれ設計上の選択が異なります。prolog-reasoner は意図的にステートレスで、必要なときだけ使う設計です。Prolog は論理が重要なときに呼び出す計算機であり、エージェントの記憶の基盤ではありません。
| prolog-reasoner | Stateful Prolog MCPs | |
|---|---|---|
| Prolog の役割 | 呼び出しごとの推論ツール | プロジェクト全体のナレッジベース |
| 状態 | ステートレスな実行(各呼び出しは独立)。再利用可能な静的ルールのための名前付きルールベースは任意で指定できますが、呼び出し間で共有されるセッションメモリはありません | 永続セッション/階層化された KB |
| 再現性 | 同じ入力(同じルールベースを含む)なら、常に同じ出力になります | 蓄積された状態に依存します |
| 統合にかかる労力 | 論理が重要な場面で使い、そうでない場面では使わずに済みます | アーキテクチャ上のコミットメントが必要です |
| LLM のみの場合との A/B テスト | 可能(各呼び出しが統制された実験になります) | 構造上、比較できません |
精度ベンチマークをここで公開しており、他所では公開していないのもこのためです。ステートレスであることで、同条件での比較が可能になります。
永続的なエージェントメモリ、ハルシネーションを防ぐ事実の保存、または完全なニューロシンボリック基盤が必要な場合は、他のプロジェクトのほうが適している可能性があります。
- adamrybinski/prolog-mcp — 保存/読み込み可能なセッションに対応する Trealla WASM
- umuro/prolog-mcp — ファイルベースの永続化に対応する階層化 KB
- vpursuit/model-context-lab — セキュリティサンドボックス機能を備えた SWI-Prolog
- dr3d/prolog-reasoning — 書き込み経路の安全性を備えたニューロシンボリックメモリ
私たちは必要なときだけ使う選択肢です。
開発
# Build dev image
docker build -f docker/Dockerfile -t prolog-reasoner-dev .
# Run tests (no API key needed — LLM calls are mocked)
docker run --rm prolog-reasoner-dev
# With coverage
docker run --rm prolog-reasoner-dev pytest tests/ -v --cov=prolog_reasoner
# Or via docker compose
docker compose -f docker/docker-compose.yml run --rm test
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。