paint-brush
AI および PDF サービスを使用して文書の要約を自動化する方法@raymondcamden
5,330 測定値
5,330 測定値

AI および PDF サービスを使用して文書の要約を自動化する方法

Raymond Camden8m2024/02/04
Read on Terminal Reader

長すぎる; 読むには

つまり、テキスト、フォント、色、位置などです。画像や表形式のデータも検索できるため、非常に強力な使用例につながります。 (この良い例については、複数の科学雑誌をスキャンして天文データを収集および集計し、レポートを作成している私のブログ投稿を参照してください。) このデモでは、文字通りテキストだけが必要です。そのために、REST API を利用します。利用可能な PDF サービスのほぼすべての側面の「フロー」は次のとおりです。
featured image - AI および PDF サービスを使用して文書の要約を自動化する方法
Raymond Camden HackerNoon profile picture


私が初めてDiffbot を発見したのは、2021 年に遡り、Adobe 開発者ブログ ( 「Natural Language Processing、Adobe PDF Extract、Deep PDF Intelligence」 ) 用に API のデモを作成したときでした。


そのとき、Diffbot の API の使いやすさとレスポンスの速さに感銘を受けました。しばらく API を見ていなかったのですが、数日前、テキストの要約の新しいサポートが発表されました。これをAdobe PDF Extract APIと組み合わせるのは素晴らしいことだと思いました。これが私が見つけたものです。


まず、これを自分で試してみたい場合は、次のものが必要です。


  • Adobe PDF Services の資格情報。これらは無料で、毎月 500 件のトランザクションが無料で利用できます。ご存じない方のために言っておきますが、私は Adobe で働いており、これは私が取り上げている製品の 1 つです。


  • Diffbot の認証情報。 2 週間の無料トライアルは提供されますが、無料利用枠はありません。そうは言っても、私はものを構築するときに何度か彼らに連絡する必要があり、彼らは私に本当に素晴らしいサポートを提供してくれたので、ぜひチェックしてみる価値があると思います。


さて、要約フローがどのように機能するかを見てみましょう。

ステップ 1 - テキストを抽出する

Extract API (申し訳ありませんが、「Adobe PDF Extract API」です。待ってください、これは私のブログです。短くしても構いません!) は非常に強力です。 AI を使用して PDF をインテリジェントに解析し、ドキュメント内のすべての要素の詳細を正確に見つけます。


つまり、テキスト、フォント、色、位置などです。画像や表形式のデータも検索できるため、非常に強力な使用例につながります。 (この良い例については、複数の科学雑誌をスキャンして天文データを収集および集計し、レポートを作成している私のブログ投稿を参照してください。)


このデモでは、文字通りテキストだけが必要です。そのために、REST API を利用します。利用可能な PDF サービスのほぼすべての側面の「フロー」は次のとおりです。


  • アクセストークンの認証情報を交換する


  • 入力用のファイル (この場合は抽出する PDF) のアップロードを要求します。


  • ドキュメントをアップロードする


  • 仕事を始める


  • 完了のための投票


  • ビットをダウンロードする


