איך משתמשים ב-Document AI כדי לעבד טפסים בכתב יד באופן חכם (Node.js)

1. סקירה כללית

מה זה Document AI?

‫API של Document AI הוא פתרון להבנת מסמכים שמקבל נתונים לא מובְנים, כמו מסמכים, אימיילים וכו', והופך את הנתונים לקלים יותר להבנה, לניתוח ולשימוש. ממשק ה-API מספק מבנה באמצעות סיווג תוכן, חילוץ ישויות, חיפוש מתקדם ועוד.

במדריך הזה תתמקדו בשימוש ב-Document AI API עם Node.js. במדריך הזה מוסבר איך לנתח טופס פשוט של קבלת מטופל.

מה תלמדו

  • איך מפעילים את Document AI API
  • איך מאמתים בקשות API
  • איך מתקינים את ספריית הלקוח ל-Node.js
  • איך מנתחים נתונים מטופס סרוק

מה תצטרכו

  • פרויקט ב-Google Cloud
  • דפדפן, כמו Chrome או Firefox
  • ידע ב-Node.js

סקר

איך תשתמשו במדריך הזה?

רק לקרוא לקרוא ולבצע את התרגילים

איך היית מדרג את חוויית השימוש שלך ב-Node.js?

מתחילים ביניים מומחים

איזה דירוג מתאים לדעתך לחוויית השימוש שלך בשירותי Google Cloud?

מתחילים ביניים מומחים

‫2. הגדרה ודרישות

הגדרת סביבה בקצב אישי

  1. נכנסים אל Cloud Console ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. (אם עדיין אין לכם חשבון Gmail או G Suite, אתם צריכים ליצור חשבון).

חשוב לזכור את מזהה הפרויקט, שהוא שם ייחודי בכל הפרויקטים ב-Google Cloud. (השם שלך למעלה כבר תפוס ולא יפעל בשבילך, מצטערים!). בהמשך תצטרכו לספק את המזהה הזה כ-PROJECT_ID.

  1. לאחר מכן, כדי להשתמש במשאבים של Google Cloud, צריך להפעיל את החיוב במסוף Cloud.

חשוב לפעול לפי ההוראות שבקטע 'ניקוי'. בקטע הזה מוסבר איך להשבית משאבים כדי שלא תחויבו אחרי שתסיימו את המדריך הזה. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.

מפעילים את Cloud Shell

אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-Codelab הזה משתמשים ב-Google Cloud Shell, סביבת שורת פקודה שפועלת בענן.

הפעלת Cloud Shell

  1. ב-Cloud Console, לוחצים על Activate Cloud Shell H7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-SPszMxUxDjIeWfOHBfxDHYpmLQTzUmQ7Xx8o6OJUlANnQF0iBuUyfp1RzVad_4nCa0Zz5LtwBlUZFXFCWFrmrWZLqg1MkZz2LdgUDQ.

zlNW0HehB_AFW1qZ4AyebSQUdWm95n7TbnOr7UVm3j9dFcg6oWApJRlC0jnU1Mvb-IQp-trP1Px8xKNwt6o3pP6fyih947sEhOFI4IRF0W7WZk6hFqZDUGXQQXrw21GuMm2ecHrbzQ

אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג לכם מסך ביניים (מתחת לקו הקיפול) עם תיאור של הכלי. במקרה כזה, לוחצים על המשך (והמסך הזה לא יוצג לכם יותר). כך נראה המסך החד-פעמי:

kEPbNAo_w5C_pi9QvhFwWwky1cX8hr_xEMGWySNIoMCdi-Djx9AQRqWn-__DmEpC7vKgUtl-feTcv-wBxJ8NwzzAp7mY65-fi2LJo4twUoewT1SUjd6Y3h81RG3rKIkqhoVlFR-G7w

הקצאת המשאבים והחיבור ל-Cloud Shell נמשכים רק כמה רגעים.

pTv5mEKzWMWp5VBrg2eGcuRPv9dLInPToS-mohlrqDASyYGWnZ_SwE-MzOWHe76ZdCSmw0kgWogSJv27lrQE8pvA5OD6P1I47nz8vrAdK7yR1NseZKJvcxAZrPb8wRxoqyTpD-gbhA

‫Cloud Shell מספקת לכם גישה לטרמינל של מכונה וירטואלית שמארחת בענן. המכונה הווירטואלית כוללת את כל הכלים הדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את הביצועים והאימות ברשת. אפשר לבצע את רוב העבודה ב-codelab הזה, אם לא את כולה, באמצעות דפדפן או Chromebook.

