分享一个测GPT是否降智的油猴脚本

SeaMod 2026-09-03 00:58 1

由这个 https://www.nodeseek.com/post-908122-1 帖子的代码扔给claude魔改为油猴插件

该插件只能检测是否降低模型,降低思考强度是无法检测的

直接复制粘贴以下代码导入到油猴插件里:


// ==UserScript==
// @name ChatGPT Route Checker v4
// @name:zh-CN ChatGPT 模型路由检测器 v4
// @namespace local.chatgpt.route-checker
// @version 4.1.0
// @description Display the requested model and model-routing metadata exposed by ChatGPT Web.
// @description:zh-CN 显示 ChatGPT 网页请求的模型及服务端暴露的模型路由标注。
// @match https://chatgpt.com/*
// @match https://chat.openai.com/*
// @run-at document-start
// @sandbox raw
// @grant none
// @noframes
// ==/UserScript==
(() => {
"use strict";
if (window.__CHATGPT_ROUTE_CHECKER_V4__) {
console.log("Route Checker v4 已在运行");
return;
}
window.__CHATGPT_ROUTE_CHECKER_V4__ = true;

const nativeFetch = window.fetch.bind(window);
const nativeBeacon = navigator.sendBeacon
? navigator.sendBeacon.bind(navigator)
: null;

const state = {
active: false,
finished: false,
requestModel: null,
thinkingEffort: null,
serverModel: null,
assistantModel: null,
resolvedModel: null,
requestedExperience: null,
domModel: null
};

// 供 scanObject 使用:本次扫描内“字段是否真的变化 / 是否命中 server_ste_metadata”
let dirty = false;
let sawServerMeta = false;
function setField(key, value) {
if (state[key] !== value) {
state[key] = value;
dirty = true;
}
}

let finishTimer = null;

// ---------------- UI ----------------
const panel = document.createElement("div");
Object.assign(panel.style, {
position: "fixed",
right: "16px",
bottom: "16px",
zIndex: "2147483647",
width: "410px",
maxWidth: "calc(100vw - 32px)",
padding: "14px 16px",
border: "1px solid #444",
borderRadius: "12px",
background: "#111",
color: "#eee",
font: "13px/1.7 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace",
boxShadow: "0 8px 30px rgba(0,0,0,.4)",
// 整个显示框缩小为原来的 70%
transform: "scale(0.7)",
transformOrigin: "right bottom"
});

function mountPanel() {
if (!panel.isConnected && document.documentElement) {
document.documentElement.appendChild(panel);
}
}
mountPanel();

const esc = value =>
String(value).replace(/[&<>"']/g, c => ({
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#39;"
})[c]);

function display(value) {
return value ? esc(value) : state.finished ? "本次未返回" : "搜索中…";
}

function modelFamily(slug) {
const m = String(slug || "").match(/^gpt-(\d+)-(\d+)/i);
return m ? `gpt-${m[1]}-${m[2]}` : null;
}

function verdict() {
if (!state.active) return "⏳ 等待发送一条新消息";
if (!state.serverModel) return "🔎 检测中,等待服务端模型标注…";
if (!state.requestModel) return "✅ 已取得服务端模型标注";
if (state.requestModel === state.serverModel) {
return "✅ 请求模型与服务端模型标注一致";
}
const reqFamily = modelFamily(state.requestModel);
const srvFamily = modelFamily(state.serverModel);
if (reqFamily && reqFamily === srvFamily) {
return "✅ 同一模型系列(内部 slug 不同)";
}
return "🚨 请求模型与服务端模型标注不一致";
}

function refreshDomModel() {
const els = document.querySelectorAll('[data-message-author-role="assistant"]');
if (!els.length) return;
const value = els[els.length - 1].getAttribute("data-message-model-slug");
if (value) state.domModel = value;
}

function render() {
mountPanel();
refreshDomModel();
panel.innerHTML = `
<div style="font-weight:700;font-size:14px;margin-bottom:8px">
ChatGPT Route Checker v4
</div>
<div style="margin-bottom:10px">${verdict()}</div>
<div style="border-top:1px solid #333;border-bottom:1px solid #333;padding:10px 0;margin-bottom:10px">
<div style="color:#aaa">实际回复模型标注</div>
<div style="font-size:18px;font-weight:700;margin-top:2px">
${display(state.serverModel)}
</div>
<div style="color:#777;font-size:11px;margin-top:2px">
server_ste_metadata.model_slug
</div>
</div>
<div>
请求的模型:<b>${display(state.requestModel)}</b><br>
请求的思考强度:<b>${display(state.thinkingEffort)}</b><br><br>
server_ste_metadata.model_slug:<b>${display(state.serverModel)}</b><br>
assistant metadata.model_slug:<b>${display(state.assistantModel)}</b><br>
resolved_model_slug:<b>${display(state.resolvedModel)}</b><br>
requested_model_experience:<b>${display(state.requestedExperience)}</b><br>
DOM data-message-model-slug:<b>${display(state.domModel)}</b>
</div>
<div style="border-top:1px solid #333;margin-top:10px;padding-top:7px;color:#777;font-size:11px">
主判断:server_ste_metadata.model_slug<br>
其余字段仅用于交叉验证
</div>
`;
}

// ---------------- 单轮状态管理 ----------------
function beginTurn(req) {
clearTimeout(finishTimer);
state.active = true;
state.finished = false;
state.requestModel = typeof req?.model === "string" ? req.model : null;
state.thinkingEffort =
typeof req?.thinking_effort === "string" ? req.thinking_effort : null;
state.serverModel = null;
state.assistantModel = null;
state.resolvedModel = null;
state.requestedExperience = null;
state.domModel = null;
render();
}

function scheduleFinish(delay = 2000) {
clearTimeout(finishTimer);
finishTimer = setTimeout(() => {
state.finished = true;
refreshDomModel();
render();
}, delay);
}

// ---------------- 扫描 JSON ----------------
function scanObject(obj, depth = 0, seen = new WeakSet()) {
if (obj == null || depth > 15) return;

if (typeof obj === "string") {
const s = obj.trim();
if (
(s.startsWith("{") || s.startsWith("[")) &&
(s.includes("model_slug") ||
s.includes("server_ste_metadata") ||
s.includes("resolved_model_slug"))
) {
try {
scanObject(JSON.parse(s), depth + 1, seen);
} catch {}
}
return;
}

if (typeof obj !== "object" || seen.has(obj)) return;
seen.add(obj);

// server_ste_metadata 可能出现在三种位置:{type, metadata}、直属字段、turn_analytics 内
const serverMeta =
(obj.type === "server_ste_metadata" && obj.metadata) ||
obj.server_ste_metadata ||
obj.turn_analytics?.server_ste_metadata;
if (serverMeta && typeof serverMeta === "object") {
if (typeof serverMeta.model_slug === "string") {
setField("serverModel", serverMeta.model_slug);
}
if (typeof serverMeta.requested_model_experience === "string") {
setField("requestedExperience", serverMeta.requested_model_experience);
}
sawServerMeta = true;
}

// assistant 消息的 metadata.model_slug:可能是本对象,也可能包在 .message 里
const assistantNode =
obj.author?.role === "assistant"
? obj
: obj.message?.author?.role === "assistant"
? obj.message
: null;
if (typeof assistantNode?.metadata?.model_slug === "string") {
setField("assistantModel", assistantNode.metadata.model_slug);
}

if (typeof obj.resolved_model_slug === "string") {
setField("resolvedModel", obj.resolved_model_slug);
}

for (const value of Object.values(obj)) {
scanObject(value, depth + 1, seen);
}
}

function parseData(raw) {
if (!raw) return;
const text = raw.trim();
if (!text || text === "[DONE]") return;
let obj;
try {
obj = JSON.parse(text);
} catch {
return;
}
dirty = false;
sawServerMeta = false;
scanObject(obj);
if (dirty) render();
if (sawServerMeta) scheduleFinish(1500);
}

function scanWholeText(text) {
if (!text) return;
parseData(text); // 整体可能就是一个 JSON
for (let line of text.split(/\r?\n/)) {
line = line.trim();
if (!line) continue;
if (line.startsWith("data:")) line = line.slice(5).trim();
parseData(line);
}
}

// ---------------- 实时 SSE 读取 ----------------
async function watchStream(response) {
if (!response.body) {
try {
scanWholeText(await response.text());
} catch {}
scheduleFinish();
return;
}

const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
let eventLines = [];
const flushEvent = () => {
if (eventLines.length) {
parseData(eventLines.join("\n"));
eventLines = [];
}
};

try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });

