コンテンツにスキップ

専用パーサー

低コストのオプトイン署名検出によって、汎用ルーティングラダーより前へ指名されるパーサーを追加します。

パーサーはすべての汎用ルートへ追加されるのではなく、適合する文書で指名されます。読み取りとともに SignatureDetector プロトコルの低コストな検出を実装し、--signatures または signature_detection=True で要求します。cheap_signals()extract_text()extract_fields() は独自コードを表し、indx と接する部分はすべて実際の公開契約です。パッケージ化とインストールは概要の手順に従います。

from indx_interfaces import (
CapabilityId,
PageOutput,
ScopeKind,
ScopeRef,
SignatureId,
SignatureMatch,
)
CAPABILITY_ID = CapabilityId("acme-purchase-order")
class PurchaseOrderParser:
def detect(
self, content: bytes, media_type: str
) -> tuple[SignatureMatch, ...]:
evidence = cheap_signals(content, media_type)
if len(evidence) < 2:
return ()
return (
SignatureMatch(
scope=ScopeRef(kind=ScopeKind.DOCUMENT),
signature_id=SignatureId("purchase-order"),
tag="purchase_order",
confidence=min(1.0, len(evidence) / 3),
candidate_capability_id=CAPABILITY_ID,
evidence=evidence,
),
)
def read(
self, content: bytes, media_type: str, pages: tuple[int, ...]
) -> tuple[PageOutput, ...]:
return tuple(
PageOutput(
page=page,
text=extract_text(content, media_type, page),
metadata={
"purchase_order": extract_fields(content, page),
},
)
for page in pages
)

ページ読み取りと同じ Provider.create() パターンでこの実装を返し、PARSER 記述子として宣言します。検出は計画時に実行されるため、低コスト、ローカル、決定論的で、OCR、レンダリング、モデル、ネットワーク呼び出しを含まない必要があります。一致した場合も、パーサーの後ろには汎用フォールバックが残ります。

一致のスコープは DOCUMENTPAGE にしてください。REGION スコープの一致は呼び出し側が見られるよう計画に残りますが、何もノミネートしません。計画が保持するのはドキュメントとページの割り当てだけであり、そこからルーティングすると「このリージョンに発注書の表がある」を「このページは発注書である」と読み替えてしまうためです。

kind は作業内容を表すものであり、ルートへの入り口を選ぶものではありません。PARSER は「自身の detect() が先に認識したドキュメントに対してのみ正しい」能力を意味し、ルートに入る唯一の道はノミネーションです。そのため、パーサーだけが宣言するメディアタイプを signature_detection なしで計画すると、パーサー名とフラグを明記した unsatisfied なプランが返ります。フォーマットを汎用的に読み取れる能力であれば NATIVE_EXTRACTION として宣言し、ワークド・イグザンプルが acme-plaintextacme-purchase-order を対にしているように、パーサーを併せて同梱してください。

  • 高コスト処理なしで、検出の一致と不一致をテストする。