抓包对比工具补一批一次性脚本:拆预设、对请求、跑 A/B 与拒答抽样。

这些脚本都是我对着酒馆真实请求手工核对用的,留在仓库里方便下次重跑;跑出来的本地数据目录含接口 key,已经写进忽略规则。
This commit is contained in:
2026-10-26 01:09:56 +08:00
parent e2413b0677
commit 1a5ef3b2bc
24 changed files with 1568 additions and 0 deletions
@@ -0,0 +1,86 @@
// 从「酒馆真实抓包」直接复刻出一个预设:messages 原样搬,tools.description 搬成 system 块。
// 用法: node build-clone-from-capture.mjs <capture.json> <输出名>
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
const captureFile = process.argv[2];
const name = process.argv[3] || "wa-clone";
const OUT = "D:/progarm/my/writing-agent/tools/st-request-diff/presets/" + name + ".json";
mkdirSync(path.dirname(OUT), { recursive: true });
const outer = JSON.parse(readFileSync(captureFile, "utf8"));
const body = JSON.parse(outer.body);
const msgs = body.messages || [];
const toolDescs = (body.tools || []).map((t) => {
const fn = t.function || t;
return "# [工具声明] " + (fn.name || "") + "\n" + String(fn.description || "");
});
const blocks = [];
msgs.forEach((m, i) => {
const content = String(m.content ?? "");
if (!content.trim()) return;
blocks.push({
identifier: "clone_" + String(i).padStart(2, "0"),
name: "复刻消息 " + i + "(" + m.role + ")",
role: ["system", "user", "assistant"].includes(m.role) ? m.role : "system",
content,
});
});
toolDescs.forEach((d, i) => {
blocks.push({ identifier: "clone_tool_" + i, name: "复刻工具声明 " + i, role: "system", content: d });
});
const markers = [
["worldInfoBefore", "World Info (before)"],
["personaDescription", "Persona Description"],
["charDescription", "Char Description"],
["charPersonality", "Char Personality"],
["scenario", "Scenario"],
["worldInfoAfter", "World Info (after)"],
["dialogueExamples", "Chat Examples"],
["chatHistory", "Chat History"],
].map(([identifier, nm]) => ({
identifier, name: nm, marker: true, system_prompt: true, role: "system", content: "",
injection_position: 0, injection_depth: 4, injection_order: 100, enabled: true,
}));
const prompts = [
...markers,
...blocks.map((b) => ({
identifier: b.identifier, name: b.name, enabled: true, role: b.role,
content: b.content, injection_position: 0, injection_depth: 4, injection_order: 100,
system_prompt: false, marker: false, forbid_overrides: false,
})),
];
const prompt_order = [
{
character_id: 100001,
order: [
...blocks.map((b) => b.identifier),
"worldInfoBefore", "personaDescription", "charDescription", "charPersonality", "scenario", "worldInfoAfter",
"dialogueExamples", "chatHistory",
].map((identifier) => ({ identifier, enabled: true })),
},
];
const preset = {
name,
temperature: 1, frequency_penalty: 0, presence_penalty: 0, top_p: 0.99, top_k: 60,
max_context_unlocked: true, openai_max_context: 200000, openai_max_tokens: 3000,
names_behavior: 0, send_if_empty: "",
new_chat_prompt: "[chat Start]", new_example_chat_prompt: "{{mesExamples}}",
continue_nudge_prompt: "[继续]",
wi_format: "{0}", scenario_format: "{{scenario}}", personality_format: "{{personality}}",
stream_openai: true, use_sysprompt: true, squash_system_messages: true,
function_calling: false, reasoning_effort: "low", seed: -1, n: 1,
prompts, prompt_order,
};
writeFileSync(OUT, JSON.stringify(preset, null, 2), "utf8");
console.log("已写入 " + OUT);
console.log("消息 " + msgs.length + " 条(原样搬 " + blocks.filter((b) => b.name.startsWith("复刻消息")).length + " 条)、工具声明 " + toolDescs.length + " 段");
console.log("正文合计 " + prompts.reduce((n, p) => n + String(p.content || "").length, 0) + " 字");
console.log("来源抓包: " + path.basename(captureFile) + " receivedAt=" + outer.receivedAt);