GLiNER2からJSONが返ってきたら、それを保存して終わりにしてよいだろうか。今回は、抽出モデルの出力と、アプリで使う記録の間に必要な処理を整理する。
執筆メモ(2026-09-25、公開時に削除):実装前の設計草稿。以下のスキーマ、JSON、処理手順は提案であり、実行済みコードやモデル出力ではない。公開前にバージョン固定したコード、実出力、失敗例、評価結果を追加する。
最初に取り出す項目を絞る
最初の対象は人物、テーマ、イベント、日付とする。心理状態や能力のように判断が広がりやすい項目は対象外にする。
| 項目・関係 | 意味 | 混同しないもの |
|---|---|---|
| person | 本文中で言及された人物 | 発言者、アカウントID |
| topic | 明示された関心・会話の対象 | 隠れた関心の推測 |
| event | 名前や記述で特定できる催し | 将来あり得る催し全般 |
| date | 本文中の日付表現 | 実際に開催・参加した証拠 |
| expressed_interest_in | 関心を表明した | 専門能力、参加意思、申込み |
| attended | 参加したとの記述 | 参加予定、不参加、仮定 |
上の名前はアプリで試すラベルであり、GLiNER2が常に正しく判定できる組み込みの保証ではない。ラベル名と説明文も評価対象にする。
GLiNER2の呼び出し口
公式READMEでは、エンティティ抽出の extract_entities、構造化抽出の extract_json、関係抽出の extract_relations、スキーマを組み合わせる extract が説明されている。
原文との対応には include_spans、モデルのスコア取得には include_confidence を検討する。採用するモデル・バージョンで実際の返り値を確認し、アプリ側の変換処理をテストする。READMEには複数のモデル系列があるため、異なる系列の例を無条件に混ぜない。
具体的な導入手順は、パッケージのバージョンとモデルrevisionを固定した時点で確定する。初回モデル取得、ロード、推論は測定を分ける。
モデルの前後に必要な処理
取り込み元の権限・利用目的を確認
-> 原文の版とハッシュを保存
-> 長文なら分割し、原文との位置対応を保持
-> GLiNER2で候補を抽出
-> 戻り値の形式と引用範囲を検査
-> 人物の同定、日付の解釈、否定・予定を確認
-> 根拠付きの未確認候補として保存
-> 人が採用・訂正・保留
-> 現在の権限に従って検索用データを更新
原文の改行や文字を正規化してから推論すると、返された位置が元の本文とずれる場合がある。最初は原文を保持し、加工する場合は位置の対応表も持つ。
長文を分割する場合は、人物名が前の区切りに、関係の説明が次の区切りにあるケースを試す。重なり部分の抽出を単純に追加すると重複するため、原文の版と文字範囲などで整理する。
モデルの出力を直接公開しない
たとえば、次のような正規化済み候補をアプリ内部で扱う。
{
"candidate_id": "cand-001",
"source_revision_id": "rev-001",
"subject_mention": "アキ",
"predicate": "expressed_interest_in",
"object_mention": "Python",
"subject_id": null,
"review_status": "pending",
"resolution_status": "unresolved",
"extractor": "gliner2",
"model_revision": null
}
これは説明用の手作りデータだ。実行時には使用したモデルrevisionを必須で記録し、人物IDが解決していない候補を人物の確定プロフィールには載せない。
高いconfidenceだけで採用を決めない。原文との一致、誰についての記述か、否定や予定の扱いを別に確認する。
間違えると困る例からテストする
| 入力例 | 期待する扱い |
|---|---|
| アキはPythonに興味がある。 | 関心の候補。専門家や講師とは断定しない |
| アキは読書会には参加しなかった。 | 肯定の参加履歴を作らない |
| 来月の読書会に参加したい。 | 希望として扱い、参加確定にしない |
| Pythonが好きなのはミナで、私は初心者です。 | 関心を発言者へ誤って割り当てない |
| 興味がないわけではない。 | 判断が難しければ保留する |
| 前は使っていたが、今は使っていない。 | 過去と現在を一つの状態に潰さない |
| アキという人が別のグループにもいる。 | 同名だけで人物IDを統合しない |
抽出で否定を落とした場合、保存側だけで必ず修復できるとは限らない。モデルの失敗を記録し、曖昧な候補を保留する経路を用意する。ルールで補う場合も同じ評価用データで確認する。
やり直しても壊さない
抽出単位の識別には、原文の版、抽出器、モデルrevision、スキーマ・設定のハッシュを使う。同じ処理の再試行と、設定を変えた新しい抽出を区別する。
実行失敗は「候補がなかった」と区別する。処理中の一部だけが採用済みになる状態を避け、実行状態を記録する。
すでに人が訂正した関係については、新しい候補との差分を表示する。再実行のたびに古い誤りへ戻らないことを確認する。
評価の読み方
エンティティ抽出の正解率が高くても、不参加を参加に変える誤りがあるなら、イベントの自動参加者リストには使えない。項目ごとの抽出性能と、用途としての受入条件は分ける。
第2部で分けた未使用データについて、抽出結果、余分な抽出、取りこぼし、訂正内容を記録する。主観的に「よく取れた」とまとめず、どの条件では保留が必要だったかまで残す。
次回は、こうして保存した記録を個人の外部記憶として検索し、ブログの材料へ変える。