【立项背景与目标】
网约车平台每来一个司机注册申请,审核员要打开后台,逐项核对身份证、驾驶证、行驶证、交强险、网约车驾驶员证、网约车运输证六类证件,还要确认车辆有没有被其他司机绑定、这辆车符不符合入驻城市的准入要求。其中很大一部分是机械判断——证件号对不对、过期没有、年龄够不够、车龄超没超、准驾车型符不符。真正麻烦的是两件事:一是各地准入规则不一样,全国近百个城市的要求都不同,规则散在多份表格里,新人上手容易出错;二是同一个人审同一份材料,早上的结论和下午可能就不一样。我在做人工复检时发现,工具判断和人工判断的分歧几乎全部集中在"边界情况"上,说明问题不在人的态度,而在于规则从来没有被明确写下来。本项目要做的就是把这些标准固化下来:机械判断交给程序,需要主观判断的(照片合不合规、信息真不真)留给人。
【核心功能模块】
一、审核单自动定位与信息抽取:输入司机 ID,自动在待审队列里找到对应审核单,拉取六类证件的全部字段(含平台已识别的 OCR 结果),不需要人工复制粘贴。
二、证件核验自动化:对未核验的证件,一键发起平台核验并自动轮询取回结论。把原本"点按钮—等结果—看结论"三步,合并成一步。
三、政务网站自动查询:深圳、西安两地的运输证需要去交通主管部门官网按车牌查询。深圳官网有图形验证码,用浏览器自动化配合 OCR 识别;西安官网没有验证码,直接用 HTTP 请求解析返回页面。同样是查一个证,两套手段,成本差了一个数量级。
四、城市准入规则引擎:把全国近百个城市的准入口径——哪些证件必须上传、交强险是否强制、有没有官网查询渠道——做成一份可配置的表,判定时按城市自动套用。口径变了只改配置,不改代码。
五、三态判定引擎:每一单输出"可通过 / 需人工 / 不能通过"三种结论之一,并把判定依据逐条写清楚,方便人工复核和对账。
六、台账输出:批量审核后自动生成 Excel 反馈台账,结论按三态着色,附汇总表与核验结果表。
【流程说明】
输入司机 ID 或批量拉取待审队列 → 拉取审核详情 → 对未核验证件发起系统核验 → 深圳/西安车证转官网查询 → 按城市准入规则逐项判定 → 输出三态结论与逐条原因 → 生成 Excel 台账,人工只需处理"需人工"那部分。
这里有一条我坚持的原则:工具只做"核对 + 通过 + 标记",永远不调用驳回接口。所有"不能通过"的结论都只是标记,最终怎么处置由人来定。我把产品定位成"审核员的副驾",而不是替代者。
【整体架构与设计思路】
采用"分层解耦 + 配置驱动"的单机架构,用 Python 标准库为主、轻量依赖为辅,能在办公环境直接跑,不需要部署服务器。接入层统一封装平台鉴权(动态签名、时间戳、会话),集中处理错误码;数据层按证件类型归一化字段,屏蔽接口的命名陷阱(比如交强险字段实际叫 safetyNo / pic / endDate,而不是直觉上的 policyNo / img);规则层把城市准入表和判定引擎彻底分开,业务口径变化只需要改配置;输出层生成三态结论、Excel 台账和 Markdown 报告。
技术选型上做了差异化处理:深圳官网有验证码,就用 Playwright 驱动浏览器配合 OCR 识别;西安官网没有验证码但返回结构化页面,就改用 HTTP 直连解析,单次查询从几十秒降到毫秒级。同样的业务目标,用成本最低的手段解决。
【我负责的模块与量化结果】
我负责业务建模、规则设计与全链路方案设计,编码环节借助 AI 编程助手落地实现。这个项目我自己最看重的不是写了多少代码,而是把散落在表格和口头约定里的审核标准,整理成了一套可执行、可验证的规则。
一是城市准入表建设:把原本分散在多份表格里的全国城市准入口径结构化为可配置项,顺带修正了一处长期存在的口径错误——原先认为只有 5 个城市要求强制双证,实际是 26 个。
二是校准闭环:建立"工具判定 × 人工复检"的比对机制,用人工结论反向校准工具规则,迭代 3 轮把一致率从 75% 提升到 100%。
三是实测结果:50 条样本中约七成可以自动出结论,其余转人工,每一单都能给出可追溯的判定依据。
【踩过的坑】
一是核验状态误判,这是最险的一次。平台返回的核验状态有多个取值,我最初把所有"非通过"状态都当成"核验无结果",险些把还在核验途中的申请批量判为拒绝。后来逐条拉取原始返回比对,发现其中两个状态的更新时间戳恰好是我方发起核验的时刻、且返回体为空,证明它们是"在途"而不是"无结果"。据此把状态拆成四类,并只在"在途超时"之后才判定无结果。这次的教训是:影响面越大的规则,越要先穷举它的边界。
二是判定结论粒度不够导致误伤。官网判定模块一开始只输出"通过 / 需人工"两态,下游把"需人工"一律当作"不能通过",结果把"待签注"状态的合规车辆误判成了拒绝。后来引入三态判定,明确"待签注、待年审既不通过也不拒绝"。业务语义的粒度不够,下游一定会误用。
三是静默失败排查。某次批量运行,深圳的车辆全部失败,日志却只显示"识别失败"。逐层排查发现是 OCR 密钥配置没随脚本部署,而识别函数用异常捕获兜底返回了空字符串,把"配置缺失"伪装成了"识别不准"。修复方式是显式校验配置存在性并抛出真实异常,问题定位时间从数小时缩短到秒级。兜底逻辑写得太温柔,会把故障藏起来。