コンテンツにスキップ

Planner

計画のポート — 低コストな観察を、シリアライズ可能な RoutePlan へ。

英語版が原文です。

プロトコル: Planner.plan(request: PlanRequest, loaded: PreloadedSource | None = None) -> PlanResult

Planner は、ソースを検査し、indx がそれをどう処理すべきかを選択するための境界です。ソース、ルーティング制約、省略可能な固定済み機能スナップショット、要求された埋め込み空間、シグネチャ検出の指定を受け取ります。シリアライズ可能なルート計画を返します。

計画は、ドキュメント、ページ、リージョンの各スコープでルートを特定します。各割り当ては、選択された機能と順序付きフォールバック、そして公開の判断理由を含みます。計画はさらに、ソースダイジェスト、メディアタイプ、機能スナップショット、ポリシーバージョン、見積もり、そしてリクエストが ready か制約未充足かを記録します。

計画を実行から分離することで、高価なパーサー、OCR システム、モデル、埋め込み器が動く前に、ルーティングを低コストで検査できます。呼び出し側は、提案された作業を実行とは独立に理解、保存、比較、承認できます。

結果を正規化済みの入力とバージョン付きの判断コンテキストに束縛することで、同一の計画リクエストは再現可能になり、後の実行が黙って別のルートを選ぶことも防がれます。

入力は PlanRequest で、リクエスト ID、ソース、制約、省略可能な機能スナップショット ID、埋め込み空間 ID、シグネチャ検出フラグを運びます。

loaded はすでに手元にあるそのソースで、省略可能です。何も読み込んでいない呼び出し側はこれを省略し、プランナーが取得します。すでにバイト列を持っている呼び出し側はそれを渡します。エグゼキューターがまさにその呼び出し側です。計画を渡さないエンコードはソースを読み込んで観察しますが、これ以前は plan() の中で二度目の転送と、すでに得た判定と食い違いうる二度目の SSRF 判定にも払っていました。PreloadedSource はモデルではなく indx-interfaces の構造的プロトコルです。作業用のコピーは indx-source に private のままであり、indx-interfaces はその下にあってこれをインポートできません。ワイヤーに載るものは何もなく、PlanRequest は変わりません。

