Automatice el procesamiento de facturas con Streamlit y Amazon Bedrock

El procesamiento de facturas es una tarea crítica, pero a menudo engorrosa, para empresas de todos los tamaños, especialmente para las grandes empresas que manejan facturas de múltiples proveedores con diferentes formatos. El gran volumen de datos, junto con la necesidad de precisión y eficiencia, pueden hacer que el procesamiento de facturas sea un desafío importante. Las facturas pueden variar ampliamente en formato, estructura y contenido, lo que dificulta el procesamiento eficiente a escala. Los métodos tradicionales que se basan en la entrada manual de datos o secuencias de comandos personalizadas para el formato de cada proveedor no sólo pueden generar ineficiencias, sino que también pueden aumentar el potencial de errores, lo que resulta en discrepancias financieras, cuellos de botella operativos y retrasos.

Para extraer detalles clave como números de factura, fechas e importes, utilizamos Roca Amazónicaun servicio totalmente administrado que ofrece una selección de modelos básicos (FM) de alto rendimiento de empresas líderes en IA como AI21 Labs, Anthropic, Cohere, Meta, Mistral AI, Stability AI y Amazon a través de una única API, junto con una amplia conjunto de capacidades que necesita desarrollar IA generativa aplicaciones con seguridad, privacidad e IA responsable.

En esta publicación, proporcionamos una guía paso a paso con los componentes básicos necesarios para crear un iluminado Aplicación para procesar y revisar facturas de múltiples proveedores. Streamlit es un marco de código abierto para que los científicos de datos creen de manera eficiente aplicaciones de datos interactivas basadas en web en Python puro. Usamos el modelo Claude 3 Sonnet de Anthropic en Amazon Bedrock y Streamlit para construir el front-end de la aplicación.

Descripción general de la solución

Esta solución utiliza el Bases de conocimiento de Amazon Bedrock chatear con función de documento para analizar y extraer detalles clave de sus facturas, sin necesidad de una base de conocimientos. Los resultados se muestran en una aplicación Streamlit, con las facturas y la información extraída una al lado de la otra para una revisión rápida. Es importante destacar que su documento y sus datos no se almacenan después del procesamiento.

La capa de almacenamiento utiliza Servicio de almacenamiento simple de Amazon (Amazon S3) para guardar las facturas que cargan los usuarios empresariales. Después de la carga, puede configurar un trabajo por lotes normal para procesar estas facturas, extraer información clave y guardar los resultados en un archivo JSON. En esta publicación, guardamos los datos en formato JSON, pero también puedes optar por almacenarlos en tu base de datos SQL o NoSQL preferida.

La capa de aplicación utiliza Streamlit para mostrar las facturas en PDF junto con los datos extraídos de Amazon Bedrock. Para simplificar, implementamos la aplicación localmente, pero también puedes ejecutarla en Amazon SageMaker Estudio, Nube de computación elástica de Amazon (Amazon EC2)o Servicio de contenedor elástico de Amazon (Amazon ECS) si es necesario.

Requisitos previos

Para realizar esta solución, complete lo siguiente:

Instalar dependencias y clonar el ejemplo.

Para comenzar, instale los paquetes necesarios en su máquina local o en una instancia EC2. Si es nuevo en Amazon EC2, consulte la Guía del usuario de Amazon EC2. En este tutorial usaremos la máquina local para la configuración del proyecto.

Para instalar dependencias y clonar el ejemplo, siga estos pasos:

  1. Clona el repositorio en una carpeta local:
    git clone https://github.com/aws-samples/genai-invoice-processor.git

  2. Instalar dependencias de Python
    • Navegue al directorio del proyecto:
      cd </path/to/your/folder>/genai-invoice-processor

    • pipa de actualización
      python3 -m pip install --upgrade pip

    • (Opcional) Cree un entorno virtual para aislar las dependencias:
    • Activar el entorno virtual:
      1. Mac/Linux:
      2. Ventanas:
  3. En el directorio clonado, invoque lo siguiente para instalar los paquetes de Python necesarios:
    pip install -r requirements.txt

    Esto instalará los paquetes necesarios, incluidos Boto3 (AWS SDK para Python), Streamlit y otras dependencias.

  4. Actualizar el region en el config.yaml archivo en la misma región configurada para su AWS CLI donde están disponibles Amazon Bedrock y el modelo Claude 3 Sonnet de Anthropic.

