地产金融业务中的文档并不只是“等待 OCR 的 PDF”。一份贷款材料可能混合评估报告、租约、财务报表、施工预算和扫描附件,后续还要经过拆分、分类、字段提取、规则判断与跨文档推理。Built 与 AWS 生成式 AI 创新中心、AWS 合作伙伴 AND Digital 及 AWS 客户团队合作,构建了一套可扩展的 AI 文档处理引擎,将部分原本需要数天的流程缩短到分钟级,并覆盖数百种文档类型。
真正困难的是流水线,而不只是模型
复杂文档处理通常包含五类不同任务:
- 分类:识别上传文件属于租约、估值报告、贷款申请还是其他材料。
- 拆分:从合并 PDF 中找出各份逻辑文档的起止页。
- 提取:把借款人、物业地址、租金、净营业收入等内容转成结构化字段。
- 评估:依据业务规则检查字段是否缺失、矛盾或超出阈值。
- 推理:结合多个页面或多份材料回答需要上下文的问题。
这五步不适合全部交给一次大模型调用。OCR 与版面分析需要稳定、可重复;分类和提取需要受控输出;评估通常还要执行确定性规则;只有涉及语义关系、模糊表述和跨文档关联时,生成式 AI 才最有价值。
因此,一个可维护的实现可以将流程拆成异步阶段:文档先进入对象存储,由事件触发编排任务;OCR、分类、拆分和字段提取分别执行;结构化结果连同证据页码写入数据库;推理服务只读取经过权限过滤的内容。这样的设计也便于单独替换模型、提示词或某个文档处理器。
让专家和工程师围绕同一份处理器协作
Built 的方案不仅追求自动化,也为技术团队和行业专家提供了共同构建、改进文档处理器的环境。这一点决定了系统能否长期覆盖数百种文档类型。
工程师关心接口、吞吐量、成本、版本和失败重试;地产金融专家更关心字段含义、证据位置以及判断是否符合业务惯例。两类角色需要共享同一套可观察对象,例如:
- 文档类型及分类置信度;
- 提取字段、标准化值和原始证据;
- 使用的处理器、模型与提示词版本;
- 人工修正结果及修正原因;
- 按文档类型统计的准确率、漏提率和人工复核率。
不要只保存大模型最终生成的 JSON。每个值都应尽量附带页码、原文片段和置信信息。否则专家发现错误时,团队只能看到“结果不对”,却无法判断问题出在 OCR、拆分、提示词还是业务规则。
可以这样实践:搭建一个最小异步处理入口
下面是一个可改造的 AWS SAM 示例。它假设 PDF 上传到 S3 后,由 Lambda 将处理任务写入 SQS;实际项目可继续接入 Step Functions、OCR 服务、Amazon Bedrock 模型调用以及人工复核界面。部署前需要安装并配置 AWS CLI 与 AWS SAM CLI,同时把区域和权限策略调整为所在组织允许的配置。
# template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
DocumentQueue:
Type: AWS::SQS::Queue
Properties:
VisibilityTimeout: 180
RedrivePolicy:
deadLetterTargetArn: !GetAtt DocumentDLQ.Arn
maxReceiveCount: 3
DocumentDLQ:
Type: AWS::SQS::Queue
UploadBucket:
Type: AWS::S3::Bucket
IntakeFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: python3.12
Handler: app.handler
CodeUri: src/
Timeout: 30
Environment:
Variables:
QUEUE_URL: !Ref DocumentQueue
Policies:
- SQSSendMessagePolicy:
QueueName: !GetAtt DocumentQueue.QueueName
- S3ReadPolicy:
BucketName: !Ref UploadBucket
Events:
PdfUploaded:
Type: S3
Properties:
Bucket: !Ref UploadBucket
Events: s3:ObjectCreated:*
Filter:
S3Key:
Rules:
- Name: suffix
Value: .pdf
Outputs:
UploadBucketName:
Value: !Ref UploadBucket
对应的 Lambda 入口只负责验证事件并投递任务,不在上传事件中同步完成整份文档分析:
# src/app.py
import json
import os
import urllib.parse
import boto3
sqs = boto3.client('sqs')
QUEUE_URL = os.environ['QUEUE_URL']
def handler(event, context):
queued = 0
for record in event.get('Records', []):
bucket = record['s3']['bucket']['name']
key = urllib.parse.unquote_plus(record['s3']['object']['key'])
task = {
'bucket': bucket,
'key': key,
'pipeline_version': 'real-estate-finance-v1',
'requested_steps': [
'classify', 'split', 'extract', 'evaluate', 'reason'
],
}
sqs.send_message(QueueUrl=QUEUE_URL, MessageBody=json.dumps(task))
queued += 1
return {'statusCode': 202, 'queued': queued}
将两个文件放到对应路径后即可部署:
sam build
sam deploy --guided
这个入口刻意保持简单。生产系统还应增加文件哈希去重、恶意文件扫描、租户标识、加密密钥、任务幂等键和全链路审计。对于超大 PDF,还要避免把二进制内容放进消息,只传递受控的对象引用。
准确率必须按业务风险拆开衡量
“字段提取准确率达到某个百分比”不足以判断系统能否上线。物业地址识别错误可能造成检索失败,而贷款金额、净营业收入或债务偿付覆盖率识别错误可能直接影响风险判断,两者代价完全不同。
建议按字段和流程分别设置门槛:高风险字段要求证据引用与人工确认;低置信度文档进入复核队列;规则评估应保留输入值、规则版本和结论;跨文档推理必须能返回引用来源。上线前还要用真实但经过合规处理的数据建立回归集,覆盖扫描件、旋转页面、手写内容、重复附件和表格跨页等情况。
生成式模型也会引入边界问题:它可能生成文档中不存在的值,或者在上下文过长时忽略关键页面。处理方法不是依赖一句“不要幻觉”的提示词,而是限制输出模式、校验字段类型、要求证据片段、对关键数值执行确定性复算,并在证据不足时允许模型明确返回 unknown。
采用前的检查清单
将这类平台引入生产环境时,可以从以下事项开始:
- 先选择一种高频、字段定义稳定且人工成本高的文档类型试点;
- 分开度量分类、拆分、提取、评估和推理质量;
- 为结果保存页码、证据、置信度和处理器版本;
- 使用队列、幂等处理与死信队列隔离失败任务;
- 对敏感金融数据实施最小权限、加密、保留期限和审计;
- 将专家修正转化为可版本化测试集,而不是直接覆盖历史结果;
- 同时观察处理时延、单页成本和人工复核率。
Built 的实践说明,文档智能的价值并不来自单个提示词,而来自一条可扩展、可评估、可由行业专家持续改进的处理链路。团队应先把证据、评测和人工复核机制建好,再逐步扩大文档类型和自动决策范围。