2026年9月4日 金曜日
AI時短ラボ
検証· 約15

データ漏洩を55の公理でコーディングエージェントに検問させるomds──GEPAでMLパイプラインのコードそのものを進化させる仕組みも同梱

OSSパッケージomds(oh-my-datascience)は、train/testリーク・指標の誤用をコーディングエージェントに静的検知させるガードレール群「omds.ontology」(12パック・55公理)と、GEPAでMLパイプラインのコードを進化させ、5段階のブロッキングゲートを通ったものだけを内部PRとして昇格させる「E-GDS」を、同じコードグラフ層の上で1つのパッケージにまとめている。

データ漏洩を55の公理でコーディングエージェントに検問させるomds──GEPAでMLパイプラインのコードそのものを進化させる仕組みも同梱
執筆・編集:
目次

3行まとめ

  1. omdsは「1つのPythonパッケージが2つのことをする」構成のOSSで、①コーディングエージェント向けのデータサイエンス・ガードレール(train/testリーク検知、指標の誤用検知、データ来歴の追跡、実験台帳)と、②GEPAでMLパイプライン自身のコードを進化させるオフライン最適化器「E-GDS」を、同じ「オントロジー(公理)層」と「コードグラフ層」の上に乗せている。
  2. ガードレール層は12パック・55公理(漏洩・ターゲット漏洩・指標・評価・再現性など汎用7パック+不正検知・AML・信用リスク・クオンツ・保険の業界別5パック)を持ち、公式READMEはuv run pytestで「1478 passed, 6 skipped」を実測値として明記している。
  3. E-GDSはgepa==0.1.1optimize_anythingAPIをsingle-task searchモードで使い、変異候補は5段階のブロッキングゲート(静的公理チェック→pytest→pyright→ruff→ホールドアウトでの実行時検証)を全部通過して初めて「内部PR」として昇格できる設計になっている。

2つの顔を持つパッケージ

READMEの冒頭は、omdsを次のように説明している。

  1. コーディングエージェント向けのデータサイエンス・ガードレールツールキット ── omds-*というCLI群と、どのコーディングエージェントからも使えるポータブルな「Agent Skills」で、Pythonコードのtrain/testリークや指標の誤用をチェックし、コードグラフを通じてデータの来歴を追跡し、恒久的な実験台帳とエピソード記憶を保つ。オプションでMCPサーバーやClaude Codeプラグインとしても使える。
  2. E-GDS ── MLパイプライン向けのオフライン進化的最適化器 ── omdsコマンド(init/evolve/promote/inspect/models)が、パイプラインのワークスペース自身のコードをGEPA(Genetic-Pareto reflective evolution)で進化させ、コードグラフを使って変異箇所を狙い撃ちし、5段階のブロッキングゲートを全部通った変種だけを昇格させる。

READMEは「これらは2つの別コードベースではない」と強調しており、両方が同じ「オントロジー的グラウンディング層」(omds.ontology──漏洩・ターゲット漏洩・スコアリング・評価・再現性・シンプレックス上の注意点・宣言済み形状の汎用7パックに加え、不正検知・AML・信用リスク・クオンツファイナンス・保険向けのオプトイン5業界パックを合わせた12パック55公理)と、同じ「コードグラフ層」(omds.codegraph──AST依存関係+データ来歴)の上に立っている。GEPAの昇格を止める公理レジストリは、文字通りomds-guardrails checkがエージェントの編集したファイルに対して走らせているのと同じレジストリで、どちらもomds.ontology.static_check.runomds.ontology.axioms.default_registryと一緒に呼んでいる、とREADMEは明記している。

実際にソースコードを開いて数えると、確かに12パック・55公理だった