Después de completar estos pasos, el código del procesador de facturas se configurará en su entorno local y estará listo para las siguientes etapas de procesamiento de facturas utilizando Amazon Bedrock.

Procesar facturas con Amazon Bedrock

Ahora que la configuración del entorno está completa, está listo para comenzar a procesar facturas e implementar la aplicación Streamlit. Para procesar facturas con Amazon Bedrock, siga estos pasos:

Almacenar facturas en Amazon S3

Almacene facturas de diferentes proveedores en un depósito de S3. Puede cargarlos directamente mediante la consola, la API o como parte de su proceso comercial habitual. Siga estos pasos para cargar usando la CLI:

  1. Cree un depósito S3:
    aws s3 mb s3://<your-bucket-name> --region <your-region>

    Reemplazar your-bucket-name con el nombre del depósito que creaste y your-region con la Región configurada para su AWS CLI y en config.yaml (Por ejemplo, us-east-1)

  2. Cargue facturas al depósito S3. Utilice uno de los siguientes comandos para cargar la factura en S3.
    • Para cargar facturas a la raíz del depósito:
      aws s3 cp </path/to/your/folder> s3://<your-bucket-name>/ --recursive

    • Para cargar facturas en una carpeta específica (por ejemplo, invoices):
      aws s3 cp </path/to/your/folder> s3://<your-bucket-name>/<prefix>/ --recursive

    • Validar la carga:
      aws s3 ls s3://<your-bucket-name>/

Procesar facturas con Amazon Bedrock

En esta sección, procesará las facturas en Amazon S3 y almacenará los resultados en un archivo JSON (processed_invoice_output.json). Extraerá los detalles clave de las facturas (como números de factura, fechas y montos) y generará resúmenes.

Puede activar el procesamiento de estas facturas utilizando la CLI de AWS o automatizar el proceso con un Puente de eventos de Amazon regla o AWS Lambda desencadenar. Para este tutorial, utilizaremos la CLI de AWS para activar el procesamiento.

Empaquetamos la lógica de procesamiento en el script Python. invoices_processor.pyque se puede ejecutar de la siguiente manera:

python invoices_processor.py --bucket_name=<your-bucket-name> --prefix=<your-folder>

El --prefix El argumento es opcional. Si se omite, se procesarán todos los archivos PDF del depósito. Por ejemplo:

python invoices_processor.py --bucket_name=’gen_ai_demo_bucket’

o

python invoices_processor.py --bucket_name="gen_ai_demo_bucket" --prefix='invoice'

Usa la solución

