亚马逊AWS官方博客

欧税通基于 Claude 3 实现发票精准识别

应用背景

本文主要介绍在海外税务处理流程中发票信息提取场景下,欧税通和亚马逊云科技一起探索了 Claude 3 系列模型应用在该场景中的可行性,我们最终让 Claude 3 Haiku 实现了高达 91% 的综合识别(发票单号、公司、日期、币种、金额几要素全对)正确率。在 Amazon Bedrock Claude 3 模型的视觉识别能力的辅助下,通过非常简单的人工快速审核结合少量识别错误后的人工矫正,显著提升了运营人员的工作效率、降低了运营人员的工作疲劳感和乏味感并最终降低了整体的人力成本。我们希望这个方案能够在类似场景中能给大家一些启发,帮助大家更好地利用好AI的能力去提升业务价值和工作效率。

欧税通集团成立于 2019 年,是一家全球领先的跨境电商合规服务平台,致力于用创新的产品和服务提升全球出海合规业务健康发展。欧税通集团旗下现拥有欧税通、麦德通、小贸出海等知名品牌,提供税务服务、产品合规认证服务、知识产权服务、境外工商服务等一站式出海合规服务,业务覆盖全球 220+ 国家和地区,目前已为 20W+ 出海企业提供国际合规服务。海量的出海企业选择欧税通为其提供一站式出海合规服务时,大量的企业客户需要欧税通帮助其在各国完成税务申报和本土化合规工作,其中的涉及到大量的发票处理工作给欧税通带来一些挑战。如何充分利用最先进的 AI 能力,如何快速、正确、低成本地处理这些发票,进而保证欧税通领先的服务效率和服务质量,是欧税通一直都在不断思考的问题之一。

在发票自动化处理领域,正确处理全球各个国家或者公司的发票一直是非常有挑战性的工作。具体而言,这个场景下痛点为发票的版面样式、语种、金额和币种、数据内容的格式、关键性名词的描述术语、发票文件格式(PDF、图片等)等具体的税务关键信息并没有统一的标准;可能我们在国内一些场景或者消费类 APP 上经常会看到收货地址或者快递信息的自动录入,但是显著区别在于后者有比较明显的规律而且数据量较小,而前者几乎完全没有规律并且数据量较大。以往发票识别这些非标准化的工作都是在全手工的方式或者传统 OCR 辅助下以半手工的方式来实现,以保证报税金额、报税公司等信息绝对不会出现错误,用手工的处理方式在实际应用时,我们会发现识别并提取发票信息的运营人员在工作经验、工作强度、工作效率等因素影响下,保证运营人员长期维持一致的高标准的快速发票处理效率要付出极大的时间成本和精力。

解决方案整体架构

方案架构设计

Amazon Bedrock 是一项完全托管的服务,通过单个 API 提供来自 AI21 Labs、Anthropic、Cohere、Meta、Mistral AI、Stability AI 和 Amazon 等领先人工智能公司的高性能基础模型(FM),以及通过安全性、隐私性和负责任的人工智能构建生成式人工智能应用程序所需的一系列功能。其中来自 Anthropic 的 Claude 3 系列模型为我们带来了视觉处理能力,可以帮助我们完成图片识别并做智能化的内容提取和处理。因此发票识别方案以 Bedrock 模型为核心,设计了在亚马逊云科技上全托管的解决方案架构。

如下是解决方案架构图:

发票识别处理流程

从用户上传发票到最终处理以及审核,包含的主要的步骤如下:

  1. 上传发票文件到后端服务器上,一般是保存在 AWS S3 长期保存。
  2. 对发票进行预处理,将各种类型的发票转换为图片。
  3. 提示词模版填充。
  4. 交给 Claude 3 Haiku 进行识别提取。
  5. 识别结果由运营人员进行审核。这里我们为运营人员做了一个 web 可视化交互页面(后续会有提到)。
    • 如果识别结果完全正确,运营人员直接批准保存到数据库,实测完全(全部的提取项的内容)正确率可以到 91%。
    • 如果识别结果部分正确,运营人员可以直接矫正某个单项中的值,然后批准保存到数据库,实测部分正确率占比 5% 左右。
    • 如果识别偏差比较大,例如有 2 项或者多项错误。运营人员可以选择重新识别或者完全手动修改,最后批准保存到数据库。
  6. 保存到数据库的信息可以直接用来和外部的税务 API 交互,进行自动化税务处理。