出力は RoutePlan で、次を運びます。

  • 決定的な計画 ID と、呼び出し側のリクエスト ID。
  • ソースダイジェスト、メディアタイプ、機能スナップショット ID、ポリシーバージョン。
  • スコープ付きの選択済みルートと、順序付きフォールバック。
  • 判断理由と、省略可能なシグネチャ一致。
  • 要求された埋め込み空間と、コスト・レイテンシ・品質の見積もり。
  • ready または unsatisfied のステータスと、明示的な未充足制約。
  • 計画中はソースの低コストな観察だけを行う。呼び出し側が signature_detection を指定した場合に限り、それはインストール済みの SignatureDetector 実装を作成し、何を認識するか尋ねることまで広がります。これは「計画は何も呼び出さない」の計画時における唯一の例外であり、呼び出し側のオプトインによるもので、事前観察(preflight)と同じ予算に縛られます。
  • kind の固定ラダー上でルーティングする — テキスト層があればネイティブ抽出、次に OCR、次にビジョンモデル、最後に手動レビュー(manual review)。機能 ID に対しては決して行いません。parser が意図的にラングでないのは、パーサーが「何かが先に認識したドキュメントに対してのみ正しい」専用機能だからです。シグネチャによるノミネーションがその唯一の扉であり、フォーマットを汎用的に読む機能は、その仕組みがどれほど専門的でも native_extraction を宣言します。パーサーだけが宣言するメディアタイプをシグネチャ検出なしで計画すると、黙って手動レビュールートになるのではなく、パーサー名とフラグを明記した unsatisfied な計画になります(POLICY_VERSION 0.5.0。以前からルーティング可能だったすべての入力の判断は変わりません)。
  • ラダーと kind の集合を、閉じたファーストパーティのものとして扱う。kind は 6 つ、エスカレーションのラングは 3 つ、デバイス優先は 1 つ、ポリシーが読む事前観察の signal は 2 つ。ディストリビューションをインストールしてもどれも増えません。それぞれが「ルーティング先となるモノ」ではなく、「indx が何にルーティングするか」というポリシーの判断だからです。作業が 6 つのどれでもないディストリビューションは最も近い kind を宣言し、デプロイ側が INDX_ROUTING_ECONOMICS で数値を補正します。ポリシーが読まない signal は、誤りではなく無効です。kind、ラング、意味の追加は、POLICY_VERSION の更新を伴うファーストパーティの変更です。
  • ドキュメントスコープまたはページスコープのシグネチャからのみノミネートする。リージョンスコープの一致は計画に載りますが、何もルーティングしません。それはページの一部についての主張であり、それがなるべきリージョン割り当ては存在せず、ページへ昇格させれば「このリージョンに請求書の表がある」を「このページは請求書である」と読み替えることになります(POLICY_VERSION 0.7.0。ファーストパーティのパーサーはリージョンスコープの一致を出さないため、以前到達可能だった入力のルートは変わりません)。
  • 要求された埋め込み空間の拒否は、名前付きレーンではなく、実行が生成するものに対して判断する。空間が unsatisfied となるのは、実行がドキュメント埋め込み器に渡す入力を 1 つも埋め込めないときで、それは DOCUMENT_EMBEDDING_MODALITIES が一度だけ述べます(POLICY_VERSION 0.6.0)。ドキュメントロールの画像埋め込み器を宣言する空間は、以前は「実際には持っているテキスト埋め込み器を欠いている」と報告されていました。実行がレンダリング済みのページを生成するようになってこのリストが image を得たため、そうした空間は unsatisfied ではなくルーティング可能になりました。その結果 1 つの空間が 2 つの埋め込み器を実行しうるため、デバイスの規則は最初の 1 つではなくそれぞれに適用されます(POLICY_VERSION 0.8.0)。
  • ノミネートされた機能は汎用ラダーの前に置き、ラダーの代わりには決して置かない。シグネチャは推測であり、フォールバックを押しのける推測は、誤った一致をドキュメントの失敗に変えてしまいます。
  • ディテクターには固定順で問い合わせ、一致はその内容で並べる。これにより、発見順が plan_id に届くことはありません。
  • ディテクターに計画を失敗させない。ロードできない、例外を投げる、シグネチャでないものを返すディテクターは何も寄与せず、ログに残ります。シグネチャなしは、それ自体がすでに完全な答えです。
  • リクエストを、選択された機能スナップショットとルーティングポリシーに対して評価する。
  • そのスナップショットに存在する機能 ID と埋め込み空間 ID だけを選択する。
  • 品質、レイテンシ、コスト、ハードウェア、レジデンシー、埋め込み空間、スナップショットの制約を適用する。
  • 同一の正規化済み入力・ポリシー・スナップショットに対して、決定的な出力を生成する。
  • 各ルートが選択された理由を説明し、適格なフォールバックを保持する。
  • 制約を満たせないときは、明示的な unsatisfied な計画を返す。

このプロトコルが記述するのは計画の振る舞いであり、事前観察の内部ではありません。証拠の語彙は公開されています — PageEvidenceRegionEvidenceTextLayerState と signal 定数は indx-interfaces にあります。オブザーバーは独立したディストリビューションとして配布され、名付けられない証拠は出せないからです。事前観察のコンテキスト全体と作業用レジストリモデルは、ルーター実装の内部にとどまります。コンテキストは計画が束縛されるソースダイジェストを運び、それをそこで発行することが、インストール済みオブザーバーが自分で取得していないソースの識別子を名乗ることを防ぎます。SourceObserver を参照してください。

公開の indx.plan() ファサードと POST /v1/plan オペレーションは、プランナーに委譲します。返される PlanResult は計画を plan に運び、それはそのまま検査することも実行ワークフローに渡すこともできます。その隣の components には、それを生み出したローダー、sniffer、オブザーバーがディストリビューション名で、ハッシュされるアーティファクトの外に載ります。計画を渡さないエンコードは、まず合成された indx サービスを通じて、すでに読み込んだバイト列を渡しながら計画を取得し、そのトレースはプランナーの中で観察したオブザーバーを名指しします。