אחרי שמתחברים ל-Cloud Shell, אמור להופיע אימות שכבר בוצע ושהפרויקט כבר הוגדר לפי מזהה הפרויקט.

  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שעברתם אימות:
gcloud auth list

פלט הפקודה

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

פלט הפקודה

[core]
project = <PROJECT_ID>

אם לא, אפשר להגדיר אותו באמצעות הפקודה הבאה:

gcloud config set project <PROJECT_ID>

פלט הפקודה

Updated property [core/project].

‫3. הפעלת Cloud Document AI API

כדי להתחיל להשתמש ב-Document AI, צריך להפעיל את ה-API. פותחים את מסוף Cloud בדפדפן.

  1. לוחצים על תפריט הניווט ☰ > APIs & Services (ממשקי API ושירותים) > Library (ספרייה). Search API
  2. חפשו את Document AI API, ואז לחצו על הפעלה כדי להשתמש ב-API בפרויקט בענן של Google.

4. יצירה ובדיקה של מעבד

כדי להשתמש במעבד Form Parser בפלטפורמת Document AI לצורך המדריך הזה, צריך קודם ליצור מופע של המעבד.

  1. במסוף, עוברים אל Document AI Platform Overview.
  2. לוחצים על יצירת מעבד ובוחרים באפשרות ניתוח טופסמעבדים.
  3. מציינים את שם המעבד ובוחרים את האזור מהרשימה.
  4. לוחצים על יצירה כדי ליצור את המעבד.
  5. מעתיקים את מזהה המעבד. תצטרכו להשתמש בערך הזה בקוד בהמשך.

(אופציונלי) אפשר להעלות מסמך כדי לבדוק את המעבד במסוף. לוחצים על העלאת מסמך ובוחרים טופס לניתוח. אם אין לכם טופס זמין, אתם יכולים להוריד את הטופס לדוגמה הזה ולהשתמש בו.

טופס בריאות

הפלט שלכם אמור להיראות כך: טופס שנותח

5. אימות בקשות API

כדי לשלוח בקשות ל-Document AI API, צריך להשתמש בחשבון שירות. חשבון שירות שייך לפרויקט שלכם, וספריית הלקוח של Google Node.js משתמשת בו כדי לשלוח בקשות API. בדומה לכל חשבון משתמש אחר, חשבון שירות מיוצג על ידי כתובת אימייל. בקטע הזה נשתמש ב-Cloud SDK כדי ליצור חשבון שירות, ואז ניצור את פרטי הכניסה שנדרשים לאימות כחשבון השירות.

קודם כול, מגדירים משתנה סביבה עם PROJECT_ID שבו תשתמשו לאורך ה-Codelab הזה:

export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value core/project)

בשלב הבא, יוצרים חשבון שירות חדש כדי לגשת אל Document AI API באמצעות:

gcloud iam service-accounts create my-docai-sa \
  --display-name "my-docai-service-account"

לאחר מכן, יוצרים פרטי כניסה שהקוד של Node.js משתמש בהם כדי להיכנס בתור חשבון השירות החדש. יוצרים את פרטי הכניסה ושומרים אותם כקובץ JSON ‏~/key.json באמצעות הפקודה הבאה:

gcloud iam service-accounts keys create ~/key.json \
  --iam-account  my-docai-sa@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

לבסוף, מגדירים את משתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS, שהספרייה משתמשת בו כדי למצוא את פרטי הכניסה שלכם. מידע נוסף על אימות באמצעות טופס זמין במדריך. צריך להגדיר את משתנה הסביבה לנתיב המלא של קובץ ה-JSON עם פרטי הכניסה שיצרתם, באמצעות הפקודה:

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/key.json"

6. הורדת טופס לדוגמה

יש לנו טופס לדוגמה שמאוחסן בקטגוריה של דוגמאות ציבוריות ב-Google Cloud Storage. כדי להוריד אותו לספריית העבודה, משתמשים בפקודה הבאה.

gsutil cp gs://cloud-samples-data/documentai/form.pdf .

כדי לוודא שהקובץ הורד ל-Cloud Shell, מריצים את הפקודה הבאה:

ls -ltr form.pdf

7. התקנת ספריית הלקוח

לאחר מכן מגדירים את הקוד בספריית העבודה.

מאתחלים חבילת Node.js חדשה:

npm init

מתקינים את ספריית הלקוח של Document AI:

npm install @google-cloud/documentai

8. שליחת בקשה סינכרונית לעיבוד מסמך

