Auromix/expense-reimbursement-skill

Agent skill for invoice & expense reimbursement.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add Auromix/expense-reimbursement-skill

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentación

企业报销材料整理

把用户给的一堆原始报销材料,整理成结构清晰、命名规范、可直接交财务的一套交付物:分桶归档的材料 + 填好的费用明细表 + 给财务看的额外说明 + 可追溯的过程台账。

三条不可逾越的红线

  1. 原始材料和原模板永不修改。 一切改动都发生在备份件和模板副本上。
  2. 绝不臆造信息。 看不清、对不上、要素缺失的,列入存疑清单向用户索取,宁可问也不编。
  3. 一笔消费只入表一行,绝不重复计费。 发票和它的支付截图是同一笔;改签前后是同一程;企业已代付的部分不报。详见 references/归类与命名规范.md 第 3.1–3.3、第六节。

命令一律用 python3(很多环境没有 python 别名);脚本路径用相对本 skill 目录的 scripts/...


开始前要拿到的输入

  1. 原始材料文件夹路径(里面可能是 jpg/png/pdf/ofd/excel/各种格式混在一起,可能有子目录)。
  2. 报销模板 .xlsx 路径。
  3. 身份信息(姓名、部门、提交日期、币种、默认所属部门、默认所属项目编码、预支现金)。
    • 先检查 过程文件/身份信息.json 是否已存在(上次跑存下的);存在就读取复用,并跟用户确认一句是否沿用。
    • 不存在或不全,向用户索取缺的字段后,写入 过程文件/身份信息.json 供下次复用。

模板字段、列含义、事由必填要素见 references/模板与字段映射.md,开工前先读它。


可调的三个默认行为(用户一句话即可改)

  • 自主程度(默认:拿不准才问)。置信度高的自动归类归桶;分不清差旅交通 vs 市内交通、看不清金额、疑似私人消费、事由要素缺失的,攒成存疑清单一次性问用户。用户也可要求全自动逐条确认
  • 身份信息(默认:第一次问,存盘复用)。见上。
  • 多币种(默认:换算成 RMB 入表)。外币票据(USD/KRW 等,如境外 Uber 收据)按用户指定汇率换算,没给汇率不要自己拍——先列存疑问用户(或按票面日期的中国银行牌价并注明来源);原币种/金额/汇率/结果写进 额外说明/,并在台账「原币种金额/汇率」列填好。也可改成按原币种填、汇率用户自理。

工作流

第 0 步:搭工作区 + 备份(脚本)

python3 scripts/setup_workspace.py --source <原始材料文件夹> [--out <工作区根目录>] [--template <报销模板.xlsx>]
  • --out 可不给:默认在原始材料文件夹旁边(其父目录=默认位置)新建一个有具体含义的工作区 <原文件夹名>_报销整理_<YYYYMMDD>;也可用 --out 指定到用户要的目录。
  • --template 可不给:不同用户的模板可能不一样、甚至没有。没模板就走"无模板"分支(见第 6 步),最后用 make_default_table.py 生成一份通用费用明细表。 它会:建十个子文件夹(有票/无票/辅助材料/待核实/替票/额外说明/过程文件/备份/补充材料/无关)、把原始材料全量备份进 备份/(模板本身和 *.skill 不当作材料、会被自动跳过)、有模板时把模板原件存进 备份/_模板原件/ 并生成可写副本 <原名>_已填写.xlsx、生成 过程文件/manifest.json。 工作区建在原始材料文件夹之外。stdout 回传各关键路径(workspace/writable_template,无模板时 writable_template 为 null)。所有脚本均纯 python3跨平台(mac/linux/windows 通用),不依赖系统专有命令。

第 1 步:逐份读取与理解材料

manifest.json 顺序逐份读,按类型选读法:

  • 图片(jpg/png/webp 等):直接用视觉看图理解(本模型可读图),不必先 OCR。读出:消费日期、商户/项目、金额、是否正式发票、起止地点/人数等要素。
  • PDF:先 extract-text 或 pdf-reading skill 取文本;扫描件/版式票据取不到文本时,转成图片再用视觉读(参考 pdf-reading skill 的栅格化方法)。
  • OFD(国标电子发票)
    python3 scripts/extract_ofd.py <file.ofd> --json
    
    取不到文本时(纯图层 OFD),兜底:转图片后视觉识别。
    • 铁路电子客票:读出「票价」(正常乘车的应报额)还是「退票费/差额退票」(退票,金额很小),注意「始发改签」标记。
    • 增值税发票:入表金额取价税合计(含税),不是不含税的「金额」(见 references/模板与字段映射.md)。
  • Excel/CSVextract-text file.xlsx 或 pandas 读,常见于话费单、对账单、明细汇总。
  • 其他/不认识的格式:先 file <path> 探类型,再选合适读法;实在读不了就列入存疑清单。

