people-reading/backend/app/services/bazi_analyzer.py
2026-05-12 20:50:15 +08:00

95 lines
6.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
from app.services.analyzer_common import DISCLAIMER, BaseAnalyzer
USER_PROMPT_TEMPLATE = (
"请基于下面这份八字排盘结果,生成中文八字娱乐报告。"
"排盘结果由后端计算,不能自行改动四柱:{chart_json}"
"必须覆盖四柱结构、日主与五行、五行分布、十神关系、学习成长、事业节奏、关系沟通、近期行动。"
"写作要求:"
"1. dimensions 固定输出 7 项:四柱底色、日主与五行、十神互动、学习成长、事业节奏、关系沟通、近期行动。"
"2. overall_summary 用 2 到 4 句话,像给用户本人看的开场结论,不要像百科解释。"
"3. 每个 interpretation 必须落到现实场景,例如学习效率、职业节奏、沟通方式、情绪恢复、计划执行。"
"4. observations 可以写排盘证据,但不要只堆术语;每条都要让普通用户看得懂。"
"5. 每个 advice 必须是今天或本周能做的小建议,避免空话。"
"6. strengths、challenges、suggestions 要分别覆盖生活、学习、事业、关系,语言要具体。"
"7. 可以少量使用日主、五行、十神等术语,但必须用普通人能听懂的话解释。"
"8. 不预测寿命、灾祸、婚姻成败、财富结果,不做宿命论。"
"9. 如果时辰不详,要诚实降低相关维度 confidence并说明分析会更偏概览。"
)
class BaziAnalyzer(BaseAnalyzer):
async def analyze(self, chart: dict) -> dict:
if not self.client:
return self._mock_report(chart)
prompt = USER_PROMPT_TEMPLATE.format(chart_json=json.dumps(chart, ensure_ascii=False))
try:
return await self._create_text_report(prompt)
except Exception as exc:
report = self._mock_report(chart)
report["quality_check"] = {
"can_analyze": True,
"reason": f"模型响应较慢,已先基于后端排盘生成本地报告:{exc}",
"confidence": 0.62,
}
report["overall_summary"] = "模型响应较慢,先生先根据后端排出的四柱给你一份基础娱乐解读。等模型接口稳定后,可以再次生成更细腻的版本。" + report["overall_summary"]
return report
def _mock_report(self, chart: dict) -> dict:
pillars = chart.get("pillars", {})
day_master = chart.get("day_master", "日主")
return {
"quality_check": {"can_analyze": True, "reason": "mock mode", "confidence": 0.76},
"overall_summary": f"这是一份基于 {pillars.get('year', '')} {pillars.get('month', '')} {pillars.get('day', '')} {pillars.get('time', '')} 的娱乐八字报告。整体看,你的日主线索偏向“{day_master}”,适合先建立稳定节奏,再去放大自己的表达和行动力。近期最重要的是别急着求大结果,先把可执行的小计划跑起来。",
"dimensions": [
{
"name": "四柱结构",
"observations": [f"年柱:{pillars.get('year')}", f"月柱:{pillars.get('month')}", f"日柱:{pillars.get('day')}", f"时柱:{pillars.get('time')}"],
"interpretation": "四柱结构象征一个人的底色、节奏和外部互动方式。放到现实里,你更适合把目标拆成阶段,不必要求自己一步到位。",
"confidence": 0.72,
"advice": "今天先写下一个 7 天目标,只保留最关键的三件事。",
},
{
"name": "日主与五行",
"observations": [f"日主:{day_master}", f"五行分布:{chart.get('wuxing_balance', {})}"],
"interpretation": "日主象征你处理世界的核心方式,五行分布则像精力使用习惯。现实里,你适合先找到稳定补给,再去应对学习、工作和关系里的变化。",
"confidence": 0.7,
"advice": "这周给自己固定一个恢复时间,别把精力全部交给外界安排。",
},
{
"name": "十神关系",
"observations": [f"十神线索:{chart.get('shi_shen', {})}"],
"interpretation": "十神关系可以理解为你和资源、表达、规则、压力之间的互动方式。现实里,适合把压力转成清单,而不是只在脑子里反复想。",
"confidence": 0.66,
"advice": "遇到复杂任务时,先写下“我能控制的部分”。",
},
{
"name": "学习成长",
"observations": ["适合阶段式吸收", "需要稳定反馈"],
"interpretation": "学习上你更适合循序渐进。比起临时爆发,持续复盘更能帮你看到进步。",
"confidence": 0.68,
"advice": "今天结束前写 5 行复盘,记录一个学到的点。",
},
{
"name": "事业节奏",
"observations": ["适合沉淀方法", "不宜频繁自我推翻"],
"interpretation": "事业上适合先做稳定交付,再逐步争取主动权。越是焦虑时,越需要用作品和结果给自己定心。",
"confidence": 0.65,
"advice": "本周整理一个能展示的小成果,哪怕只是文档或案例。",
},
{
"name": "关系沟通",
"observations": ["需要清晰边界", "适合具体表达"],
"interpretation": "关系里你可能会先照顾气氛,但真正有效的是把需求讲清楚。温和不等于什么都自己消化。",
"confidence": 0.63,
"advice": "把一个模糊的不舒服,改写成一句具体请求。",
},
],
"strengths": ["适合长期积累", "能在变化里调整节奏", "对关系氛围比较敏感"],
"challenges": ["压力大时容易想太多", "计划过满会消耗行动力"],
"suggestions": ["生活上固定恢复时间", "学习成长上做短复盘", "事业工作上沉淀可展示成果", "关系沟通上把需求说具体"],
"lucky_keywords": ["阶段推进", "稳定补给", "具体表达"],
"disclaimer": DISCLAIMER,
}