使用できる SDK もありますが、REST API は非常にシンプルなので、エンドポイントに直接アクセスするだけであることに注意してください。抽出プロセスを実行するために作成したスクリプトは次のとおりです。これは基本的に上記で述べたすべてであり、ローカル ファイル システム内のソース PDF を指します。


 /* This demo is a two step process. This file, step one, handles extracting and storing the JSON from a PDF. */ import 'dotenv/config'; import fs from 'fs'; import { Readable } from 'stream'; import { finished } from 'stream/promises'; const SOURCE_PDF = '../../source_pdfs/boring_adobe_security_doc.pdf'; const REST_API = "https://pdf-services.adobe.io/"; const CLIENT_ID = process.env.CLIENT_ID; const CLIENT_SECRET = process.env.CLIENT_SECRET; async function delay(x) { return new Promise(resolve => { setTimeout(() => resolve(), x); }); } async function getAccessToken(id, secret) { const params = new URLSearchParams(); params.append('client_id', id); params.append('client_secret', secret); let resp = await fetch('https://pdf-services-ue1.adobe.io/token', { method: 'POST', headers: { 'Content-Type':'application/x-www-form-urlencoded' }, body:params }); let data = await resp.json(); return data.access_token; } async function getUploadData(mediaType, token, clientId) { let body = { 'mediaType': mediaType }; body = JSON.stringify(body); let req = await fetch(REST_API+'assets', { method:'post', headers: { 'X-API-Key':clientId, 'Authorization':`Bearer ${token}`, 'Content-Type':'application/json' }, body: body }); let data = await req.json(); return data; } async function uploadFile(url, filePath, mediaType) { let stream = fs.createReadStream(filePath); let stats = fs.statSync(filePath); let fileSizeInBytes = stats.size; let upload = await fetch(url, { method:'PUT', redirect:'follow', headers: { 'Content-Type':mediaType, 'Content-Length':fileSizeInBytes }, duplex:'half', body:stream }); if(upload.status === 200) return; else { throw('Bad result, handle later.'); } } async function pollJob(url, token, clientId) { let status = null; let asset; while(status !== 'done') { let req = await fetch(url, { method:'GET', headers: { 'X-API-Key':clientId, 'Authorization':`Bearer ${token}`, } }); let res = await req.json(); status = res.status; if(status === 'done') { asset = res; } else { await delay(2000); } } return asset; } async function downloadFile(url, filePath) { let res = await fetch(url); const body = Readable.fromWeb(res.body); const download_write_stream = fs.createWriteStream(filePath); return await finished(body.pipe(download_write_stream)); } async function extractJob(asset, token, clientId) { let body = { 'assetID': asset.assetID } let resp = await fetch(REST_API + 'operation/extractpdf', { method: 'POST', headers: { 'Authorization':`Bearer ${token}`, 'X-API-KEY':clientId, 'Content-Type':'application/json' }, body:JSON.stringify(body) }); return resp.headers.get('location'); } let accessToken = await getAccessToken(CLIENT_ID, CLIENT_SECRET); console.log('Got our access token.'); let uploadedAsset = await getUploadData('application/pdf', accessToken, CLIENT_ID); await uploadFile(uploadedAsset.uploadUri, SOURCE_PDF, 'application/pdf'); console.log('Source PDF Uploaded.'); let job = await extractJob(uploadedAsset, accessToken, CLIENT_ID); console.log('Job created. Now to poll it.'); let result = await pollJob(job, accessToken, CLIENT_ID); console.log('Job is done.'); await downloadFile(result.content.downloadUri, 'extract.json'); console.log('All done.');

はい、まだ読んでいただければ幸いです。一般に、このような巨大なコード ブロックを投稿することは避けるようにしていますが、最後の行に注目すると、上記のフローで説明したことを実行するユーティリティ関数を実行しているだけであることがわかります。認証し、PDF のアップロードを要求し、ジョブを開始して確認し、結果をダウンロードします。


一つ注意事項を追加しておきます。 Extract は、JSON 結果セット、およびオプションでテーブルと画像を含む zip ファイルを返します。 REST API の優れた点の 1 つは、JSON に直接アクセスして保存できることです。


JSON の結果は非常に巨大になる可能性があります。 3 ページのソース PDF (信じられないほど退屈な Adobe セキュリティ ドキュメント) の場合、結果として得られる JSON の長さは 4560 行になります。私のソース PDF はここにあり、Extract からの生の出力はここにあります。