Esta sección examina la invoices_processor.py código. Puede chatear con su documento en la consola de Amazon Bedrock o utilizando Amazon Bedrock Recuperar y generar API (SDK). En este tutorial, utilizamos el enfoque API.

    1. Inicialice el entorno: el script importa las bibliotecas necesarias e inicializa el cliente Amazon Bedrock y Amazon S3.
      import boto3
      import os
      import json
      import shutil
      import argparse
      import time
      import datetime
      import yaml
      from typing import Dict, Any, Tuple
      from concurrent.futures import ThreadPoolExecutor, as_completed
      from threading import Lock
      from mypy_boto3_bedrock_runtime.client import BedrockRuntimeClient
      from mypy_boto3_s3.client import S3Client
      
      # Load configuration from YAML file
      def load_config():
          """
          Load and return the configuration from the 'config.yaml' file.
          """
          with open('config.yaml', 'r') as file:
              return yaml.safe_load(file)
      
      CONFIG = load_config()
      
      write_lock = Lock() # Lock for managing concurrent writes to the output file
      
      def initialize_aws_clients() -> Tuple[S3Client, BedrockRuntimeClient]:
          """
          Initialize and return AWS S3 and Bedrock clients.
      
          Returns:
              Tuple[S3Client, BedrockRuntimeClient]
          """
          return (
              boto3.client('s3', region_name=CONFIG['aws']['region_name']),
              boto3.client(service_name="bedrock-agent-runtime", 
                           region_name=CONFIG['aws']['region_name'])
          )

    2. Configurar: El config.yaml El archivo especifica el ID del modelo, la región, las solicitudes para la extracción de entidades y la ubicación del archivo de salida para su procesamiento.
      aws: 
          region_name: us-west-2 
          model_id: anthropic.claude-3-sonnet-20240229-v1:0
          prompts: 
              full: Extract data from attached invoice in key-value format. 
              structured: | 
                  Process the pdf invoice and list all metadata and values in json format for the variables with descriptions in <variables></variables> tags. The result should be returned as JSON as given in the <output></output> tags. 
      
                  <variables> 
                      Vendor: Name of the company or entity the invoice is from. 
                      InvoiceDate: Date the invoice was created.
                      DueDate: Date the invoice is due and needs to be paid by. 
                      CurrencyCode: Currency code for the invoice amount based on the symbol and vendor details.
                      TotalAmountDue: Total amount due for the invoice
                      Description: a concise summary of the invoice description within 20 words 
                  </variables> 
      
                  Format your analysis as a JSON object in following structure: 
                      <output> {
                      "Vendor": "<vendor name>", 
                      "InvoiceDate":"<DD-MM-YYYY>", 
                      "DueDate":"<DD-MM-YYYY>",
                      "CurrencyCode":"<Currency code based on the symbol and vendor details>", 
                      "TotalAmountDue":"<100.90>" # should be a decimal number in string 
                      "Description":"<Concise summary of the invoice description within 20 words>" 
                      } </output> 
                  Please proceed with the analysis based on the above instructions. Please don't state "Based on the .."
              summary: Process the pdf invoice and summarize the invoice under 3 lines 
      
      processing: 
          output_file: processed_invoice_output.json
          local_download_folder: invoices

    3. Configurar llamadas API: el RetrieveAndGenerate API recupera la factura de Amazon S3 y la procesa utilizando FM. Se necesitan varios parámetros, como el mensaje, el tipo de fuente (S3), el ID del modelo, la región de AWS y el URI de S3 de la factura.
      def retrieve_and_generate(bedrock_client: BedrockRuntimeClient, input_prompt: str, document_s3_uri: str) -> Dict[str, Any]: 
          """ 
          Use AWS Bedrock to retrieve and generate invoice data based on the provided prompt and S3 document URI.
      
          Args: 
              bedrock_client (BedrockRuntimeClient): AWS Bedrock client 
              input_prompt (str): Prompt for the AI model
              document_s3_uri (str): S3 URI of the invoice document 
      
          Returns: 
              Dict[str, Any]: Generated data from Bedrock 
          """ 
          model_arn = f'arn:aws:bedrock:{CONFIG["aws"]["region_name"]}::foundation-model/{CONFIG["aws"]["model_id"]}' 
          return bedrock_client.retrieve_and_generate( 
              input={'text': input_prompt}, retrieveAndGenerateConfiguration={ 
                  'type': 'EXTERNAL_SOURCES',
                  'externalSourcesConfiguration': { 
                      'modelArn': model_arn, 
                      'sources': [ 
                          { 
                              "sourceType": "S3", 
                              "s3Location": {"uri": document_s3_uri} 
                          }
                      ] 
                  } 
              } 
          )

    4. Procesamiento por lotes: el batch_process_s3_bucket_invoices La función por lotes procesa las facturas en paralelo en el depósito S3 especificado y escribe los resultados en el archivo de salida (processed_invoice_output.json según lo especificado por output_file en config.yaml). Se basa en la función Process_invoice, que llama a la API de Amazon Bedrock RetrieveAndGenerate para cada factura y aviso.
      def process_invoice(s3_client: S3Client, bedrock_client: BedrockRuntimeClient, bucket_name: str, pdf_file_key: str) -> Dict[str, str]: 
          """ 
          Process a single invoice by downloading it from S3 and using Bedrock to analyze it. 
      
          Args: 
              s3_client (S3Client): AWS S3 client 
              bedrock_client (BedrockRuntimeClient): AWS Bedrock client 
              bucket_name (str): Name of the S3 bucket
              pdf_file_key (str): S3 key of the PDF invoice 
      
          Returns: 
              Dict[str, Any]: Processed invoice data 
          """ 
          document_uri = f"s3://{bucket_name}/{pdf_file_key}"
          local_file_path = os.path.join(CONFIG['processing']['local_download_folder'], pdf_file_key) 
      
          # Ensure the local directory exists and download the invoice from S3
          os.makedirs(os.path.dirname(local_file_path), exist_ok=True) 
          s3_client.download_file(bucket_name, pdf_file_key, local_file_path) 
      
          # Process invoice with different prompts 
          results = {} 
          for prompt_name in ["full", "structured", "summary"]:
              response = retrieve_and_generate(bedrock_client, CONFIG['aws']['prompts'][prompt_name], document_uri)
              results[prompt_name] = response['output']['text']
      
          return results

      def batch_process_s3_bucket_invoices(s3_client: S3Client, bedrock_client: BedrockRuntimeClient, bucket_name: str, prefix: str = "") -> int: 
          """ 
          Batch process all invoices in an S3 bucket or a specific prefix within the bucket. 
      
          Args: 
              s3_client (S3Client): AWS S3 client 
              bedrock_client (BedrockRuntimeClient): AWS Bedrock client 
              bucket_name (str): Name of the S3 bucket 
              prefix (str, optional): S3 prefix to filter invoices. Defaults to "". 
      
          Returns: 
              int: Number of processed invoices 
          """ 
          # Clear and recreate local download folder
          shutil.rmtree(CONFIG['processing']['local_download_folder'], ignore_errors=True)
          os.makedirs(CONFIG['processing']['local_download_folder'], exist_ok=True) 
      
          # Prepare to iterate through all objects in the S3 bucket
          continuation_token = None # Pagination handling
          pdf_file_keys = [] 
      
          while True: 
              list_kwargs = {'Bucket': bucket_name, 'Prefix': prefix}
              if continuation_token:
                  list_kwargs['ContinuationToken'] = continuation_token 
      
              response = s3_client.list_objects_v2(**list_kwargs)
      
              for obj in response.get('Contents', []): 
                  pdf_file_key = obj['Key'] 
                  if pdf_file_key.lower().endswith('.pdf'): # Skip folders or non-PDF files
                      pdf_file_keys.append(pdf_file_key) 
      
              if not response.get('IsTruncated'): 
                  break 
                  continuation_token = response.get('NextContinuationToken') 
      
          # Process invoices in parallel 
          processed_count = 0 
          with ThreadPoolExecutor() as executor: 
              future_to_key = { 
                  executor.submit(process_invoice, s3_client, bedrock_client, bucket_name, pdf_file_key): pdf_file_key
                  for pdf_file_key in pdf_file_keys 
              } 
      
              for future in as_completed(future_to_key):
                  pdf_file_key = future_to_key[future] 
                  try: 
                      result = future.result() 
                      # Write result to the JSON output file as soon as it's available 
                      write_to_json_file(CONFIG['processing']['output_file'], {pdf_file_key: result}) 
                      processed_count += 1 
                      print(f"Processed file: s3://{bucket_name}/{pdf_file_key}") 
                  except Exception as e: 
                      print(f"Failed to process s3://{bucket_name}/{pdf_file_key}: {str(e)}") 
      
          return processed_count

    5. Postprocesamiento: Los datos extraídos en processed_invoice_output.json Se puede estructurar o personalizar aún más para satisfacer sus necesidades.

