Mistral生成JSON博客解析报错,求无错解析方案
解决Mistral流式响应JSON解析SyntaxError的可靠方案
核心问题在于流式返回的内容可能混杂非JSON前缀/后缀、不完整数据碎片、隐藏控制字符,简单截取或清理无法覆盖所有异常场景。以下是落地性强的解决步骤:
1. 完整拼接流式响应
流式模式下API会逐块返回数据(多为SSE格式的data:片段),必须先拼接所有有效数据,跳过结束标记[DONE],过滤非数据行:
async function generatePosts() { const response = await fetch('https://api.mistral.ai/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_KEY' }, body: JSON.stringify({ model: 'mistral-large', messages: [{ role: 'user', content: '生成博客内容,返回严格标准的JSON格式,不要任何额外说明' }], stream: true }) }); const reader = response.body.getReader(); const decoder = new TextDecoder('utf-8'); let fullContent = ''; while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value, { stream: true }); // 处理SSE格式的分块内容 const validLines = chunk.split('\n').filter(line => line.trim().startsWith('data:')); for (const line of validLines) { const dataSegment = line.slice(5).trim(); if (dataSegment === '[DONE]') continue; fullContent += dataSegment; } } // 后续处理fullContent }
2. 精准提取完整JSON结构
不要粗暴截取起始位置,用正则匹配从{开始到对应闭合}的完整JSON(支持嵌套结构),同时过滤前后的空白和无关文本:
const jsonMatch = fullContent.match(/^\s*({[\s\S]*})\s*$/); if (!jsonMatch) { throw new Error('响应中未找到有效JSON结构'); } const rawJson = jsonMatch[1];
3. 清理无效字符
移除JSON规范不允许的控制字符(比如换行符之外的不可见字符),但保留字符串内部的合法空白:
const cleanedJson = rawJson.replace(/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/g, '');
4. 容错解析与结构验证
用try-catch包裹解析逻辑,同时验证解析后的数据结构是否符合预期(避免解析成功但内容不符合需求):
let parsedResult; try { parsedResult = JSON.parse(cleanedJson); // 验证结构,比如检查是否包含预期的posts字段 if (!parsedResult || typeof parsedResult !== 'object' || !parsedResult.posts) { throw new Error('JSON结构不符合要求'); } } catch (error) { console.error('解析失败,原始响应:', fullContent); throw error; } return parsedResult;
额外优化:从源头减少无效内容
在prompt里明确要求模型返回无任何额外说明的纯JSON,比如:
生成1篇关于前端性能优化的博客内容,返回严格符合JSON规范的结果,格式为{"title":"标题","content":"内容","tags":["标签1","标签2"]},不要添加任何解释、注释或多余文本。
内容的提问来源于stack exchange,提问作者Xhris
相关产品推荐
相关产品推荐

