Data & analysis

数据流水线字段名漂移排查

Try it

当数据流水线里某个字段「一直读不到」、某类条目静默消失、或下游把「有数据」当成「没数据」时,用契约名比对法定位字段名漂移(同一逻辑字段在采集/暂存/落盘/读取四处各有一个名字),并写「契约名回归测试」钉死。含 grep 排查模板、死变量识别、回填对账顺序。当用户说「这个字段怎么一直是空的」「数据明明有却读不到」「回填没效果」「某类记录莫名不见了」时使用。

What it does

某字段在库里「一直是空的 / 一直是待补」,但数据源明明返回了 下游按某个字段做量级/等级判断,结果把「有大数字」的条目当成「没有数据」 回填脚本跑完显示「N 条已更新」,但目标字段还是空的 某类记录静默消失(不报错、不进异常日志)

The skill document

数据流水线字段名漂移排查

什么时候用

出现下面任一症状,先怀疑字段名漂移,不要先去怀疑数据源或解析器:

  • 某字段在库里「一直是空的 / 一直是待补」,但数据源明明返回了
  • 下游按某个字段做量级/等级判断,结果把「有大数字」的条目当成「没有数据」
  • 回填脚本跑完显示「N 条已更新」,但目标字段还是空的
  • 某类记录静默消失(不报错、不进异常日志)

漂移 bug 的共同特征:不报错。 因此它比解析失败更难发现 —— 表现是「今天没采到东西」而不是「今天崩了」。

第一步:把所有引用点摊开比对(核心动作)

按逻辑字段名(人话,比如「近 30 天收入」)在整仓搜,不要按你猜的键名搜:

# 1) 契约声明在哪(数据 schema / 字段清单文档)
grep -rn "字段中文名\|last_30d_revenue" docs/ data/sources.json README.md

# 2) 谁在写、谁在读、谁只是路过
grep -rn "last_30d_revenue\|revenue_last30d\|last30Days\|last30\b" \
  --include="*.py" --include="*.js" --include="*.json" --include="*.md" . \
  | grep -v "__pycache__\|node_modules\|/.git/\|dist/\|public/"

# 3) 落盘数据里实际存在哪些键(最硬的证据)
python -c "
import json,collections
d=json.load(open('data/xxx.json',encoding='utf-8'))
c=collections.Counter()
for r in (d if isinstance(d,list) else d.values()):
    for k in (r.get('metrics') or {}): c[k]+=1
print(dict(c))
"

第 3 条最关键:如果某个键在落盘数据里出现次数为 0,那它在读取侧就是死代码,无论代码写得多对。

典型的三套命名(实测踩过):

位置键名
契约文档(sources.json / schema)last_30d_revenue
采集内部暂存(_api / 原始响应转发)revenue_last30d
落盘(metrics)一个都没写
读取(下游评分/初筛)last_30d_revenue ← 永远读不到

第二步:找「读出来但没写入」的死变量

这是最隐蔽的一种。表现是变量声明并赋值了,但从没进入输出:

last30 = rev.get("last30Days") or 0     # 读出来了
total  = rev.get("total") or 0

if mrr and not m.get("mrr"):
    m["mrr"] = mrr                      # 写入了
if total and not m.get("all_time"):
    m["all_time"] = total               # 写入了
# ... last30 再也没出现过 —— 死变量,静默丢数

排查手法:把赋值过的局部变量名丢进 grep,看它是否只出现一次(定义那一次)。只出现一次 = 死变量。

grep -n "last30" script.py     # 期望看到「定义 + 至少一次使用」

第三步:修法(三条铁律)

  1. 以契约文件为唯一真名。 向内落盘(写进 metrics / 数据库列)一律用契约名;采集层的内部暂存(原样转发的响应)可以保留原名,但要加注释说明两者关系,否则下一个人还会踩。
  2. 口径照实写。 如果新字段的量级与既有字段差很多(实测有 36 倍差),文案里必须区分,别把「月流水」写成「MRR」。同时把口径写进该记录的 metric_note / 字段说明。
  3. 只补空,不覆盖。 回填脚本要幂等:if val and not m.get(key)。跑第二遍必须是「0 条更新」。

第四步:用「契约名回归测试」钉死

普通单测测「有没有写」,不够 —— 键名再漂移一次,同样的故障会重演。要测三件事:

CONTRACT_KEY = "last_30d_revenue"      # 改这个字符串等于改契约,要一起动

class WritesField(unittest.TestCase):
    def test_键名是契约名(self):
        B.merge_record(r, rich)
        self.assertIn(CONTRACT_KEY, r["metrics"])
        self.assertNotIn("revenue_last30d", r["metrics"],
                         "又用回采集内部暂存名了 —— 下游会读不到")

    def test_下游能读到(self):
        # 端到端:写入方写进去的键,读取方必须真的取得出值
        B.merge_record(r, rich)
        self.assertEqual(Downstream.revenue_of(r), 79596.73)

    def test_幂等(self):
        B.merge_record(r, rich); first, _ = B.merge_record(r, rich)
        self.assertFalse(first)

class RealData(unittest.TestCase):
    def test_存量数据里没有漂移键名(self):
        # 扫全库落盘数据,出现非契约键名即失败
        ...

最后一条最值得写:它是唯一能在数据层面拦住漂移的断言。

第五步:验证顺序(别跳步)

  1. 先跑纯函数单测(离线、秒级)
  2. 再跑回填/修复脚本的 --dry-run 看会改什么
  3. 确认后正式跑(要备份:cp data/x.json _backup/x.json.bak-$(date +%Y%m%d-%H%M%S))
  4. 对账:改了多少条、目标字段覆盖从几变成几、下游分布是否真的收敛了
  5. 最后跑全量测试 + 重建派生产物(静态站 / 打包产物)