以下是具体的处理流程图:

Claude 3 发票识别的最佳实践

对发票内容信息进行准确高效的提取是整个解决方案的核心,需要针对发票识别场景做了深入的定制优化;为了得最佳的识别效果,具体而言我们从发票预处理、Claude 3 提示词优化、人工审核校验等几个方面进行了优化。

发票文档预处理

为了更高的识别精度,在用户上传的发票文档后,需要对文档进行预处理,将预处理的图片和文本两种模态的信息同时输入到 Amazon Bedrock Haiku 模型中,进行信息融合抽取,得到最终结果。经过不断迭代优化,多模态预处理可采用如下流程:

PDF 文档解析

一般有发票 PDF 文档可以分为两类:

  1. 可解析出发票文字的数字文档:可以采用 PDF 解析器,提取 PDF 中所包含的原始文本,文本准确性高,可以保证模型更精准识别每一个字符甚至标点符号;
  2. 只有图片内容的扫描文档:由于 Claude 3 在对一些非英文语种的识别上有小概率认错字,因此可以选择 OCR 模型(如 Amazon Rekognition 或特定语言的 OCR 模型),提取原始字符信息,作为模型的辅助信息输入。

以上预处理的文本中已经包含了大量有价值信息,但是由于发票格式种类繁多,提取的文本往往格式较混乱,没有通用的处理方法。因此可以将未经格式化的文本输入给 Claude 模型,利用多模态大模型强大的信息融合能力,得到更有效的处理结果。

图片预处理

在提取文字的同时,还应将文档转为图片格式,有以下几点注意事项:

  1. 使用最合适的图片分辨率和尺寸。
    • 过大的图片尺寸会适得其反:Claude 3 处理图像的最大分辨率为长边 1568 像素,过大的图片尺寸不会对识别效果产生正面作用。因为超过限制的过大的图片在推理前会在 Claude 3 中先进行一次 resize,为了避免图片在后台压缩导致耗时增加,以及减少请求流量大小,尽量先将图片 resize 到 1568 像素以下再调用 API。
    • 过小分辨率的图片会导致无法正确理解图片内容,在 OCR 场景中,应尽量选择更大的分辨率,请至少确保人肉眼是可读的。
    • 推荐使用典型的图片宽高比比,一般典型的比例有 1:1、3:4、2:3、9:16、1:2。
  2. 注意图片方向,有些扫描的图片是正常图片旋转 90、180、270 等角度后展示的,建议调整为人类正常阅读所习惯的由上到下方向,这样在 Claude 模型处理才会有好的效果。这里可以选用如 tesseract 之类的工具对文档方向进行预检测,并调整图片方向。
  3. 使用合适的图片编码来减少数据传输,实现相同更快的响应速度。所有图片在请求时需要转换为 base64 编码格式,因此选择更高效的图片编码格式,如 WepP 格式,在相同图片压缩质量的情况下会比 JPEG 减少 25%-34% 的存储量。

图片预处理代码示例如下,代码片段的目的是先检查图片方向、对图片尺寸进行调整和对图片进行 Base64 编码;这里使用到了 pdf2image、pytesseract、Pillow 库来处理图像:

import io
import base64

import numpy as np
from PIL import Image
import pytesseract
from pdf2image import convert_from_path

MAX_SIZE = 1568

