diff --git a/demo/web/server.py b/demo/web/server.py index be5fbcd..77eb486 100644 --- a/demo/web/server.py +++ b/demo/web/server.py @@ -18,7 +18,7 @@ import psycopg2 import psycopg2.pool from fastapi import FastAPI, HTTPException, Query from fastapi.staticfiles import StaticFiles -from fastapi.responses import RedirectResponse +from fastapi.responses import RedirectResponse, StreamingResponse from pydantic import BaseModel # --------------------------------------------------------------------------- @@ -932,6 +932,8 @@ def generate_paradigm( ], "response_format": {"type": "json_object"}, "temperature": 0.4, + "stream": True, + "stream_options": {"include_usage": False}, }).encode("utf-8") req = _urllib.Request( @@ -944,14 +946,40 @@ def generate_paradigm( method="POST", ) - try: - with _urllib.urlopen(req, timeout=60) as resp: - result = json.loads(resp.read().decode("utf-8")) - content = result["choices"][0]["message"]["content"] - parsed = json.loads(content) - return parsed - except Exception as exc: - raise HTTPException(status_code=502, detail=f"LLM 调用失败: {exc}") + def stream_generator(): + """SSE 流式生成器,逐块推送 LLM content delta。""" + try: + resp = _urllib.urlopen(req, timeout=120) + buffer = b"" + while True: + chunk = resp.read(4096) + if not chunk: + break + buffer += chunk + while b"\n" in buffer: + line, buffer = buffer.split(b"\n", 1) + line = line.strip() + if not line: + continue + if line.startswith(b"data:"): + data_str = line[5:].strip() + if data_str == b"[DONE]": + yield "data: [DONE]\n\n" + return + try: + chunk_obj = json.loads(data_str) + delta = chunk_obj.get("choices", [{}])[0].get("delta", {}) + content = delta.get("content", "") + if content: + yield f"data: {json.dumps({'content': content}, ensure_ascii=False)}\n\n" + except (json.JSONDecodeError, IndexError, KeyError): + continue + resp.close() + except Exception as exc: + yield f"data: {json.dumps({'error': str(exc)}, ensure_ascii=False)}\n\n" + yield "data: [DONE]\n\n" + + return StreamingResponse(stream_generator(), media_type="text/event-stream") @app.get("/api/sync/status") diff --git a/demo/web/static/index.html b/demo/web/static/index.html index 1323509..211e6df 100644 --- a/demo/web/static/index.html +++ b/demo/web/static/index.html @@ -1132,13 +1132,63 @@ async function generateParadigm() { const result = document.getElementById('paradigm-result'); btn.disabled = true; btn.textContent = '生成中...'; - result.innerHTML = '
正在调用千问 LLM 生成标准范式对话,请稍候...
'; + result.innerHTML = ` +LLM 返回内容无法解析为 JSON,以下为原始输出:
+${escapeHtml(fullContent)}
+ 生成失败: ${e.message}
`; } finally {