知识包
解读文本与门派属性怎么与内核分开、内嵌默认包里有什么、怎么写覆盖包、三语言怎么读。
适合:要在排盘结果之上给出文字解读的人
排完盘拿到的是事实:命宫在午、武曲在财帛且化权、这张盘成了府相朝垣。 接下来要回答的「武曲是什么意思」「府相朝垣好在哪里」不是事实,是观点—— 不同门派、不同书、不同老师给的答案不一样。
x-iztro 把这两件事分开:内核只做事实判定(排盘、运限、格局), 解读文本与星耀的门派属性放在知识包里。知识包是一份 JSON, 协议是「语言无关标识 → 文本与属性」。库里内嵌一份默认包,开箱即用; 不认同其中的说法,写一份覆盖包逐条改掉。
内核与知识包的分工
| 内核 | 知识包 | |
|---|---|---|
| 内容 | 十二宫、星耀落宫、亮度、四化、运限、格局命中 | 星耀解读、格局解读、宫位与四化含义、术语、星耀的门派属性 |
| 性质 | 事实,可与 iztro 逐字段对照 | 观点,换一家说法就换一份 |
| 出错的样子 | 盘排错了 | 解读你不认同 |
| 怎么改 | 不能改(改了就不是这套算法) | 换包或写覆盖包 |
两边的接缝就是语言无关标识:星耀用 ziweiMaj、格局用 zi_fu_tong_gong、
宫位用 soulPalace、四化用 sihuaLu。内核输出的每个字段都带这些标识
(见标识体系),拿它去知识包里取文本即可,
不必匹配译名,也不受盘面语言影响。
内嵌的默认包里有什么
| 段 | 条目数 | 内容 |
|---|---|---|
stars | 162 | 主星 14、辅星 14、杂耀 38、神煞 46、流耀 50——全部 StarKey 都有条目。主辅杂神各带卡片属性(阴阳、五行、斗分、化气、职业、职务、别号、五行色、能量色)与特性正文;14 颗主星另有与其他主星的双星组合解读;流耀条目(category: "flow")是指向对应本命辅星的对照性条目,机器可读对照表由 flow_star_counterparts(Go FlowStarCounterparts)提供 |
patterns | 64 | 每条带古籍引文、成立条件的文字描述与解读正文 |
palaces | 12 | 十二宫各自的含义 |
mutagens | 4 | 禄权科忌各自的含义 |
concepts | 49 | 术语与基础概念(同宫、本宫、身宫、地支六合、三方四正、飞星四化…) |
内容取自 iztro-docs 的《学习》各页
(MIT License,作者 Sylar Long),锁定来源 commit(source.commit),文本经 x-iztro 整理改写为第三人称释义口吻(source.adapted 注明),
包的 source 段完整记录来源、commit、许可与作者。文本字段是 Markdown。
默认包目前只有 zh-CN
其他五种语言没有内嵌默认包:Rust 的 KnowledgePack::builtin 返回 None,
Python 与 Go 报 invalid_argument。要别的语言,自己写一份包,
或者把中文条目连同盘一起交给大模型,让它边译边解读。
默认包让 Go 侧内嵌的 wasm 增大了约 380 KB。Rust 与 Python 侧同样内嵌这份数据。
包长什么样
权威格式规范(字段表、标识值域、合并算法、校验与版本兼容、覆盖包完整示例)见仓库的 knowledge/SCHEMA.md。
所有条目与字段都可选——缺什么就是没写:
{
"schema": 1,
"id": "iztro-docs",
"version": "2026-08-19+ec2d58b",
"language": "zh-CN",
"extends": null,
"source": {
"name": "iztro-docs",
"url": "https://github.com/SylarLong/iztro-docs",
"commit": "ec2d58bb8b2a0d243d91212a1e3c87ab866858ee",
"license": "MIT",
"author": "Sylar Long",
"retrievedAt": "2026-08-19",
"adapted": "文本由 x-iztro 在 iztro-docs 原文基础上整理改写为第三人称释义口吻……"
},
"stars": {
"ziweiMaj": {
"name": "紫微",
"category": "major",
"group": null,
"attributes": {
"yinYang": "yin",
"fiveElements": "earth",
"stem": "ji",
"dipper": "中天星系",
"chemistry": "尊贵",
"career": "官禄主",
"duty": "众星枢纽,长五行,孕万物",
"aliases": ["帝王星", "老板星", "俸禄星"],
"elementColor": "黄色",
"energyColor": "紫光"
},
"intro": "紫微星号称 `帝王星`,并非指紫微坐命者能成帝王……",
"combinations": { "tianfuMaj": "紫微星和 `天府星` 都是帝星……" }
}
},
"patterns": {
"zi_fu_tong_gong": {
"name": "紫府同宫",
"quotes": ["紫府同宫终身福厚。"],
"conditions": "指紫微星和天府星同宫,这两颗星只会在寅宫和申宫同宫;其组合特质与紫微天府星曜组合一致。",
"intro": "“终身福厚”并非定数,但紫府同宫格的人一定无法接受平凡的人生……"
}
},
"palaces": { "soulPalace": { "name": "命宫", "intro": "命宫是决定星盘主人属性的宫位……" } },
"mutagens": { "sihuaLu": { "name": "化禄", "intro": "**五行**:土;**意象**:开心、忙碌、增加、包容、多\n\n化禄星简称 `禄`,是一种 `增加` 的力量……" } },
"concepts": { "tong-gong": { "title": "遇、加、逢、同宫、同度", "intro": "指星曜在同一个宫位里面……" } }
}读一份包
use x_iztro::{KnowledgePack, Language, StarKey};
let pack = KnowledgePack::builtin(Language::ZhCN).expect("zh-CN 有默认包");
let ziwei = pack.star(StarKey::ZiweiMaj).unwrap();
println!("{:?} {:?}", ziwei.name, ziwei.attributes.aliases);
let head: String = pack.star_intro(StarKey::ZiweiMaj).unwrap().chars().take(12).collect();
println!("{head}");Some("紫微") Some(["帝王星", "老板星", "俸禄星"])
紫微星号称 `帝王星`,查不到的键统一返回空:Rust / Python 是 None,Go 是 nil(StarIntro 为空串)。
和格局结果搭配
格局命中的 key 就是知识包 patterns 段的键,一一对上:
let pack = KnowledgePack::builtin(Language::ZhCN).unwrap();
let chart = by_solar("2000-8-16", 2, Gender::Female, true, Language::ZhCN, Config::default())?;
for hit in chart.patterns() {
let entry = pack.pattern(hit.key).unwrap();
let quote = entry.quotes.as_ref().and_then(|q| q.first());
println!("{} | {:?}", translate_pattern(hit.key, Language::ZhCN), quote);
}府相朝垣 | Some("府相朝垣命必荣")星耀同理:盘上每颗星的 key 直接拿去 pack.star(key),宫位用 palaceNameKey,
四化用四化标识。
写一份覆盖包
覆盖包是同样格式的 JSON,只写要改的条目与字段,extends 记被覆盖包的 id。
下面这份改掉紫微的解读与别号、换掉紫府同宫的解读,其余原样保留:
{
"schema": 1,
"id": "my-school",
"version": "2026-08-19",
"language": "zh-CN",
"extends": "iztro-docs",
"stars": {
"ziweiMaj": {
"intro": "紫微在我这一派看来先看格局高低,再论性情。",
"attributes": { "aliases": ["帝座"] }
}
},
"patterns": {
"zi_fu_tong_gong": { "intro": "紫府同宫,我只把它当作起点高,不当作福厚。" }
}
}合并出一份新包:
let base = KnowledgePack::builtin(Language::ZhCN).unwrap();
let overlay = KnowledgePack::from_json(&std::fs::read_to_string("my-school.json")?)?;
let pack = base.merged(&[&overlay]);
let ziwei = pack.star(StarKey::ZiweiMaj).unwrap();
println!("{:?} {:?} {:?}", ziwei.name, ziwei.attributes.aliases, ziwei.attributes.chemistry);
println!("{:?}", pack.pattern_intro(PatternKey::ZiFuTongGong));三侧输出一致:紫微的 name(紫微)与 chemistry(尊贵)保留,intro 与 aliases 换成覆盖包的;
紫府同宫的 intro 换掉,quotes 与 conditions 保留。
合并只在 Rust 内核实现了一处,Python 与 Go 的 merged / Merged 都是调进内核算的,
所以三侧的合并结果逐字节一致,不会各写各的规则。
合并规则
以底包为底,逐段(stars / patterns / palaces / mutagens / concepts)按键合并:
- 覆盖包里出现的条目,其非 null 字段覆盖底包同键条目的对应字段,未出现的字段保留
attributes与combinations同样按字段 / 子键合并- 数组字段(
aliases、quotes)整体替换,不做逐项合并 - 底包没有的键直接新增
- 把某字段显式写成
null不会删除底包内容(缺省与 null 同义);要删除请整包替换 - 合并后的
id/version/language/source取覆盖包的(若非空),extends保留底包的
schema 高于本库支持的版本直接报错,不做降级解析。
为什么星耀的阴阳五行放在这里
星耀的五行看起来像事实,其实也是观点。iztro 自带的 starsInfo 表与
iztro-docs 星耀卡片本身就对不上:
| 星 | iztro 的 starsInfo | iztro-docs 卡片 |
|---|---|---|
| 贪狼 | 水 | 甲木(气为水) |
| 巨门 | 阴土 | 癸水、己土(藏金、木) |
同一位作者的两处数据都不一致,说明这类属性是门派说法而非唯一答案。
所以 x-iztro 的核心 StarInfo 保持与 iztro 逐值一致(迁移过来的代码不会变行为),
卡片上那套属性放进知识包,想换就换。
之后
同一套协议之上还能做覆盖包的加载与分发、以及把知识包连同盘一起交给大模型解读—— 这些属于应用层的事,不在库里。
API 参考
来源与署名
默认包的全部文本取自 iztro-docs 的《学习》各页, MIT License,作者 Sylar Long。知识包协议、默认包文本的整理改写与三语言 API 是 x-iztro 的实现。