VLAgent 智能文档识别平台架构解读
依据 vlagent 前后端仓库(vlagent-backend / vlagent-frontend)与工程内文档编制,用于项目组内部分享。文中五张图表均为交互式:支持缩放、语义视图、关系追踪与 PNG/SVG 导出。
一、项目概览
VLAgent 是部署在银行内网 K8s 上的智能文档识别平台:以 Qwen-VL 多模态大模型为主、PaddleOCR 为辅,对银行流水、结算凭证、询证函、发票、类凭证等影像做结构化抽取与规则核验,替代柜面与审计场景中的人工初核。系统以 iframe 嵌入**星辰智能助手(IOA)**对外提供服务,前端工作台与 FastAPI 后端共享同一 Ingress 域名(生产为 aisit.qdccb.cn / vlagent 路径)。
| 端 | 技术栈 | 仓库 |
|---|---|---|
| 前端 | Vue 3.5 · TypeScript 5.9 · Vite 7.2 · Tailwind 4.1 · OpenResty 托管 | vlagent-frontend/ |
| 后端 | Python 3.13 · FastAPI + uvicorn · SQLModel/asyncpg · uv 包管理 | vlagent-backend/ |
| AI | Qwen-VL 网关(OpenAI 兼容协议)· PaddleOCR PP-StructureV3 | 内网服务 |
| 基础设施 | GitLab · Jenkins · nerdctl · Harbor · Helm · NFS | 银行内网 |
两个工程均为"垂直切片"式组织:后端 src/ 下每个业务模块自带 router + service + models + prompts;前端除平铺的 views/ 外,settlement/、credit_comparison/ 两个新模块采用自带 views/components/api 的 feature 目录,代表较新的组织方式。
二、业务架构
平台服务两类用户:柜面柜员(凭证影像上传、核验结果确认)与审计/运营人员(流水核对、报表核对)。接入侧通过 iframe 嵌入星辰智能助手(IOA),JWT 多通道取 token,用户无需二次登录;首页模块卡片由后端 modules + permissions/me 接口动态驱动,按权限渲染、前端零改动即可上下架模块。
业务能力划分为三个域 + 平台服务域,共九个业务模块:
| 能力域 | 模块 | 说明 | 状态 |
|---|---|---|---|
| 识别提取域 | 银行流水识别 | 11 家银行策略模式适配(工/农/中/建/交/招/光大/广发/邮储/济宁/齐鲁),汇总 + 逐页明细抽取,导出标准化 Excel | 未上线(开发完成) |
| 发票识别 | 发票批量识别 | 已上线 | |
| 类凭证识别 | 身份证、银行卡、电子印章、授权书等 8 类凭证要素与签字提取 | 已上线 | |
| 询证函识别 | 13 字段 AI 抽取可人工修正 | 已上线 | |
| 通用 PDF 提取 | 用户自定义字段(≤10)动态生成 Schema 与 Prompt | 未上线(开发完成) | |
| 核验比对域 | 结算凭证要素核验 | 当前演进重心:结算业务申请书 + 「转账支票+进账单」三件套联合核验,详见需求规格说明书 | 已上线 |
| 询证函格式比对 | 与标准模板逐项比对 | 已上线 | |
| 文档比对 | DOCX/PDF 结构化提取后页级/章节级 diff 高亮 | 未上线(开发完成) | |
| 报表核对域 | 统计报送数据核对 | Word 数据变动说明 vs Excel 报表跨源对账,锚点匹配 + 异常高亮 | 已上线 |
| 平台服务域 | 模块注册 · 权限管理 | 上游星辰智能助手(IOA)库定时单向同步,多副本 Advisory Lock 防重 | 已上线 |
各模块复用同一套"上传 → 异步识别 → 轮询 → 展示/导出"骨架,差异只在 prompt、schema 与导出模板——这是平台能快速叠加新票种的根本原因。
三、技术架构
3.1 前端
- 无第三方组件库、无 Pinia:全部手写 Vue 组件 + Tailwind 工具类;状态用 composables 的模块级
ref单例(useUser)与函数式状态机(useAuth、useSettlementRecords)共享。 - API 层单文件收敛:
src/api/index.ts约 400 行封装全部后端接口,统一注入 Bearer token、401 全局登出、blob 预览与下载。 - 重前端计算:
credit_comparison在前端完成 Word 段落锚点匹配、高亮分词、Excel 行列识别(约 1000 行纯前端数据变换);PDF 渲染用 pdfjs-dist(含中文 cmaps),Word 用 docx-preview。 - 通信模式为纯 HTTP + 轮询(典型 3 秒,完成后自动停止),全库无 SSE/WebSocket。
3.2 后端
- 入口链路:
main.py组装 app(启动时自动alembic upgrade head、按需起 JVM 与上游同步、APScheduler)→api.py统一挂载 13 组子路由,全部默认要求 JWT(HS256,支持?token=URL 参数以适配 iframe)。 - 无消息队列:异步识别全部走 FastAPI 后台任务 +
asyncio.to_thread,全局asyncio.Semaphore(2)限流——2 副本 × 4 workers × 2 = 16 并发,压在 AI 网关 20 并发上限之内。 - 银行流水策略模式:抽象基类
BankHandler+@register_bank注册表,11 家银行各一个 handler 与独立表结构,config/bank_schemas/外置 schema。 - 文档处理链:pdf2image/poppler 拆页压缩、pdfplumber/pymupdf 结构化提取、容器内 LibreOffice 做 DOCX→PDF、diff-match-patch 做比对。
3.3 AI 混合管线
核心设计是抽取与核验分离:Qwen-VL 只做忠实抽取(含裁片精读),PaddleOCR 只做定位(印章 bbox、版面),合规判定完全在确定性规则层。所有模型不确定性被限制在第一阶段,判定层可单测、可审计。
前后端共享一个 Ingress:/vlagent/api → 后端 8000,/vlagent/ → 前端 OpenResty 8001,同源免跨域;前端三套环境 .env.sit/.uat/.production 值完全相同,差异只在构建模式。
四、数据架构
双库架构:业务主库 vlagent(PostgreSQL,asyncpg 异步驱动)+ 上游星辰智能助手(IOA)只读库。APScheduler 定时单向同步模块与权限,用 PG Advisory Lock 保证多副本多 worker 只有一个实例执行。
建表策略:表结构真相在 SQLModel 模型,由 init_db() 的 create_all 创建;alembic 仅做增量列变更(基线迁移为空操作,后续迁移逐条 ADD COLUMN IF NOT EXISTS 保证幂等)。
表清单概览(约 38 张):
| 域 | 表 | 说明 |
|---|---|---|
| 流水 | filerecords + 11 家银行 × 2 张 {Bank}Summary/{Bank}Transaction | 以 file_id 外键关联上传记录 |
| 结算核验 | settlement_check_records + settlement_check_items | 总记录(raw_extraction、Paddle 目录、软删)+ 逐条结论(rule_no、severity、evidence) |
| 文档比对 | document_compare_tasks / document_page_diffs / document_sections | 双管线(structured/page),sections 自关联树 |
| 信用对账 | credit_compare_task + 5 张业务表 | batch_id + word/excel_record_id 双外键关联 |
| 其余模块 | confirmation / invoice / credential / pdf_extract 各自 files+results | 统一"文件表 + 结果表"模式 |
| 平台 | user_permissions / modules | modules 启动时 seed 九个模块 |
证据链是数据架构的一等公民:原始文件按模块落 NFS(upload/download 各 10Gi),PaddleOCR 输出目录全量持久化,每条核验结论携带 evidence 可回溯到具体裁片与要素值。
五、核心流程:凭证核验主链路
以结算凭证核验为代表的通用异步契约:
- 接入:柜员上传 PDF(魔数校验、防路径穿越)→ 建
pending记录 → 接口立即返回任务 ID,前端开始 3 秒轮询。 - AI 抽取:按票种分发 Handler(prompt + Pydantic schema)→ Qwen-VL 整图多面抽取 → PaddleOCR 印章定位 + VLM 裁片精读覆盖 stamps。
- 自修复:盲区二次提取、金额复核读(裁左右半分读大小写)、付款人账号跨单复核,矛盾消解后才覆盖。
- 规则核验:极简规则引擎(
Rule.check() → Engine → Report)对要素总集逐条判定,输出五态结论(通过/不通过/警告/不适用/待人工复核),总体取最严重态。 - 交付:记录 + 逐条明细落库,前端轮询到完成态后渲染报告,支持证据定位与导出。
六、CI/CD 发布流水线
三环境分级流转,生产网与研发网物理隔离:
| 环境 | 触发 | 构建 | 部署 |
|---|---|---|---|
| SIT | push sit 分支 | nerdctl 构建 → Harbor | Helm → star-sit,push 即部署 |
| UAT | release/* 分支 | 同上 | 双模式:purpose=uat 直接部署 vl-flow-uat;purpose=production 只导出制品 |
| 生产 | 生产 Jenkins | 无构建 | FTP 下载镜像 tar + Chart → nerdctl load → 生产 Harbor → Helm → vl-flow(2 副本 + 污点容忍) |
双工程构建策略差异是理解流水线的关键:
- 前端在容器内多阶段构建(node:lts-bullseye 内 npm install + vite build → 拷入 OpenResty),
.dockerignore排除 lock 文件以适配内网 npm 源; - 后端采用 Agent 预构建 + 纯打包(Jenkins Agent 上
uv sync生成.venv,镜像只 COPY venv + 源码),基础镜像vlagent-backend-runtime:1.1预装 poppler、中文字体、LibreOffice 与 tini。
配置注入走 Helm:非敏感项进 ConfigMap、密钥进 Secret,Pod 以 config-hash/secret-hash 注解实现配置变更自动重启;上传产物落 nfs-client PVC。
七、工程质量与演进方向
- 测试重心:44 个测试文件、361 个用例,其中 settlement_check 占 33 个文件约 300 例(规则逐条一测、印章管线 40 例、可注入假 extractor 不依赖网络/DB),TDD 痕迹明显;HTTP 层与早期模块(banks/files)基本无单测。
- 已知文档滞后:前端 README 提及的 Tiptap、api 分文件与后端的
native_statement模块均与当前代码不符,以代码为准。 - 值得关注的取舍:无消息队列(进程内后台任务 + 信号量)在当前并发规模下最简可靠,但识别吞吐受副本数硬约束;轮询而非 SSE 也是同源 iframe 场景下的务实选择。
- 演进方向:结算凭证特种票种扩展、HTTP 层集成测试补齐、识别结果缓存与幂等重试。