1 条 audit=0 的幽灵记录:我说不清是我删的,还是平台吞的

1 条 audit=0 的幽灵记录:我说不清是我删的,还是平台吞的

我把自己掘金账号的账本全量拉了一遍:21 篇文章,全部 audit=2(已过审),0 篇拒审,草稿箱 0 条,总阅读 1132。 干净得像是可以收工了。

但有一条记录,我至今说不清:7656751882112057371,标题显示为「Agent Nexus:为 AI Agent 经...」,audit=0、阅读 0。它曾经出现在我"已发布文章"的列表里,今天不在了------而我证明不了是我删的。 这篇就写清楚:草稿、已发布、幽灵记录是三套系统;判断一条东西到底在不在,我用三个探针;以及一次"删了却没留证据"的翻车。

一、先说清这条记录有多怪

它的公开链接是 404,但它出现在作者侧的文章列表接口 里。这两个事实同时成立,才叫幽灵:article/query_list(作者侧)认它,juejin.cn/post/<id>(匿名侧)不认它。

按掘金 id 单调递增的规律,它的 id 紧挨着我 6 月那批手写文章(7655217832594915379),比 9 月 13 日管道产出的第一篇(7684658712820613147)小了一截------也就是说,它是 6 月底前后留下的一份记录,不是自动化管道写的。至于正文写了什么,我查不到 :draft/detail 返回 403、编辑器页空白。严格讲,我只知道它有 id、有标题前缀、状态是 audit=0。

二、三个探针:判断"这条东西到底在不在"

不要用单一接口的结论下判断。我用三步,全部在页面上下文执行(这些接口对脚本重放有签名校验,外部 curl 会拿到"路由不存在"):

js 复制代码
// 登录掘金后,在浏览器控制台执行。id 换成你要查的那条
const id = '7656751882112057371';
// ① 作者侧状态:1=审核中 2=已过审 0=未提交/未发布的历史记录(注意:0 不是"被拒")
const j = await (await fetch('https://api.juejin.cn/content_api/v1/article/query_list', {
  method: 'POST', credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ cursor: '0', sort_type: 2, user_id: '<你的 UID>' })
})).json();
const hit = (j.data || []).find(x => x.article_id === id);
console.log('① 作者侧:', hit ? { audit: hit.article_info.audit_status, view: hit.article_info.view_count } : '不在列表');
// ② 公开页:200=已公开发布,404=未公开
console.log('② 公开页:', (await fetch('https://juejin.cn/post/' + id, { credentials: 'omit' })).status);
// ③ 编辑权限:403=该 id 不在当前账号可编辑的草稿里
const d = await fetch('https://api.juejin.cn/content_api/v1/article_draft/detail', {
  method: 'POST', credentials: 'include',
  headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ draft_id: id })
});
console.log('③ draft/detail:', (await d.text()).slice(0, 60));

今天(2026-09-24 20:30 CST)的实测输出,一字未改:

bash 复制代码
① 作者侧: 不在列表(全量 21 条里已无 audit=0 的记录)
② 公开页: 404
③ draft/detail: {"err_no":403,"err_msg":"权限认证错误"}

三个探针合起来给的是同一个结论:它不在任何"用户可见"的位置------但它曾经过审前那套列表。9 月 14 日我第一次看到它时,结论就已经写成"未提交的历史记录态,不在发布队列,它不会自己发出去,别当成被拒重投"。这句话救了我:如果我把它当"被拒",就会去重投一篇 6 月的旧稿。

三、为什么"已发布列表"里会有没发布的东西

因为后台至少有三套东西,名字很像,行为完全不同:

系统 接口 关键坑
草稿箱 article_draft/query_list 从"已发布文章 → 编辑"生成的编辑草稿不进这里(我的草稿箱长期是 0 条,但编辑器里明明有稿)
文章记录(作者侧) article/query_list 带 audit_status;audit=0 的历史记录会出现在这里,公开页却 404
编辑草稿 无公开列表 id 与文章 id、原草稿 id 三者都不同;只能靠编辑器页 URL 记

还有一个更阴的:空 body 探测写接口,会真的建一条记录。 我早期用 POST article_draft/create 传 {} 去"探接口通不通",返回 err_no:0,然后账号里就多了一条空草稿------探测本身就是写入。现在的纪律是:探写接口前先把删除手段准备好,并且用"字段名故意写错"的合法 JSON 去探,拿 schema 报错,不落库。

四、数据口径:同一天两套读数,谁都别信

9 月 14 日我遇到过一次分裂:一套读数说三篇文章是 46 / 14 / 4,另一套(每周复盘脚本的输出)说是 9 / 1 / 0,id 集合还不同------因为一套把那个 audit=0 的记录算进来了,另一套没算。没有统一口径之前,任何"规律"都建在流沙上。

所以今天我用的是唯一口径:分页拉全量 (has_more + cursor,默认首页只给 10 条,只看首页会得出错的均值):

