Proven について
Provenは、AI生成コードを使うチーム向けのPythonコードチェッカーです。インポートや呼び出し、事実の出典、モデル出力の検証、エラー処理、テストをルールに沿って確認し、MCP経由でエージェントに結果を渡せます。
主な機能
- 01requirementsとインストール済みパッケージに基づくインポート確認
- 02存在しない呼び出しや手入力の事実の検出
- 03モデル出力の検証状態の追跡
- 04握りつぶされたエラーや不足・不十分なテストの検出
- 05コマンドライン、pre-commit、GitHub Actions、MCPサーバー対応
活用シーン
- 01マージ前のAI生成Pythonコードの確認
- 02コード内の古い事実や出典のない値の検査
- 03エージェントへの実行可能なコードレビュー結果の提供
MCP 対応
ProvenはMCPクライアントに`proven_check`、`proven_explain`、`proven_rules`ツールを公開し、エージェントによるチェック実行とルール確認を可能にします。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
3掲載時のツール一覧 · 5 日前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| path | string | はい | プロジェクトフォルダー(proven.toml がある場所)または単一ファイルの絶対パス。 |
| files | array | いいえ | 省略可:これらのファイルまたはフォルダーのみを対象にします。パスは絶対パスまたはプロジェクトルートからの相対パスです。 |
詳細
Proven
AI が書いたコードの判定ツールです。 構文は通常の Python です。ルールはハルシネーションを防ぎます。
基本原則は、証明されるまでは何も存在しないということです。パッケージが存在するのは、requirements でバージョンが固定されている場合です。関数が存在するのは、インストール済みのバージョンに含まれている場合です。事実が存在するのは、出典と日付がある場合です。モデルの回答がユーザーに届くのは、チェックに合格した後です。関数が動作するのは、テストで証明された場合です。
理由
AI モデルは、人が読み切れないほど多くのコードを書きます。成功する言語とは、コンパイラーがレビュアーの役割を果たす言語です。TypeScript は 2025 年に GitHub で第 1 位の言語になりました(GitHub Octoverse 2025)。GitHub は、型付き言語によって AI 支援コードの信頼性が高まることが、その理由だとしています。新しい言語が答えではありません。モデルは新しい言語をほとんど知りません。役立つのは、モデルが最もよく知っている古い言語に、厳格な判定ツールを組み合わせることです。TypeScript が JavaScript の上に築かれたのと同じです。
Proven は Python に対して同じことを行いますが、型エラーではなくハルシネーションを検出します。
6 つのルール
| コード | ルール | 検出するもの |
|---|---|---|
| P1 | インポート先が実在する | 捏造されたパッケージ、バージョンが固定されていないパッケージ、インストールされていないモジュール |
| P2 | 呼び出し先が実在する | 存在しない関数、クラス、属性、モジュール |
| P3 | 記憶に基づく事実を使わない | 手入力された公的統計、税率、法律の条文番号、URL、古くなった事実 |
| P4 | モデルの出力を検証する | チェックなしでユーザーやデータベースに渡されるモデルの回答、不正に偽装されたチェック |
| P5 | エラーを握りつぶさない | 裸の except、何も出力しない except: pass |
| P6 | 関数をテストで証明する | テストのない公開関数、何も検証しないテスト |
各ルールの詳細:SPEC.md。
実際のコード
examples/bad/bot.py のコードは、誰にもチェックされない場合に AI モデルが書くコードの例です。カザフスタン向けの法律回答ボットです。
import anthropik # a typo
MRP = 3932 # Kazakhstan's monthly index, the 2025 value "from memory"
def handle(phone, question):
raw = llm(question)
answer = f"{raw}\n\nLegal basis: Article 46 of the Labour Code"
try:
json.loadz(answer)
except:
pass
send(phone, answer)
判定ツール:
$ python proven.py check examples/bad
Proven 0.2.0 · root: /path/to/proven/examples · python: /usr/bin/python3 3.12.3 · requirements: requirements.txt · packages from: the judge's own
bad/bot.py:4:1 P1 package "anthropik" is not in requirements.txt — it may be invented
bad/bot.py:5:1 P1 version of "requests" is not pinned with == (now: ">=2.31")
bad/bot.py:7:1 P3 "MRP" is a number typed from memory — it needs a dated source
bad/bot.py:9:10 P3 address "adilet.zan.kz" typed by hand — move it to a config or allowed_url_hosts
bad/bot.py:12:1 P6 function "llm" is not called in any test
bad/bot.py:16:5 P4 public function "llm" returns unverified model output — annotate it "-> Unverified" or return verify(...)
bad/bot.py:19:1 P6 function "send" is not called in any test
bad/bot.py:23:1 P6 function "handle" is not called in any test
bad/bot.py:25:14 P3 law article number typed by hand: "Article 46" — take it from the database
bad/bot.py:27:9 P2 module "json" has no name "loadz"
bad/bot.py:28:5 P5 bare except catches everything, even Ctrl+C and program exit
bad/bot.py:30:5 P4 unverified model output goes into "send"
How to fix:
P1 Imports are real — Check the exact package name on PyPI, add a name==version line ...
...
Proven: 12 issue(s) in 1 file(s). Code rejected.
同じボットをルールに従って修正したものです — examples/good/bot.py:
MRP = Fact(4325, source='Law of the Republic of Kazakhstan "On the Republican Budget '
'for 2026–2028" No. 239-VIII',
date="2026-01-01")
def ask_model(question, llm) -> Unverified:
return unverified(llm(question))
def answer(question, llm, checker, send):
raw = ask_model(question, llm)
send(verify(raw, checker)) # the user only gets what has been verified
$ python proven.py check examples/good
Proven: no issues. Code accepted.
クイックスタート
Python 3.11 以降。依存関係はありません。標準ライブラリのみを使用します。
pip install proven-judge # the package is "proven-judge", the command is "proven"
proven init # create proven.toml
proven check # check the project
終了コード:0 — コードに問題なし、1 — 問題あり。機械処理向けには --json を使用できます。
proven rules # list the rules
proven explain P4 # explain a rule
コードでは from proven_types import Fact, Unverified, unverified, verify をインポートし、requirements.txt に proven-judge==0.2.0 を追加します(Proven にも P1 が適用されます)。
インストールしない場合は、proven.py と proven_types.py をプロジェクトにコピーして、python proven.py check を実行してください。
pre-commit
# .pre-commit-config.yaml
repos:
- repo: https://github.com/malikabyl/proven
rev: v0.2.0
hooks:
- id: proven
このフックは変更されたファイルだけでなく、プロジェクト全体をチェックします。P6 ではテストを確認する必要があるためです。
GitHub Actions
- uses: actions/checkout@v4
- uses: malikabyl/[email protected]
問題は、プルリクエストの該当行への注釈とジョブの概要に表示されます。入力項目:path(実行するフォルダー)、args(proven check に渡す追加引数)、python(依存関係がインストールされているインタープリター。P1 と P2 が依存関係を確認できるようにします。デフォルトは python3 です)。GitHub Actions の外では、proven check --github を実行すると同じ注釈が表示されます。
MCP サーバー
Proven は MCP サーバーでもあるため、AI エージェントが判定ツールを直接呼び出せます。ツールは proven_check、proven_explain、proven_rules です。追加パッケージは必要ありません。
Claude Code:
claude mcp add proven -- uvx proven-judge mcp --no-installed-check
その他のクライアント(Claude Desktop、Cursor など):
{
"mcpServers": {
"proven": {
"command": "uvx",
"args": ["proven-judge", "mcp", "--no-installed-check"]
}
}
}
uvx はサーバーを独立した環境で実行するため、プロジェクトのパッケージはインストールされていません。そのため、--no-installed-check を指定します。パッケージのインストール状況もチェックする(P1)には、代わりにプロジェクトの環境からサーバーを実行します。pip install proven-judge を実行してから、proven mcp を実行してください。エージェントには、プロジェクトの絶対パスを渡します。
AI モデルとのループ
Proven は、AI モデル向けのコンパイラーのように機能します。モデルがコードを書き、判定ツールが問題点と修正方法を伝え、モデルが修正します。判定ツールのメッセージは、そのままモデルに渡せるように書かれています。
Claude Code。 リポジトリにはすでに .claude/settings.json があります。.py ファイルを編集するたびに判定ツールがチェックし、問題があれば Claude がレポートを受け取って修正します。.claude フォルダーをプロジェクトにコピーしてください。
プロンプト内のルール。 システムプロンプトまたは CLAUDE.md 用のチートシートは PROMPT.md にあります。モデルは最初からルールに従い、残りの問題を判定ツールが検出します。
GitHub。 ワークフロー .github/workflows/proven.yml は、プッシュとプルリクエストのたびに判定ツールとテストを実行します。
既存のプロジェクト
古いコードでは、判定ツールが多くの問題を一度に見つけます。一日ですべてを修正しなくて済むようにするには、次のようにします。
python proven.py baseline
現在の問題は、古い負債として .proven-baseline.json に記録されます。それ以降、判定ツールはそれらをスキップしますが、新しい問題は拒否します。負債を少しずつ返済し、ベースラインを書き換えてください。
プロジェクトの Python で判定ツールを実行してください。 P1 と P2 はインストール済みパッケージを調べます。各レポートの最初の行には、判定ツールが何を使って測定したか、つまりプロジェクトのルート、Python、requirements ファイル、読み取った環境が記載されます。proven.toml がない場合、ルートは pyproject.toml、requirements.txt、または .git がある最も近いフォルダーになります。判定ツールが独自の環境で実行される場合、プロジェクトの .venv(または venv、env、$VIRTUAL_ENV)も読み取ります。そこにあるパッケージはインストール済みとして扱われ、含まれる名前はインポートせずにコードを読み取ってチェックされます。
テストがまったくないプロジェクトでは、関数ごとに問題が出るのではなく、P6 の問題が 1 件出ます。テストが用意されるまでは、disable = ["P6"] にしてレポートを読みやすくできます。
免除
最終判断を下すのは人間です。理由を添えれば、1 行だけルールを無効にできます。
MRP = 3932 # proven: allow P3: computing an archived 2025 fine
理由のない免除自体が問題(P0)になります。コメントは同じ行か、その前の行に記述します。P5 の場合は、説明を書くことが多いハンドラーの中に記述することもできます。
except OSError:
pass # proven: allow P5: logging a call must not break the answer to the client
意図的に、通常のコメントだけでは不十分です。モデルは「pass」と同じくらい簡単に「# intentional」と書けてしまうからです。ロシア語のキーワードも使えます。# proven: разрешить P3: reason。
正直な限界
判定ツールが検出するのは、捏造されたものであり、間違ったものではありません。
- P3 は、事実に出典と新しい日付があるかをチェックしますが、その値が法律と一致しているかはチェックしません。出典と照らし合わせるのは、人または
verify()内のチェックの役割です。 - P2 は、モジュールとクラス内の名前をチェックします。オブジェクトのメソッド(
response.jsonn())は静的にはチェックできません。テストで検出します(P6)。 - P2 は、内部を調べるために判定ツール自身の環境にインストールされたパッケージをインポートします。その際、パッケージのインポートコードが実行されます。プロジェクトの
.venvにあるパッケージはインポートせずに読み取ります。check_attributes = falseにすると無効にできます。 - P4 は、ファイル内および名前で識別した関数間のデータの流れを追跡します。慎重に判定するため、判断に迷う場合はデータを未検証として扱います。モデル出力を返す公開関数には、
-> Unverifiedを付ける必要があります。別のファイルで作成されたモデルクライアントは、その関数名がsourcesに記載されている場合にのみ認識されます。 - P6 は、モジュールではなく関数名で関数とテストを対応付けます。
- 間違っていても一貫性のあるロジックは、どの静的判定ツールでも検出できません。テストと最終判断で検出してください。
レイアウト
proven.py the judge (CLI)
proven_types.py Unverified, Verified, verify(), Fact
proven.toml settings (the judge checks itself)
SPEC.md the rules in detail and every setting
CHANGELOG.md what changed in each version
PROMPT.md a cheat sheet for an AI model
examples/bad code with hallucinations
examples/good the same code following the rules
tests/ the judge's tests
pyproject.toml the proven-judge package
action.yml the GitHub Action
server.json the MCP Registry entry
.pre-commit-hooks.yaml the pre-commit hook
.claude/settings.json the hook for Claude Code
.github/workflows/ the check on GitHub and the release to PyPI
リリース:proven.py の VERSION を更新し、タグ vX.Y.Z を付けて GitHub リリースを公開します。release ワークフローは、タグ、VERSION、server.json の値が一致していることを確認し、パッケージをビルドして PyPI に公開した後、MCP Registry に公開します。VERSION と合わせて、server.json の2つのバージョンも更新してください。
判定器自体を確認します。
pip install -r requirements-dev.txt
python proven.py check # the judge accepts itself
python -m pytest
サンプルに記載されている値(カザフスタンの MRP など)は、2026年11月3日に情報源と照合済みで、参考例として掲載しています。実運用のコードでは、カザフスタンの公式法律データベースである adilet.zan.kz で確認してください。
ライセンス
MIT。詳しくは LICENSE をご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。