# 智能票据闭环 ## 当前能力 票据中心已经形成“主动上传 → 加密存档 → OCR 识别 → 字段核对 → AI 建议 → 人工确认 → 匹配流水 → 生成凭证”的本地闭环。发票与收付款流水是两类不同证据,因此人工确认票据不会新建收支流水,避免把“取得发票”误当成“已经付款”。只有匹配到已有真实流水并经人工确认后,系统才生成凭证关联并追加分类修订。 当前开放增值税发票图片,单张不超过 2.5 MB,支持 PNG、JPEG、BMP 和 WebP。文件按内容哈希去重,重复选择同一图片不会重复建档。 ## 状态与数据 - `documents`:保存加密原图、内容哈希、文件类型和处理状态。 - `ocr_runs`:追加保存每次识别的供应商、耗时、状态,以及服务可解析时的原始响应。 - `document_extractions`:保存经过归一化的可编辑字段,金额统一使用整数分。 - `ai_runs`:追加保存模型调用状态、服务可解析时的原始响应、校验后的建议和置信度。 - `document_reviews`:追加保存每次人工确认时的字段快照与时间。 - `vouchers`:保存票据、流水、入账分类、经营用途、匹配规则版本和确认前快照。 - `voucher_events`:追加保存凭证确认与撤销事件,不覆盖历史状态。 原始 OCR 结果不会因人工修改而被覆盖。失败调用同样留下审计状态,但日志和界面不显示供应商密钥。 ## 安全阀 - 文件签名与大小在发出网络请求前校验。 - OCR 只发送用户当前主动选择的图片。 - LLM 只接收识别后的必要字段,不读取整本账簿。 - LLM 返回必须是结构化 JSON,并通过方向、分类白名单、金额一致性、日期和置信度校验。 - 任何解析或校验失败都只显示失败,不产生记账结果。 - AI 建议与人工确认是两个独立动作,AI 永远不能自动入账。 - 流水候选使用确定性规则,不调用 LLM。金额和收支方向必须完全一致,日期相差不超过 45 天,交易对方相似度只参与排序和风险提示。 - 同一张票据或同一笔流水同时只能存在一张有效凭证。 - 撤销凭证通过追加反向事件和分类修订完成。如果用户在凭证确认后又手工修改过流水,撤销不会覆盖这次更新。 ## 服务端迁移 正式客户端发布前,把 `providers` 中的供应商 HTTP 调用移至服务端。客户端保留上传、复核和状态展示,通过小白记账 API 获取识别结果与建议。服务端负责供应商密钥、租户隔离、限流、重试和调用成本审计。 ## 回归检查 每次修改票据功能至少验证: 1. 不支持或超限文件在本地被拒绝。 2. 同一文件不会重复建档。 3. OCR 金额满足“不含税金额 + 税额 = 价税合计”的允许误差。 4. LLM 非 JSON、非法分类或金额不一致时不会产生建议。 5. 人工修改后保存的是新复核快照,OCR 原始结果仍可追溯。 6. 人工确认不会改变收支流水与税务计算结果。 7. 本机真实配置、测试票据和密钥不会进入 Git 或安装包。 8. 同额、同方向且日期相近的流水会成为候选,不同金额或相反方向不会出现。 9. 确认凭证不会新建第二笔流水,撤销后原始票据、流水和凭证历史仍可追溯。