每份材料把提取到的要素写进 过程文件/extracted/<原名>.json

第 2 步:归桶 + 归类 + 关联事件

依据 references/归类与命名规范.md

  • 判进 有票 / 无票 / 辅助材料 哪个桶(判据见参考文件第一节)。关键:只有截图、没正式发票的真实消费进「无票」(它就是主证据),不是「辅助材料」(第 1.1 节);辅助材料旁边必须有主证据。一旦出现无票项,记得在沟通里提醒客户放替票到 替票/(见『特殊目录·替票/』)。
  • 判属于 12 类费用中的哪一类→对应模板的哪一列(列映射见 references/模板与字段映射.md)。注意 J 差旅交通 vs Q 市内交通 的区分。
  • 给同一笔消费的多份材料分配同一个事件号(发票 + 支付截图 + 行程单 + 退款截图 都串到同一事件号)。改签前后、企业代付/个人垫付也串到同一事件(第 3.1–3.3 节)。
  • 疑似私人/与本行程无关(个人订阅、无关国家签证、无票高额单据等)进存疑清单,默认不计入(第五节);经用户确认与本次无关/不报/跨期的,移入 无关/(不计入本期)。
  • 拿不准的别硬塞:桶/类别/能否报判不准的材料,先放 待核实/不要先放进 有票/无票/;攒成存疑清单问用户,确认后再从 待核实/ 移到正确的桶。

第 3 步:建台账(过程文件)

过程文件/物料台账.csv(UTF-8-SIG)里,每份原始材料一行,列结构见 references/归类与命名规范.md 第四节。台账是后续回填和审阅报告的唯一数据源——先把台账做对

第 4 步:复制 + 重命名 + 归桶

按命名规范 日期_费用类型_关键信息_金额,从 备份/ 复制材料到对应桶并重命名。同事件跨桶同名、同桶加语义后缀(规则见参考文件)。把新文件名回填进台账。

第 5 步:写额外说明(按需)

凡有合并、部分退费、外币换算、拆分/AA、或材料金额≠入表金额的,按 references/额外说明写法.md额外说明/ 写 txt,并在台账「备注」里指向它。

第 6 步:台账 → 去重勾稽 → 生成 ledger → 回填模板副本(脚本)

先做去重勾稽(references/归类与命名规范.md 第六节):按事件号把台账折叠成"每事件一行"——发票/无票主证据出金额,辅助材料和退款截图不单独成行;退票只计退票费;企业代付只计个人垫付;外币换算成 RMB。记下 Σ(ledger 金额) 作为勾稽基准。

按时间顺序排列:模板表头要求"按时间顺序依次填写"。ledger 里的 items 应按消费发生日升序排列(同日多笔可按"先正票后退票/补差"排)。fill_template.py 默认也会按 月/日 稳定升序兜底排序(如需保留你给的顺序用 --no-sort)。

再整理成 过程文件/ledger.json(结构见 scripts/fill_template.py 顶部注释:identity + items,每条给「列」或「类别」+ 金额 + 事由 + 起止/部门/项目编码)。事由必须按 references/模板与字段映射.md 补齐财务批注要的要素。然后:

python3 scripts/fill_template.py --xlsx <writable_template> --ledger 过程文件/ledger.json

fill_template.py 会自动处理超 31 行的插行与 SUM 扩展,并在输出的 computed 里直接给出各列小计/总额的预期值——先核对它与你的勾稽基准一致。

再重算公式(二选一):

# 首选: xlsx skill(需 LibreOffice)
python3 /mnt/skills/public/xlsx/scripts/recalc.py <writable_template>
# 没有 LibreOffice / 无该路径时, 用本 skill 自带兜底(--write 把数值写回, 交付件直接显示数字):
python3 scripts/recalc_fallback.py <writable_template> --write

必须确认 total_errors 为 0,且重算结果与 fill_templatecomputed、与台账加总三者一致。

无模板分支:用户没有模板时,跳过 fill_template.py/recalc,改用脚本生成一份通用费用明细表(直接写好数值与合计,并附 .md 预览):

python3 scripts/make_default_table.py --ledger 过程文件/ledger.json --out <工作区>/<有含义的名字>.xlsx

此时 ledger.json 用"无模板版"结构(见 make_default_table.py 顶部注释:identity 可含标题/报销人/部门等,items 每条给 日期/类别/事由/商户/币种/原金额/汇率/金额(RMB)/备注)。生成的 xlsx 总额应与台账加总一致。

第 7 步:审阅报告 + 交付

在工作区根目录写 审阅报告.md

  • 按费用类别汇总金额、总报销额;
  • 勾稽核对:台账加总 = 模板总额 = 各桶材料金额之和(逐项列出,不一致要标红说明);
  • 存疑清单:需用户补充的项(招待人数、出差天数、汇率、看不清的金额、疑似私人消费等);
  • 各桶文件计数、额外说明清单。 把 <writable_template> 放第一个(有 present_files 之类的呈现工具就用,没有就直接给出工作区路径和文件清单),连同审阅报告一起呈现给用户,并把存疑清单当面问清。

