# 知识包 (/zh/docs/guide/guides/knowledge-pack)

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



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

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

x-iztro 把这两件事分开：内核只做事实判定（排盘、运限、格局），
解读文本与星耀的门派属性放在**知识包**里。知识包是一份 JSON，
协议是「语言无关标识 → 文本与属性」。库里内嵌一份默认包，开箱即用；
不认同其中的说法，写一份覆盖包逐条改掉。

## 内核与知识包的分工 [#内核与知识包的分工]

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

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

## 内嵌的默认包里有什么 [#内嵌的默认包里有什么]

| 段          | 条目数 | 内容                                                                                                                                                                                                                         |
| ---------- | --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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](https://github.com/SylarLong/iztro-docs) 的《学习》各页
（MIT License，作者 Sylar Long），锁定来源 commit（`source.commit`），文本经 x-iztro 整理改写为第三人称释义口吻（`source.adapted` 注明），
包的 `source` 段完整记录来源、commit、许可与作者。文本字段是 Markdown。

<Callout type="warn" title="默认包目前只有 zh-CN">
  其他五种语言没有内嵌默认包：Rust 的 `KnowledgePack::builtin` 返回 `None`，
  Python 与 Go 报 `invalid_argument`。要别的语言，自己写一份包，
  或者把中文条目连同盘一起交给大模型，让它边译边解读。
</Callout>

<Callout type="info">
  默认包让 Go 侧内嵌的 wasm 增大了约 380 KB。Rust 与 Python 侧同样内嵌这份数据。
</Callout>

## 包长什么样 [#包长什么样]

权威格式规范（字段表、标识值域、合并算法、校验与版本兼容、覆盖包完整示例）见仓库的 [`knowledge/SCHEMA.md`](https://github.com/x-haose/x-iztro/blob/main/knowledge/SCHEMA.md)。
所有条目与字段都可选——缺什么就是没写：

```json
{
  "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": "指星曜在同一个宫位里面……" } }
}
```

## 读一份包 [#读一份包]

<Tabs items="['Rust', 'Python', 'Go']">
  <Tab value="Rust">
    ```rust
    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}");
    ```

    ```text
    Some("紫微") Some(["帝王星", "老板星", "俸禄星"])
    紫微星号称 `帝王星`，
    ```
  </Tab>

  <Tab value="Python">
    ```python
    from x_iztro import KnowledgePack
    from x_iztro.enums import MajorStar

    pack = KnowledgePack.builtin()
    ziwei = pack.star(MajorStar.ZIWEI)

    print(ziwei.name, ziwei.attributes.aliases)
    print(pack.star_intro(MajorStar.ZIWEI)[:12])
    ```

    ```text
    紫微 ['帝王星', '老板星', '俸禄星']
    紫微星号称 `帝王星`，
    ```
  </Tab>

  <Tab value="Go">
    ```go
    pack, err := iztro.BuiltinKnowledgePack(iztro.LanguageZhCN)
    if err != nil {
        log.Fatal(err)
    }
    ziwei := pack.Star(iztro.StarZiweiMaj)

    fmt.Println(ziwei.Name, ziwei.Attributes.Aliases)
    fmt.Println(string([]rune(pack.StarIntro(iztro.StarZiweiMaj))[:12]))
    ```

    ```text
    紫微 [帝王星 老板星 俸禄星]
    紫微星号称 `帝王星`，
    ```
  </Tab>
</Tabs>

查不到的键统一返回空：Rust / Python 是 `None`，Go 是 `nil`（`StarIntro` 为空串）。

## 和格局结果搭配 [#和格局结果搭配]

格局命中的 `key` 就是知识包 `patterns` 段的键，一一对上：

<Tabs items="['Rust', 'Python', 'Go']">
  <Tab value="Rust">
    ```rust
    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);
    }
    ```

    ```text
    府相朝垣 | Some("府相朝垣命必荣")
    ```
  </Tab>

  <Tab value="Python">
    ```python
    pack = KnowledgePack.builtin()
    chart = Astro().by_solar("2000-8-16", 2, "female")

    for hit in chart.patterns():
        entry = pack.pattern(hit.key)
        print(hit.name, "|", entry.quotes[0])
    ```

    ```text
    府相朝垣 | 府相朝垣命必荣
    ```
  </Tab>

  <Tab value="Go">
    ```go
    pack, _ := iztro.BuiltinKnowledgePack(iztro.LanguageZhCN)
    chart, _ := iztro.BySolar("2000-8-16", 2, iztro.GenderFemale, true, iztro.LanguageZhCN, nil)
    hits, _ := chart.Patterns(nil)

    for _, hit := range hits {
        entry := pack.Pattern(hit.Key)
        fmt.Println(hit.Name, "|", entry.Quotes[0])
    }
    ```

    ```text
    府相朝垣 | 府相朝垣命必荣
    ```
  </Tab>
</Tabs>

星耀同理：盘上每颗星的 `key` 直接拿去 `pack.star(key)`，宫位用 `palaceNameKey`，
四化用四化标识。

## 写一份覆盖包 [#写一份覆盖包]

覆盖包是同样格式的 JSON，只写要改的条目与字段，`extends` 记被覆盖包的 `id`。
下面这份改掉紫微的解读与别号、换掉紫府同宫的解读，其余原样保留：

```json
{
  "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": "紫府同宫，我只把它当作起点高，不当作福厚。" }
  }
}
```

合并出一份新包：

<Tabs items="['Rust', 'Python', 'Go']">
  <Tab value="Rust">
    ```rust
    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));
    ```
  </Tab>

  <Tab value="Python">
    ```python
    base = KnowledgePack.builtin()
    overlay = KnowledgePack.from_json(open("my-school.json", encoding="utf-8").read())
    pack = base.merged(overlay)

    ziwei = pack.star(MajorStar.ZIWEI)
    print(ziwei.name, ziwei.attributes.aliases, ziwei.attributes.chemistry)
    print(pack.pattern_intro(PatternKey.ZI_FU_TONG_GONG))
    ```
  </Tab>

  <Tab value="Go">
    ```go
    base, _ := iztro.BuiltinKnowledgePack(iztro.LanguageZhCN)
    data, _ := os.ReadFile("my-school.json")
    overlay, err := iztro.ParseKnowledgePack(data)
    if err != nil {
        log.Fatal(err)
    }
    pack, err := base.Merged(overlay)
    if err != nil {
        log.Fatal(err)
    }

    ziwei := pack.Star(iztro.StarZiweiMaj)
    fmt.Println(ziwei.Name, ziwei.Attributes.Aliases, ziwei.Attributes.Chemistry)
    fmt.Println(pack.PatternIntro(iztro.PatternZiFuTongGong))
    ```
  </Tab>
</Tabs>

三侧输出一致：紫微的 `name`（紫微）与 `chemistry`（尊贵）保留，`intro` 与 `aliases` 换成覆盖包的；
紫府同宫的 `intro` 换掉，`quotes` 与 `conditions` 保留。

<Callout type="info">
  合并只在 Rust 内核实现了一处，Python 与 Go 的 `merged` / `Merged` 都是调进内核算的，
  所以三侧的合并结果逐字节一致，不会各写各的规则。
</Callout>

## 合并规则 [#合并规则]

以底包为底，逐段（`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 参考 [#api-参考]

* [Rust — knowledge](/zh/docs/rust/knowledge)
* [Python — knowledge](/zh/docs/python/knowledge)
* [Go — KnowledgePack](/zh/docs/go/knowledge)

## 来源与署名 [#来源与署名]

默认包的全部文本取自 [iztro-docs](https://github.com/SylarLong/iztro-docs) 的《学习》各页，
MIT License，作者 Sylar Long。知识包协议、默认包文本的整理改写与三语言 API 是 x-iztro 的实现。
