astrologybazi-api / case_matcher.py
th
fix(reading): add multi-chart evidence guardrails
fefbb42
Raw History Blame Contribute Delete
18.4 kB
"""
滴天髓案例匹配器 (Ditianshi Case Matcher)
基于经典命理案例,增强AI解读的深度和准确性
核心功能:
1. 根据用户八字匹配相似案例
2. 提取案例中的核心洞察
3. 生成现代化的实用建议
匹配算法:
- 五行分布权重: 25%
- 十神配置权重: 30%
- 格局特征权重: 25%
- 分类匹配权重: 20%
🦊 Generated with Sisi - Sparksverse AI Studio
"""
from typing import Dict, List, Any, Optional, Tuple
from dataclasses import dataclass
from enum import Enum
# ==================== 核心法则库 ====================
# 何知章 - 富贵贫贱寿夭核心法则
HEZHI_PRINCIPLES = {
# 富命法则
"财气通门户": {
"category": "wealth",
"conditions": ["身旺财旺", "食神生财", "官星护财"],
"interpretation": "财运好的关键不在财星数量多,而在于五行流通有情。你的财富来自于资源配置能力和商业眼光。",
"advice": ["适合经商投资", "中年财运最旺", "忌过度冒险", "专注商业模式优化和资源整合"]
},
"食神生财": {
"category": "wealth",
"conditions": ["食神有力", "财星得生"],
"interpretation": "靠技艺或口才生财,收入稳定且可持续。你的财富来源是一技之长和专业能力。",
"advice": ["适合技术或服务行业", "可发展副业", "注重技能提升"]
},
# 贵命法则
"官星有理会": {
"category": "nobility",
"conditions": ["官星得令得地", "有印护或财生"],
"interpretation": "有领导才能和管理能力,适合在组织中发展。你的成功需要耐心等待时机。",
"advice": ["重视人脉关系", "培养领导力", "把握晋升机会", "35岁前扎实提升能力"]
},
"杀印相生": {
"category": "nobility",
"conditions": ["七杀有印化", "制化得宜"],
"interpretation": "有魄力有谋略,能在竞争中脱颖而出。复杂的竞争环境反而是你的优势。",
"advice": ["适合竞争性行业", "培养决断力", "30岁后大胆出击"]
},
# 贫命法则
"财神不真": {
"category": "poverty",
"conditions": ["财星无根", "身弱财旺", "财被克破"],
"interpretation": "容易守不住财,花钱大手大脚。需要强制储蓄和专业理财。",
"advice": ["强制储蓄投资", "不要义气用事乱借钱", "请专业财务规划师"]
},
"财官太重": {
"category": "poverty",
"conditions": ["日主太弱", "财官并旺"],
"interpretation": "有才华但承载能力不足,容易眼高手低。",
"advice": ["专注一个领域深耕", "提升执行力", "不要什么机会都想抓"]
},
# 寿命法则
"性定元神厚": {
"category": "longevity",
"conditions": ["五行流转相生", "通根生旺", "有情有序"],
"interpretation": "命格和谐有情,适合长期主义战略。注重养生能享长寿。",
"advice": ["定期体检", "培养多元兴趣", "回馈社会做慈善"]
},
# 夭命法则
"气浊神枯": {
"category": "short_life",
"conditions": ["五行偏枯", "湿土晦火", "寒金无火"],
"interpretation": "健康和寿命需要特别注意,务必重视养生和预防。",
"advice": ["避开湿冷环境", "加强锻炼", "定期体检", "购买充足保险"]
}
}
# 性情章 - 五行性格法则
XINGQING_PRINCIPLES = {
"五行中和": {
"personality_type": "balanced",
"positive": ["情绪稳定", "待人真诚", "是团队润滑剂"],
"negative": ["可能缺少锋芒", "有时犹豫"],
"advice": ["保持平衡", "适时展现立场", "适合管理调解工作"]
},
"火炎土燥": {
"personality_type": "fire_intense",
"positive": ["热情洋溢", "感染力强", "行动力强"],
"negative": ["情绪波动大", "容易冲动", "喜怒无常"],
"advice": ["学习情绪管理", "做重大决定前冷静24小时", "避免财务等需要冷静的工作"]
},
"水奔性柔": {
"personality_type": "water_rushing",
"positive": ["聪明灵活", "适应力强", "善于变通"],
"negative": ["可能优柔寡断", "易受环境影响"],
"advice": ["培养定力", "坚持目标", "避免随波逐流"]
},
"木仁心软": {
"personality_type": "wood_soft",
"positive": ["仁慈善良", "有同情心", "乐于助人"],
"negative": ["可能过于心软", "易被利用"],
"advice": ["学会拒绝", "保护自己", "分清善恶"]
},
"金刚正义": {
"personality_type": "metal_rigid",
"positive": ["正直果断", "有原则", "执行力强"],
"negative": ["可能过于刚硬", "不够圆融"],
"advice": ["学习柔性处理", "考虑他人感受", "适度妥协"]
},
"土厚信重": {
"personality_type": "earth_stable",
"positive": ["稳重可靠", "诚实守信", "踏实肯干"],
"negative": ["可能过于保守", "缺乏变通"],
"advice": ["接受新事物", "适度冒险", "培养创新思维"]
}
}
# 女命章 - 婚姻子女法则
FEMALE_PRINCIPLES = {
"夫星得用": {
"category": "marriage_good",
"conditions": ["官星清透", "财生官旺", "印护夫星"],
"interpretation": "传统象意更强调伴侣关系中的协作与共同目标;它不证明配偶的职业、财富或婚姻结果。",
"advice": ["把期待说清楚", "支持彼此但保持自我", "共同决策、平等相处"]
},
"伤官见官": {
"category": "marriage_bad",
"conditions": ["伤官旺盛", "官星受克", "多合多冲"],
"interpretation": "传统象意提示沟通、边界与权责更容易出现张力;它不等于必然分手或婚姻失败。",
"advice": ["把分歧具体化", "先冷静再讨论", "为关系保留共同规则"]
},
"食神吐秀": {
"category": "children_good",
"conditions": ["食神有力", "子女宫吉"],
"interpretation": "传统象意更适合读作照护、教养与创造性亲子互动的资源;它不能证明子女数量、健康或成就。",
"advice": ["重视稳定陪伴", "培养彼此独立性", "不过度替对方做决定"]
},
"子女宫受克": {
"category": "children_bad",
"conditions": ["时柱受冲克", "食伤被制"],
"interpretation": "传统象意提示亲子角色、照护边界或家庭节奏需要更多沟通与支持;不能据此推断生育能力或是否生育。",
"advice": ["提前讨论照护边界", "需要时寻求专业支持", "把精力投入可验证的家庭安排"]
}
}
# ==================== 匹配器类 ====================
@dataclass
class MatchResult:
"""匹配结果"""
principle_key: str
principle_data: Dict
match_score: float
matched_conditions: List[str]
category: str
class CaseMatcher:
"""滴天髓案例匹配器"""
def __init__(self, bazi_data: Dict, wuxing: Dict, shishen: Dict, patterns: List[str], gender: str = "male"):
"""
初始化匹配器
Args:
bazi_data: 八字数据 {year, month, day, hour}
wuxing: 五行分布 {木, 火, 土, 金, 水}
shishen: 十神配置
patterns: 识别出的格局列表
gender: 性别 male/female
"""
self.bazi = bazi_data
self.wuxing = wuxing
self.shishen = shishen
self.patterns = patterns
self.gender = gender
self.day_master = bazi_data.get('day', {}).get('gan', '')
def _get_wuxing_characteristics(self) -> Dict[str, Any]:
"""分析五行特征"""
total = sum(self.wuxing.values()) if self.wuxing else 1
distribution = {k: v/total for k, v in self.wuxing.items()} if self.wuxing else {}
# 判断五行偏枯
max_element = max(distribution.items(), key=lambda x: x[1])[0] if distribution else None
min_element = min(distribution.items(), key=lambda x: x[1])[0] if distribution else None
is_balanced = all(0.15 <= v <= 0.25 for v in distribution.values()) if distribution else False
is_extreme = any(v >= 0.4 for v in distribution.values()) if distribution else False
return {
"distribution": distribution,
"dominant": max_element,
"weakest": min_element,
"is_balanced": is_balanced,
"is_extreme": is_extreme
}
def _check_condition_match(self, conditions: List[str]) -> Tuple[float, List[str]]:
"""检查条件匹配度"""
matched = []
total = len(conditions)
for condition in conditions:
# 检查五行相关条件
if "旺" in condition:
element = condition.replace("旺", "").replace("身", "")
if element in self.wuxing and self.wuxing.get(element, 0) >= 3:
matched.append(condition)
elif "弱" in condition:
element = condition.replace("弱", "").replace("日主", "")
if element in self.wuxing and self.wuxing.get(element, 0) <= 1:
matched.append(condition)
# 检查十神相关条件
if any(ss in condition for ss in ["食神", "财星", "官星", "印绶", "比劫", "伤官", "七杀"]):
for ss in ["食神", "财星", "官星", "印绶", "比劫", "伤官", "七杀"]:
if ss in condition:
if ss in str(self.shishen):
matched.append(condition)
break
# 检查格局相关条件
for pattern in self.patterns:
if pattern in condition or condition in pattern:
matched.append(condition)
break
score = len(matched) / total if total > 0 else 0
return score, matched
def match_wealth_nobility(self) -> List[MatchResult]:
"""匹配何知章法则(富贵贫贱寿夭)"""
results = []
for key, principle in HEZHI_PRINCIPLES.items():
score, matched = self._check_condition_match(principle.get("conditions", []))
if score > 0:
results.append(MatchResult(
principle_key=key,
principle_data=principle,
match_score=score,
matched_conditions=matched,
category=principle.get("category", "")
))
# 按匹配度排序
results.sort(key=lambda x: x.match_score, reverse=True)
return results[:3] # 返回前3个最匹配的
def match_personality(self) -> List[MatchResult]:
"""匹配性情章法则(五行性格)"""
results = []
wuxing_chars = self._get_wuxing_characteristics()
for key, principle in XINGQING_PRINCIPLES.items():
score = 0.0
matched = []
# 五行中和
if key == "五行中和" and wuxing_chars["is_balanced"]:
score = 0.9
matched.append("五行分布均衡")
# 火炎土燥
elif key == "火炎土燥":
fire_ratio = wuxing_chars["distribution"].get("火", 0)
earth_ratio = wuxing_chars["distribution"].get("土", 0)
if fire_ratio >= 0.3 or (fire_ratio >= 0.2 and earth_ratio >= 0.25):
score = fire_ratio + earth_ratio * 0.5
matched.append("火土偏旺")
# 水奔性柔
elif key == "水奔性柔":
water_ratio = wuxing_chars["distribution"].get("水", 0)
if water_ratio >= 0.3:
score = water_ratio
matched.append("水旺")
# 木仁心软
elif key == "木仁心软":
wood_ratio = wuxing_chars["distribution"].get("木", 0)
if wood_ratio >= 0.3:
score = wood_ratio
matched.append("木旺")
# 金刚正义
elif key == "金刚正义":
metal_ratio = wuxing_chars["distribution"].get("金", 0)
if metal_ratio >= 0.3:
score = metal_ratio
matched.append("金旺")
# 土厚信重
elif key == "土厚信重":
earth_ratio = wuxing_chars["distribution"].get("土", 0)
if earth_ratio >= 0.3:
score = earth_ratio
matched.append("土旺")
if score > 0:
results.append(MatchResult(
principle_key=key,
principle_data=principle,
match_score=score,
matched_conditions=matched,
category="personality"
))
results.sort(key=lambda x: x.match_score, reverse=True)
return results[:2]
def match_female_destiny(self) -> List[MatchResult]:
"""匹配女命章法则(婚姻子女)"""
if self.gender != "female":
return []
results = []
for key, principle in FEMALE_PRINCIPLES.items():
score, matched = self._check_condition_match(principle.get("conditions", []))
if score > 0:
results.append(MatchResult(
principle_key=key,
principle_data=principle,
match_score=score,
matched_conditions=matched,
category=principle.get("category", "")
))
results.sort(key=lambda x: x.match_score, reverse=True)
return results[:2]
def get_comprehensive_insights(self) -> Dict[str, Any]:
"""获取综合洞察"""
insights = {
"wealth_nobility": [],
"personality": [],
"female_destiny": [],
"key_advice": [],
"life_principles": []
}
# 匹配何知章
wealth_results = self.match_wealth_nobility()
for result in wealth_results:
insights["wealth_nobility"].append({
"principle": result.principle_key,
"interpretation": result.principle_data.get("interpretation", ""),
"advice": result.principle_data.get("advice", []),
"match_score": result.match_score
})
insights["key_advice"].extend(result.principle_data.get("advice", [])[:2])
# 匹配性情章
personality_results = self.match_personality()
for result in personality_results:
insights["personality"].append({
"type": result.principle_key,
"positive": result.principle_data.get("positive", []),
"negative": result.principle_data.get("negative", []),
"advice": result.principle_data.get("advice", [])
})
insights["key_advice"].extend(result.principle_data.get("advice", [])[:1])
# 匹配女命章
if self.gender == "female":
female_results = self.match_female_destiny()
for result in female_results:
insights["female_destiny"].append({
"principle": result.principle_key,
"interpretation": result.principle_data.get("interpretation", ""),
"advice": result.principle_data.get("advice", [])
})
insights["key_advice"].extend(result.principle_data.get("advice", [])[:1])
# 去重建议
insights["key_advice"] = list(dict.fromkeys(insights["key_advice"]))[:8]
return insights
# ==================== 辅助函数 ====================
def generate_case_enhanced_interpretation(
bazi_data: Dict,
wuxing: Dict,
shishen: Dict,
patterns: List[str],
gender: str = "male"
) -> str:
"""
生成案例增强的解读
这个函数整合经典案例的智慧,生成现代化的实用建议。
不会引用"历史上有人...",而是直接给出洞察和建议。
"""
matcher = CaseMatcher(bazi_data, wuxing, shishen, patterns, gender)
insights = matcher.get_comprehensive_insights()
interpretation_parts = []
# 财运贵气洞察
if insights["wealth_nobility"]:
best_match = insights["wealth_nobility"][0]
interpretation_parts.append(f"【{best_match['principle']}】\n{best_match['interpretation']}")
# 性格洞察
if insights["personality"]:
personality = insights["personality"][0]
positive_str = "、".join(personality["positive"][:3])
negative_str = "、".join(personality["negative"][:2])
interpretation_parts.append(
f"【性格特质:{personality['type']}】\n"
f"优势:{positive_str}\n"
f"注意:{negative_str}"
)
# 女命专属洞察
if insights["female_destiny"]:
female = insights["female_destiny"][0]
interpretation_parts.append(f"【婚姻事业】\n{female['interpretation']}")
# 核心建议
if insights["key_advice"]:
advice_str = "\n".join([f"• {a}" for a in insights["key_advice"][:5]])
interpretation_parts.append(f"【核心建议】\n{advice_str}")
return "\n\n".join(interpretation_parts)
if __name__ == "__main__":
# 测试示例
test_bazi = {
"year": {"gan": "甲", "zhi": "子"},
"month": {"gan": "丙", "zhi": "寅"},
"day": {"gan": "戊", "zhi": "寅"},
"hour": {"gan": "己", "zhi": "未"}
}
test_wuxing = {"木": 4, "火": 2, "土": 3, "金": 1, "水": 2}
test_shishen = {"食神": 2, "偏财": 1, "正印": 1}
test_patterns = ["食神生财", "身旺"]
result = generate_case_enhanced_interpretation(
test_bazi, test_wuxing, test_shishen, test_patterns, "male"
)
print("=" * 50)
print("案例增强解读:")
print("=" * 50)
print(result)