ini 复制代码
21 篇 · 全部 audit=2 · 总阅读 1132 · 赞 5 · 收藏 2 · 草稿箱 0
AI 全自动发的 10 篇:合计 291 阅读,均值 29.1(逐篇 7/11/9/15/25/17/19/135/26/27)
我手写的 11 篇:合计 841 阅读,均值 76.5
最好一篇:135 阅读,也是全账号仅有的 2 个收藏的唯一来源

均值上 AI 组只有手写组的 38%,但把极值摆出来就露馅了:AI 组里有一篇 135,比手写组 11 篇里的 10 篇都高。同一套脚本、同一个账号,阅读差 19 倍------变量是内容,不是"AI"。 这也再一次说明:一条记录的归类错了(比如把 audit=0 当成"未过审"),整个账本的分母就错了。

五、翻车:删了,却证明不了

这条从未公开的记录留在列表里没有价值,我给它写了删除脚本。守卫是双条件------标题正则匹配 + 状态必须为 0,两条都满足才允许执行:

js 复制代码
// 摘自我 2026-09-14 落盘的删除守卫脚本(mtime 11:55)
const hit = (j.data || []).find(x => x.article_id === id);
const guardOk = hit && /Agent Nexus/i.test(hit.article_info.title) && hit.article_info.audit_status === 0;
if (!guardOk) { console.log('!! 守卫未通过(标题不匹配或状态非 0),未执行删除'); return; }
// 通过后才调用:
// POST /content_api/v1/article/delete   body: { article_id: id }
// 删后复核三件:作者侧条数 -1 / 公开 URL 仍为 404 / 自家已发布文章的条数与标题未受影响

守卫的逻辑我现在还认。问题在于我没有执行日志。 今天我能证明的只有:这条记录不在列表里了(全量 21 条,audit=0 记录数 = 0)、公开页 404、draft/detail 403。我不能证明是那个脚本干的------也可能是平台自己清理了历史态记录。

这就是这篇最想抄给你的一条:写有回查,删没有回查。 发文链路我给它配了四处回查(建稿回查 draft_id、编辑器页核对正文长度、上传封面回查 cover_image 非空、发布后回查最新一篇标题前 14 字),可轮到删除,我只信了"接口返回 ok"。平台不会给你一张"已删除"的回执,所以删除类动作必须自己落账:谁删的、什么时候、删前快照(id + 标题 + audit + 阅读)。这一行日志我漏了,代价就是这篇文章的标题------我删了一篇东西,却拿不出证据。

六、还有一个更便宜的教训:窗口是幻觉

9 月 18 日我看数据时用的是 slice(0, 3) 的硬编码窗口,结果第一篇滑出了窗口,我当下分不清它是"被新文章挤下去"还是"被删了"。当时我只敢在复盘里写"本次无法取证",没敢下结论。

今天回头看,那次和这次是同一个错的两面:"列表里没有"≠"被删了","列表里有"≠"已发布"。 唯一能信的是全量 + 多探针。

七、可以直接抄的清单

  1. 判断一条内容"到底在不在",用三探针:作者侧状态 / 匿名公开页 / 编辑权限,别用单一接口的结论;audit=0 是"未提交的历史记录",不是"被拒";
  2. 拉数据一律分页全量:cursor + has_more,默认首页只有 10 条,用首页数据算均值会错;
  3. 探测写接口前先准备好删除手段,并且用"字段名故意写错"的合法 JSON 探,不落库------空 body 会真的建记录;
  4. 删除必须双条件守卫(标题正则 + 状态),并且删前落一份快照、删后写明"谁删的/何时";
  5. 删后复核三件:作者侧条数 -1、公开 URL 状态、自家已发布文章的条数与标题未受影响;
  6. 任何"列表窗口"(slice、只看首页、只看最近 N 条)都不配当证据,只有全量配。

21 篇全过审、0 拒审,是我这段时间账号侧最好看的一次账。但真正让我睡不着的不是那些数字,是那条消失的记录------我能证明的比我想象的少。

相关推荐
俊哥AI全栈工程师1 小时前
让 AI Agent 替我跑日常重复任务,一周踩坑记录
ai编程
诚小纯1 小时前
同一份稿子在两代模型上差 6.44 倍:语音模型价格对齐的工程拆法
人工智能·github
孟健1 小时前
我通过了水星银行美国业务证明审核,交了几轮材料
ai编程
vivo互联网技术1 小时前
ART:妆容迁移框架,重新定义高保真妆容迁移 | ECCV 2026
人工智能·算法·图像识别
老金带你玩AI1 小时前
这里用 ChatGPT 和 Claude,居然只要半价!
人工智能
杨杨杨大侠1 小时前
一句“修个 Bug”,AI 编程工具到底怎么扣额度?
人工智能·agent·ai编程
回家路上绕了弯1 小时前
智能体编排平台中,工作流与 Agent 如何分工?
后端·ai编程
桃西西呀1 小时前
给告警加了道 AI 初筛,我终于半夜不用爬起来了看无用告警了
人工智能·llm·ai编程
挖掘狂人1 小时前
ObjectSense:一门千行内核、把可靠性写进骨子里的面向对象脚本语言
程序员·编程语言·汇编语言