Este enfoque permite el manejo de facturas de múltiples proveedores, cada uno con su propio formato y estructura únicos. Al utilizar modelos de lenguaje grande (LLM), extrae detalles importantes como números de factura, fechas, montos e información de proveedores sin requerir scripts personalizados para cada formato de proveedor.

Ejecute la demostración de Streamlit

Ahora que tiene los componentes instalados y las facturas procesadas con Amazon Bedrock, es hora de implementar la aplicación Streamlit. Puede iniciar la aplicación invocando el siguiente comando:

streamlit run review-invoice-data.py

o

python -m streamlit run review-invoice-data.py

Cuando la aplicación esté activa, se abrirá en su navegador web predeterminado. Desde allí, puede revisar las facturas y los datos extraídos en paralelo. Utilice las flechas Anterior y Siguiente para navegar sin problemas a través de las facturas procesadas para que pueda interactuar y analizar los resultados de manera eficiente. La siguiente captura de pantalla muestra la interfaz de usuario.

Hay cuotas para Amazon Bedrock (algunos de los cuales son ajustables) que debe considerar al construir a escala con Amazon Bedrock.

Limpieza

Para limpiar después de ejecutar la demostración, siga estos pasos:

  • Elimine el depósito de S3 que contiene sus facturas usando el comando
    aws s3 rb s3://<your-bucket-name> --force

  • Si configura un entorno virtual, desactívelo invocando deactivate
  • Elimine cualquier archivo local creado durante el proceso, incluido el repositorio clonado y los archivos de salida.
  • Si utilizó algún recurso de AWS, como una instancia EC2, finalícelo para evitar cargos innecesarios.

