|
|
@@ -0,0 +1,58 @@
|
|
|
+from langchain_openai import ChatOpenAI
|
|
|
+from langchain_core.messages import SystemMessage, HumanMessage
|
|
|
+from app.config import settings
|
|
|
+from app.monitoring import monitor_agent
|
|
|
+from app.prompt_service import get_prompt
|
|
|
+import json
|
|
|
+import logging
|
|
|
+
|
|
|
+logger = logging.getLogger(__name__)
|
|
|
+
|
|
|
+SYSTEM_PROMPT = """你是一位家庭教育出题助手。根据给定的文章内容,为读者生成 3 道单项选择题。
|
|
|
+
|
|
|
+要求:
|
|
|
+1. 每题 4 个选项,选项以 "A. "、"B. "、"C. "、"D. " 开头
|
|
|
+2. 题目考察文章核心内容的理解,适合青少年读者
|
|
|
+3. 每题标注所属五维(body/mind/wisdom/action/wealth),缺省为 wisdom
|
|
|
+4. 以 JSON 数组格式返回,不要返回其他文字,只返回 JSON 数组
|
|
|
+
|
|
|
+输出格式:
|
|
|
+[
|
|
|
+ {"question": "问题", "options": ["A. xxx", "B. xxx", "C. xxx", "D. xxx"], "answer": "A", "dimension": "wisdom", "explanation": "解析"}
|
|
|
+]
|
|
|
+"""
|
|
|
+
|
|
|
+
|
|
|
+class ArticleQuizAgent:
|
|
|
+ def __init__(self):
|
|
|
+ self.llm = ChatOpenAI(
|
|
|
+ model=settings.llm_model,
|
|
|
+ api_key=settings.llm_api_key,
|
|
|
+ base_url=settings.llm_base_url,
|
|
|
+ temperature=settings.llm_temperature,
|
|
|
+ )
|
|
|
+
|
|
|
+ @monitor_agent("article_quiz")
|
|
|
+ async def run(self, article_title: str, article_content: str, profile_summary: str = "") -> dict:
|
|
|
+ """根据文章内容生成 3 道选择题,失败返回空 questions"""
|
|
|
+ try:
|
|
|
+ human = f"文章标题:{article_title}\n文章内容:{article_content}"
|
|
|
+ if profile_summary:
|
|
|
+ human += f"\n用户画像摘要:{profile_summary}"
|
|
|
+ messages = [
|
|
|
+ SystemMessage(content=await get_prompt("article_quiz") or SYSTEM_PROMPT),
|
|
|
+ HumanMessage(content=human),
|
|
|
+ ]
|
|
|
+ response = await self.llm.ainvoke(messages)
|
|
|
+ content = response.content.strip()
|
|
|
+ if "```json" in content:
|
|
|
+ content = content.split("```json")[1].split("```")[0].strip()
|
|
|
+ elif "```" in content:
|
|
|
+ content = content.split("```")[1].split("```")[0].strip()
|
|
|
+ questions = json.loads(content)
|
|
|
+ if not isinstance(questions, list):
|
|
|
+ return {"questions": [], "fallback_used": True}
|
|
|
+ return {"questions": questions, "fallback_used": False}
|
|
|
+ except Exception as e:
|
|
|
+ logger.warning("文章出题生成失败: %s", e)
|
|
|
+ return {"questions": [], "fallback_used": True}
|