OCI VisionとOCI Generative AIによる請求書画像の自動化
はじめに
企業は、多くの場合、サプライヤやサービス・プロバイダに由来するスキャンされた画像やPDFとして、数千もの請求書を非構造化形式で受け取ります。請求書番号、顧客名、購入アイテム、合計金額など、これらの請求書からデータを手動で抽出することは、時間がかかり、エラーが発生しやすいプロセスです。
これらの処理の遅延は、買掛金のサイクルやキャッシュ・フローの可視性に影響するだけでなく、コンプライアンス、監査、レポート作成のボトルネックにもなります。
このチュートリアルでは、Oracle Cloud Infrastructure (OCI)のバケットで受信請求書イメージを監視し、OCI Visionを使用してテキスト・コンテンツを抽出し、OCI Generative AI (LLM)を適用して請求書番号、顧客、アイテム・リストなどの構造化された会計データを抽出する自動パイプラインを実装する方法を示します。
このチュートリアルで使用するOCIサービスは次のとおりです。
サービス | 目 的 |
---|---|
OCI Vision | アップロードされた請求書イメージに対してOCRを実行します。 |
OCI生成AI | 少数のショット・プロンプトを使用して、RAW OCRテキストから構造化JSONデータを抽出します。 |
OCIオブジェクト・ストレージ | 入力請求書イメージおよび出力JSON結果を格納します。 |
目的
-
OCI Object Storageからの請求書取込みを自動化します。
-
半構造化スキャンされたドキュメントから構造化データを抽出します。
-
OCI AI Servicesを使用して、光学文字認識(OCR)とLLMをリアルタイム・パイプラインに統合します。
前提条件
-
次のものにアクセスできるOCIアカウント:
-
OCI Vision
-
OCI生成AI
-
OCIオブジェクト・ストレージ
-
-
Python
3.10
以降のバージョン。 -
入力イメージのバケット(
input-bucket
など)、出力ファイルのバケット(output-bucket
など)。 -
次のファイルをダウンロードします。
タスク1: Pythonパッケージの構成
-
次のコマンドを使用して、
requirements.txt
ファイルを実行します。pip install -r requirements.txt
-
Pythonスクリプト(
main.py
)を実行します。 -
請求書イメージ(
.png
、.jpg
など)を入力バケットにアップロードします。 -
イメージが処理され、抽出されたJSONが出力バケットに保存されるまで待ちます。
タスク2: コードの理解
-
ロード構成:
with open("./config", "r") as f: config_data = json.load(f)
このコードは、ネームスペース、バケット名、コンパートメントID、LLMエンドポイントなど、必要なすべての構成値をロードします。
config
ファイルに構成パラメータを入力します。{ "oci_profile": "DEFAULT", "namespace": "your_namespace", "input_bucket": "input-bucket", "output_bucket": "output-bucket", "compartment_id": "ocid1.compartment.oc1..xxxx", "llm_endpoint": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com" }
-
OCIクライアントの初期化:
oci_config = oci.config.from_file("~/.oci/config", PROFILE) object_storage = oci.object_storage.ObjectStorageClient(oci_config) ai_vision_client = oci.ai_vision.AIServiceVisionClient(oci_config)
このコードは、OCI Object StorageおよびOCI VisionサービスにアクセスするためのOCI SDKクライアントを設定します。詳細は、「OCI Vision」を参照してください。
-
LLMの初期化:
llm = ChatOCIGenAI( model_id="meta.llama-3.1-405b-instruct", service_endpoint=LLM_ENDPOINT, compartment_id=COMPARTMENT_ID, auth_profile=PROFILE, model_kwargs={"temperature": 0.7, "top_p": 0.75, "max_tokens": 2000}, )
このコードは、自然言語の理解とテキストから構造への変換のために、OCI生成AIモデルを初期化します。
-
ショットが少ないプロンプト:
few_shot_examples = [ ... ] instruction = """ You are a fiscal data extractor. ... """
このコードでは、予測される出力の例を提供して、
number of invoice
、customer
、location
、items
などの構造化フィールドを抽出する方法をモデルが学習するように、いくつかのショット学習を使用します。 -
OCI VisionのOCR:
def perform_ocr(file_name): print(f"📄 Performing OCR on: {file_name}") response = ai_vision_client.analyze_document( analyze_document_details=oci.ai_vision.models.AnalyzeDocumentDetails( features=[ oci.ai_vision.models.DocumentTableDetectionFeature( feature_type="TEXT_DETECTION")], document=oci.ai_vision.models.ObjectStorageDocumentDetails( source="OBJECT_STORAGE", namespace_name=NAMESPACE, bucket_name=INPUT_BUCKET, object_name=file_name), compartment_id=COMPARTMENT_ID, language="POR", document_type="INVOICE") ) print(response.data) return response.data
このファンクションは、次の操作を実行します。
- イメージをOCI Visionに送信します。
- テキスト検出を要求します。
- 抽出されたRAWテキストを返します。
-
LLMによるデータ抽出:
def extract_data_with_llm(ocr_result, file_name): # 🔍 Extrai texto OCR (usando a estrutura da resposta do OCI Vision) extracted_lines = [] for page in getattr(ocr_result, 'pages', []): for line in getattr(page, 'lines', []): extracted_lines.append(line.text.strip()) plain_text = "\n".join(extracted_lines) # 🧠 Monta o prompt com instrução, few-shot e texto OCR limpo prompt = instruction + "\n" + "\n".join(few_shot_examples) + f"\nInvoice text:\n{plain_text}\nExtracted fields (JSON format):" # 🔗 Chamada ao LLM response = llm([HumanMessage(content=prompt)]) # 🧪 Tenta extrair JSON puro da resposta try: content = response.content.strip() first_brace = content.find("{") last_brace = content.rfind("}") json_string = content[first_brace:last_brace + 1] parsed_json = json.loads(json_string) except Exception as e: print(f"⚠️ Erro ao extrair JSON da resposta do LLM: {e}") parsed_json = {"raw_response": response.content} return { "file": file_name, "result": parsed_json, "timestamp": datetime.utcnow().isoformat() }
このファンクションは、次の操作を実行します。
- 命令、数ショットの例、およびOCRテキストを組み合わせます。
- OCI Visionから返されるOCRデータを準備します。
- OCI生成AIに送信します。
- 構造化されたJSONフィールドを(文字列として)受信します。
- OCI Visionはポルトガル語OCRをサポートしています(
"ENG"
のかわりにlanguage="POR"
を使用できます)。
-
出力をOCIオブジェクト・ストレージに保存します:
def save_output(result, file_name): ...
このコードは、元のファイル名と
.json
拡張子を使用して、構造化結果を出力バケットにアップロードします。 -
メイン・ループ- モニターおよびプロセス:
def monitor_bucket(): ...
次の主なルーチン:
- 30秒ごとに入力バケットを監視します。
- 新しい
.png
、.jpg
、.jpeg
ファイルを検出します。 - OCR、LLMを実行し、順番にアップロードします。
- すでに処理されたファイルがメモリー内で追跡されます。
-
エントリ・ポイント:
if __name__ == "__main__": monitor_bucket()
このコードはバケット・ウォッチャを起動し、請求書の自動処理を開始します。
タスク3: コードの実行
次のコマンドを使用してコードを実行します。
python main.py
タスク4: テストの提案
-
法的製品ラインおよび顧客名を含む実際の請求書またはダミー請求書を使用します。
-
入力バケットに複数の画像を順番にアップロードして、自動処理を確認します。
-
OCIコンソールにログインし、オブジェクト・ストレージに移動して両方のバケットの結果を確認します。
ノート:このチュートリアルでは、ブラジルの請求書を使用して、属性と処理の複雑さ、およびこのケースを解決するためのプロンプトの作成方法を示します。
タスク5: 予想される出力の表示
アップロードされた請求書イメージごとに、処理された出力バケット・ファイルを確認します。次の図に示すように、対応する.json
ファイルが構造化コンテンツとともに生成されます。
ノート:
- OCI Visionはポルトガル語OCRをサポートしています(
"ENG"
のかわりにlanguage="POR"
を使用できます)。- LLMプロンプトは、
CNPJ
、quantidade
、data de emissão
などの他のフィールドを抽出するように調整できます。processed_files
をデータベースまたはファイルとともに永続化して、プロセスをフォルト・トレラントにすることを検討してください。- このプロセスは、請求書解決用のマルチエージェント通信プロトコル・サーバーを使用したAIエージェントの作成というユースケースで、前処理済請求書イメージとして使用できます。請求書は、会社の顧客からの逸脱請求書です。顧客および場所のフィールドは、請求書作成者から取得されます。
関連リンク
確認
- 著者 - 星川クリスティアーノ(Oracle LAD A - チーム・ソリューション・エンジニア)
その他の学習リソース
docs.oracle.com/learnで他のラボを確認するか、Oracle Learning YouTubeチャネルで無料のラーニング・コンテンツにアクセスしてください。また、education.oracle.com/learning-explorerにアクセスして、Oracle Learning Explorerになります。
製品ドキュメントについては、Oracle Help Centerを参照してください。
Automate Invoice Images with OCI Vision and OCI Generative AI
G39790-01
Copyright ©2025, Oracle and/or its affiliates.