如何解析OpenAIStream以消除空格并正确格式化列表?
问题修复方案
针对你遇到的流式返回结果多余空格、列表解析失败问题,以下是具体修复步骤:
核心问题分析
- 流式传输时对每个chunk单独trim,破坏了原始文本的换行和空格结构
- 格式化函数提前将所有空白字符替换为单个空格,丢失了列表依赖的换行符
- OpenAIStream中过滤了早期包含换行的chunk,导致列表开头内容丢失
- 中间消息更新时额外添加空格,造成冗余空格堆积
具体修复代码
1. 修正generateText中的chunk传递
移除chunk的trim操作,保留原始文本结构:
// 原代码 onUpdate(text.trim(), isFirstChunk, false); // 修改为 onUpdate(text, isFirstChunk, false);
2. 调整handleSubmit中的chunk积累方式
存储原始chunk,不再提前trim:
// 原代码 messageChunks.push(chunk.trim()); // 修改为 messageChunks.push(chunk);
同时修正中间消息更新逻辑,避免额外添加空格:
// 原代码 text: prevMessages[lastSystemMessageIndex].text + ' ' + chunk.trim(), // 修改为 text: prevMessages[lastSystemMessageIndex].text + chunk,
3. 删除OpenAIStream中的换行过滤逻辑
移除导致早期列表内容丢失的代码块:
// 删除以下代码 if (counter < 2 && text.includes("\n")) { return; }
4. 重写formatText函数,正确解析列表
保留换行符先处理列表,再清理冗余空格:
const formatText = (text) => { // 按换行分割文本,过滤空行 const lines = text.split('\n').map(line => line.trim()).filter(line => line); let formattedParts = []; let currentList = []; // 判断是否为有序列表项 const isNumberedListItem = (line) => /^\d+\.\s+/.test(line); for (const line of lines) { if (isNumberedListItem(line)) { // 提取列表项编号和内容 const [, number, content] = line.match(/^(\d+)\.\s+(.*)$/); currentList.push(`<li>${number}. ${content.replace(/\s+/g, ' ')}</li>`); } else { // 如果正在构建列表,先闭合列表 if (currentList.length > 0) { formattedParts.push(`<ol>${currentList.join('')}</ol>`); currentList = []; } // 清理普通文本中的冗余空格 formattedParts.push(line.replace(/\s+/g, ' ')); } } // 添加剩余的列表项 if (currentList.length > 0) { formattedParts.push(`<ol>${currentList.join('')}</ol>`); } // 拼接所有内容,修正标点符号前后的空格 let formattedText = formattedParts.join(' '); formattedText = formattedText .replace(/\s+([.,!?:;])/g, '$1') .replace(/([.,!?:;])\s+/g, '$1 '); // 解码HTML实体 formattedText = he.decode(formattedText); return formattedText; };
5. 修正最终消息格式化逻辑
直接拼接原始chunk,不再提前替换空格:
// 原代码 const formattedMessage = formatText(messageChunks.join(' ').replace(/\s+/g, ' ')); // 修改为 const fullText = messageChunks.join(''); const formattedMessage = formatText(fullText);
修复原理说明
- 保留原始chunk的换行和空格结构,确保列表的格式信息不丢失
- 先按行解析列表项,再清理冗余空格,避免破坏列表结构
- 移除不必要的chunk过滤,确保所有返回内容都被处理
- 修正中间消息的空格添加逻辑,避免冗余空格堆积
内容的提问来源于stack exchange,提问作者Unnamed Mistress
相关产品推荐
相关产品推荐

