|
|
@@ -665,8 +665,25 @@ PLAN_SYSTEM_PROMPT = """你是一个专业的家庭健康方案规划师。根
|
|
|
|
|
|
REGENERATE_SECTION_SYSTEM_PROMPT = """你是一个家庭健康方案规划师。根据用户反馈重新生成指定部分内容。
|
|
|
|
|
|
-## 输出格式
|
|
|
-只输出新的 content 字段值(Markdown 格式字符串),不要输出 JSON 结构。
|
|
|
+## 输出格式(必须输出合法 JSON,不要有其他内容)
|
|
|
+{
|
|
|
+ "content": "重新生成的 Markdown 内容",
|
|
|
+ "tasks": [
|
|
|
+ {
|
|
|
+ "action_type": "buy|read|exercise|checkin|diet|activity",
|
|
|
+ "title": "可执行任务标题",
|
|
|
+ "dimension": "body|mind|wisdom|action|wealth",
|
|
|
+ "frequency": "once|daily",
|
|
|
+ "notes": "补充说明"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+}
|
|
|
+
|
|
|
+## tasks 约定
|
|
|
+- action_type 取值:buy/read/exercise/checkin/diet/activity
|
|
|
+- dimension 取值:body/mind/wisdom/action/wealth
|
|
|
+- frequency:once=一次性;daily=每日重复
|
|
|
+- 无行动项时 tasks 输出 []
|
|
|
|
|
|
## 原则
|
|
|
- 保持与原格式一致
|
|
|
@@ -925,7 +942,26 @@ async def health_plan_regenerate(req: HealthPlanRegenerateRequest):
|
|
|
|
|
|
try:
|
|
|
response = await llm.ainvoke([SystemMessage(content=prompt)])
|
|
|
- return {"success": True, "content": response.content}
|
|
|
+ answer = response.content
|
|
|
+ start = answer.find("{")
|
|
|
+ end = answer.rfind("}") + 1
|
|
|
+ content = answer
|
|
|
+ tasks = []
|
|
|
+ if start >= 0 and end > start:
|
|
|
+ try:
|
|
|
+ parsed = json.loads(answer[start:end])
|
|
|
+ content = parsed.get("content") or answer
|
|
|
+ raw_tasks = parsed.get("tasks") or []
|
|
|
+ # 用 PlanTask 校验,非法条目丢弃
|
|
|
+ for t in raw_tasks:
|
|
|
+ try:
|
|
|
+ pt = PlanTask.model_validate(t)
|
|
|
+ tasks.append(pt.model_dump())
|
|
|
+ except Exception:
|
|
|
+ continue
|
|
|
+ except Exception as e:
|
|
|
+ logger.warning("解析重生成 section JSON 失败: %s", e)
|
|
|
+ return {"success": True, "content": content, "tasks": tasks}
|
|
|
except Exception as e:
|
|
|
logger.error("重新生成 section 失败: %s", e)
|
|
|
return {"success": False, "error": str(e)}
|