PageEntityExtractor and ChunkEntityExtractor
1 ページ・1 チャンクの中の固有表現を見つけ、それがどこにあるかを述べるポート。
英語版が原文です。
プロトコル:
PageEntityExtractor.id: ExtractorIdPageEntityExtractor.extract(text: str) -> Mapping[str, tuple[EntitySpan, ...]]PageEntityExtractorProvider.page_entity_extractors() -> tuple[PageEntityExtractor, ...]ChunkEntityExtractor.id: ExtractorIdChunkEntityExtractor.extract(text: str) -> Mapping[str, tuple[EntitySpan, ...]]ChunkEntityExtractorProvider.chunk_entity_extractors() -> tuple[ChunkEntityExtractor, ...]
エンティティ抽出器はテキストの中の名前を見つけ、それがどこにあるかを述べます。回答はラベル — person、organization、location、date、money、invoice_number — から EntitySpan への写像で、各項目は表層のテキスト、[start, end) の文字範囲、[0, 1] の信頼度を持ちます。
ラベルは自由な文字列です。indx-interfaces はエンティティのラベルを列挙しません。ファセットを列挙しないのと同じ理由で、有用な集合は契約のものではなくドメインのものだからです。日本語の請求書を読むデプロイメントにとって、登録番号は PERSON がそうでない仕方で重要です。
DocumentEntityExtractor は意図的に存在しません。ページがすでに隙間なく文書を敷き詰めているので、文書全体のポートはページのポートが直接生成するものを生成するために入力を内部で窓分割することになり、そのスパンはブロックではなく連結を指すことになります。
これは分類器の分割の 2 つ目の軸です。分類器はこのテキストが何であるかに答え、抽出器はその中で何が名指しされていて、どこにあるかに答えます。どちらも出力への注釈であり、どちらも何もルーティングせず、どちらも ID による opt-in です — しかし戻り値の型を共有できません。LabelScore はラベルと数値であって位置を置く場所がなく、位置のないエンティティは、利用者に見せることも、ページに突き合わせて確認することもできない事実です。
エンティティを分類器のポートに押し込むのは自明で安上がりな手であり、この設計が拒む唯一のものです。それは肝心のスパンを捨てながらエンティティ抽出を広告することになるからです(ADR-0029)。
スパンは、それを名指しするブロックの text を指します。 抽出器が渡されたテキストが組み立てられたものならそれではなく、文書全体の連結でもなく、バイトでもなく、文字で、1 つのブロック自身の text フィールドを指します。それはレスポンスがすでに運んでいるものです。これがアドレッシングの規則のすべてであり、抽出器が一度に 1 つの単位で尋ねられる理由です(ADR-0030)。バイトではなく文字であることは日本語にとって効いています。両者は 3 倍違うからです。
入力は 1 ページまたは 1 チャンクの全文です。トークン窓を持つ抽出器は長いページを丸ごと見て自分でスライスし、自分の窓ではなく入力テキストの座標でスパンを返します。
ChunkEntityExtractor はチャンク粒度を要し、リクエストが CHUNK を求めていないときは取得前の 422 で拒否されます。未知の ID と data_residency 下の external な実装も同じように、同じ理屈で拒否されます。黙って飛ばされた抽出器は、呼び出し側が与えられたと信じて与えられなかった回答だからです。ID は分類器のポートと 1 つの名前空間を共有します。
raise はログに残され、その単位は飛ばされます。device、cost_usd、builtin はプロトコルの外にあり、既定値付きで読まれます。
- 渡されたテキストを、その最初の文字から数えて指すスパンを返す。窓については正しく入力については誤っているオフセットは、スパンが無いより悪い。下流の何もそれを検出できないからです。
- 1 つのラベルについて重なるスパンを返さない。2 つの読みが競合するなら、弁護できるほうを返し、2 つ目の抽出器に異議を唱えさせる。
- 弁護できる信頼度を報告する。辞書のヒットもモデルの softmax も自己申告であり、どちらもラベル付きコーパスに対して較正されていません — ベンチマークには較正の相手になる正解がありません(ADR-0035)。
- 空のタプルを出すくらいならラベルを省く。
- モジュールスコープを安価に保ち、エンジンは最初の呼び出しの背後で構築する。辞書やモデルは数十メガバイトあり、検出がその代価を払ってはなりません。
- 動けないときは何も公表しない。エクストラなし、辞書なし、モデルなしなら、抽出器なし。
システム内の位置
Section titled “システム内の位置”DocumentExecutor.encode は取得前に有効化された ID を解決してレジデンシーを確認し、文書を読み、チャンク粒度が求められていればチャンクに切り、有効化された各抽出器に各単位をリクエスト順で尋ねます。
回答はすべて文書ブロックの metadata に ENTITIES_METADATA_KEY として、そのエンティティが見つかったブロック ID で引ける形で書かれます — ページブロックもチャンクブロックも同じです。チャンクブロック自身は不活性のまま、テキスト、bbox、埋め込み、来歴を持ち、メタデータを持ちません。これはエグゼキューター自身のテストが固定している不変条件です(ADR-0031)。
ブロックごとのスパンと並んで、文書ブロックは集約を運びます。(ラベル, NFKC 正規化した表層形) ごとの数と、その傍らに残された生の表層形です。数は同一性ではありません。 共参照解析はスコープ外なので、「山田太郎」と「山田」は 2 つの項目であり、ここではそれが同一人物だとは主張しません(ADR-0032)。
entities は languages、classification に並ぶ 3 つ目の予約メタデータキーです。EncodeRequest.metadata はこれをきっぱり拒否します。
POLICY_VERSION は動かず、機能スナップショット ID も動きません。抽出器の ID を広告するフィールドはコンテンツハッシュから除外されているので、抽出器をインストールしても既存の計画は無効になりません。