AI 写的办公自动化脚本总跑偏:批量改名、对账、报表该先动哪个
数据截至 2026-07,各产品的额度与报错口径以官方最新说明为准。
多数人把”AI 写的自动化脚本不能用”归到模型能力上,其实九成的翻车点在于任务本身没有可判定的验收标准。 批量改名失败,你能一眼看出来;对账对不平,你未必说得清是数据错了还是口径没定义。让模型去写代码之前,先分清哪一类任务是”结果自带答案”的,哪一类是”答案得你先给”,选错起点,后面再怎么调都是在原地绕。
一、三类任务的可验证性排序,决定你先动哪个
批量改名、对账、汇总报表看起来都是”重复劳动交给脚本”,但它们的验收难度差了一个量级。
批量改名的输入输出都是文件系统里的客观事实:跑之前有多少个文件、跑之后有多少个、每个文件的内容哈希有没有变,这些都能枚举、能比对、能回滚。你不需要业务知识就能判断脚本对不对。所以这类任务最适合当起点——不是因为它简单,而是因为它错了你立刻知道。
汇总报表次之。口径一旦固定下来,同样的输入应该出同样的数,你可以拿上个月人工做的那份对一遍。麻烦在于口径经常是隐性的:去年谁口头说过”退款不计入当月”,这句话不在任何文档里。
对账最难。它不是一个计算问题,是一个定义问题。两边数据什么算匹配上了、差几分钱算不算平、跨天的交易归哪一天、哪一侧是权威源——这几条没定死之前,写出来的脚本只是在把你的模糊认知固化成代码。
AI 在这三类任务里能接手的部分其实高度一致:文件遍历、编码处理、正则与解析、分页拉数、重试退避、差异清单导出、干跑报告。这些都是有标准解法的工程动作,模型写得又快又稳。而必须你来定的也高度一致:唯一性怎么判、容差多少、时间边界在哪、失败之后谁有权改动生产数据。这四条交给模型猜,它一定会给你一个看起来合理的答案,而这个答案没有任何人为它负责。
顺带说清本篇跟站内两篇的分工:表格文件本身的读写坑(合并单元格、公式、多 sheet 那些)在 AI 处理 Excel 自动化 里讲得更细;数出来之后怎么落到看板和图上,看 用 AI 做数据看板。本篇不重复这两块,只管中间那段——脚本跑起来之后出问题,你按什么顺序往下查。
二、现象到成因的判别表
出问题时先别急着让模型改代码。先按现象定位成因,判别成本比重写低得多。
| 现象 | 大概率成因 | 怎么验证 | 处置动作 |
|---|---|---|---|
| 你机器上跑对,同事那儿乱码或找不到文件 | 编码与路径处理依赖了默认值 | 两台机器各打印一次 locale.getpreferredencoding(False) 和 sys.getfilesystemencoding() 比对(别用 sys.getdefaultencoding(),它在 Python 3 恒为 utf-8,两边一模一样,区分不出问题),再把路径用 repr() 打出来看真实字符 | 所有读写显式写 encoding,路径统一用 pathlib.Path,不拼字符串 |
| 跑到一半中断,目录半新半旧 | 没有映射表,执行与决策混在一个循环里 | 对同一目录再跑一次,看是二次改名还是报错 | 先扫描生成计划文件,再按计划执行,执行时写流水账 |
| 改名后文件总数变少 | 目标名冲突被静默覆盖 | 把计划文件的新路径列切出来,排序后用 uniq -d 查重(命令见第三节),重复条数若与减少的文件数吻合即坐实;查不出重复再去查有没有整批被过滤掉 | 执行前做目标名唯一性检测,冲突即中止 |
| 每次跑对账结果都不一样 | 时间窗口用了相对时间或时区不统一 | 固定一份输入快照连跑两次,diff 输出 | 时间参数一律显式传入,存储统一时区,切日规则写进参数 |
| 金额差几分钱 | 浮点累加,或四舍五入发生在错误的层 | 用 Decimal 对同一批数据重算一遍 | 金额用整数分或 Decimal,只在输出层格式化 |
| 报表比昨天少一截数据 | 分页拉取漏页或边界重叠 | 对比总条数与源系统计数,检查翻页依据 | 用游标或主键区间翻页,不用偏移量配可变排序 |
| 拉数中途返回 429 或超时 | 接口限流、网络抖动(ETIMEDOUT / ECONNRESET) | 看响应状态码与重试日志,确认是限流还是断连 | 指数退避重试,配幂等键,失败条目落单独队列 |
| 脚本”成功”了但输出是空的 | 异常被吞掉,或匹配规则一条没命中 | 打印命中率与处理条数,检查是否有裸 except | 加零结果保护,命中率低于预期直接以非零码退出 |
| 连内网接口报证书链校验失败 | 公司代理做了 TLS 中间人,自签根证书不在信任库 | 单独用 curl 试一次,看是握手失败还是应用层报错 | 把企业根证书配进受信任 CA,不要关掉证书校验 |
这张表的用法是从上往下扫,先排除环境类原因,再看流程设计类原因,最后才怀疑业务逻辑。顺序反了,你会花大量时间调一段其实没错的代码。
三、从批量改名开始:把一次执行拆成四段
真正省事的做法不是让模型写一个”扫描并改名”的脚本,而是让它写四个互不耦合的阶段。
第一段,只读扫描。 输出一份纯文本的计划文件,每行至少包含旧路径、新路径、文件大小、修改时间、内容哈希前八位。这一段绝对不碰磁盘写操作。
python rename.py --scan ./inbox --out plan.csv
wc -l plan.csv
第二段,人工过一遍加冲突检测。 计划是文本,你能直接看,也能进版本库。目标名重复是最常见的隐患,提前查出来:
cut -d, -f2 plan.csv | sort | uniq -d
git add plan.csv && git commit -m "chore: 本轮改名计划"
第三段,按计划执行并写流水账。 执行器不做任何判断,只忠实照着计划文件动手,每完成一条追加一行到 journal。中断之后重跑,读 journal 跳过已完成的,天然可续跑。
第四段,验收与回滚。 验收动作要具体到能在终端里跑出来:文件数守恒、内容哈希集合守恒(改名不改内容)、随机抽十条人工看、journal 行数与计划行数一致。回滚就是把 journal 倒着读一遍。
python rename.py --apply plan.csv --journal journal.csv
python rename.py --undo journal.csv
这套结构值钱的地方在于:模型写这四段代码毫无难度,但它不会主动把流程拆成这样——你不说,它默认给你一个一把梭的循环。拆分是你的工程决策,代码才是它的活儿。
四、对账和报表:先写口径,再写代码
轮到对账,动手顺序要反过来。先用大白话把四件事写下来,落成一个文件跟脚本放一起:
- 匹配键是什么。是订单号,还是订单号加金额加日期的组合,重复怎么办。
- 容差是多少。有没有手续费差异的合理区间,超出多少算异常。
- 时间归属规则。跨零点的交易算哪天,以哪一侧的时间戳为准。
- 谁是权威源。对不上的时候以谁为基准,谁可以被修正。
这四条写完,让模型生成的代码就有了可测的靶子,而且差异要按类型分开输出:单边多、单边少、金额不符、状态不符。四类差异的处理路径完全不同,混成一个”异常清单”等于没分。
报表同理。每个指标写清取数范围、去重规则、排除项,每次跑完在结果里带上口径版本号和输入快照的哈希。做到这一步,下个月数对不上时你能立刻分清是数据变了还是口径改了,而不是从头查一遍。
拉数环节的凭据一律走环境变量,脚本里只读不存:
export REPORT_API_BASE="https://你的接口域名"
export REPORT_API_TOKEN="..."
python report.py --date 2026-07-28 --tz Asia/Shanghai --out daily.csv
curl -s -o /dev/null -w "%{http_code}\n" "$REPORT_API_BASE/ping"
金额计算这一处单独强调,因为它出错时不报警:
from decimal import Decimal
total = sum((Decimal(str(x)) for x in amounts), Decimal("0"))
五、什么情况下别再折腾
需要一条明确的止损线,否则你会在一个本来该停下的问题上耗掉整天。
同一类错误改了三轮还在复现,停手。 这时候要做的不是让模型再试一版,而是把输入缩到十条以内,把中间量全打印出来。绝大多数情况下,你会发现真正的问题是某条规则你自己也没想清楚——那是拍板的事,不是编码的事。
没有回滚点就不要开跑。 判断标准很硬:执行前有没有备份、有没有 journal、有没有数据库快照。三样都没有,那这次跑的不是脚本,是赌博。真误删了文件,恢复窗口很窄,路径可以参考 AI 误删文件后的恢复,但代价永远比提前备份大。
判断该换条路的三个信号。 一是源系统本来就有导出或接口,你却在解析界面或 PDF,那是在给自己造问题;二是这个任务一年只跑一次,却已经在写重试、日志、配置分层,工程化的投入永远收不回来;三是脚本要处理的是别人手工维护的表格,格式每月都变,这种情况下更该推动上游改格式,而不是把脚本写得更聪明。
还有一类止损跟工具本身有关:如果你打算把这些脚本挂到海外的托管服务上跑,先确认可用性。相关厂商官方对中国大陆有区域限制、不支持直连;市面上确实存在第三方中转,但稳定性和合规责任要你自己评估,我不做任何背书。让整条自动化链路依赖一个你不能确保明天还通的通道,本身就是个止损点没设好。
六、避坑清单
直接在原目录跑第一版。 会踩是因为模型给的示例代码默认原地操作,也很少主动带干跑开关,你复制过来就顺手执行了。避免方法:复制一份样本目录,跑通全流程再上真数据,第一版脚本连写权限都不给。
拿文件名当唯一标识。 会踩是因为平时确实这么用,但改名任务里名字正在变,前后两步引用的就不是同一个东西了。避免方法:扫描阶段就把绝对路径和内容哈希记进计划文件,后续所有环节只认哈希。
让脚本自己判断”看起来重复就删掉”。 会踩是因为模型倾向于给出完整的清理逻辑,显得贴心。避免方法:把所有删除动作改成移动到隔离目录,保留一周再人工清空,删除权限不下放给脚本。
CSV 从表格软件导出后第一列读不到。 会踩是因为文件头带 BOM,而代码用的是普通 UTF-8 解码,第一个列名前面多了看不见的字符。避免方法:读这类文件用 utf-8-sig,更多编码类问题看 文件编码与 BOM 的处理。
金额用浮点数累加。 会踩是因为示例代码里 float 最顺手,而且小数据量时误差看不出来。避免方法:入口就转成整数分或 Decimal,展示层才格式化,细节见 金额浮点精度问题。
定时任务重跑造成重复处理。 会踩是因为脚本假设自己只会被执行一次,而调度器在超时或重启时会补跑。避免方法:每条记录带幂等键,处理前先查标记,重复输入直接跳过并计数。
把密钥连同报错一起贴出去求助。 会踩是因为报错栈里常常带着完整的请求头,复制的时候没人逐行看。避免方法:凭据只走环境变量,日志输出统一做脱敏,贴之前先扫一遍。
遇到证书报错就关掉校验。 会踩是因为加一个跳过参数立刻就通了,而正确做法要找 IT 要根证书。避免方法:把企业根证书配进受信任列表,代码里保留校验,否则这个”临时方案”会一路带到生产环境。
收个尾
选起点的逻辑其实就一句:先做那些错了会立刻暴露的任务。批量改名把流程拆成扫描、审核、执行、回滚四段之后,你既拿到了实际收益,也把干跑、流水账、幂等这套习惯练成了肌肉记忆;等到做对账和报表时,这套习惯才是真正防住数据事故的东西。
开跑前过一遍这个清单:
- 计划文件生成了吗,是文本的、能进版本库吗?
- 目标唯一性和冲突检测跑过了吗?
- 有 journal 或备份吗,回滚命令写出来了吗?
- 时间参数和时区是显式传入的吗?
- 金额有没有走浮点?
- 零结果保护有吗,空输出会不会被当成成功?
- 凭据是不是全在环境变量里,日志脱敏了吗?
- 这次改动的止损线是什么,到哪一步你就停手找人拍口径?