README記載の「12パック・55公理」という数字を鵜呑みにせず、実際にGitHub上のディレクトリとソースコードを開いて数え直した。python/omds/src/omds/ontology/packs/ディレクトリには、__init__.py_domain.py_tracing.pyという補助ファイルを除くと、ちょうど12個のPythonファイルが並んでいた——汎用7ファイル(evaluation.pyleakage.pyreproducibility.pyscoring.pyshapes.pysimplex_transforms.pytarget_leakage.py)と、業界別5ファイル(aml.pycredit_risk.pyfraud.pyinsurance.pyquant.py)で、README本文の「汎用7パック+業界別5パック」という説明と一致する。

さらに、各ファイル内で公理を表すid="ax:..."という記述の出現回数を数えたところ、次の内訳になった。

パック 公理数
insurance(保険) 10
credit_risk(信用リスク) 7
evaluation(評価) 7
aml(AML) 6
fraud(不正検知) 6
quant(クオンツ) 6
leakage(漏洩) 5
reproducibility(再現性) 3
scoring(指標) 2
shapes(宣言済み形状) 2
simplex_transforms(シンプレックス上の注意点) 1
target_leakage(ターゲット漏洩) 0(別の命名規則で定義)
合計 55

合計はちょうど55件になり、README本文の「55公理」という主張と実際のソースコードの記述が一致することを確認できた。python/omds/pyproject.toml(パッケージ本体の設定ファイル)を直接開くと、dependencies"gepa==0.1.1"という記載もあり、E-GDS部分で使われているGEPAのバージョン指定もREADMEの記述通りだった。

ガードレール層が検知するもの(12パック・55公理)

READMEが挙げる汎用パックの一部を引くと、たとえばleakageパックは「スケーラ・エンコーダ・欠損値補完・特徴量選択・Pipeline・サーチオブジェクトを全データやテスト分割に対してfitしてしまう」「SMOTEなどのリサンプリングを訓練分割の外で行う」「fillna(df.mean())のようなグローバル統計量を分割前に計算する」「GBDTの早期終了でテスト分割をeval_setに使う」「時系列データをシャッフル分割する」といったパターンを検知対象に挙げている。scoringパックは「log_loss/brier_score_lossをロジットや決定スコア、ハードラベルに対して計算する」「roc_auc_scoreのようなランキング指標を.predict()の出力に対して計算する」といった、指標の当てはめ間違いを検知する。

業界別パックは「ドメインを明示的に指定するまで無効」(README原文: "Domain packs are inert until you name the domain")で、たとえばis_fraudという列名があるだけで自動的に不正検知モデルだと推測することはしない、と明記されている。--domainフラグやpyproject.toml内の[tool.omds.guardrails]設定、あるいはtask.yamldomains:指定で有効化する。

検知結果はcertain(コードから証明可能な誤り、フックがそのターンをブロックする)・warn(コードだけでは証明できないが、実行時アサーションで確定可能)・advice(ハイジーンやベストプラクティス)の3段階で重み付けされ、# omds: ignore[ax:fit_on_train_only]のようなコメントで個別に抑制できるが、READMEは「CLI・MCPツール・フックはこの抑制コメントを尊重するが、最適化器のゲートは尊重しない」と明記している。つまりGEPAが提案する変種は、コメントで公理チェックをすり抜けることができない設計になっている。

E-GDS──5段階のブロッキングゲート

READMEが示すアーキテクチャ図によれば、E-GDSはtask.yaml(目標・データの役割・指標・許容範囲・評価予算)を起点に、オントロジー層→コードグラフ層→オフラインGEPA進化エンジンという順で処理が進む。各候補は隔離されたクローン(git worktreeuvの仮想環境、リソース制限、ネットワーク遮断)の中で評価され、以下5つのゲートを順番に、すべてブロッキングとして通過しなければならない。