特殊目录(按需处理,都不污染主流程勾稽)

除上面 0–7 的核心流程外,还有四个目录按需启用;它们各自独立,不影响 有票/无票/辅助材料 的台账与勾稽。

待核实/ —— 拿不准的先存这里

判不准(进哪个桶、算哪类、能不能报)的材料,先放 待核实/,绝不先塞进 有票/无票/。攒成存疑清单一次性问用户;用户拍板后再从 待核实/ 移到正确的桶并入账。交付时 待核实/ 最好为空;若仍有未决项,在审阅报告里点名。

无关/ —— 与本次无关 / 本期不报 / 跨期

经用户确认与本次报销无关、本期不报或跨到下一期的材料(跨期机票、与本行程无关的签证等),从备份复制一份到 无关/ 单独存放,不计入本期台账与模板;审阅报告里列明"已移入无关"。既不污染勾稽,也不丢材料。

替票/ —— 可选的替票池(不转有票、不计金额)

有些"无票"项是真实消费但拿不到正式发票(公司租房水电费、零星个人代付等)。客户可选提供平时其他消费的正规发票放进 替票/,在金额上大致凑齐这些无票项、给财务附发票——也可以不提供最关键:替票与无票不是一一对应的真票,只是金额接近。 所以:

  • 替票绝不转入 有票/,无票项也绝不改判为「有票」——无票始终按无票管理(它才是这笔真实消费的记录)。
  • 替票留在 替票/ 单独附给财务,不进台账费用行、不计入报销金额(否则与无票项重复计钱)。
  • 只在 过程文件/替票池.csv 记替票清单与池总额,和无票总额做粗略覆盖对比;不做 1:1 映射、不改桶、不改 ledger
  • 只要出现无票项,就在沟通里提醒客户一句可选地放替票(列出无票项与合计金额,说明"可给可不给")。不替客户硬凑、不假设一定会补。

补充材料/ —— 客户后续补的材料(处理后清空)

客户后续补的材料(之前缺的发票、漏的票据)放进 补充材料/。再次运行时按下面处理,做完 补充材料/ 应清空

  1. 备份留存:每份复制进 备份/_补充_<日期>/(原件不丢)。
  2. 理解 + 关联事件:用第 1 步读法识别,挂到已有事件号或新建事件。
  3. 补发票动作:某笔原是"无票(待补发票)",补来正式发票后——发票进 有票/、原截图改归 辅助材料/,台账该事件的桶/置信度/金额(改用价税合计)一并更新,删掉对应存疑项。
  4. 重新去重勾稽 + 回填:按第 6 步重算,确认总额更新、仍三方一致。
  5. 清空 补充材料/:处理完移除文件(备份与各桶已有副本),保持为空便于下次。

完成后的目录长这样

<工作区>/
├── <原名>_已填写.xlsx        ← 填好的费用明细表(交付物)
├── 审阅报告.md
├── 有票/        有正式票据、能独立作证的(确认无误才放进来)
├── 无票/        真实消费但无正式发票的主证据(确认无误才放进来)
├── 辅助材料/    侧面佐证(下单/支付/行程截图)
├── 待核实/      拿不准(桶/类别/能否报)的先放这里,不要急着塞进 有票/无票;核实后再移走
├── 替票/        可选的替票池:大致凑齐无票金额给财务,不转有票、不计金额(见『特殊目录』)
├── 额外说明/    给财务看的 txt(合并/退费/外币/拆分)
├── 过程文件/    身份信息.json、manifest.json、extracted/、物料台账.csv、ledger.json、(替票池.csv)
├── 备份/        原始材料 1:1 备份 + _模板原件/(模板与 *.skill 不计入材料备份)
├── 补充材料/    客户后续补的材料丢这里;处理后会清空(见『特殊目录』)
└── 无关/        经确认与本次无关/本期不报/跨期的材料,单独存放,不计入本期

收尾自检

  • 原始材料与原模板均未被改动(只动备份件/副本)
  • 每份材料都进了某个目录,且在台账里有一行
  • 无重复计费:每个事件号在 ledger 里只有一行;发票+支付截图、改签前后、退款冲减都没被算成多笔
  • 增值税发票按**价税合计(含税)**入表;退票只计退票费;企业代付只计个人垫付
  • 外币已换算且汇率有来源(或已列存疑)
  • 模板按时间顺序填;recalc 后零公式错误,且 模板总额 = ledger 加总 = fill_template 的 computed
  • 事由都满足对应批注要求(人数/时间/起止/天数等)
  • 待核实/ 已清空(都已落定)、补充材料/ 已清空;替票/(若有)不计入金额
  • 疑似私人/无关项与其它存疑项已全部当面向用户确认

Skills relacionados