使用指南

知识包

解读文本与门派属性怎么与内核分开、内嵌默认包里有什么、怎么写覆盖包、三语言怎么读。

适合:要在排盘结果之上给出文字解读的人

排完盘拿到的是事实:命宫在午、武曲在财帛且化权、这张盘成了府相朝垣。 接下来要回答的「武曲是什么意思」「府相朝垣好在哪里」不是事实,是观点—— 不同门派、不同书、不同老师给的答案不一样。

x-iztro 把这两件事分开:内核只做事实判定(排盘、运限、格局), 解读文本与星耀的门派属性放在知识包里。知识包是一份 JSON, 协议是「语言无关标识 → 文本与属性」。库里内嵌一份默认包,开箱即用; 不认同其中的说法,写一份覆盖包逐条改掉。包是 to_text 家族的参数:传给 带释义的文本,释义就按盘取材内联在事实旁—— 每宫事实后跟该宫星耀释义,格局列表后跟格局释义,文末附四化释义。

内核与知识包的分工

内核知识包
内容十二宫、星耀落宫、亮度、四化、运限、格局命中星耀解读、格局解读、宫位与四化含义、术语、星耀的门派属性
性质事实,可与 iztro 逐字段对照观点,换一家说法就换一份
出错的样子盘排错了解读你不认同
怎么改不能改(改了就不是这套算法)换包或写覆盖包

两边的接缝就是语言无关标识:星耀用 ziweiMaj、格局用 zi_fu_tong_gong、 宫位用 soulPalace、四化用 sihuaLu。内核输出的每个字段都带这些标识 (见标识体系),拿它去知识包里取文本即可, 不必匹配译名,也不受盘面语言影响。

内嵌的默认包里有什么

段条目数内容
stars162主星 14、辅星 14、杂耀 38、神煞 46、流耀 50——全部 StarKey 都有条目。主辅杂神各带卡片属性(阴阳、五行、斗分、化气、职业、职务、别号、五行色、能量色)与特性正文;14 颗主星另有与其他主星的双星组合解读;流耀条目(category: "flow")是指向对应本命辅星的对照性条目,机器可读对照表由 flow_star_counterparts(Go FlowStarCounterparts)提供
patterns64每条带古籍引文、成立条件的文字描述与解读正文
palaces12十二宫各自的含义
mutagens4禄权科忌各自的含义
concepts49术语与基础概念(同宫、本宫、身宫、地支六合、三方四正、飞星四化…)

内容取自 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, 四化用四化标识。

按盘取材

整包 162 颗星、64 条格局,一张盘用不到这么多。for_astrolabe 从包里裁出只含这张盘的子包, for_horoscope 在此之上再加运限层的材料:

段for_astrolabefor_horoscope 另加
stars十二宫上出现的星:主星、辅星、杂耀与四组十二神;14 主星的 combinations 只保留对方主星确在同宫的那些各层流耀
patterns按格局口径命中的格局大限到流时各层视角命中的格局
mutagens禄权科忌四条,与盘无关—
palaces / concepts空——宫位与术语与盘无关,按需从整包直接查—

格局口径可选传:Rust 走 for_astrolabe_with(&chart, &PatternConfig) / for_horoscope_with(&chart, &h, &PatternConfig)(不带 _with 的两个即默认口径), Python 是 config= 关键字,Go 是第二个参数 *PatternConfig(nil 即默认)。 子包要和 patterns / patterns_to_text 配同一口径:口径不同,命中集合不同,释义就会缺项或多项。 Go 另有 BuiltinKnowledge().ForAstrolabe(chart, nil) 这条路,让内核直接读内嵌包,不必先取整包再送回。

返回的仍是标准知识包(元信息沿用本包),可以继续合并、序列化、按 key 查, 或者反过来作为 to_text 的释义参数。2000-8-16 寅时 女这张盘从默认包取出的子包: 本命 108 星 / 1 格局 / 4 四化,序列化约 75 KB(整包约 219 KB); 2025-1-1 的运限再加流耀与各层格局,158 星 / 16 格局。

let pack = KnowledgePack::builtin(Language::ZhCN).unwrap();
let sub = pack.for_astrolabe(&chart);
println!("{} {} {} {}", sub.stars.len(), sub.patterns.len(), sub.mutagens.len(), sub.palaces.len());

let h = chart.horoscope("2025-1-1", 0)?;
let sub = pack.for_horoscope(&chart, h.data());
println!("{} {}", sub.stars.len(), sub.patterns.len());

三侧输出一致:108 1 4 0 与 158 16(Python 第一行的后两项是 True None)。 带释义的 to_text 按同一套规则取材:子包里有的星与格局,文本里就有对应的释义条目 (十二神除外——子包收录它们,to_text 不为它们写释义)。

写一份覆盖包

覆盖包是同样格式的 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 的 starsInfoiztro-docs 卡片
贪狼水甲木(气为水)
巨门阴土癸水、己土(藏金、木)

同一位作者的两处数据都不一致,说明这类属性是门派说法而非唯一答案。 所以 x-iztro 的核心 StarInfo 保持与 iztro 逐值一致(迁移过来的代码不会变行为), 卡片上那套属性放进知识包,想换就换。

之后

同一套协议之上还能做覆盖包的加载与分发——这属于应用层的事,不在库里。

API 参考

来源与署名

默认包的全部文本取自 iztro-docs 的《学习》各页, MIT License,作者 Sylar Long。知识包协议、默认包文本的整理改写与三语言 API 是 x-iztro 的实现。

本页目录