paint-brush
Cómo utilizar servicios de IA y PDF para automatizar resúmenes de documentospor@raymondcamden
5,330 lecturas
5,330 lecturas

Cómo utilizar servicios de IA y PDF para automatizar resúmenes de documentos

por Raymond Camden8m2024/02/04
Read on Terminal Reader

Demasiado Largo; Para Leer

Entonces texto, fuentes, colores, posición, etc. También puede encontrar imágenes y datos tabulares, lo que conduce a algunos casos de uso bastante potentes. (Para ver un buen ejemplo de esto, consulte la publicación de mi blog donde escaneo varias revistas científicas para recopilar y agregar datos astronómicos y crear informes). Para esta demostración, literalmente solo necesitamos el texto. Para eso, usaré las API REST. El "flujo" para casi todos los aspectos de los servicios PDF disponibles son:
featured image - Cómo utilizar servicios de IA y PDF para automatizar resúmenes de documentos
Raymond Camden HackerNoon profile picture


Descubrí Diffbot por primera vez en 2021, cuando creé una demostración de sus API para el blog de desarrolladores de Adobe ( "Procesamiento de lenguaje natural, extracción de PDF de Adobe y inteligencia profunda de PDF" ).


En ese momento, me impresionó lo fácil que era la API de Diffbot y también lo rápido que respondía. Hacía tiempo que no miraba su API, pero hace unos días anunciaron un nuevo soporte para resumir texto. Pensé que sería genial combinarlo con Adobe PDF Extract API . Esto es lo que encontré.


En primer lugar, si quieres probar esto tú mismo, necesitarás:


  • Credenciales de los servicios Adobe PDF. Son gratuitos y obtienes 500 transacciones por mes gratis. Para aquellos que quizás no lo sepan, trabajo para Adobe y este es uno de los productos que cubro.


  • Credenciales de Diffbot. Ofrecen una prueba gratuita de dos semanas pero no un nivel gratuito. Dicho esto, tuve que comunicarme con ellos varias veces mientras creaba cosas, y me brindaron un gran apoyo, así que definitivamente creo que vale la pena que les eches un vistazo.


Muy bien, veamos cómo podría funcionar un flujo de resumen.

Paso uno: extraiga el texto

La API de extracción (lo siento, la "API de extracción de PDF de Adobe", espera, este es mi blog, ¡puedo acortar las cosas!) es bastante poderosa. Utiliza IA para analizar inteligentemente un PDF y encontrar correctamente todos y cada uno de los detalles de los elementos del documento.


Entonces texto, fuentes, colores, posición, etc. También puede encontrar imágenes y datos tabulares, lo que conduce a algunos casos de uso bastante potentes. (Para ver un buen ejemplo de esto, consulte la publicación de mi blog donde escaneo varias revistas científicas para recopilar y agregar datos astronómicos y crear informes).


Para esta demostración, literalmente solo necesitamos el texto. Para eso, usaré las API REST. El "flujo" para casi todos los aspectos de los servicios PDF disponibles son:


  • Intercambiar credenciales por un token de acceso


  • Solicite cargar un archivo para ingresar (en este caso, un PDF para extraer)


  • Sube el documento


  • Empezar el trabajo


  • Encuesta para completar


  • descargar los bits


Tenga en cuenta que también hay SDK que puede usar, pero nuestras API REST me parecen tan simples que simplemente accedo a los puntos finales directamente. Aquí está el script que escribí para realizar el proceso de extracción. Es básicamente todo lo que dije anteriormente y apunta a un PDF de origen en mi sistema de archivos local.


 /* 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.');

Ok, con suerte, todavía estás leyendo. En general, trato de evitar publicar bloques gigantes de código como ese, pero si te concentras en las líneas al final, verás que solo estoy accediendo a funciones de utilidad que hacen lo que describí en el flujo anterior. Autentíquese, solicite cargar un PDF, inicie un trabajo, verifíquelo y descargue el resultado.


Una nota que agregaré. Extract devuelve un archivo zip que contiene un conjunto de resultados JSON y, opcionalmente, tablas e imágenes. Una cosa buena de la API REST es que puedo acceder directamente al JSON y simplemente almacenarlo.


El resultado JSON puede ser bastante grande. Para mi PDF de origen (un documento de seguridad de Adobe increíblemente aburrido) de tres páginas, el JSON resultante tiene 4560 líneas. Puede encontrar mi PDF fuente aquí y el resultado sin procesar de Extract aquí .


En lugar de poner todas las 4,5k líneas aquí, permítanme mostrarles un fragmento: dos elementos únicos encontrados por la API:


 { "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" } },

En el ejemplo anterior, puede ver que el primer elemento es textual y contiene una propiedad Text , mientras que el segundo es una figura. Para mi demostración, solo necesito usar la propiedad Text cuando exista. Veámoslo en acción.

Paso dos: crear el resumen

Mencioné anteriormente que la API de Diffbot era bastante sencilla de usar. Déjame demostrarlo.


Primero, configuraré algunas variables y leeré el JSON que obtuve en el primer paso. Para ser claros, podría hacer todo en un solo proceso, pero realmente no tiene sentido ejecutar Extract más de una vez. Lo bueno es que podría hacer varias llamadas sobre el resultado.


Como ejemplo, otra característica interesante que tiene Diffbot es obtener entidades a partir de texto, es decir, de qué habla un documento (personas, lugares, etc.). De todos modos, aquí está el comienzo:


 /* 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}.`);


A continuación, necesito analizar el texto del resultado del extracto:


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


A continuación, elaboro una solicitud HTTP para Diffbot. Consulte sus documentos para obtener más información.


 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();


Y eso es. Como paso final, simplemente lo genero:


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


Dado el PDF fuente, el resultado final es:


 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.


Mi PDF de tres páginas es ahora un simple párrafo. Puede imaginar lo útil que sería esto para organizaciones con millones de documentos. Combine esto con otros servicios (como la función de entidades que mencioné anteriormente) y hará que trabajar con bibliotecas grandes sea mucho más fácil.

¡Intentalo!

Si desea comprobar esto usted mismo, puede obtener todo el código aquí: https://github.com/cfjedimaster/document-services-demos/tree/main/random_demos/extract_diffbot_summary . Como dije, todo lo que hay aquí se puede probar de forma gratuita, así que pruébalo y déjame saber lo que piensas en un comentario a continuación.