This commit is contained in:
2025-09-24 21:19:12 +08:00
parent c528125115
commit 4126e5b1e1

View File

@@ -18,7 +18,6 @@ from problem.models import Problem
from submission.models import Submission, JudgeStatus
from account.decorators import login_required
from ai.models import AIAnalysis
from textwrap import dedent
# 常量定义
@@ -429,63 +428,42 @@ class AIAnalysisAPI(APIView):
client = OpenAI(api_key=api_key, base_url="https://api.deepseek.com")
system_prompt ="""
你是一个风趣的编程老师,学生使用判题狗平台进行编程练习。
请根据学生提供的详细数据和每周数据,给出用户的学习建议。
请使用 markdown 格式输出,不要在代码块中输出。
最后不要忘记写一句祝福语。
"""
user_prompt = f"""
这段时间内的详细数据: {details}
每周或每月的数据: {weekly}
"""
system_prompt = "你是一个风趣的编程老师,学生使用判题狗平台进行编程练习。请根据学生提供的详细数据和每周数据,给出用户的学习建议。请使用 markdown 格式输出,不要在代码块中输出。最后不要忘记写一句祝福语。"
user_prompt = f"这段时间内的详细数据: {details} \n每周或每月的数据: {weekly}"
analysis_chunks = []
saved = False
save_error = None
store_error_sent = False
saved_instance = None
completed = False
def try_save():
nonlocal saved, save_error
if saved:
return
if not analysis_chunks:
saved = True
return
try:
AIAnalysis.objects.create(
user=user,
data={"details": details, "weekly": weekly},
system_prompt=dedent(system_prompt).strip(),
user_prompt="这段时间内的详细数据, 每周或每月的数据",
analysis="".join(analysis_chunks).strip(),
)
except Exception as exc:
save_error = str(exc)
finally:
saved = True
def save_analysis():
nonlocal saved_instance
if analysis_chunks and not saved_instance:
try:
saved_instance = AIAnalysis.objects.create(
user=user,
provider="deepseek",
model="deepseek-chat",
data={"details": details, "weekly": weekly},
system_prompt=system_prompt,
user_prompt=user_prompt,
analysis="".join(analysis_chunks).strip(),
)
except Exception:
pass
def stream_generator():
nonlocal store_error_sent
nonlocal completed
try:
stream = client.chat.completions.create(
model="deepseek-chat",
messages=[
{
"role": "system",
"content": system_prompt,
},
{
"role": "user",
"content": user_prompt,
},
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
],
stream=True,
)
except Exception as exc:
payload = json.dumps({"type": "error", "message": str(exc)})
yield f"data: {payload}\n\n"
yield f"data: {json.dumps({'type': 'error', 'message': str(exc)})}\n\n"
yield "event: end\n\n"
return
@@ -497,54 +475,26 @@ class AIAnalysisAPI(APIView):
continue
choice = chunk.choices[0]
finish_reason = getattr(choice, "finish_reason", None)
delta = getattr(choice, "delta", None)
raw_content = getattr(delta, "content", None)
if raw_content:
if isinstance(raw_content, list):
text_content = "".join(
(
item.get("text")
if isinstance(item, dict)
else getattr(item, "text", None) or ""
)
for item in raw_content
)
else:
text_content = str(raw_content)
if text_content:
analysis_chunks.append(text_content)
payload = json.dumps(
{"type": "delta", "content": text_content}
)
yield f"data: {payload}\n\n"
if finish_reason:
try_save()
if save_error and not store_error_sent:
error_payload = json.dumps(
{"type": "store_error", "message": save_error}
)
yield f"data: {error_payload}\n\n"
store_error_sent = True
payload = json.dumps({"type": "done"})
yield f"data: {payload}\n\n"
if choice.finish_reason:
completed = True
save_analysis()
yield f"data: {json.dumps({'type': 'done'})}\n\n"
break
except Exception as exc:
payload = json.dumps({"type": "error", "message": str(exc)})
yield f"data: {payload}\n\n"
finally:
try_save()
if save_error and not store_error_sent:
error_payload = json.dumps(
{"type": "store_error", "message": save_error}
)
yield f"data: {error_payload}\n\n"
store_error_sent = True
content = choice.delta.content
if content:
analysis_chunks.append(content)
yield f"data: {json.dumps({'type': 'delta', 'content': content})}\n\n"
except Exception as exc:
yield f"data: {json.dumps({'type': 'error', 'message': str(exc)})}\n\n"
finally:
save_analysis()
if saved_instance and not completed:
try:
saved_instance.delete()
except Exception:
pass
yield "event: end\n\n"
response = StreamingHttpResponse(