let nl;
while ((nl = buffer.indexOf("\n")) !== -1) {
let line = buffer.slice(0, nl);
buffer = buffer.slice(nl + 1);
if (line.endsWith("\r")) line = line.slice(0, -1);

if (line === "") {
flushEvent();
} else if (line.startsWith("data:")) {
eventLines.push(line.slice(5).trimStart());
} else {
const t = line.trim();
if (t.startsWith("{") || t.startsWith("[")) parseData(t);
}
}
}
const rest = buffer.trim();
if (rest.startsWith("data:")) {
eventLines.push(rest.slice(5).trimStart());
} else if (rest) {
parseData(rest);
}
flushEvent();
} catch (err) {
console.debug("[Route Checker] stream reader:", err);
}
scheduleFinish(3000);
}

// ---------------- Request body ----------------
async function bodyText(body) {
try {
if (body == null) return "";
if (typeof body === "string") return body;
if (body instanceof Blob) return await body.text();
if (body instanceof URLSearchParams) return body.toString();
if (body instanceof ArrayBuffer) return new TextDecoder().decode(body);
if (ArrayBuffer.isView(body)) return new TextDecoder().decode(body);
} catch {}
return "";
}

async function getRequestText(input, init) {
if (init?.body != null) return await bodyText(init.body);
if (input instanceof Request) {
try {
return await input.clone().text();
} catch {}
}
return "";
}