def preprocessing_image(pdf_path):
    # input  [pdf_path]:      pdf file path
    # output [images_base64]: list of image base64 encoding
    
    # pdf to images
    images = convert_from_path(pdf_path)
    images_base64 = []
    
    for image in images:
        # detect orientation and rotate
        orientation = pytesseract.image_to_osd(
            np.array(image), 
            output_type=pytesseract.Output.DICT
        )["orientation"]
        image = Image.fromarray(np.rot90(np.array(image), k=orientation//90))

        # resize image if is large than 1568
        width, height = image.size
        max_size = max(width, height)
        if max_size > MAX_SIZE:
            width = round(width * MAX_SIZE / max_size )
            height = round(height * MAX_SIZE / max_size )
            image = image.resize((width, height))

        # to base64
        buffer = io.BytesIO()
        image.save(buffer, format="webp", quality=85)
        image_data = buffer.getvalue()

        images_base64.append(base64.b64encode(image_data).decode("utf-8"))
    return images_base64

Claude 3 提示词优化技巧

  1. 图片在文本提示词之前输入,对于多页文档,应将每一页文档都分别转为图片输入,已取得更好的识别效果,Claude 3 一次最多处理 20 张图,即最大处理 20 页的文档,这已经可以完全产品实际需求。多个完全独立的发票识别任务,建议不要用同一个对话上下文,而是每个独立的识别任务用一个独立的对话 session。有些超过 20 页连续图片的发票识别场景,对于其中的单个识别任务而言,我们可以通过在一个对话 session 中分多次请求的方式来处理保证上下文的连续性。
  2. 对于需要提取的关键字,给出明确和直接的业务相关的提示词示例,并尽可能提供一些补充描述,如包含一些常用的数据录入规则,货币标识说明等;
  3. 给 Claude 明确的角色扮演提示,可以采用 system 参数输入,比如:”You are a financial staff responsible for identifying and entering procurement invoices. (假设你是一个专业财务分析人员,你正在进行发票内容提取和识别)”;
  4. 因为 Claude 3 模型训练语料的大部分为英文数据,因此在多语言场景下,采用英文提示词通常会取得比中文提示词取得更好的效果。所以前面提到的将文本+图片两种模态的信息组合后进行融合提取的方式能非常显著的降低文字识别错误的可能性。

以下是我们实际使用的提示词模版示例,可供参考:

prompts = f"""
The unformated raw text in the image is pre parsed in <parsed_text>, please prioritize <parsed_text> results when responding, and keep the exact spelling of words in uppercase and lowercase letters.
<parsed_text>
{pdf_text}
</parsed_text>
please provide the following information based on the invoices provided, and output it in JSON array format. Please note that the invoices I provide are 1 to multiple consecutive images, which are continuous. If you find multiple different invoices in these consecutive images, please output them in a JSON array according to <json_format>. The result does not need additional explanation fields and can be directly parsed as JSON.
<json_format>
"seller_company": I need the invoice seller's name , not the seller's name. the seller's company name may be described as "seller", "sold from", "vendor", "supplier", "卖方", "乙方", "供应商". usually at the top center of the invoice,Prioritize company name in title or first line of the invoice,Prioritize original English Company Name,if only chinese company name, priority traditional chinese name;DO NOT translate name. The buyer's name is generally marked with terms such as "Buyer", "to", "向", "甲方", "买方", "买家", "客户", "购买方", etc., representing the buyer.
"date": Creation Date, the value is in the YYYY-MM-DD format.
"invoice_number": invoice number, could also be described as purchase number, order number, serial number, if this are none of these, output an empty string.
"currency": currency abbreviation in ISO 4217 standard, like USD, EUR, CNY, CAD, HKD, JPY, AUD etc. DO NOT use other abbreviations.
"total_amount": the total amount of this order in float data type.
</json_format>
"""
body = json.dumps({
    "anthropic_version": "bedrock-2023-05-31",
    "max_tokens": 2048,
    "system": "You are a financial staff responsible for identifying and entering procurement invoices.",
    "messages": [
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": f"image/{image_format}",
                        "data": image_base64,
                    },
                },
                {
                    "type": "text",
                    "text": prompts,
                }
            ],
        }
    ],
}, ensure_ascii=False)
bedrock_runtime = boto3.client(service_name='bedrock-runtime', region_name="us-west-2")
response = bedrock_runtime.invoke_model(
    body=body, 
    modelId="anthropic.claude-3-haiku-20240307-v1:0"
)
result = json.loads(response.get('body').read())["content"][0]["text"]

