本页目录
从非结构化数据中提取结构化数据,是 LLM 最强大的用例之一。
在这个示例中,我们会把任意文件传给 LLM,让它帮助我们分析文件。
这里使用的是一份 PDF 发票。我们会把 PDF 传给 LLM,让它从中提取结构化数据。
这意味着可以把系统中的各种文档转换成能够存入数据库、查询和搜索的数据。
创建 Schema
由于要使用结构化数据,先创建一个 Zod schema 来处理它。
import { z } from "zod";const schema = z.object({total: z.number().describe("The total amount of the invoice."),currency: z.string().describe("The currency of the total amount."),invoiceNumber: z.string().describe("The invoice number."),companyAddress: z.string().describe("The address of the company or person issuing the invoice.",),companyName: z.string().describe("The name of the company issuing the invoice.",),invoiceeAddress: z.string().describe("The address of the company or person receiving the invoice.",),}).describe("The extracted data from the invoice.");
这个对象包含不少内容:发票总金额、货币、发票编号、地址、公司名称以及收票方地址。
这种写法前面已经见过,不过请注意,我尽可能为每个属性都提供了描述,以便让 LLM 获得最高的成功概率。
从发票中提取数据
滚动式代码讲解
1
下面创建一个 extractDataFromInvoice 函数。在函数内部,把 schema 传给 generateObject,并附上一段简短的系统提示词。
我们期望得到一个 invoicePath,它是文件系统中 PDF 的路径。
2
前面的图像示例使用了 messages 数组。PDF 也可以采用相同方式,不过这次使用的内容类型是 file ,而不是 image.
这里使用 readFileSync 读取文件系统中文件的原始二进制数据,并把数据直接传给 AI SDK。
3
还需要传入 MIME 类型,告诉 LLM 它收到的是什么文件。LLM 或许可以通过检查文件的魔数自行判断,但明确说明一下总归更妥当,对吧?
4
最后返回这个对象,这样就能得到预期的对象结果。
import { generateObject } from "ai";export const extractDataFromInvoice = async (invoicePath: string,) => {await generateObject({model,system:`You will receive an invoice. ` +`Please extract the data from the invoice.`,schema,});};
运行示例
试着运行一下。我准备了一份虚构发票的 PDF,把它传进去看看效果。
const result = await extractDataFromInvoice("./invoice.pdf",);console.dir(result, { depth: null });
可以看到,我们成功从发票中获得了需要的数据。
这个示例结合了前面学过的两项能力:向 Vercel AI SDK 传入任意文件,以及使用结构化数据。非常实用。
登录以保存进度。