debug: 修复流式传输语句重复的问题

This commit is contained in:
肖应宇 2026-03-03 14:37:03 +08:00
parent 485b07c12f
commit a8f631a034
2 changed files with 56 additions and 24 deletions

View File

@ -140,6 +140,8 @@ async def chat_endpoint(request: Request):
temperature=temperature
)
full_content = "" # 用于累计完整内容
for idx, response in enumerate(responses):
if response.status_code == 200:
# 检查响应是否包含预期的内容
@ -156,6 +158,29 @@ async def chat_endpoint(request: Request):
'content' in response.output.choices[0]['message']):
content = response.output.choices[0]['message']['content']
# 只有当内容发生变化时才发送增量
if len(content) > len(full_content):
delta_content = content[len(full_content):]
full_content = content
if delta_content.strip(): # 只有当有非空白新内容时才发送
# 构建 SSE 数据块
data = {
"id": f"chatcmpl-{uuid.uuid4()}",
"object": "chat.completion.chunk",
"created": int(datetime.utcnow().timestamp()),
"model": model,
"choices": [
{
"index": 0,
"delta": {"content": delta_content},
"finish_reason": None
}
]
}
yield f"data: {json.dumps(data, ensure_ascii=False)}\n\n"
# 否则尝试从 output.text 获取内容DashScope特定格式
elif (hasattr(response, 'output') and
response.output and
@ -163,26 +188,28 @@ async def chat_endpoint(request: Request):
content = response.output.get('text')
if content:
# 构建 SSE 数据块
data = {
"id": f"chatcmpl-{uuid.uuid4()}",
"object": "chat.completion.chunk",
"created": int(datetime.utcnow().timestamp()),
"model": model,
"choices": [
{
"index": 0,
"delta": {"content": content} if content else {},
"finish_reason": None
}
]
}
# 只有当内容发生变化时才发送增量
if len(content) > len(full_content):
delta_content = content[len(full_content):]
full_content = content
yield f"data: {json.dumps(data)}\n\n"
else:
# 如果响应中没有内容,跳过
continue
if delta_content.strip(): # 只有当有非空白新内容时才发送
# 构建 SSE 数据块
data = {
"id": f"chatcmpl-{uuid.uuid4()}",
"object": "chat.completion.chunk",
"created": int(datetime.utcnow().timestamp()),
"model": model,
"choices": [
{
"index": 0,
"delta": {"content": delta_content},
"finish_reason": None
}
]
}
yield f"data: {json.dumps(data, ensure_ascii=False)}\n\n"
else:
# 错误处理
error_data = {
@ -193,7 +220,7 @@ async def chat_endpoint(request: Request):
"code": response.code
}
}
yield f"data: {json.dumps(error_data)}\n\n"
yield f"data: {json.dumps(error_data, ensure_ascii=False)}\n\n"
break
# 发送结束信号
@ -210,9 +237,8 @@ async def chat_endpoint(request: Request):
}
]
}
yield f"data: {json.dumps(finish_data)}\n\n"
yield f"data: {json.dumps(finish_data, ensure_ascii=False)}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
error_data = {
"error": {
@ -220,7 +246,7 @@ async def chat_endpoint(request: Request):
"type": "server_error"
}
}
yield f"data: {json.dumps(error_data)}\n\n"
yield f"data: {json.dumps(error_data, ensure_ascii=False)}\n\n"
return StreamingResponse(event_generator(), media_type="text/event-stream")
else:
@ -272,7 +298,7 @@ async def chat_endpoint(request: Request):
"totalTokens": response.usage.total_tokens
}
return JSONResponse(content=chat_response)
return JSONResponse(content=chat_response, ensure_ascii=False)
else:
raise HTTPException(
status_code=500,

View File

@ -164,6 +164,12 @@ class ChatApi {
if (match) {
try {
const data = JSON.parse(match[1]);
// 检查是否有完成原因,如果是完成则跳出
const finishReason = data.choices?.[0]?.finish_reason;
if (finishReason && finishReason !== "null") {
break;
}
const content = data.choices?.[0]?.delta?.content;
if (content) {
yield content;