ゲート 内容
ontology_static ワークスペース全体のAST公理チェック。error重大度の違反ゼロが必須(warningはゲート5の実行時証明が必要、adviceはゲートに影響しない)
pytest パイプラインワークスペース自身の契約テストスイート
pyright 型チェック(クローンのvenvにpyrightが無い場合はSKIP扱いで、ハード失敗にはならない)
ruff 正確性に関わるlintルールのみ(F, E9, B
runtime_validation ホールドアウトデータに対する実際の計装済みパイプライン実行。未解決の実行時アサーション警告ゼロ、指標がtask.yamlの許容範囲内、evolution.regression_toleranceを超える退行が無いこと

全ゲートを通過し、パレートフロンティア上で選ばれた変種は「内部PR」として扱われる。omds promote --dry-runは指標の差分・触れた公理・blame対象・トレースIDをレポートとして出すだけでマージはせず、omds promote --approve <id>mainにリベース、5ゲートを再実行してからマージする。設定のデフォルトpromotion.require_human: trueは常にレポート止まりで、人間の承認を挟む設計になっている。

進化の中核はgepa==0.1.1optimize_anythingAPIをsingle-task search(dataset=None)モードで使う部分で、GEPAのデフォルトLLMベース反射の代わりに、コードグラフに沿って狙いを絞り、オントロジー層の情報をブリーフィングとして与えるcustom_candidate_proposerを使っている。READMEは「ループの中で唯一の生きたLLM呼び出しはこの反射器(reflector)だけで、それ以外(クローン・ゲート・訓練実行)はモデルを介さない実作業だ」と説明している。

バージョンと数字の内訳

項目 内容
テスト状況 uv run pytest実測: 1478 passed, 6 skipped(うち6件はすべてオプトイン階層、加えて既存のsklearn UndefinedMetricWarning2件)
v1からの変更点 v1にあったomds run(AutoGen GraphFlowによるマルチエージェント実行ループ)はv2で削除。autogen-*依存も削除済み
GEPAバージョン gepa==0.1.1
進化対象の管理 ハーネス本体リポジトリとは別に、タスクごとの「パイプラインワークスペース」というgitリポジトリを<task_dir>/workspace/に持ち、GEPAの変種はgit worktreeクローンとして扱われる

GitHub上ではまだ誰にも見つかっていないリポジトリ

GitHubのリポジトリページを直接確認すると、本記事執筆時点でスター0・フォーク0・ウォッチャー0だった。リポジトリの作成日は2026年7月12日で、タグはpre-phase-dv0.2.0v0.3.0の3件、ライセンスはApache-2.0。55公理・12パック・GEPA連携という作り込みの割に、この記事の執筆時点ではまだ外部からの反応(スター・フォーク)が一切付いていない、ごく早期のプロジェクトだ。

テスト件数1478件は自己申告のまま、実行はしていない

上記で確認した「12パック・55公理」「gepa==0.1.1」という数字・仕様は実際のソースコードを開いて裏取りできたが、筆者は手元でomdsをインストールし、uv run pytestを実際に実行して「1478 passed, 6 skipped」という数字を再現する検証はしていない(本記事の執筆ルール上、Anthropic有料APIの新規消費を伴う検証は見送っている)。テスト件数自体は開発元の自己申告のままで、第三者による監査結果は今回の調査範囲では見つけられなかった。E-GDSの5段階ゲートについても、実際にGEPAでMLパイプラインを進化させて動かした検証はしていない。日本語圏でのZenn記事検索では「omds」という文字列自体の該当記事は見当たらなかった(一般名詞に近く検索ノイズが大きいため、この記事では「omds oh-my-datascience」という組み合わせでの言及有無までは確認していない)。

関連記事

シェア: ポスト はてブ

出典・参照資料

AIニュースの解説を動画でも

YouTubeでは注目ニュースの背景を解説し、Xでは新着記事をお知らせしています。

コメント

まだコメントはありません。最初のコメントを書いてみませんか?

AIについて聞きたいことはありますか?

質問箱で無料で受け付けています。回答は公開され、他の方の参考にもなります。

質問箱を見る →

新しい記事をメールで受け取る

AIの新しい発表を、出典付きで整理して届けます。

関連記事