/** * 去除深度思考模型输出的 ... 标签及其内容 * * 1. stripThink(text) — 用于非流式,直接去除完整文本中的 块 * 2. createThinkStreamFilter() — 用于流式,返回有状态的过滤器,逐 chunk 过滤 */ /** * 非流式:去除完整文本中的 ... */ export function stripThink(text: string): string { return text.replace(/[\s\S]*?<\/think>/g, "").trim(); } /** * 流式:创建一个有状态的 chunk 过滤器 * * 用法: * ```ts * const filter = createThinkStreamFilter(); * for await (const chunk of textStream) { * const filtered = filter.push(chunk); * if (filtered) msg.send(filtered); * } * ``` */ export function createThinkStreamFilter() { let insideThink = false; let buffer = ""; return { /** * 输入一个 chunk,返回过滤后需要输出的文本(可能为空字符串) */ push(chunk: string): string { let output = ""; let i = 0; while (i < chunk.length) { if (insideThink) { // 正在 内部,寻找 const closeIdx = chunk.indexOf("", i); if (closeIdx !== -1) { // 找到闭合标签,跳过标签内容 insideThink = false; i = closeIdx + "".length; } else { // 整个剩余 chunk 都在 think 内,全部丢弃 break; } } else { // 不在 内部 const openIdx = chunk.indexOf("", i); if (openIdx !== -1) { // 找到开启标签,输出标签之前的内容 output += buffer + chunk.slice(i, openIdx); buffer = ""; insideThink = true; i = openIdx + "".length; } else { // 没有发现 ,但可能 chunk 末尾是不完整的 "" 的不完整前缀 * 如 "<", "