坑

  • 回填脚本走逐条详情页兜底时很慢(每条 sleep + 网络),全量可能 6 分钟以上,会撞前台超时 → 放后台跑,输出重定向到日志文件(注意 Python 重定向时 stdout 有缓冲,日志会长时间为空,属正常)。
  • 别在自测运行时做构建。自测脚本常会「备份→临时改数据→还原」,期间构建会把中间态写进产物;读数据做统计也会得到错数(实测出现过候选池 31/33/34 三个数)。
  • 顺带确认派生产物是否该包含这份数据(比如未核实的原始队列通常不该进对外发布的那一份)。默认输出目录常是「本地预览版」,对外版另有开关。

Related skills

Generate and edit Draw.io, Mermaid, and Excalidraw diagrams from natural language using a structured JSON spec.

by nssa.io1.0k installs47 stars

Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.

by Iván855 installs69 stars

Run Git operations — commits, branches, merges, rebases, conflict resolution, and recovery — with safety rules enforced.

by Iván535 installs31 stars

Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.

by Iván559 installs18 stars

Fetch raw ad creative, app, ranking, and revenue data from AdMapix as structured JSON.

by fly0pants4.3k installs296 stars

More from oracis

Browse all skills

把本地 Skill 打包并发布到 SkillHub(腾讯 skillhub.cn)与 ClawHub,覆盖预检、发布、状态回读与竞品对标全链路,并在上传被拒时用二分/ddmin 脚本把「服务端 WAF 拦内容(566)」与「包结构/字段问题」精确区分开。当用户说「发布技能到市场」「上架 skill」「SkillHub 提交失败」「Failed to fetch」「566」「上传 zip 报错」「技能审核状态」「版本号被拒」时使用。也讲清「入库成功 ≠ 已公开」——用 `mine` 的 `reviewStatus`、重发探测 `409 VERSION_EXISTS`、`/versions/<v>/signature` 三个探针判断版本到底走到哪一步。

by oracis1 installs1 stars

平台只有网页后台、没有上传 API 时,用本机已装的 Chrome/Edge + CDP 自动化走完上传/发布/填表流程——复用真实登录态、零安装(不下载 500MB Chromium)、能给文件选择框塞文件;并实测富文本编辑器(公众号 / CMS / 邮件模板)里到底哪些 CSS 能活下来,以及在决定是否接入平台自带的「一键排版 / AI 美化」前先抓它输出做结构化 diff。当用户说「只能网页上传」「后台发布」「网页填表自动提交」「发布到技能市场/各平台控制台」「复用已登录的浏览器」「公众号排版样式不生效/保存后样式没了」「一键排版要不要用」「点了按钮没反应/提交没成功也没报错」时使用。

by oracis2 installs

一键安装并实测验证已验证可用的免费 LLM 到 WorkBuddy/Claude Code,无需注册、无需 API Key。当用户说「装免费模型」「加免费模型」「免费 LLM」「免费模型一键装」「验证免费模型可用吗」「免费模型怎么接入」「帮我配几个免费模型」「监控免费模型」「免费模型挂了吗」「kilo 网关」「kilo-auto」「nemotron 免费」「space-bunny」「智谱 glm 免费」「zhipu 免费」「glm-4-flash」「glm-4.7-flash」「glm-z1-flash」「glm-4v-flash」「探测国外免费模型」「国外平台免费 llm」「优先用免费模型」「读图桥接」「vision bridge」「给 glm-4-flash 加读图」「不读图的模型怎么看图」「阶跃星辰」「stepfun」「step 5」「step-5-preview」「限时免费模型」「ccproxy 读图转发」「给 claude code 加读图」时使用。也用于验证已有免费模型配置是否真的可用(tool calling 是否支持、是否限流、是否支持读图),以及定期 watch 监控免费模型是否下线/限流/失去工具调用能力。

by oracis1 installs

在中国大陆网络环境下用 yt-dlp 下载视频(含 Windows GUI 封装)。当用户要下载 YouTube、Bilibili、SoundCloud 等 yt-dlp 支持的站点内容,或遇到「yt-dlp 装不上 / 下载报 502 / Tunnel connection failed / ffmpeg not found / 缺 JS runtime / TLS fingerprint / watch?v=&list= 把整个列表都下了 / Sign in to confirm you're not a bot / The page needs to be reloaded / 下到一半突然下不动 / 下回来的视频糊、有拖影残影 / 下载速度特别慢」等问题时使用。

by oracis2 installs

聚合搜索百度网盘/夸克网盘/阿里云盘等网盘分享链接。当用户想按作者名、课程名、剧名、书名、软件名找网盘下载路径,或提到「网盘搜索」「PanSou」「盘搜」「找到下载链接」「夸克/百度/阿里网盘资源」时使用。包含已验证的 PanSou 协议端点、绕过系统代理的必要写法、以及可直接运行的本地 Web 应用 panradar.py。

by oracis2 installs

在 WorkBuddy(Windows)环境里交付零依赖本地 Web 应用,并绕开官方测试技能完全不覆盖的本机专属坑。当用户要在本机跑起来一个本地 Web 应用 / 单文件工具 / 案例库 / 看板 / 小工具,或要验证刚写完的 HTML/JS/Python 交付物真的能工作时使用。独家覆盖:Bash 缺 coreutils、bash 是 WSL 启动桩、rm 是坏 shim、PowerShell 不回显 stdout、cwd 漂移、预览面板靠 HEAD 探活——这些在干净 Linux 环境里遇不到。

by oracis1 installs