运营人员审批校验

任何 AI 大模型都有一定的概率出现错误,所以发票数据由 Claude 3 提取后,我们可以简单的给运营人员一个审核工具,由于识别率正确率已经足够高,所以绝大多数情况下运营人员只需要简单对比下后即可审批通过。相比以前的全手工或者半手工方式,效率极大的提升了,工作负担得到了极大的降低。对于小概率出现的个别错误,运营人员可以选择少量手工更正。

典型实测效果

以下是几个在发票识别场景的实测效果,可以看到对于多种复杂格式的文档,结合了上述的优化手段后,Claude 3 Haiku 都可以取得精准的识别效果。

文档图片 识别结果
{
"seller": "Acme Supplies Inc.",
"date": "2019-05-02",
"invoice_number": "634",
"currency": "USD",
"total_amount": 8855.03
}
{
"seller": "Paragon Steel",
"date": "2018-10-04",
"invoice_number": "PO-S*******d.-00135",
"currency": "CAD",
"total_amount": 3010.0
}
{
"seller": "Taylor Dickens",
"date": "2017-04-26",
"invoice_number": "PO***5",
"currency": "USD",
"total_amount": 228.47
}
{
"seller_company": "汉堡王食品(深圳)有限公司",
"date": "2024-05-15",
"invoice_number": "2495**********21111",
"currency": "CNY",
"total_amount": 37.64
}

Claude 3 Haiku 成本估算

下面是根据 Anthropic Claude 3 Sonnet Image costs 进行的图片识别成本估算表,以 1092*1092 分辨率的图片识别为例,成本大约是每一千张图片 4.8 美元。

Image size # of Tokens Cost / image Cost / 1K images
200×200 px(0.04 megapixels) ~54 ~$0.00016 ~$0.16
1000×1000 px(1 megapixel) ~1334 ~$0.004 ~$4.00
1092×1092 px(1.19 megapixels) ~1590 ~$0.0048 ~$4.80

本文中的方案在经过充分优化和测试后发现 Haiku 的效果和 Sonnet 非常接近,我们最后选择了 Haiku。Haiku 在单位成本上是 Sonnet 的 1/12,因此我们基本可以大致估算出本方案的成本大约是每一千张图片 0.4 美元!这是一个非常有性价比的选择。

总结

文本介绍了欧税通与亚马逊云科技合作在发票识别场景中应用 Claude 3 模型的创新实践,详细介绍了基于 Amazon Bedrock Claude 3 的解决方案架构和流程,以及发票预处理、Claude 3 提示词优化及人工审核校验等最佳实践,并最终成功应用在实际的报税处理流程中,极大提高了工作效率,降低了人力成本。该实践不仅解决了当下的痛点,更为未来大规模应用 AI 技术在更多复杂非结构化数据场景提供了宝贵经验。未来生成式 AI 将为企业带来更多创新应用,提升运营效率,释放人力潜能。

*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您了解行业前沿技术和发展海外业务选择推介该服务。

参考链接

本篇作者

杨伟成

欧税通资深开发工程师,主要负责系统的整体设计与开发,多年开发经验,善于引导团队迭代以及解决技术难题,为项目注入创新力。

张佳楠

亚马逊云科技业务拓展经理,有多年服务跨境电商客户的经验,一直专注于帮助企业拓展海外市场,利用 AWS 的云计算、人工智能和大数据等创新技术,助力跨境电商卖家在全球范围内实现业务增长。

罗新宇

亚马逊云科技解决方案架构师,在架构与开发领域有非常丰富的实践经验,目前致力于 Serverless 在云原生架构中的应用。

校阅作者

吴健

亚马逊云科技解决方案架构师,专注于在企业中推广云计算与生成式 AI 的最佳实践。拥有多年的云计算开发和架构设计经验。