4.5k 行すべてをここに置く代わりに、API で見つかった 2 つの固有の要素のスニペットを示します。


 { "Bounds": [ 44.62139892578125, 756.9429931640625, 245.0037841796875, 766.3184967041016 ], "Font": { "alt_family_name": "* Arial", "embedded": true, "encoding": "Identity-H", "family_name": "* Arial", "font_type": "CIDFontType0", "italic": false, "monospaced": false, "name": "*Arial-6539", "subset": false, "weight": 400 }, "HasClip": false, "Lang": "en", "Page": 0, "Path": "//Document/Sect/P", "Text": "Adobe Vendor Security Review Program White Paper ", "TextSize": 8.5, "attributes": { "SpaceAfter": 18 } }, { "Bounds": [ 0.0, 0.0, 630.0, 820.7799987792969 ], "ClipBounds": [ 548.72802734375, 739.1929931640625, 602.5444488525391, 820.7799987792969 ], "Page": 0, "Path": "//Document/Sect/Figure", "attributes": { "BBox": [ 548.9779999999737, 739.4429999999993, 587.61599999998, 790.920999999973 ], "Placement": "Block" } },

上のサンプルでは、最初の要素はテキストでありTextプロパティが含まれており、2 番目の要素は図であることがわかります。私のデモでは、 Textプロパティが存在する場合はそれを使用するだけです。実際にそれを見てみましょう。

ステップ 2 - 概要を作成する

先ほど、Diffbot API の使用は非常に簡単であると述べました。それを実証してみましょう。


まず、いくつかの変数を設定し、最初のステップで取得した JSON を読み込みます。誤解のないように、1 つのプロセスですべてを実行できますが、Extract を複数回実行するのは実際には意味がありません。すごいのは、結果に対して実際に複数の呼び出しを実行できることです。


一例として、Diffbot のもう 1 つの優れた機能は、テキストからエンティティ、つまりドキュメントで話されている内容 (人、場所など) を取得することです。とにかく、ここからが始まりです:


 /* In this file, we take the result from our Extract operation and pass it to Diffbot */ import 'dotenv/config'; import fs from 'fs'; const DIFFBOT_KEY = process.env.DIFFBOT_KEY; const SOURCE_JSON = './extract.json'; const data = JSON.parse(fs.readFileSync(SOURCE_JSON, 'utf8')); console.log(`Read in source data from ${SOURCE_JSON}.`);


次に、抽出結果からテキストを解析する必要があります。


 let text = data.elements.reduce((text, el) => { if(el.Text) text += el.Text + '\n'; return text; },'');


次に、Diffbot への HTTP リクエストを作成します。詳細については、ドキュメントを確認してください。


 let fields = 'summary'; let url = `https://nl.diffbot.com/v1/?fields=${fields}&token=${DIFFBOT_KEY}`; let body = [{ content:text, lang:'en', format:'plain text' }]; console.log('Passing text to Diffbot.'); let req = await fetch(url, { method:'POST', body:JSON.stringify(body), headers: { 'Content-Type':'application/json' } }); let result = await req.json();


以上です。最後のステップとして、単純に出力します。


 console.log(`Summary of PDF:\n${result[0].summary}`);


ソース PDF を指定すると、最終結果は次のようになります。


 Adobe has a vendor security review program that evaluates vendors that collect, store, process, transmit, or dispose of Adobe data outside of Adobe-controlled physical offices or data center locations. The VSR program includes requirements for vendors to follow when handling sensitive data and assigns a risk level score to vendors based on their compliance with Adobe standards. If a vendor fails the VSR program, Adobe holds discussions with the business owner to understand the details of the vendor's security practices and determine whether or not to continue working with them.


3 ページの PDF が 1 つの単純な段落になりました。数百万ものドキュメントを扱う組織にとって、これがどれほど役立つか想像できるでしょう。これを他のサービス (前述したエンティティ機能など) と組み合わせると、大規模なライブラリの操作がはるかに簡単になります。

それを試してみてください!

これを自分で確認したい場合は、ここからすべてのコードを取得できます: https://github.com/cfjedimaster/document-services-demos/tree/main/random_demos/extract_diffbot_summary 。先ほども言いましたが、ここにあるものはすべて無料でテストできるので、ぜひ試してみて、以下のコメントでご意見をお聞かせください。