用 Amazon Bedrock Data Automation 构建可扩展的扫描文档 PII 脱敏流水线

2026-09-16 12 预计阅读时间: 1 分钟
来源: aws.amazon.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:11 分钟

扫描件、低清复印件和手写表单中的个人信息,往往比普通文本更难处理。OCR 可能漏掉字符,字段位置也不稳定;如果只依赖整页遮盖,又会损失文档的业务可用性。

一种更稳妥的做法,是把 Amazon Bedrock Data Automation、定制 blueprint、AWS Step Functions 和 AWS Lambda 组合起来:先从文档中提取结构化字段,再只对敏感字段做精确脱敏,并用 token matching 质量检查弥补退化图像和手写内容中的召回损失。

从“整页打码”转向“字段级脱敏”

这类流水线的核心不是简单识别某个字符串,而是同时回答两个问题:

  1. 文档中有哪些业务字段?
  2. 哪些字段属于需要隐藏的 PII?

定制 blueprint 可以把文档描述为一组字段,例如姓名、地址、身份证号、电话号码、银行账号或保单号。处理结果不再只是“这一页包含 PII”,而是可以定位到具体字段,并据此生成脱敏后的文档或结构化输出。

字段级处理有几个直接收益:

  • 保留日期、金额、产品名称等非敏感信息,方便后续审核和检索。
  • 对姓名、联系方式等字段单独设置遮盖策略。
  • 让审计日志记录“哪个字段被处理”,而不是只记录一页图片被修改。
  • 可以针对不同文档类型复用不同 blueprint,而不必为每类文档编写一套 OCR 规则。

不过,blueprint 的字段定义需要和真实文档样本一起迭代。字段名称、数据类型、是否必填以及可能出现的位置,都应该通过正常样本、低质量扫描件和手写样本验证。

用 Step Functions 编排异步处理流程

一个适合生产环境的处理链路可以拆成以下阶段:

S3 输入文档
    │
    ▼
Step Functions
    ├── Lambda:校验文件、生成 job 元数据
    ├── Bedrock Data Automation:按 custom blueprint 提取字段
    ├── Lambda:检查 token matching 质量
    ├── Choice:通过则进入脱敏;失败则重试或转人工审核
    └── Lambda:写入脱敏结果和审计记录

Step Functions 的价值在于把重试、超时、分支和人工审核边界显式化。不要把所有逻辑塞进一个 Lambda:文档较大、处理时间较长时,单个函数容易受到运行时长、内存和临时文件空间的限制。

下面是一份便于改造成 Amazon States Language 的配置草案。Resource 中的 ARN 需要替换为实际部署的 Lambda;Bedrock Data Automation 的调用参数也应按照目标区域和 SDK 版本补齐。

Comment: PII redaction pipeline with quality gating
StartAt: ValidateInput
States:
  ValidateInput:
    Type: Task
    Resource: arn:aws:lambda:REGION:ACCOUNT_ID:function:validate-document
    Retry:
      - ErrorEquals: [States.Timeout, Lambda.ServiceException]
        MaxAttempts: 3
        BackoffRate: 2.0
        IntervalSeconds: 2
    Next: ExtractWithBlueprint

  ExtractWithBlueprint:
    Type: Task
    Resource: arn:aws:lambda:REGION:ACCOUNT_ID:function:start-bedrock-data-automation-job
    TimeoutSeconds: 900
    Retry:
      - ErrorEquals: [States.Timeout, States.TaskFailed]
        MaxAttempts: 2
        BackoffRate: 2.0
        IntervalSeconds: 5
    Next: CheckTokenQuality

  CheckTokenQuality:
    Type: Task
    Resource: arn:aws:lambda:REGION:ACCOUNT_ID:function:check-token-quality
    Next: QualityGate

  QualityGate:
    Type: Choice
    Choices:
      - Variable: $.quality.recall_estimate
        NumericGreaterThanEquals: 0.98
        Next: RedactFields
    Default: ManualReview

  RedactFields:
    Type: Task
    Resource: arn:aws:lambda:REGION:ACCOUNT_ID:function:redact-pii-fields
    Next: PublishResult

  ManualReview:
    Type: Task
    Resource: arn:aws:lambda:REGION:ACCOUNT_ID:function:send-to-review-queue
    End: true

  PublishResult:
    Type: Task
    Resource: arn:aws:lambda:REGION:ACCOUNT_ID:function:publish-redacted-document
    End: true

这份示例故意把 Data Automation 的调用封装在 Lambda 中。这样做可以隔离 SDK 版本变化,也便于在提交任务前统一处理 S3 URI、blueprint 标识、幂等键和权限校验。

用 token matching 发现 OCR 漏检