בשלב הזה, מבצעים קריאה למסמך תהליך באמצעות נקודת הקצה הסינכרונית. כדי לעבד כמויות גדולות של מסמכים בו-זמנית, אפשר להשתמש גם ב-API האסינכרוני. כדי לקבל מידע נוסף על השימוש ב-Form Parser APIs, אפשר לקרוא את המדריך כאן.

יוצרים קובץ index.js ומדביקים את הקוד הבא. ממלאים את המשתנים הרלוונטיים בפרטי המעבד.

const { DocumentProcessorServiceClient } = require('@google-cloud/documentai').v1;
const fs = require('fs');

/**
 * Runs the sample document through Document AI to get key/value pairs and
 * confidence scores.
 */
async function processDocument(projectId, location, processorId, filePath, mimeType) {
    // Instantiates a client
    const documentaiClient = new DocumentProcessorServiceClient();

    // The full resource name of the processor, e.g.:
    // projects/project-id/locations/location/processor/processor-id
    // You must create new processors in the Cloud Console first
    const resourceName = documentaiClient.processorPath(projectId, location, processorId);

    // Read the file into memory.
    const imageFile = fs.readFileSync(filePath);

    // Convert the image data to a Buffer and base64 encode it.
    const encodedImage = Buffer.from(imageFile).toString('base64');

    // Load Binary Data into Document AI RawDocument Object
    const rawDocument = {
        content: encodedImage,
        mimeType: mimeType,
    };

    // Configure ProcessRequest Object
    const request = {
        name: resourceName,
        rawDocument: rawDocument
    };

    // Use the Document AI client to process the sample form
    const [result] = await documentaiClient.processDocument(request);

    return result.document;
}

/**
 * Run the codelab.
 */
async function main() {
    const projectId = 'YOUR_PROJECT_ID';
    const location = 'YOUR_PROJECT_LOCATION'; // Format is 'us' or 'eu'
    const processorId = 'YOUR_PROCESSOR_ID'; // Should be a Hexadecimal string

    // Supported File Types
    // https://cloud.google.com/document-ai/docs/processors-list#processor_form-parser
    filePath = 'form.pdf'; // The local file in your current working directory
    mimeType = 'application/pdf';

    const document = await processDocument(projectId, location, processorId, filePath, mimeType);
    console.log("Document Processing Complete");

    // Print the document text as one big string
    console.log(`Text: ${document.text}`);
}

main(...process.argv.slice(2)).catch(err => {
    console.error(err);
    process.exitCode = 1;
});

מריצים את הקוד ועכשיו אמור להופיע הטקסט הבא במסוף.

Text: FakeDoc M.D.
HEALTH INTAKE FORM
Please fill out the questionnaire carefully. The information you provide will be used to complete
your health profile and will be kept confidential.
Name:
Date:
Sally
Walker
DOB: 09/04/1986
Address: 24 Barney Lane City: Towalo State: NJ Zip: 07082
Email: Sally, waller@cmail.com Phone #: (906) 917-3486
Gender:
Marital Status: Single Occupation: Software Engineer
Referred By: None
Emergency Contact: Eva Walker Emergency Contact Phone: (906) 334-8926
Describe your medical concerns (symptoms, diagnoses, etc):
Runny nose, mucas in throat, weakness,
aches, chills, tired
Are you currently taking any medication? (If yes, please describe):
Vyvanse (25mg) daily for attention

בשלבים הבאים, תחלצו נתונים מובְנים שאפשר לאחסן בקלות רבה יותר במסדי נתונים או להשתמש בהם באפליקציות אחרות.

9. חילוץ צמדי מפתח/ערך מטופס

עכשיו אפשר לחלץ מהטופס את צמדי המפתח/ערך ואת ציוני הוודאות התואמים. אובייקט התגובה Document מכיל רשימה של דפים ממסמך הקלט. כל אובייקט page מכיל רשימה של שדות בטופס והמיקומים שלהם בטקסט.

הקוד הבא מבצע איטרציה בכל דף ומחלץ כל מפתח, ערך וציון מהימנות.

מוסיפים את הפונקציה הבאה לקוד.

/**
 * Extract form data and confidence from processed document.
 */
