# VLAgent 智能文档识别平台架构解读

> 面向项目组内部分享的 vlagent 前后端工程全景解读：业务架构、技术架构、数据架构、核心核验流程与 CI/CD 发布流水线，附五张交互式图表。

---

LLMS 索引： [llms.txt](/llms.txt)

---

依据 vlagent 前后端仓库（`vlagent-backend` / `vlagent-frontend`）与工程内文档编制，用于项目组内部分享。文中五张图表均为交互式：支持缩放、语义视图、关系追踪与 PNG/SVG 导出。

## 一、项目概览 {#overview}

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 目录，代表较新的组织方式。

## 二、业务架构 {#business}

平台服务两类用户：**柜面柜员**（凭证影像上传、核验结果确认）与**审计/运营人员**（流水核对、报表核对）。接入侧通过 iframe 嵌入星辰智能助手（IOA），JWT 多通道取 token，用户无需二次登录；首页模块卡片由后端 `modules` + `permissions/me` 接口动态驱动，按权限渲染、**前端零改动**即可上下架模块。

业务能力划分为三个域 + 平台服务域，共九个业务模块：

| 能力域 | 模块 | 说明 | 状态 |
|---|---|---|---|
| 识别提取域 | 银行流水识别 | 11 家银行策略模式适配（工/农/中/建/交/招/光大/广发/邮储/济宁/齐鲁），汇总 + 逐页明细抽取，导出标准化 Excel | 未上线（开发完成） |
| | 发票识别 | 发票批量识别 | 已上线 |
| | 类凭证识别 | 身份证、银行卡、电子印章、授权书等 8 类凭证要素与签字提取 | 已上线 |
| | 询证函识别 | 13 字段 AI 抽取可人工修正 | 已上线 |
| | 通用 PDF 提取 | 用户自定义字段（≤10）动态生成 Schema 与 Prompt | 未上线（开发完成） |
| 核验比对域 | 结算凭证要素核验 | 当前演进重心：结算业务申请书 + 「转账支票+进账单」三件套联合核验，详见[需求规格说明书](../settlement-verification-spec/) | 已上线 |
| | 询证函格式比对 | 与标准模板逐项比对 | 已上线 |
| | 文档比对 | DOCX/PDF 结构化提取后页级/章节级 diff 高亮 | 未上线（开发完成） |
| 报表核对域 | 统计报送数据核对 | Word 数据变动说明 vs Excel 报表跨源对账，锚点匹配 + 异常高亮 | 已上线 |
| 平台服务域 | 模块注册 · 权限管理 | 上游星辰智能助手（IOA）库定时单向同步，多副本 Advisory Lock 防重 | 已上线 |

<iframe src="/ai/xingchen/04-vlagent-business-architecture.html" title="VLAgent 业务架构" loading="lazy" style="width:100%;height:700px;border:1px solid #e5e7eb;border-radius:8px;"></iframe>

<a href="/ai/xingchen/04-vlagent-business-architecture.html" target="_blank">全屏打开 ↗</a>

> [!NOTE]
> 各模块复用同一套"上传 → 异步识别 → 轮询 → 展示/导出"骨架，差异只在 prompt、schema 与导出模板——这是平台能快速叠加新票种的根本原因。

## 三、技术架构 {#tech}

### 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、版面），合规判定完全在确定性规则层。所有模型不确定性被限制在第一阶段，判定层可单测、可审计。

<iframe src="/ai/xingchen/05-vlagent-tech-architecture.html" title="VLAgent 技术架构" loading="lazy" style="width:100%;height:700px;border:1px solid #e5e7eb;border-radius:8px;"></iframe>

<a href="/ai/xingchen/05-vlagent-tech-architecture.html" target="_blank">全屏打开 ↗</a>

> [!TIP]
> 前后端共享一个 Ingress：`/vlagent/api` → 后端 8000，`/vlagent/` → 前端 OpenResty 8001，同源免跨域；前端三套环境 `.env.sit/.uat/.production` 值完全相同，差异只在构建模式。

## 四、数据架构 {#data}

**双库架构**：业务主库 `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 九个模块 |

<iframe src="/ai/xingchen/06-vlagent-data-architecture.html" title="VLAgent 数据架构" loading="lazy" style="width:100%;height:700px;border:1px solid #e5e7eb;border-radius:8px;"></iframe>

<a href="/ai/xingchen/06-vlagent-data-architecture.html" target="_blank">全屏打开 ↗</a>

> [!NOTE]
> 证据链是数据架构的一等公民：原始文件按模块落 NFS（upload/download 各 10Gi），PaddleOCR 输出目录全量持久化，每条核验结论携带 evidence 可回溯到具体裁片与要素值。

## 五、核心流程：凭证核验主链路 {#flow}

以结算凭证核验为代表的通用异步契约：

1. **接入**：柜员上传 PDF（魔数校验、防路径穿越）→ 建 `pending` 记录 → 接口立即返回任务 ID，前端开始 3 秒轮询。
2. **AI 抽取**：按票种分发 Handler（prompt + Pydantic schema）→ Qwen-VL 整图多面抽取 → PaddleOCR 印章定位 + VLM 裁片精读覆盖 stamps。
3. **自修复**：盲区二次提取、金额复核读（裁左右半分读大小写）、付款人账号跨单复核，矛盾消解后才覆盖。
4. **规则核验**：极简规则引擎（`Rule.check() → Engine → Report`）对要素总集逐条判定，输出**五态结论**（通过/不通过/警告/不适用/待人工复核），总体取最严重态。
5. **交付**：记录 + 逐条明细落库，前端轮询到完成态后渲染报告，支持证据定位与导出。

<iframe src="/ai/xingchen/07-vlagent-recognition-flow.html" title="VLAgent 凭证核验主流程" loading="lazy" style="width:100%;height:700px;border:1px solid #e5e7eb;border-radius:8px;"></iframe>

<a href="/ai/xingchen/07-vlagent-recognition-flow.html" target="_blank">全屏打开 ↗</a>

## 六、CI/CD 发布流水线 {#cicd}

三环境分级流转，**生产网与研发网物理隔离**：

| 环境 | 触发 | 构建 | 部署 |
|---|---|---|---|
| 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。

<iframe src="/ai/xingchen/08-vlagent-cicd-pipeline.html" title="VLAgent CI/CD 发布流水线" loading="lazy" style="width:100%;height:700px;border:1px solid #e5e7eb;border-radius:8px;"></iframe>

<a href="/ai/xingchen/08-vlagent-cicd-pipeline.html" target="_blank">全屏打开 ↗</a>

## 七、工程质量与演进方向 {#quality}

- **测试重心**：44 个测试文件、361 个用例，其中 settlement_check 占 33 个文件约 300 例（规则逐条一测、印章管线 40 例、可注入假 extractor 不依赖网络/DB），TDD 痕迹明显；HTTP 层与早期模块（banks/files）基本无单测。
- **已知文档滞后**：前端 README 提及的 Tiptap、api 分文件与后端的 `native_statement` 模块均与当前代码不符，以代码为准。
- **值得关注的取舍**：无消息队列（进程内后台任务 + 信号量）在当前并发规模下最简可靠，但识别吞吐受副本数硬约束；轮询而非 SSE 也是同源 iframe 场景下的务实选择。
- **演进方向**：结算凭证特种票种扩展、HTTP 层集成测试补齐、识别结果缓存与幂等重试。

---

反链：

- [星辰智能](/docs/ai/xingchen-intelligence/)