Conclusión

En esta publicación, analizamos una guía paso a paso para automatizar el procesamiento de facturas con Streamlit y Amazon Bedrock, abordando el desafío de manejar facturas de múltiples proveedores con diferentes formatos. Mostramos cómo configurar el entorno, procesar facturas almacenadas en Amazon S3 e implementar una aplicación Streamlit fácil de usar para revisar e interactuar con los datos procesados.

Si desea mejorar aún más esta solución, considere integrar funciones adicionales o implementar la aplicación en servicios escalables de AWS, como Amazon SageMaker, Amazon EC2o Amazon ECS. Debido a esta flexibilidad, su solución de procesamiento de facturas puede evolucionar con su negocio, brindando valor y eficiencia a largo plazo.

Le animamos a aprender más explorando Roca Amazónica, Acceda a los modelos de cimentación de Amazon Bedrock, Recuperar y generar API y Cuotas para Amazon Bedrock y crear una solución utilizando la implementación de muestra proporcionada en esta publicación y un conjunto de datos relevante para su negocio. Si tienes dudas o sugerencias, deja un comentario.


Acerca de los autores

Deepika Kumar es arquitecto de soluciones en AWS. Tiene más de 13 años de experiencia en la industria de la tecnología y ha ayudado a empresas y organizaciones SaaS a construir e implementar de forma segura sus cargas de trabajo en la nube. Le apasiona utilizar la IA generativa de manera responsable, ya sea para impulsar la innovación de productos, aumentar la productividad o mejorar las experiencias de los clientes.

Jobandeep Singh es arquitecto de soluciones asociado en AWS y se especializa en aprendizaje automático. Apoya a clientes de una amplia gama de industrias para aprovechar AWS e impulsar la innovación y la eficiencia en sus operaciones. En su tiempo libre le gusta practicar deportes, con especial afición al hockey.

Ratan Kumar es un arquitecto de soluciones con sede en Auckland, Nueva Zelanda. Trabaja con grandes clientes empresariales ayudándoles a diseñar y crear aplicaciones a escala de Internet seguras, rentables y confiables utilizando la nube de AWS. Le apasiona la tecnología y le gusta compartir conocimientos a través de publicaciones en blogs y sesiones de Twitch.