INTEGRATION · 上游要做的三处改动

接入这套闭环,上游需要改三处。

编目员每次修改 AI 产出的字段,都是一条「AI 这次错在哪」的证据。 现在这些证据改完就没了。接上之后,它们会被归纳成规则回流给编目链路, 让同类错误下次不再发生。本页讲清要改哪三处、各几行、怎么自证接通了。

为什么这件事有时间窗。人机并行期一旦开始, 当天没接通就等于当天的数据永久流失,事后无法追补—— 它不像代码可以回头补写。这是整个项目里唯一不可逆的一项。

要改的三处

#位置工作量做什么
1编目员保存字段修改时~10 行推一条修正事件
2一条内容处理完成时~10 行推一条完成事件
3前端修改弹窗一个下拉框reason 必填,五选一

第 3 处最容易被砍掉,但砍了这套机制就不成立

只知道「这个字段被改了」,无法区分「AI 抓错了源」(该改采集策略) 和「AI 编造了内容」——两套完全不同的解法。

所以修改原因是枚举而不是自由文本,五选一:

来源错误 · 格式不符 · 语义偏差 · 幻觉编造 · 漏抓补全

这五类不是拍脑袋分的——它们按解法不同划分,与规则类型一一对应。 分析环节据此直接决定该提哪一类规则,不必让模型自由发挥。 枚举外的值会被拒绝并进兜底队列。

为什么两条事件都要

只推修正事件,能算出的永远是修正次数,不是修正率—— 吞吐量一变,前后就不可比。

完成事件记录每条内容各字段有没有值、有没有被改动,它是分母。 缺了它,验收标准里「修正率下降 ≥20%」「难字段填充率提升 ≥10 个百分点」两条都判不了。

一个容易搞错的口径:filled 指的是 人工校对前 AI 有没有给出值——留空的字段即便人工补上了, filled 仍是 false。 否则填充率会被人工的劳动虚高。

最小代码:只依赖标准库

import json, urllib.request

BASE  = "https://<埋点服务域名>"
TOKEN = "<单独提供,不要写进代码库>"

def push(path, payload):
    req = urllib.request.Request(
        BASE + path, data=json.dumps(payload).encode(),
        headers={"Content-Type": "application/json",
                 "X-Api-Token": TOKEN,
                 "User-Agent": "<你们的客户端名>/1.0"},
        method="POST")
    with urllib.request.urlopen(req, timeout=5) as r:
        return r.status

# 1. 保存一次字段修改
push("/api/corrections", {
    "title_id": tid, "title": title, "field": field, "field_layer": "L3",
    "old_value": ai_value, "new_value": human_value,
    "source": source_name, "confidence": ai_confidence,
    "operator": user_id, "reason": reason_from_dropdown, "session_id": sid,
})

# 2. 一条内容处理完成
push("/api/completions", {
    "title_id": tid, "title": title, "operator": user_id, "session_id": sid,
    "fields": {f: {"filled": ai_gave_a_value(f), "corrected": f in changed}
               for f in all_fields_this_run},
})

没有 SDK、没有依赖、不需要引入客户端库。仓库里另有一份可直接运行的完整示例。

怎么自证接通了

接入方跑一条命令即可,不需要等对方确认:

python3 scripts/verify_ingest.py --base-url https://<域名> --token <口令>

跑出 9/9 通过说明四条防线都按约定工作:

防线验的是什么
落盘正常事件确实写进日志
去重原值等于新值时正常跳过,不制造假修正
校验枚举外原因、越界置信度被拒,且进兜底队列可重放
鉴权缺 Token 与错 Token 都拒绝

自检探针写入的记录带保留标记,不会污染真实统计,跑完可一键清除。

三个已经踩过的坑

1 · 机器人防护可能在边缘悄悄吃掉请求

域名接入 CDN 的机器人防护后,请求可能按 User-Agent 被拦在边缘。 实测 12 种常见客户端,只有一种被拦,主流客户端全部放行。

请务必用真实的 User-Agent 先测一次。被边缘拦掉的请求 根本到不了服务端——兜底队列救不了它,日志里也看不到, 表现为「上游以为发了,接收端什么都没有」,正是那种不可追补的丢法。

最快的判断办法:同一请求用 curl 再发一次。 curl 通、程序不通 = 按 UA 拦在边缘;两者都不通 = 服务或隧道的问题。

顺带一提:实测通过就不要加放行规则—— 加规则等于主动放弃这段路径的机器人防护,为一个并不存在的问题付出真实代价。

2 · 重试是上游的责任

服务端保证「收到即不丢」,但收不到就是收不到

响应上游该怎么做
200
422不要丢弃——接收端已存兜底队列可重放,上游也记一份便于排查
401配置错,不要重试
500建议重试

3 · 口令不要写进代码库

用配置或密钥管理下发。接收端侧未配置口令时服务直接拒绝启动—— 不存在「忘了开鉴权」这种状态。

接完之后:第二步可以稍后

闭环的右端,是让编目链路消费规则包——一个版本化的 JSON 配置, 四种规则类型各对应一个执行分支,按灰度比例抽样执行。 加载器参考实现只依赖标准库,约一天工作量。

但顺序不能倒过来:没有埋点数据,后面所有环节都只是在空转。 差异分析没有素材,规则提取没有证据,看板没有分母。

← 使用方法 · 架构详解 · 先看演示