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}