feat: 优化前端显示&修复若干bug
This commit is contained in:
@@ -231,35 +231,83 @@ class AIAnalyzer:
|
||||
|
||||
async for chunk in response.aiter_text():
|
||||
if chunk:
|
||||
chunk_str = chunk.strip()
|
||||
if chunk_str.startswith("data: "):
|
||||
chunk_str = chunk_str[6:] # 去除"data: "前缀
|
||||
|
||||
if chunk_str == "[DONE]":
|
||||
logger.debug("收到流结束标记 [DONE]")
|
||||
continue
|
||||
|
||||
try:
|
||||
# 解析数据块
|
||||
chunk_data = json.loads(chunk_str)
|
||||
delta = chunk_data.get("choices", [{}])[0].get("delta", {})
|
||||
content = delta.get("content", "")
|
||||
|
||||
if content:
|
||||
chunk_count += 1
|
||||
buffer += content
|
||||
collected_messages.append(content)
|
||||
# 分割多行响应(处理某些API可能在一个chunk中返回多行)
|
||||
lines = chunk.strip().split('\n')
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
# 直接发送每个内容片段,不累积
|
||||
yield json.dumps({
|
||||
"stock_code": stock_code,
|
||||
"ai_analysis_chunk": content,
|
||||
"status": "analyzing"
|
||||
})
|
||||
except json.JSONDecodeError:
|
||||
# 忽略无法解析的块
|
||||
logger.error(f"JSON解析错误,块内容: {chunk_str[:100]}...")
|
||||
continue
|
||||
# 处理以data:开头的行
|
||||
if line.startswith("data: "):
|
||||
line = line[6:] # 去除"data: "前缀
|
||||
|
||||
if line == "[DONE]":
|
||||
logger.debug("收到流结束标记 [DONE]")
|
||||
continue
|
||||
|
||||
try:
|
||||
# 处理特殊错误情况
|
||||
if "error" in line.lower():
|
||||
error_msg = line
|
||||
try:
|
||||
error_data = json.loads(line)
|
||||
error_msg = error_data.get("error", line)
|
||||
except:
|
||||
pass
|
||||
|
||||
logger.error(f"流式响应中收到错误: {error_msg}")
|
||||
yield json.dumps({
|
||||
"stock_code": stock_code,
|
||||
"error": f"流式响应错误: {error_msg}",
|
||||
"status": "error"
|
||||
})
|
||||
continue
|
||||
|
||||
# 尝试解析JSON
|
||||
chunk_data = json.loads(line)
|
||||
|
||||
# 检查是否有finish_reason
|
||||
finish_reason = chunk_data.get("choices", [{}])[0].get("finish_reason")
|
||||
if finish_reason == "stop":
|
||||
logger.debug("收到finish_reason=stop,流结束")
|
||||
continue
|
||||
|
||||
# 获取delta内容
|
||||
delta = chunk_data.get("choices", [{}])[0].get("delta", {})
|
||||
|
||||
# 检查delta是否为空对象
|
||||
if not delta or delta == {}:
|
||||
logger.debug("收到空的delta对象,跳过")
|
||||
continue
|
||||
|
||||
content = delta.get("content", "")
|
||||
|
||||
if content:
|
||||
chunk_count += 1
|
||||
buffer += content
|
||||
collected_messages.append(content)
|
||||
|
||||
# 直接发送每个内容片段,不累积
|
||||
yield json.dumps({
|
||||
"stock_code": stock_code,
|
||||
"ai_analysis_chunk": content,
|
||||
"status": "analyzing"
|
||||
})
|
||||
except json.JSONDecodeError:
|
||||
# 记录解析错误并尝试恢复
|
||||
logger.error(f"JSON解析错误,块内容: {line}")
|
||||
|
||||
# 如果是特定错误模式,处理它
|
||||
if "streaming failed after retries" in line.lower():
|
||||
logger.error("检测到流式传输失败")
|
||||
yield json.dumps({
|
||||
"stock_code": stock_code,
|
||||
"error": "流式传输失败,请稍后重试",
|
||||
"status": "error"
|
||||
})
|
||||
return
|
||||
continue
|
||||
|
||||
logger.info(f"AI流式处理完成,共收到 {chunk_count} 个内容片段,总长度: {len(buffer)}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user