const isConversation = (url, method) =>
method === "POST" && /\/backend-api\/f\/conversation(?:\?|$)/.test(url);
const isTelemetry = (url, method) =>
method === "POST" && /\/ces\/v1\/telemetry\/intake(?:\?|$)/.test(url);

// ---------------- fetch hook ----------------
window.fetch = async function (input, init = {}) {
const url = typeof input === "string" ? input : input?.url || "";
const method = String(init.method || input?.method || "GET").toUpperCase();

if (isConversation(url, method)) {
const reqText = await getRequestText(input, init);
try {
beginTurn(JSON.parse(reqText));
} catch {
beginTurn({});
}
} else if (isTelemetry(url, method)) {
scanWholeText(await getRequestText(input, init));
}

const response = await nativeFetch(input, init);

if (isConversation(url, method)) {
try {
void watchStream(response.clone());
} catch {}
}
return response;
};

// ---------------- sendBeacon telemetry ----------------
if (nativeBeacon) {
try {
navigator.sendBeacon = function (url, data) {
if (/\/ces\/v1\/telemetry\/intake(?:\?|$)/.test(String(url || ""))) {
void bodyText(data).then(scanWholeText);
}
return nativeBeacon(url, data);
};
} catch {}
}

// ---------------- DOM observer(用 rAF 合并高频 DOM 变动) ----------------
let domCheckQueued = false;
const observer = new MutationObserver(() => {
if (domCheckQueued) return;
domCheckQueued = true;
requestAnimationFrame(() => {
domCheckQueued = false;
mountPanel();
const before = state.domModel;
refreshDomModel();
if (state.domModel !== before) render();
});
});
observer.observe(document, {
subtree: true,
childList: true,
attributes: true,
attributeFilter: ["data-message-model-slug"]
});

render();
console.log("ChatGPT Route Checker v4 已启动,发送一条新消息即可。");
})();
最新回复 (11)
  • theliser 09-03 01:00
    1

    这排班...

    你就不能放到markdown代码块里面去吗

  • barry66688 09-03 01:02
    2

    大佬辛苦了

  • Opus94 09-03 01:03
    3

    ^-^ ^-^ ^-^

  • -niuniu- 09-03 01:06
    4

    好贴

  • SeaMod 楼主 09-03 01:17
    5

  • morningstar 09-03 01:18
    6

    mark

  • zyy3096 09-03 01:26
    7

    mark

  • 让我们一起荡起双桨 09-03 01:27
    8

    666

  • 让我们一起荡起双桨 09-03 01:32
    9

    GPT-5.6 Thinking是GPT-5.6 Sol吗?


  • corenuclear 09-03 06:54
    10

    感谢分享,收藏了

  • skyzc 09-03 06:59
    11

    666

* 帖子来源NodeSeek
返回