P&ID から知識グラフへ
処理は決定論的なスクリプトとあなた(AIエージェント)に分割されています:
- スクリプトはページを分類し(ベクター/スキャン)、読み取り可能なタイルにレンダリングし、OCR/テキストヒントを収集し、グラフの構築、チェック、保存、クエリを行います。
- あなたは図面を読み、シートごとに1つの構造化抽出ファイルを作成します。記号認識と線のトレースは視覚的な推論であり、スクリプトがうまくできない部分です。
すべてのスクリプトはこのファイルの隣の scripts/ にあります。フルパスで呼び出し(以下のコマンドでは scripts/ と省略)、作業ディレクトリはユーザーの現在のフォルダ(例:work/<plant>)に保ってください。
セットアップ。 ユーザーの多くはエンジニアであり、プログラマーではないため、セットアップはあなた自身で行ってください。スクリプトには Python 3.10 以上が必要です。初回実行前に、pip install -r <skill dir>/scripts/requirements.txt で依存関係をインストールしてください(ユーザーのPythonが他の作業と共有されている場合は仮想環境を使ってください)。Pythonがインストールされていない場合は、ユーザーに python.org からインストールするよう伝え、そこで処理を停止してください。
基本ルール
- P&IDのページのみ扱うこと。 図面は長い許可申請書や設計レポートの中にあることがよくあります。ユーザーがページを指定した場合は
--pagesで渡します。指定がなく、PDFのページ数が多い場合は、プローブしてページの概要を確認するかユーザーに尋ね、その後--pagesを付けてプローブを再実行し、以降のステップでレポート、凡例、P&ID以外の図面をスキップします。 - 1プラント、1作業ディレクトリ、1グラフ。 異なるプラントのシートを同じ作業ディレクトリに入れないでください。タグが無関係なプラント間でマージされてしまいます。ユーザーが複数のプラントを提供した場合は、それぞれに対してワークフロー全体を個別に実行します。
- グラフごとに1つの設定。 PDFに同じ図面の2つのリビジョン(同じタイトルまたはエリア、重複するタグ、例:現状反映図と古いドラフト)が含まれている場合、マージしないでください。どのリビジョンを使用するかユーザーに尋ね、そのリビジョンのみを抽出し、除外したページとその理由をレポートに記録します。QA は重複の可能性を
possible_duplicate_revisionとしてフラグします。各シートのissue_statusをタイトルブロックまたはスタンプから記録します。 - 描かれているものだけを記録すること。 グラフを完成させるためにタグ、接続、ループを捏造してはいけません。不明なものはすべて低い
confidenceで記録するか、unreadableに入れます。 - QAループは必須です。 エラーがなくなるまで再構築し、図面上ですべての警告を再確認します。
ワークフロー
以下のチェックリストをノートにコピーし、完了したらチェックを入れていきます:
- [ ] 1. プローブ: python scripts/probe_pdf.py <pdf> --work <work> --plant-name "<name>" [--pages 47-60]
- [ ] 2. レンダリング: python scripts/render_pages.py <work>
- [ ] 3. 向き確認: 各 pages/page_NN/overview_grid.png を開き、テキストが直立していない場合は回転を修正
- [ ] 4. ヒント: python scripts/make_hints.py <work>
- [ ] 5. 抽出: 各シートについて <work>/extract/page_NN.json を記述(references/extraction_procedure.md 参照)
- [ ] 6. 構築: python scripts/build_kg.py <work>
- [ ] 7. QAループ: すべてのエラーを修正し、すべての警告を再確認し、再構築(繰り返し)
- [ ] 8. レポート: 結果を要約し、未解決の問題をユーザーに報告
1. プローブ
probe_pdf.py は各ページにクラスと抽出ルートを割り当て、<work>/manifest.json を書き込みます。--pages を指定すると、以降のステップはそのページのみをレンダリングして読み取ります。
| クラス | 意味 | ルート |
|---|---|---|
vector_text | テキストレイヤー付きベクター図面 | ベクターからレンダリング、テキストレイヤーから正確なテキストをヒントとして使用 |
vector_outlined | ベクター図面、テキストはアウトライン(テキストレイヤーなし) | 高解像度ベクターレンダリング、OCRヒント |
raster | スキャン画像 | ネイティブ解像度でレンダリング、拡大およびコントラスト強調、OCRヒント |
raster_with_text | OCRテキストレイヤー付きスキャン | ラスターと同様、テキストレイヤーを(信頼できない)ヒントとして使用 |
hybrid | ベクターと大きな画像の混在 | 両方のルート |
プローブ結果を1行でユーザーに報告します。例:「14枚のベクターシート(アウトライン文字)。」
低スキャン解像度はノートにフラグが付けられます。それらのシートでは unreadable により多くの項目が記録されることを想定してください。
2-3. レンダリングと向きの確認
render_pages.py は各ページについて以下を書き込みます:
overview.pngoverview_grid.png(タイル名を表示)- 重なり合うタイル(
tiles/内) tiles.json(空白のタイルを記録)
向きは、OCRがインストールされている場合に検出されます。overview_grid.png で常に確認してください。メインの図面テキストが直立していない場合、そのページを明示的な回転角度で再レンダリングします(時計回り):render_pages.py <work> --pages N --rotation 90。
タイトルブロックは図面と異なる向きで回転していることがあります。タイトルブロックではなく、図面のラベルで向きを合わせてください。
4. ヒント
make_hints.py は hints/page_NN.json を書き込みます。各ファイルには、テキストレイヤーまたはOCRから取得された、ページ上の位置付きの候補タグが保持されます。これらはあくまでヒントです。OCRは誤読し、見落としもあります。抽出中にヒントファイルを読む必要はありません。QA はこれらを使用して、見逃した可能性のあるタグをフラグします。OCRがインストールされていない場合、このステップはスキップされます。最終レポートにその旨を記載します。
5. 各シートの抽出
これが作業の中核です。 references/extraction_procedure.md に正確に従ってください。これには以下が含まれます:
- 読み取り順序:概要、次にすべての非空白タイル、次にズームした切り抜き
- 配管ラン、ティー、タップ、信号、ページ外コネクタのモデル化方法
- 信頼度の調整
- 保存前に行う自己チェックリスト
必要に応じて参照する参考資料:
- references/isa_5_1.md:計器文字コード、バブルシンボル、信号線の種類
- references/symbol_guide.md:機器およびバルブシンボルが
kind値にどのようにマッピングされるか - references/ontology.md:グラフのノードとエッジの種類とその導出方法
references/schema/extraction.schema.json:ページファイルの正確なJSONスキーマ
extract/page_NN.json を書き込み、次のシートを開始する前に保存します。これにより、長時間のジョブでもコンテキスト内に保持されるシートは1枚だけになります。多数のシートがあり、環境がサブエージェントをサポートしている場合は、シートを並行して抽出できます。各サブエージェントに手順ファイルと自身のページディレクトリを渡します。
6-7. 構築とQAループ
build_kg.py はすべてのページファイルを検証し、スキーマエラーがある場合は正確なメッセージを表示して停止します。その後、以下のファイルを <work>/kg/ に書き込みます:
graph.jsongraph.duckdbsummary.mdqa_report.md
qa_report.md に従って作業します:
- エラー(例:
unresolved_reference)はページファイルの間違いです。修正して再構築します。 - 警告は再確認するタイルを指定します。それらのタイルをもう一度見るか、
crop.pyでズームビューを使用し、図面に異なるものが示されている場合は抽出を修正します。一般的な警告:instrument_not_located:measuresのないセンサーequipment_not_connectedunmatched_off_pagepossible_missed_tags:抽出に含まれていないOCRタグtiles_not_reviewed
- 図面上で正しいことが確認された警告はそのままにしておいても構いません。例:別の図面が提供されていないページ外コネクタ、またはOCRの誤読。これらをレポートにリストアップします。
エラーがなく、すべての警告が確認されるまで続けます。
python scripts/crop.py <work> --page 5 --bbox 0.40 0.20 0.55 0.35 # 領域のズームビュー
8. レポート
ユーザーに以下を伝えます:
- 出力先
- 主要な数(機器、計器、ループ)
summary.mdから抜粋した2~3のフローパスとループの例- 不確かな点
詳細は qa_report.md を参照するよう伝えます。グラフは機械抽出されたものであり、設計、運用、安全に使用する前に工学的レビューが必要であることを明確に述べます。
グラフの使用
summary.mdは、LLM用のコンパクトでトークン効率の良いコンテキストです。設備レベルのフロー、位置情報付き計器テーブル、ループテーブルが含まれます。graph.jsonは正規のグラフであり、任意のツールで読み取ることができます。graph.duckdbはSQL用です。ビューはequipment、equipment_flow、instruments、loops、signalsで、テーブルマクロはupstream(id)とdownstream(id)です。
kg_query.py を使用して質問に答えます。別のツールが出力を消費する場合は --json を追加します:
python scripts/kg_query.py <work>/kg downstream 660-TK-001 --equipment
python scripts/kg_query.py <work>/kg upstream FV-0502
python scripts/kg_query.py <work>/kg path 660-TK-001 660-TK-004
python scripts/kg_query.py <work>/kg instruments --on 660-PP-011
python scripts/kg_query.py <work>/kg loop FIC-0502
python scripts/kg_query.py <work>/kg sql "SELECT * FROM equipment_flow"
シートの抽出品質を測定するには、手動で小さなゴールドファイル(形式は scripts/eval_kg.py 内)にチェックし、python scripts/eval_kg.py <work>/kg gold.json を実行します。タグ、フロー、ループの適合率/再現率と計器配置をレポートします。
グラフを他のツールに移すには:python scripts/export.py <work>/kg graphml は yEd、Gephi、NetworkX 用のファイルを生成し、python scripts/export.py <work>/kg neo4j はCSVとCypherインポートスクリプトを生成します。