function extractFormData(document) {
    // Extract shards from the text field
    function getText(textAnchor, document) {
        if (!textAnchor.textSegments || textAnchor.textSegments.length === 0) {
            return '';
        }

        // First shard in document doesn't have startIndex property
        const startIndex = textAnchor.textSegments[0].startIndex || 0;
        const endIndex = textAnchor.textSegments[0].endIndex;

        return document.text.substring(startIndex, endIndex);
    }

    var formData = [];

    const pages = document.pages;

    pages.forEach((page) => {
        const formFields = page.formFields;
        formFields.forEach((field) => {
            // Get the extracted field names and remove extra space from text
            const fieldName = getText(field.fieldName.textAnchor, document);
            // Confidence - How "sure" the API is that the text is correct
            const nameConfidence = field.fieldName.confidence.toFixed(4);

            const fieldValue = getText(field.fieldValue.textAnchor, document);
            const valueConfidence = field.fieldValue.confidence.toFixed(4);

            formData.push({
                fieldName: fieldName,
                fieldValue: fieldValue,
                nameConfidence: nameConfidence,
                valueConfidence: valueConfidence
            });
        });
    });

    return formData;
}

מוסיפים קריאה לפונקציה extractFormData() מתוך הפונקציה הראשית ומדפיסים את אובייקט התוצאה כטבלה.

/**
 * Run the codelab.
 */
async function main() {
    const projectId = 'YOUR_PROJECT_ID';
    const location = 'YOUR_PROJECT_LOCATION'; // Format is 'us' or 'eu'
    const processorId = 'YOUR_PROCESSOR_ID'; // Should be a Hexadecimal string

    // Supported File Types
    // https://cloud.google.com/document-ai/docs/processors-list#processor_form-parser
    filePath = 'form.pdf'; // The local file in your current working directory
    mimeType = 'application/pdf';

    const document = await processDocument(projectId, location, processorId, filePath, mimeType);
    const formData = extractFormData(document);

    console.log('\nThe following form key/value pairs were detected:');
    console.table(formData);
}

עכשיו מריצים את הקוד. אם משתמשים במסמך לדוגמה שלנו, הפלט אמור להיראות כך:

The following form key/value pairs were detected:
┌─────────┬────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────┬────────────────┬─────────────────┐
│ (index) │                           fieldName                            │                            fieldValue                            │ nameConfidence │ valueConfidence │
├─────────┼────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┼────────────────┼─────────────────┤
│    0    │                       'Marital Status: '                       │                            'Single '                             │    '1.0000'    │    '1.0000'     │
│    1    │                            'DOB: '                             │                          '09/04/1986\n'                          │    '0.9999'    │    '0.9999'     │
│    2    │                            'City: '                            │                            'Towalo '                             │    '0.9996'    │    '0.9996'     │
│    3    │                          'Address: '                           │                        '24 Barney Lane '                         │    '0.9994'    │    '0.9994'     │
│    4    │                        'Referred By: '                         │                             'None\n'                             │    '0.9968'    │    '0.9968'     │
│    5    │                          'Phone #: '                           │                        '(906) 917-3486\n'                        │    '0.9961'    │    '0.9961'     │
│    6    │                           'State: '                            │                              'NJ '                               │    '0.9960'    │    '0.9960'     │
│    7    │                  'Emergency Contact Phone: '                   │                        '(906) 334-8926\n'                        │    '0.9925'    │    '0.9925'     │
│    8    │                           'Name:\n'                            │                        'Sally\nWalker\n'                         │    '0.9922'    │    '0.9922'     │
│    9    │                         'Occupation: '                         │                      'Software Engineer\n'                       │    '0.9914'    │    '0.9914'     │
│   10    │                            'Zip: '                             │                            '07082\n'                             │    '0.9904'    │    '0.9904'     │
│   11    │                           'Email: '                            │                    'Sally, waller@cmail.com '                    │    '0.9681'    │    '0.9681'     │
│   12    │                     'Emergency Contact: '                      │                          'Eva Walker '                           │    '0.9430'    │    '0.9430'     │
│   13    │ 'Describe your medical concerns (symptoms, diagnoses, etc):\n' │ 'Runny nose, mucas in throat, weakness,\naches, chills, tired\n' │    '0.7817'    │    '0.7817'     │
└─────────┴────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────┴────────────────┴─────────────────┘

10. מעולה!

הצלחתם להשתמש ב-Document AI API כדי לחלץ נתונים מטופס בכתב יד. מומלץ להתנסות בתמונות אחרות לטופס.

ניקוי

כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה:

  • במסוף Cloud, נכנסים לדף Manage resources.
  • ברשימת הפרויקטים, בוחרים את הפרויקט ולוחצים על Delete (מחיקה).
  • כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

מידע נוסף

רישיון

עבודה זו מורשית תחת רישיון Creative Commons שמותנה בייחוס 2.0 כללי.