生成 AI 报表摘要前,先拦截数据缺失
教程用 Python 标准库验证每日访问量数据,检查日期范围、重复记录和非法数值。缺少任一天时将总量设为 None 并单列缺失日期,避免把数据空缺误算为零后交给模型解释。
AI 深度解读
营销报表少了一天数据,如果程序顺手补成零,AI 就可能围绕一场根本没发生的流量下跌,写出解释流畅的分析。作者给出的办法很直接:先用确定性的代码检查数据,再让模型生成摘要。
这篇的价值在于把报表入口的规则讲清楚:什么算有效记录,缺失如何表达,模型能回答到哪一步。示例很小,却适合拿来检查日常 AI 报表流程中容易漏掉的环节。
缺了一天,为什么不能按零计算
作者约定,每个自然日应该有一条记录,包含 ISO 日期和非负整数形式的访问次数。检查范围包含起止日期,重复记录、范围外记录和不合法的访问次数都会被拒绝。
最关键的是区分两种状态:当天确实记录了零次访问,以及当天根本没有记录。
零是一个观测值,缺失是一种尚未查明的状态。
缺失可能来自数据源不可用、筛选条件排除了一天,也可能是导出失败。单看报表,无法判断是哪一种。如果直接补零,相当于在数据进入模型之前,就偷偷替它选好了答案。
作者的处理是:只要缺少任何一天,total 就返回 None,缺失日期单独放进 missing。已有记录仍然保留,但不能冒充整个周期的完整总数。
这条规则也方便下游页面展示:可以明确提示「周期数据不完整」,而不是展示一个看似精确、实际口径有问题的总访问量。
用几十行代码,把完整性变成硬条件
作者使用 Python 标准库和本地虚构数据,并称在 Python 3.14.9 上运行了示例。它不连接分析 API,不需要网络、凭证或外部包。将代码保存为 check.py,执行 python3 check.py 即可复现。
下面这段代码解决的是日期覆盖和记录合法性问题:
from datetime import date, timedelta
def summarize(start, end, rows):
expected = set()
day = start
while day <= end:
expected.add(day.isoformat())
day += timedelta(days=1)
found = {}
for row in rows:
day = row['day']
count = row['visits']
if day not in expected or day in found or type(count) is not int or count < 0:
raise ValueError('invalid or duplicate row')
found[day] = count
missing = sorted(expected - found.keys())
return {'total': sum(found.values()) if not missing else None, 'missing': missing}
if __name__ == '__main__':
start, end = date(2026, 1, 1), date(2026, 1, 3)
data = [{'day': '2026-01-01', 'visits': 3}, {'day': '2026-01-03', 'visits': 2}]
print(summarize(start, end, data))
data.append({'day': '2026-01-02', 'visits': 0})
print(summarize(start, end, data))
try:
summarize(start, end, data + [data[0]])
except ValueError as exc:
print(type(exc).__name__ + ': ' + str(exc))
重点看返回值那一行:只有 missing 为空才计算总数。type(count) is not int 也比宽泛的类型判断更严格,Python 中的布尔值不会被当成访问次数接受。
作者报告的本地输出如下:
{'total': None, 'missing': ['2026-01-02']}
{'total': 5, 'missing': []}
ValueError: invalid or duplicate row
第一次缺少 2026-01-02,所以总数为空;第二次补入当天真实记录的零,总数才成为 5;第三次加入重复行,直接报错。这里验证的是不同输入对应的程序行为,没有涉及模型摘要质量的对比实验。
但这还不是生产级校验器。缺少 day 或 visits 会抛出 KeyError;函数没有检查 start <= end,也不处理时区、源站故障或重复数据合并。接入真实数据源时,这些规则需要另行补齐。
模型应该接在哪一步,又该停在哪里
作者安排的流程是:采集器获取获授权的数据,确定性校验检查结构、日期覆盖和报表所需定义,模型接收通过校验的数值及缺口、来源信息,最后由人审核,再作出有实质影响的决定。
这里的「数据契约」,就是事先说清每个字段代表什么、哪些记录算合格、异常如何返回。
生产采集器还应保留数据源标识、时区、获取时间和「一次访问」的定义,并区分 API 报错与请求成功但结果为空。日期也应先按源系统预期的时区划分。两张报表即使每天都有记录,日期边界不同,仍然可能无法直接比较。

模型可以概括数字、列出待调查问题、起草简报。仅凭访问次数,它无法判断某次活动是否带来了合格客户;没有后续记录,就应该说明限制,不能编出转化率。
作者还提醒,重试需要按操作性质区分。读取超时后可以考虑有限次数、带退避的重试;调整预算或发送消息时,必须先确认上一次是否已成功。这个示例没有任何写操作,也没有提供重试实现。
我的判断
我认可作者把数据规则放在生成之前。日期缺失、重复行、负数这些问题都有明确判定条件,适合交给代码。相比只在提示词里要求模型「仔细检查数据」,校验函数的结果更容易复现,也能直接决定报表是否展示完整总数。
但它保证的范围很窄。每天都有一条合法记录,不代表源数据准确,更不代表访问量能够解释营销效果。字段通过检查,与业务结论可信之间,还隔着采集质量、指标定义和因果证据。
作者明确区分了团队配置与实际验证:他们团队的营销代理指令把分析工作、最终文案和发布分开,但这不能证明每份线上报表都正确;这段教学代码也没有被声称用于团队生产系统。
因此,这篇可以作为流程设计建议,不能当成效果证明。作者没有提供错误率、成本或摘要准确率的对照数据。示例最后也披露了文章由 AI 辅助创作。
能拿来做什么
- 在前端报表中分别展示零值和缺失值。接口返回
total: null与缺失日期时,页面应提示周期不完整,避免通过默认值把它变成零。 - 在 Node 报表任务调用模型之前,检查日期覆盖、重复记录和非负整数,并把数据源、时区、统计周期随校验结果一起传入。
- 在摘要指令中明确证据边界:允许概括已知数字和列出疑问,缺少客户或转化记录时必须说明限制,不生成没有依据的转化率。
- 把摘要生成与预算修改、消息发送分成独立步骤;为写操作设计重试前,先定义如何确认上一次执行结果。