低质量文档中,模型可能已经识别出大部分字段,但仍然漏掉一个字符或把空格、连字符处理得不一致。例如,原文中的证件号可能是 110105-1980-1234-5678,OCR 结果却变成 110105 1980 1234 5678

token matching 质量检查可以把多个来源放在一起比较:

  • blueprint 提取出的字段值;
  • OCR 的原始文本;
  • 业务系统已有的参考 token,例如订单号、客户号或文件元数据;
  • 脱敏结果中是否仍然出现敏感 token。

下面的 Python 示例不依赖 AWS SDK,可以直接运行,用于演示“规范化 token、检查匹配、决定是否放行”的最小逻辑。生产环境可以把 extracted_fields 替换为 Data Automation 的结构化输出,把 ocr_text 替换为 OCR 或文档解析结果。

运行方式:

python3 token_quality_check.py

token_quality_check.py

import re
from typing import Dict, List


def normalize(value: str) -> str:
    """忽略大小写、空格和常见分隔符,降低 OCR 格式差异的影响。"""
    return re.sub(r"[\s\-_/]+", "", value or "").casefold()


def token_present(token: str, text: str) -> bool:
    return normalize(token) in normalize(text)


def check_quality(
    extracted_fields: Dict[str, str],
    ocr_text: str,
    sensitive_fields: List[str],
    minimum_recall: float = 0.98,
) -> Dict[str, object]:
    expected = [
        value for name, value in extracted_fields.items()
        if name in sensitive_fields and value
    ]
    matched = [value for value in expected if token_present(value, ocr_text)]
    recall = len(matched) / len(expected) if expected else 1.0

    return {
        "recall_estimate": round(recall, 4),
        "passed": recall >= minimum_recall,
        "missing_tokens": [value for value in expected if value not in matched],
    }


if __name__ == "__main__":
    fields = {
        "full_name": "Zhang San",
        "phone": "138-0013-8000",
        "policy_number": "AB-2024-0009",
    }
    ocr_text = "Name: Zhang San; Phone: 138 0013 8000; Policy: AB20240009"
    result = check_quality(
        extracted_fields=fields,
        ocr_text=ocr_text,
        sensitive_fields=["full_name", "phone", "policy_number"],
    )
    print(result)
    if not result["passed"]:
        raise SystemExit("quality gate failed: route document to manual review")

这个检查器并不能替代模型评估,也不能证明“文档中不存在 PII”。它的作用是建立一个廉价、可解释的质量门:当关键 token 没有在原始文本中出现,或者不同来源的结果不一致时,暂停自动脱敏并转人工复核。

在生产环境中,召回率阈值不应固定套用。身份证号、银行账号等高风险字段可以设置更严格的阈值;低风险字段则可以结合人工抽样和业务容错率调整。还应记录误报、漏报和转人工比例,持续回放真实样本。

脱敏结果、权限和审计不能遗漏

PII 流水线的安全边界不止是模型本身。建议至少落实以下约束:

  • 原始文档和脱敏文档使用不同的 S3 前缀,必要时使用不同的 KMS 密钥。
  • Step Functions、Lambda 和 Data Automation 任务采用最小权限 IAM policy,不要为方便而授予整个存储桶的读写权限。
  • 原始文档设置生命周期策略,明确保留期限和删除责任。
  • 审计日志记录输入对象、blueprint 版本、处理状态、质量结果和输出对象,但避免把完整 PII 写进普通日志。
  • 通过幂等键避免 Step Functions 重试时重复生成结果。
  • 对失败文档保留可追踪的 job ID,并把人工审核作为明确的终态,而不是静默跳过。

还需要区分两种输出:供人查看的脱敏 PDF 或图像,以及供系统使用的结构化 JSON。前者关注遮盖区域和视觉效果,后者关注字段值、状态和审计信息。两者最好分别验证,避免出现“图片已经遮住,但 JSON 仍然泄露”的不一致。

落地时的检查清单

可以按下面的顺序推进:

  1. 收集正常扫描、低清扫描和手写样本,建立脱敏回归集。
  2. 为每类文档定义 custom blueprint 和敏感字段清单。
  3. 用 Step Functions 拆分提取、质量检查、脱敏和发布步骤。
  4. 使用 token matching 检查 OCR 漏检,并为高风险字段设置更严格的放行条件。
  5. 对失败任务、低召回结果和高置信度冲突设置人工审核路径。
  6. 通过 CloudWatch 指标或等价监控观察处理延迟、失败率、人工审核率和字段级漏检率。
  7. 在扩大吞吐量前,先验证权限、数据保留和重试幂等性。

Amazon Bedrock Data Automation 解决的是文档理解和结构化提取问题;真正可靠的 PII 脱敏系统,还需要 blueprint 设计、质量门、工作流编排和数据治理共同配合。把这些环节拆开并显式验证,才能在规模化处理扫描件时兼顾召回率、精确度和可审计性。


相关推荐