Validasi dan koreksi Document AI memanfaatkan Common Expression Language (CEL) untuk memungkinkan validasi dan manipulasi data yang fleksibel dalam alur kerja pemrosesan dokumen Anda. Document AI menawarkan serangkaian fungsi kustom, makro, dan modifikasi perilaku yang disesuaikan untuk data entitas dokumen.
Mengakses entitas dalam ekspresi CEL
Semua ekspresi dievaluasi terhadap variabel root bernama doc, yang terdiri dari entitas yang merupakan frasa atau properti milik dokumen. Entitas ini mengikuti struktur entitas dokumen yang diekstrak dengan cermat.
Meskipun entitas yang diekstrak berisi banyak properti, hanya tiga di antaranya yang tersedia untuk evaluasi CEL.
mention_text: Teks mentah yang diekstrak seperti yang ada dalam entity yang diekstrak. Defaultnya adalah string kosong.normalized_value: Teks sebutan yang dinormalisasi seperti yang ada dalam entity yang diekstrak. Nilai defaultnya adalah null. Baca selengkapnya di Normalisasi.bounding_poly: Objek khusus yang berisi representasi penempatan entitas yang diekstrak dalam dokumen dan digunakan untuk pemeriksaan perataan. Nilai defaultnya adalah null.
Model data
Struktur persis entity yang diekstrak dalam peta doc bergantung pada dua
faktor. Yang pertama adalah apakah strukturnya merupakan nilai konkret, seperti angka atau teks biasa, atau apakah berupa objek kompleks. Faktor kedua adalah apakah jenis
kemunculannya tunggal atau ganda. Untuk informasi selengkapnya, lihat OccurrenceType.
Fitur utama model data validasi adalah bahwa setiap entity yang ditentukan dalam skema, tetapi tidak diekstrak dari dokumen, akan otomatis diisi dengan nilai default. Desain ini memungkinkan Anda melewati sebagian besar pemeriksaan null eksplisit dalam ekspresi CEL, sehingga menyederhanakan ekspresi validasi Anda secara signifikan. Anda hanya perlu menulis pemeriksaan null secara eksplisit untuk memastikan entitas yang dipilih memang diekstrak.
Contoh kasus entity leaf
Bagian berikut menjelaskan cara mengakses entity dalam entity leaf, yaitu entity tanpa entity turunan bertingkat. Entitas daun langsung menyimpan nilai.
Entitas daun dengan satu kemunculan
Ini adalah kasus paling dasar, menggunakan OccurrenceType dari OPTIONAL_ONCE atau
REQUIRED_ONCE. Entitas ditampilkan sebagai objek yang berisi tiga
properti standar.
Contoh cara mengakses nilai ini adalah doc.invoice_date.normalized_value.
Strukturnya adalah:
"invoice_date": {
"mention_text": "1",
"normalized_value": 1.0,
"bounding_poly": bounding_poly_object
}
Dan nilai default:
"invoice_date": {
"mention_text": "",
"normalized_value": null,
"bounding_poly": null
}
Entitas daun dengan beberapa kemunculan
Kasus ini berlaku untuk entity leaf yang dapat muncul beberapa kali dan memiliki
OccurrenceType OPTIONAL_MULTIPLE atau REQUIRED_MULTIPLE. Misalnya, dalam
daftar tanggal jatuh tempo pembayaran, ini ditampilkan sebagai objek yang setiap propertinya
berisi daftar nilai yang sesuai dari semua kemunculan. Jadi, properti seperti mention_text, normalized_value, dan bounding_poly mungkin memiliki beberapa entitas.
Contoh cara mengakses nilai ini adalah doc.payment_due_dates.normalized_value[0].
Strukturnya adalah:
"payment_due_dates": {
"mention_text": ["Mar 1, 2024", "Apr 1, 2024"],
"normalized_value": [null, proto.timestamp(2024-04-01)],
// Note: If a value is not normalized, it is stored as a null.
"bounding_poly": [bounding_poly_object,bounding_poly_object]
}
Dan nilai default:
"payment_due_dates": {
"mention_text": [],
"normalized_value": []
"bounding_poly": []
}
Entitas bertingkat
Entitas bertingkat adalah penampung untuk entitas lain, yang merupakan "turunannya".
Entitas bertingkat dengan satu kemunculan
Jika entity bertingkat hanya muncul satu kali, misalnya receiver_address tunggal,
entity tersebut direpresentasikan sebagai objek dengan kunci adalah nama entity turunannya.
Contoh cara mengakses nilai ini adalah doc.receiver_address.city.mention_text.
Strukturnya adalah:
"receiver_address": {
"street": {
"mention_text": "123 Main St",
"normalized_value": "123 Main St",
"bounding_poly": bounding_poly_object
}
}
Dan nilai default:
"receiver_address": {
"street": {
"mention_text": "",
"normalized_value": null,
"bounding_poly": null
}
}
Entitas bertingkat dengan beberapa kejadian
Jika entitas bertingkat dapat muncul beberapa kali, entitas tersebut ditampilkan sebagai daftar objek. Setiap objek dalam daftar mewakili satu instance lengkap dari entitas bertingkat dan berisi turunannya.
Contoh cara mengakses nilai ini adalah doc.line_items[1].description.normalized_value.
Strukturnya adalah:
"line_items": [
{
"description": { "mention_text": "Product A", ... },
"quantity": { "mention_text": "2", ... }
},
{
"description": { "mention_text": "Service B", ... },
"quantity": { "mention_text": "5", ... }
}
]
Dan nilai default:
"line_items": []
Tabel konversi nilai yang dinormalisasi
Tabel ini menunjukkan cara jenis data entitas skema yang dipilih diterjemahkan ke jenis data CEL
normalized_value.
| Jenis data skema | Jenis data CEL |
|---|---|
| Mata Uang, Alamat | string |
| Angka, Uang | double |
| Datetime | proto.Timestamp |
| Kotak centang, Tanda tangan | bool
|
| Teks Biasa | T/A |
Contoh ekspresi
Berikut beberapa contoh ekspresi CEL.
// Leaf entity with a single occurrence: Get the invoice ID string
doc.invoice_id.normalized_value == "INV-12345"
// Leaf entity with multiple occurrences: Get the first payment term from the list
doc.payments.mention_text[0].matches('^\d+$')
// Nested entity with one occurrence: Access a child entity of a single nested entity
doc.receiver_address.name.normalized_value.star
tsWith("John")
// Nested entity with multiple occurrences: Access a child of a specific item in a list of nested entities
doc.line_items[1].description.normalized_value == "Premium Gadget"
// Advanced: Sum the total of all line items
doc.line_items.map(item, item.total.normalized_value).sum() == 275.0
// Advanced: Check if any line item has a quantity greater than 1
doc.line_items.exists(item, item.quantity.normalized_value > 1.0)
Berikut contoh logika CEL lainnya yang dapat Anda gunakan.
// Ensure due date is after invoice date
doc.due_date.normalized_value > doc.invoice_date.normalized_value
// Cross list validation: ensure that each employer_contribution
// has a corresponding employee deduction
doc.employer_contribution.size() == doc.employee_deduction.size() && lists.range(doc.employer_contribution.size()).all(i,doc.employee_deduction[i].current_amount.mention_text != "" && doc.employer_contribution[i].current_amount.mention_text != "")
Perubahan perilaku
Dialek CEL Document AI mengubah beberapa perilaku standar agar lebih sesuai dengan kasus penggunaan pemrosesan dokumen.
Kesamaan berbasis epsilon
Untuk mengatasi kurangnya jenis desimal di CEL dan memperhitungkan ketidakakuratan floating point umum dalam data keuangan dan numerik, operator kesetaraan (==) dan ketidaksetaraan (!=) diubah untuk jenis numerik (double, int). Daripada kesetaraan yang tepat, operator ini menggunakan perbandingan berbasis epsilon dengan toleransi 1e-2 (0,01).
Misalnya, pertimbangkan total_amount dengan nilai yang dinormalisasi sebesar 100.005.
Dengan ekspresi doc.total_amount.normalized_value == 100.0, hasilnya adalah
true. Hal ini karena abs(100.005 - 100.0) kurang dari 0.01. CEL standar
akan menampilkan false.
Untuk ekspresi doc.total_amount.normalized_value == 100.02, hasilnya adalah
false. Hal ini karena abs(100.005 - 100.02) lebih besar dari 0.01.
Batasan fungsi string
Fungsi manipulasi string CEL standar dibatasi untuk beroperasi hanya pada properti mention_text entitas. Pembatasan ini memastikan bahwa aturan validasi diterapkan secara konsisten pada string teks literal sebagaimana muncul dalam dokumen.
Fungsi yang terpengaruh adalah:
contains()endsWith()startsWith()matches()
Berikut contoh yang valid:
// Checks if the extracted currency symbol is a dollar sign.
doc.total_amount.mention_text.startsWith("$")
Berikut adalah contoh perintah yang tidak valid:
// This will produce a validation error upon save because contains() is not
// being used on a .mention_text field.
doc.supplier_name.normalized_value.contains("Inc.")
Fungsi tambahan
Bagian ini menjelaskan fungsi global dan anggota non-standar yang tersedia di lingkungan evaluasi CEL Document AI.
Fungsi sum
### sum()
Menghitung jumlah daftar elemen numerik. Fungsi ini dapat dipanggil pada daftar bilangan bulat atau ganda. Perhatikan bahwa nilai null dalam daftar akan diabaikan. Jika daftar berisi elemen non-numerik, fungsi akan memicu error.
Tanda Tangan: <list>.sum()
Berikut adalah contoh yang menjumlahkan nilai yang dinormalisasi dari beberapa item baris.
// Calculates the sum of all line item amounts.
doc.line_item_amounts.normalized_value.sum()
Fungsi OR
### or()
Menampilkan nilai asli jika bukan null; jika tidak, nilai argumen kedua (default) akan ditampilkan.
Tanda Tangan: <value>.or(<;default_value>)
Sebagai contoh, Anda dapat menggunakannya untuk memberikan nilai default saat kolom opsional mungkin tidak ada.
// If the tax amount is not found, use a default of 0.0 for calculation.
doc.tax_amount.normalized_value.or(0.0) > 5.0
Memeriksa fungsi perataan vertikal daftar
### checkVerticalAlignment()
Menampilkan true jika semua objek bounding_poly disejajarkan secara vertikal ke tingkat yang ditentukan oleh toleransi. Jika tidak, akan menampilkan error yang menjelaskan entitas mana yang tidak selaras.
Toleransi adalah argumen opsional yang menentukan tumpang-tindih poli pembatas dengan poli pembatas yang selaras terbaik yang dipilih secara otomatis, dengan 0 berarti poli pembatas tidak berpotongan, 1 berarti poli pembatas identik.
Tanda Tangan: checkVerticalAlignment([<;bounding_poly>,...],tolerance=0.8)
Sebagai contoh, Anda dapat menggunakannya untuk membantu menjaga semua entitas yang diekstrak dalam satu kolom.
// Make sure that all extracted quantities are in the same column
checkVerticalAlignment(doc.line_items.map(li,li.quantity.bounding_poly))
Periksa fungsi perataan horizontal
### checkHorizontalAlignment()
Menampilkan true jika semua objek bounding_poly disejajarkan secara horizontal ke
derajat yang ditentukan oleh toleransi. Jika tidak, akan menampilkan error yang menjelaskan entitas mana yang tidak selaras.
Toleransi adalah argumen opsional yang menentukan tumpang-tindih poli pembatas dengan poli pembatas yang paling sesuai dan dipilih secara otomatis. Arti 0 adalah poligon pembatas tidak beririsan, dan 1 berarti poligon pembatas identik.
Tanda Tangan: checkHorizontalAlignment([<;bounding_poly>,...],tolerance=0.6)
Sebagai contoh, Anda dapat menggunakan ini untuk membantu menyimpan semua entity yang diekstrak dalam satu baris.
// For all line items make sure that each extracted line item's
// children are in the same row. For example, if line item has
// quantity and description properties, it makes sure they are in
// a single row for each respective line item.
doc.line_items.all(li, checkHorizontalAlignment(li.map(col,li[col].bounding_poly)))
Makro tambahan
Bagian ini menjelaskan makro non-standar yang tersedia di lingkungan evaluasi CEL Document AI.
Untuk mengetahui informasi selengkapnya tentang makro, lihat Definisi bahasa: Makro.
Kurangi makro
### reduce()
Gunakan makro reduce untuk melakukan operasi kumulatif pada daftar.
Tanda Tangan: <list>.reduce(<;iterator_name>, <;accumulator_name>, <;initial_value>, <;loop_expression>)
iterator_name: Nama variabel untuk elemen yang diproses di setiap iterasi.accumulator_name: Nama variabel untuk nilai yang mengakumulasi hasil.initial_value: Nilai awal akumulator.loop_expression: Ekspresi yang menentukan cara akumulator diperbarui di setiap langkah.
Berikut adalah contoh penggunaan makro:
// Use reduce to sum up the quantities from all line items.
doc.line_items.reduce(item, running_total, 0.0, running_total + item.quantity.normalized_value)
// Result: 3.0
// Tip: this could also be done by concatenating map and sum:
doc.line_items.map(item,item.quantity.normalized_value).sum()
Library ekstensi CEL
Selain fitur kustom, library ekstensi CEL standar berikut tersedia.
- Daftar: Menyediakan fungsi untuk manipulasi daftar:
range, distinct, flatten, reverse, sort, slice. Untuk mengetahui informasi selengkapnya, lihat Daftar. - Math: Menyediakan fungsi matematika yang diperluas seperti
math.greatest, math.least, math.abs. Untuk mengetahui informasi selengkapnya, lihat Matematika.
Langkah berikutnya
Pelajari pemroses terlatih.