ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

开源组件搭建轻型AI中台:解决企业重复录入与对账难题

开源组件搭建轻型AI中台:解决企业重复录入与对账难题 上个月我帮一家做建材供应链的公司做收尾交付财务总监跟我聊起以前每个月月底的状态十几个Excel在四个人手里传来传去销售部录入的订单在ERP、CRM、订料系统里永远差那么几条银行回单和对账单对不上几乎是常态月底对账要花两到三天还得赔上加班和情绪。这个场景我太熟了——只要一个公司同时上过两套以上业务系统重复录入和对账困难就是早晚的事。这次我们做的就是给它部署了一整套轻型AI中台目标很朴素让数据只录一次后面所有系统自动同步让对账从人肉比对变成机器先核、AI辅助找差异、人只做确认。项目从环境准备到跑通核心流程没花一分钱买商业软件全部基于开源组件和内网私有化模型。这篇文章把整个项目从头到尾拆开讲一遍包含选型理由、部署命令、业务流程设计以及上线之后真实踩过的坑希望能给同样被重复录入和对账折磨的项目经理、IT负责人一点参考。1. 重复录入与对账困难业务规模上来之后的两个必然结果1.1 重复录入的根源系统林立与人工搬运先说重复录入这件事。大部分企业上系统是一步步来的可能先上了财务软件后来补一套CRM管客户再后来上一套进销存管库存最后再来个OA跑审批。每一套系统都是某个部门为了解决当时的问题买的没有谁从一开始就规划一套完整的数据架构。等系统越来越多麻烦就来了同一个客户在CRM里叫广州兴发建材有限公司在财务系统里可能叫兴发建材广州分公司在ERP里干脆缩写成兴发建财。客户数据对不上订单信息对不上自然就只能靠人肉搬运。我见过最夸张的情况是销售部签完一单之后要往三个系统里各录一遍ERP录物料需求CRM录客户跟进财务系统录开票信息。这三遍录入不是复制粘贴就完事的因为每个系统对字段的要求不一样有的要填税号有的要填交货地址有的要填付款账期。录完之后如果发现录错了还得三个系统挨个改。这种模式下录入员的工作量根本不是两倍三倍地涨而是随着系统数量呈组合式地涨。更深层的问题是人肉录入这件事天然不可靠。同一笔订单张三录的时候把数量从500敲成50李四在另一个系统里看到的就变成了不同的数据。月底一核对差异就浮出来了但根本没人记得是哪个环节错了。这就是重复录入最隐蔽的成本——它不只是浪费时间而是在制造错误。1.2 对账真正的开销不是核对而是定位不一致对账困难这件事很多人以为是核对这个动作难其实完全不是。真正的难点在于当两边数据对不上的时候你根本不知道到底是录错了、漏录了、还是录重了你得回溯一遍流程去查凭证、查单据、查邮件。这个过程比核对本身耗时十倍。这里的核心矛盾是系统之间没有统一的事实标准。财务的账是以发票和回单为准的销售的账是以订单和跟单记录为准的采购的账是以合同和收料单为准的。三个口径各有各的道理但对不上账的时候谁也不会主动承认自己的系统有问题。于是对账变成了一个漫长的举证过程财务抛出一张表销售要逐条确认这笔存在销售抛出一张表财务要逐条确认这笔到账了。一来一回时间全耗在沟通上。更麻烦的是跨期问题。一笔业务在业务系统里是上月发生的但银行回单这月才到两边月份对不上。或者一笔退货在业务系统已经冲销了但财务还没来得及入账对账时就成了多出来的负数。这些问题靠人看是能看明白的但靠Excel筛选是抓不出来的。我做过的绝大部分对账优化项目第一步都不是上技术而是先建立一套对齐规则——定义清楚以哪个数据源为基准、允许多大的时间窗口、哪些差异项属于已知正常范围。规则定清楚了后面上系统才有意义。2. 轻型AI中台的组件选型不买全家桶把开源件拼起来2.1 为什么是轻型先算一笔重型中台的账很多人一提AI中台就联想到云厂商几百万起步的套装方案动辄数据湖、流计算引擎、模型管理平台、自动化标注平台、企业知识图谱一套打满。这种方案确实强大但对于绝大多数年营收几千万到几个亿、IT团队只有三五个人的公司来说纯属杀鸡用牛刀。光是学习成本就够团队喝一壶的更别说后面的运维——这类平台跑起来动辄要配专用的Hadoop集群请得起专人维护Hadoop的公司真不多。我们这次刻意的定位就是轻型我反复跟甲方强调不要追求一步到位先把录入和对账这两个最痛的点打通以后要扩展AI能力再往这个骨架上挂新应用。轻型中台的定义就三句话统一的数据入口和出口、统一的主数据口径、统一的人工确认界面。至于AI能力私有化模型服务是底座工作流引擎用来编排业务这一层能解决大部分问题。2.2 组件清单与分工每个件只干它该干的事下面是这次实际采用的组件清单每个组件我都标了它的定位和选型理由层级组件用途选型理由接入层Nginx APISIX统一API入口、路由转发轻量、二次开发成本低比买API网关划算太多事件层NATS系统间事件同步、消息去重比Kafka轻一个量级资源占用极小业务量完全够用数据层PostgreSQL Redis业务数据、主数据映射、缓存PG的JSONB字段做半结构化数据非常方便文档解析MinerU PaddleOCRPDF/图片解析表格识别MinerU处理复杂PDF版面效果极佳PaddleOCR做票据、回单识别大模型推理Ollama / vLLM Qwen / DeepSeek私有化大模型接口做字段抽取和差异分析开源、内网部署、OpenAI兼容API接Dify非常顺应用编排Dify可视化编排AI工作流串联OCR→LLM→规则校验支持私有化有完整API拖拽式画流程比自研省事得多业务应用自研对账引擎 录入确认工作台规则对账、人工确认、审计留痕对账规则每家都不一样必须自己写才足够灵活这套架构跟重型中台最大的区别是没有引入任何需要专职团队维护的分布式组件。NATS单机跑就行PostgreSQL一台服务器搞定Ollama就是跑个进程Dify官方docker-compose一条命令起来。整套路线上真正需要人去维护的就三件事模型进程挂了拉起来、数据库备份、定期清理日志。这样一个IT兼职都能管得住。2.3 为什么Dify是关键拼图AI工作流不该从零开发这里我必须单独讲一下Dify。很多团队拿到大模型之后的第一反应是写代码调API结果写着写着就发现要给LLM加提示词、要做多轮函数调用、要做结果校验、要做异常分支每一块都是从零实现。这些工作在Dify里就是拖拽的事——把OCR服务、大模型节点、条件分支、人工确认节点拖到画布上连起来一个智能录入应用就成型了。Dify最方便的一点是支持自建模型供应商只要填一个兼容OpenAI格式的接口地址就能把Ollama或vLLM拉进来。这意味着模型随便换今天用Qwen跑抽取明天换成DeepSeek做分析界面里改个配置就行。加上它还提供发布为API的能力业务系统直接HTTP调用对自研系统的对接很友好。我们当时评估过n8n和Node-RED这类通用工作流工具最终还是选了Dify就是因为它的LLM应用专注度是最高的。3. 部署实操从一台空服务器到中台可用半天时间3.1 硬件与基础环境先想清楚要不要上GPU部署这套轻型AI中台硬件弹性比很多人想象的大得多。如果只是跑业务字段抽取、票据解析每天几百张单据的量级实测用纯CPU机器也能跑就是单张单据的解析耗时会到几十秒体验一般。有条件的话我还是建议上一块GPU。我们这次用的服务器是16核CPU、64GB内存、一张RTX 4090 24GB跑Qwen 14B int8量化非常从容显存占用大概16GB左右剩余空间还能同时常驻一个小一点的Embedding模型跑文本向量。如果预算更紧8GB显存的卡跑Qwen 7B Q4量化也够用抽取类任务没那么吃模型上限。热词里经常看到ollama本地部署、vllm部署deepseek这类话题本质都是在解决同一个问题把大模型的推理能力放到内网。对中台这种要接收业务敏感数据的场景来说模型必须私有化这一点没有商量余地。部署过程不复杂但有几条配置要先想清楚详见下一节。3.2 部署步骤Docker Compose一把梭服务器系统我习惯用Ubuntu 22.04 LTSDocker版本18.09之后都行Compose用v2。下面这是我们当时用的目录结构功能划分比较直观/opt/ai-platform/ ├── docker-compose.yml ├── .env ├── services/ │ ├── nginx/ │ ├── postgres/ │ ├── nats/ │ ├── redis/ │ ├── api/ # 自研业务后端 │ ├── web/ # 前端工作台 │ ├── dify/ # Dify官方编排 │ ├── ocr/ # PaddleOCR/MinerU服务 │ └── model/ # Ollama └── backup/核心的docker-compose.yml骨架长这样重点看网络和GPU配置version: 3.8 networks: ai-net: driver: bridge services: postgres: image: postgres:16-alpine environment: POSTGRES_USER: ai_platform POSTGRES_PASSWORD: change_me POSTGRES_DB: ai_platform volumes: - pg_data:/var/lib/postgresql/data networks: [ai-net] nats: image: nats:2.10 command: [-js] # 启用JetStream做持久化 networks: [ai-net] redis: image: redis:7-alpine networks: [ai-net] ollama: image: ollama/ollama:latest deploy: resources: reservations: devices: - driver: nvidia capabilities: [gpu] volumes: - ollama_models:/root/.ollama networks: [ai-net] dify-api: image: langgenius/dify-api:latest depends_on: - postgres - redis - ollama networks: [ai-net] dify-web: image: langgenius/dify-web:latest networks: [ai-net] ocr: image: registry.local/paddleocr:3.0 # 内网私有仓库里的镜像 networks: [ai-net] volumes: pg_data: ollama_models:有几条必须注意的细节deploy.resources.reservations.devices是Docker Compose v2声明GPU的标准方式前提是宿主要装好NVIDIA Container Toolkit。装完之后用nvidia-smi在容器里能看见显卡才算成功。NATS用JetStream模式启动非常关键。默认的NATS只是内存消息中转重启就丢消息。开了JetStream才会有持久化业务事件丢不起。各服务之间的通信全部走容器网络别名比如Ollama地址在Dify里填http://ollama:11434OCR服务地址填http://ocr:8000。这条路我在好几个项目里见过有人踩坑填了localhost导致容器内容器外互相找不到排查半天。Dify官方docker-compose会连带启动Postgres、Redis、Weaviate、Sandbox、Plugin Daemon等一系列组件内存占用比较大。如果服务器只有32GB建议把Weaviate换成单机模式或者干脆关掉Dify的Docker部署默认用Weaviate做知识库向量存储不用知识库功能的场景下是个纯负担。启动就三条命令cp .env.example .env # 改里面的密码、端口 docker compose config # 校验编排语法 docker compose up -d # 后台启动从拉镜像到所有服务起来实测大概二十分钟到四十分钟取决于网络。3.3 模型服务启动Ollama还是vLLM怎么选模型推理层这次用的是Ollama原因很简单部署和管理成本最低命令就两条docker compose exec ollama ollama pull qwen2.5:14b-instruct-q4_K_M docker compose exec ollama ollama pull bge-m3拉完之后Ollama会自动暴露一个兼容OpenAI的HTTP接口Dify填模型供应商的时候选OpenAI API Compatible填地址http://ollama:11434/v1就行。BGE-M3这个Embedding模型是给后面做客户名称相似度匹配用的后面讲主数据归一的时候会提到。那什么时候该换vLLM如果单张卡要跑多模型、并发请求量上去了比如同时有几十个人用每秒几十个请求Ollama的调度就会成为瓶颈。vLLM的PagedAttention机制能显著提升吞吐还支持多卡分布式推理。但vLLM对部署要求更精细模型文件格式要做转换AWQ、GPTQ量化格式兼容性要提前检查首次配置容易翻车。我们的经验是第一版一定要用最不容易出错的方案先把业务跑通并发瓶颈真出现了再平滑换到vLLM因为Dify那层改一个模型供应商地址就好业务侧零感知。模型版本的选择上字段抽取任务Qwen2.5-14B足以打主力它的结构化输出能力和中文指令跟随在开源模型里是第一梯队。DeepSeek-R1这类强推理模型更适合做差异分析和归因而不是高频抽取——原因后面踩坑篇细说。4. 消除重复录入的实现过程从多系统手工录入到一处确认全链路生效4.1 单据智能录入应用的设计这一章是业务价值最重的一环。我们选的第一个场景是采购订单和销售订单的智能录入。原来的流程是销售把客户发来的PO采购订单PDF下载下来照着里面的物料、数量、交货日期先录一遍ERP再录一遍CRM最后发一封邮件给财务备注开票信息。三个人花三个小时做同一件事。改造后的流程完全不一样了。客户发来的PO不管是什么格式——PDF、图片、Excel、甚至微信聊天的截图——先丢到统一入口OCR服务把版式解析成结构化文本Dify工作流里的LLM节点接着做字段抽取。抽取结果先过一遍规则引擎做自动校验校验通过的进人工确认队列确认人员打开界面核对几个关键字段之后点一下确认事件总线立刻把这个事件推给ERP、CRM、财务三个系统的对接接口。整个过程变成上传→确认→同步录入行为本身被消除了。Dify里这个工作流的节点大致是开始节点接收文件→ 文档解析节点调OCR服务→ LLM节点抽取字段→ 条件分支校验结果是否通过→ 通知节点进人工队列或自动通过。这些节点全是可视化配置的没有写一行业务代码。字段校验规则用Python代码写在Dify的自定义节点里两条就够用import json def check_invoice_fields(fields: dict) - dict: # 金额校验数量 * 单价 与 总金额 是否一致 calc_total round(float(fields.get(quantity, 0)) * float(fields.get(unit_price, 0)), 2) if abs(calc_total - float(fields.get(total_amount, 0))) 0.01: return {passed: False, reason: 金额不一致数量x单价与总金额相差 str(abs(calc_total - float(fields.get(total_amount, 0))))} return {passed: True, reason: }4.2 字段提取的工程化处理与人工确认兜底LLM抽取字段的准确率是所有人最关心的点。我们当时做了个压测随机抽了200张历史订单抽取准确率大概在95%左右也就是说20张里面会有1张某字段出错。这个数字看起来还行但对业务系统来说完全不可接受——订单的数量错了后面生产、采购、财务全跟着歪。所以工程化的关键不是追求模型100%准确而是把模型的不确定性挡在业务系统之外。我们的做法是这样抽出来的字段永远不会直接写入业务系统全部先进确认工作台。工作台依照置信度分成三类高置信规则校验通过、OCR和LLM抽取结果一致只需录入员扫一眼勾选确认。中置信某个字段存在模糊争议比如客户名称与主数据匹配度在60%到90%之间界面会高亮提示并给出候选值确认员只需下拉选择。低置信OCR识别模糊、字段缺失、金额校验失败这类直接强制人工填写。这个分层设计非常关键。它的价值在于绝不会因为模型出错而把错数据丢给业务系统同时也让人工从全量重新录入降级成了只处理异常。跟录入质量直接相关的还有一个被低估的问题主数据归一。同一家客户在不同系统里名称五花八门AI抽取出来之后还要做一次名称归一映射。我们建了一张客户映射表配合BGE-M3向量算相似度再叠加社会信用代码做精确匹配。第一次匹配成功后后续所有系统拿到的都是同一个主数据ID。这一步做完之后同一个客户在三个系统里是三个ID的历史问题才真正从根上解决。5. 消减对账困难的实现路径规则引擎为主干、AI差异分析做兜底5.1 自动对账工作台先讲规则再谈智能对账这类业务AI不是主角规则引擎才是。我们给财务做的对账工作台本质上是一个后台任务前端处理界面。后台每两小时自动从ERP、银行系统、财务系统拉流水统一落到一张对账明细表里然后跑一套对账规则。规则不是拍脑袋写的是跟财务一起开了三次会理出来的。沉淀下来主要就这四类优先级匹配场景匹配规则处理结果P0单号金额日期完全一致精确匹配自动核销P1单号一致、金额一致、日期相差3天内容差匹配自动核销标注日期偏移原因P2一笔应付对应多笔收款汇总匹配自动核销保留汇总明细P3其余不匹配项暂不处理进入AI差异分析池P0和P1的自动化覆盖了大概70%的对账流水这在一开始就能省掉大量人力。P2处理的是业务里常见的一笔合同分三次收款场景这个靠SQL聚合就能处理。真正复杂的是P3——差异项。每个月总有那么几十笔不是规则能定死的。5.2 AI差异分析让LLM做分类和找线索而不是做决策P3差异项的处理才是AI真正发挥价值的地方。我们把每笔差异项的信息拼成一个结构化Prompt丢给大模型做归因分类。Prompt的大致思路是这样你是一位财务对账助手。以下是系统A和系统B中无法自动匹配的一笔交易 系统A记录单号PO20240501-001金额128,500.00日期2024-05-01摘要采购铝材合同首付款 系统B记录单号INV20240515-023金额128,500.00日期2024-05-15摘要客户回款 请判断这笔差异最可能属于以下哪类 1. 跨期入账日期不一致但金额一致 2. 单号规则不同同一笔交易在两系统中编号方式不同 3. 重复录入两笔记录实为同一笔交易 4. 金额拆分/合并一笔交易拆成多笔 5. 系统录入错误 6. 无法判断 请输出分类和简要理由。实测下来DeepSeek-R1这类强推理模型在这类归因任务上的表现明显优于普通的指令微调模型。它能根据摘要中采购合同首付款和客户回款的语义关联推断这是同一笔钱的概率很高建议财务去核实。这就是为什么我刚才说强推理模型应该用在这儿而不是用来做高频字段抽取——抽字段是识别任务要求稳定快速归因是推理任务要求多想一步。但有一条底线必须守AI的所有判断都只是建议不能直接生成记账凭证。工作台上每个差异项会显示AI给出的归因标签和置信度财务人员点一下采纳或驳回才有后续动作。整个过程留痕操作人、AI判断、最终结论、时间全部落库保证审计的时候每一笔差异都查得到来龙去脉。上线之后的实际体验是原本财务花两个整天在Excel里盯着的差异项现在半小时就在工作台里全部分类完了——AI把最底层、最重复的找线索动作做了财务只需要把精力集中在少数真正有问题的账上。6. 上线实测中值得记录的四个坑6.1 抽取模型幻觉金额和账号不能赌上线第二周录入工作台抓到一个问题一张手写备注的PO数量字段被LLM从500抽成了5000规则校验没拦住因为那笔订单恰好单价×500的数量级恰好吻合某批历史价格的区间。就是这种错误但合理的幻觉最危险。排查下来是Prompt设计的问题——当时为了召回率提示词里写了如果单据中没有明确数量根据上下文推断。这句话给幻觉开了口子。修复方案很简单Prompt里强制改为只允许抽取原文中出现的数值任何推断值一律标记为缺失模型的temperature直接调到0关键数值字段在规则校验层加了一道跟OCR原始输出比对的逻辑对不上就转人工。修完之后幻觉率明显下降。这里我特别想强调对金额、账号、日期这类不可推断的硬字段宁可让模型承认不知道也不要让它猜。Prompt措辞里一旦出现推断估算补全这类词实测就是在给自己埋雷。6.2 事件总线的乱序与重复幂等设计不能省NATS本身消息投递有At-Least-Once语义也就是说同一个事件在网络抖动或客户端超时重试的情况下有可能被目标系统消费两次。我们踩的最实在的一个坑是ERP接口收到事件后处理到一半超时了ERP端显示失败于是业务系统重发了一次。结果第一次请求其实已经写了一半数据第二次又补了一份ERP里就出现了一条重复订单。解决办法有两个层面都必须做。第一是幂等键每一笔录入事件在源头生成一个全局唯一的UUID作为幂等键目标系统在入库前查这个键是否已处理过处理过就直接返回成功不再写数据。第二是NATS的JetStream消费者去重在消费者配置里开启消息去重窗口配合业务侧幂等双保险。这个问题不在线上出一次很难真正重视起来。6.3 OCR对复杂票据的识别率MinerU不是万能药PaddleOCR对清晰扫描件和电子银行回单效果很好但遇到手机拍的照片、发票上盖了红章、纸质单据折痕遮挡文字识别率就断崖式下跌。我们后来在OCR服务前面加了一道图像预处理——用OpenCV做透视矫正、去噪、增强对比度识别率提升了一截。对于多页PDF和复杂表格MinerU是更好的选择它直接带版面分析和表格重建抽出来的表格结构比纯OCR文本流干净得多。踩完这个坑之后我们在OCR架构上做了一个折中策略简单票据走PaddleOCR复杂文档自动路由到MinerU路由规则按文件类型和页数判断。效果和成本的平衡是关键别迷信任何一个工具能通吃全部场景。6.4 权限与审计中台集中了数据也集中了风险AI中台最大的特性是数据集中这也意味着权限控制一旦做不好风险比原来更集中。我们最后补了一块很重的功能按角色控制数据可见范围具体到字段级别。比如录入员能看到订单所有字段但看不到利润财务能看到金额但看不到客户联系方式管理员能看全部但所有查看操作被记录在审计日志里。这个设计纯粹是被审计逼出来的——甲方财务总监担心集中式中台把家底都暴露给一个人。我们做的审计日志记录了每个操作的主体、事件ID、对象ID、操作类型、变更前后值完全可追溯。这块在建平台第一天就该设计进去后面补真的是在给自己挖坑光是在业务代码里插桩就多花了一个星期。7. 上线后的实际效果与可以继续延伸的方向7.1 用数据说话三个指标的前后对比项目上线三个月时我做了一次完整的复盘拿上线前的三个月和上线后的三个月做了个对比指标上线前上线后变化单笔订单平均录入时间约10分钟约1.5分钟降低约85%月底对账耗时2~3人日约1.5小时降低约90%月度对账差异笔数平均20笔稳定在2~3笔降低约85%系统间数据不一致投诉每月3~5起基本归零——有意思的是录入时间降下来之后录入岗位的人没有被裁掉而是被重新分配去做数据核查与异常处理。财务团队更是明显以前月底焦头烂额现在她们可以提前把对账工作台里的异常项在日常就消化掉月底反而变成最轻松的一周。7.2 这套骨架还能往哪里延伸中台最值钱的部分不是单点功能而是把数据流、主数据、确认流程、审计机制这四件事建立了统一标准。有了这个骨架后面每加一个新场景都是往Dify里拖一个新应用。目前我们已经规划了三个方向一是合同智能审核。合同进来之后OCRLLM自动提取关键条款跟公司制度和历史合同做比对标出风险条款给法务确认。二是差旅报销自动化——发票、行程单、审批单全部自动关联财务只需要处理异常。三是做一个面向客户的智能客服入口把订单状态、物流信息通过RAG的方式接进来给客户提供问到哪查到哪的自助服务。这些方向都建立在同一个地基上数据只录一次所有系统都在同一套事实标准之下运行。地基打好了上面盖什么都结实。这个项目做到最后我最大的体会是三件事。第一AI中台不一定要贵也不一定要复杂关键是把重复录入和对账困难这两个日常最痛的场景作为切入点先让业务方感受到变化再往外扩展。第二AI在中台里的角色是多头并进的助手而不是决策者把规则引擎能干的干干好让AI只做规则覆盖不到的部分业务系统才不会失控。第三架构上先用最不容易出错的开源件把整条链路拉通以后再平滑替换单点组件这条路比上来就上重型全家桶要稳得多。希望这篇复盘能帮你少走几步弯路。
返回列表