Skip to content

Latest commit

 

History

67 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

年譜整理工具 / nianpu-processor

一鍵處理原始古籍刻本 OCR 後的中國年譜文本、或從識典古籍等下載的年譜文本,自動按年份切分、補全年號、整理段落。支援明清兩代及南明年號,並已擴展至公元年號/民國紀年的近現代年譜(民國以後),具備自我進化能力。

本工具旨在為中國歷史人物、思想史、哲學史、學術史研究搭建數字基礎文本——將結構混亂的年譜原始文本轉化為結構清晰、可由 AI Agent 自動識讀的 Markdown 格式,便於後續搭建 RAG 知識庫、進行大規模文本分析與哲學史、思想史、史學研究。

文檔分工(單源化):本 README 是唯一全文SKILL.md 只是 AI 智能體的入口頁(命令速查+自主執行策略+文檔地圖),不含易變事實,兩者無需同步維護。

🚀 快速上手 功能 · 安裝 · 快速開始

🧩 格式與原理 年份格式 · 處理流程 · 演算法 · 檢查報告

📚 成果與記錄 常見問題 · 已處理年譜 · 更新日誌

🧭 年譜擴展利用 年譜→人際網絡數據(延伸 skill)

測試報告

📋 年譜整理工具測試報告(v3.29) 40 部已歸檔年譜的覆蓋率(以人物生卒年為錨)、CBDB 生卒年核驗、三錨點一致性檢查、--fix 年號誤配自動修正與 L2 仲裁的完整實測結果。

📋 整理前後 RAG 檢索效果對比報告 以 6 部年譜(文貞公/殷譜經/王欣夫/李恕谷/袁觀瀾/陳紫峰)× 4 個年齡(25/35/45/55),用 BM25 模擬 RAG 檢索,量化「整理後按年分塊」對受限預算召回率(1,000 字預算 32.1%→85.0%、2,000 字→94.5%)的提升。

重跑測試流程(更新報告數據用):

# 以年譜資料目錄為參數,產出各年譜標題數/覆蓋率/遺漏/可疑/生卒年
python tools/nianpu_coverage.py <年譜資料目錄>        # JSON 寫入 docs/nianpu_report_data.json
python nianpu_processor.py --check <已整理.md> --cbdb <傳主名>   # 單部複查+CBDB 核驗
python tools/nianpu_rag_compare.py <年譜資料目錄> [年齡清單...]  # RAG 檢索效果對比(整理前 vs 整理後)

功能

切分與整理

  • 年份標題化八年己巳,先生年五十二### 八年己巳,先生年五十二
  • 年號補全與公元年標註 — 自動補上當前年號;標題干支後自動標 (YYYY年)
  • 月份/季節分段 — 每年內按 春/夏/秋/冬 拆分,以 **春正月** 標記
  • 嵌入式年份拆分 — 合併段落中二次掃描密集年份(八年戊子五歲。九年己丑六歲
  • 標點/斷句(LLM 驅動) — 已整理但無標點的正文,由 LLM 依 docs/標點規則.md 分塊加標點(nianpu_biaodian.py --chunk → LLM 逐塊 → --merge--verify 字符保全校驗)
  • 歸檔/整理本同步 — 定稿後複製到 年譜整理本/<書名>.md 並同步 _清單.md_清單.tsvnianpu_archive.py

格式彈性

  • 七大格式族自動預分類:有稱謂/無稱謂直接年齡/無年齡純年份/公元年號・民國/行首裸干支/現代學者整理本(已有標題),詳見「支援的年份格式」表

容錯與品質

  • OCR 容錯與字形正規化 — 自動修正常見誤讀(先元年→先生年)、統一異體年號(光緖→光緒
  • 檢查報告 — 處理後比對原文,報告遺漏年份、年齡空缺、年號切換
  • 三錨點一致性檢查+CBDB 核驗 — 年號年/干支/年齡交叉驗證;--cbdb 以生卒年為錨、--fix 自動修正年號誤配(CBDB 缺席時以內部「干支+年齡」共識出生年回退,拔外部依賴)

自我進化

  • 自動發現新年號/字形/前綴(含置信度與假陽性過濾);--record 錄入手動修正(干支形近字累積 OCR 候選規則,--status 檢視、人工複核後手動升級 _OCR_FIXES);--prune 清理無效記錄

工具腳本

  • RAG 對比tools/nianpu_rag_compare.py 量化「整理前 vs 整理後」檢索效果
  • 語義槽位模型--slots 以 LLM 推得的槽位 JSON 驅動新格式,不需改正則
  • L2 衝突仲裁nianpu_arbitrate.py 把三錨點打架的標題+上下文收集成仲裁請求,LLM 判定後保守套用(只動年號年序)並復驗
  • 標點助手nianpu_biaodian.py 分塊/合併/字符保全校驗(標點本身由 LLM 執行)
  • 歸檔助手nianpu_archive.py 複製定稿到整理本+更新 _清單.md_清單.tsv
  • 回歸測試tools/regression.py 改動腳本後驗證歷史成績不退化:testdata/ 九對「源+黃金輸出」、--selfcheck 由黃金輸出實測基線、--run 出 PASS/FAIL 表+自動生成 changelog 回歸行、--full 掃 E: 全庫、--update 刷新基線(詳見 docs/回歸測試.md
  • 數據提取(延伸) — 定稿 .md 交由 nianpu-social-network(hyperextract)按年抽出人際/社交網絡,生成統一 persons/relations TSV(見年譜擴展利用

安裝

# 下載(v3.37 起核心邏輯在 nianpu_core/ 包內,需整目錄,不能只抓單檔)
git clone https://github.com/<你的用戶名>/nianpu-processor.git
# 或:下載 nianpu_processor.py(薄門面)+ nianpu_core/ 整個目錄

# 直接執行(需要 Python 3.6+;命令與介面不變,仍是 nianpu_processor.py)
python nianpu_processor.py <輸入檔案> [輸出檔案]

以 Agent Skill 安裝(Claude Code / Cursor / Codex / OpenCode 等)

將此目錄放入任一 skill 目錄(如 ~/.claude/skills/nianpu-processor/.opencode/skills/ 等,隨 runtime 而定)後,支援 Agent Skills 標準的智能體會自動載入此 skill,直接用自然語言下達命令即可

/nianpu-processor <輸入檔案路徑> [輸出檔案路徑]        # 或直接說:「整理這個年譜」
「把《顧亭林先生年譜》整理成 Markdown」
「補全年號並標註公元年」
「用 CBDB 核驗傳主生卒年,並修正年號誤標」

不依賴特定 runtime:不採用該標準的環境可直接執行底層腳本(見上方「直接執行」)。

路徑配置(NIANPU_ROOT)

nianpu_archive.py 的預設整理本目錄與 tools/regression.py --full 的掃描根目錄,均由環境變數 NIANPU_ROOT 解析(未設定時為 E:/2022/个人研究资料/年谱项目,與原行為一致)。換機或資料搬家時設定一次即可:

set NIANPU_ROOT=D:/年譜項目            # Windows cmd(PowerShell:$env:NIANPU_ROOT="D:/年譜項目")
export NIANPU_ROOT=/home/user/nianpu   # Linux / macOS / Git Bash

快速開始

本工具設計為可供各種 AI 智能體(Claude Code、Cursor、Copilot 等)直接用自然語言調用——智能體讀取本文件與 SKILL.md 後,會自動解析意圖並執行底層 nianpu_processor.py,無需手動拼寫參數。例如:

「整理這個年譜文件」→ 自動切分年份標題、補全年號、標註公元年 「把《黃黎洲先生年譜》整理好」→ 指定檔案處理 「核驗傳主生卒年並修正年號誤標」→ 觸發 --cbdb--fix 「檢查已整理檔的可疑標題」→ 觸發 --check 「給已整理的年譜加標點」→ 觸發 nianpu_biaodian.py --chunk → LLM 逐塊標點 → --merge 「整理好後歸檔到年譜整理本」→ 觸發 nianpu_archive.py <定稿.md> --book <書名> --note <備註>

亦可在終端直接執行腳本:

# 處理年譜文件,輸出為「原檔名_已整理.md」
python nianpu_processor.py 涇舟老人洪琴西先生年譜_完整.md

# 指定輸出檔名
python nianpu_processor.py input.md output.md

# 語義槽位配置(v1 原型):LLM 依新年譜開頭推得槽位 JSON,直接套用,不需改正則
python nianpu_processor.py input.md output.md --slots slots.json

# 一鍵套用年號誤配修正(不需 --cbdb;CBDB 缺席時以內部「干支+年齡」共識出生年回退)
python nianpu_processor.py input.md output.md --fix

# 錄入手動修正;干支形近字(單字替換)累積為 OCR 候選規則(--status 可檢視)
python nianpu_processor.py --record "順治乙亥" "順治己亥" 陳紫峰先生年譜

# 查看自我進化學習狀態
python nianpu_processor.py --status

# 清理已標記為無效的學習
python nianpu_processor.py --prune

# 學習質檢閘門:pending 學習逐條「臨時套用→跑回歸→PASS 轉正」(v3.38)
python tools/regression.py --verify-learnings

# 回滾 learnings.json 至最近一次寫入前(.bak 單槽備份,每次覆寫前自動備份)
python nianpu_processor.py --revert

# —— 標點/斷句(LLM 驅動,先切分、後逐塊標點、再合併校驗)——
python nianpu_biaodian.py --chunk 袁观澜先生年谱_合并_已整理_merged.md   # 按年份塊切分 → pun_01.md…
#   → LLM 依 docs/標點規則.md 逐塊加標點(直接編輯 pun_XX.md)
python nianpu_biaodian.py --merge 袁观澜先生年谱_合并_已整理_merged.md  # 合併 → 定稿.md(自動 verify)
python nianpu_biaodian.py --verify 袁观澜先生年谱_合并_已整理_merged.md 定稿.md  # 重跑字符保全校驗

# —— L2 三錨點衝突仲裁(LLM 判定,標題打架且 --fix 無法判定時)——
python nianpu_arbitrate.py --request 陳紫峰先生年譜_已整理.md   # 收集衝突+上下文 → <名>_仲裁請求.md
#   → LLM 讀請求逐條判定(每行:{標題} → {修正後標題} 或 → 不改)
python nianpu_arbitrate.py --apply 陳紫峰先生年譜_已整理.md 仲裁結果.md  # 保守套用+復驗

# —— 歸檔/整理本同步(定稿後最後一步)——
python nianpu_archive.py 袁观澜先生年谱_合并_定稿.md --book 袁观澜先生年谱 --date 2026-08-10 --note "全文標點整理"

# —— 回歸測試(改動腳本後必跑;詳見 docs/回歸測試.md)——
python tools/regression.py --selfcheck      # 從黃金輸出實測基線
python tools/regression.py --run            # 重跑 testdata 九案例 vs 基線 → PASS/FAIL 表+回歸行+學習帳本報告(pending 摘要+verified 複驗)
python tools/regression.py --run --full     # 另掃 E: 識典數據 全庫
python tools/regression.py --run --update   # 人工審核後以本次結果刷新基線
python tools/regression.py --smoke          # 快速冒煙

輸入範例(原始年譜)

明萬厯四十七年己未,先生一歲九月初一日子時。
先生生〔家譜云:生萬厯己未九月初一日。〕
四十八年庚申,〔是歲八月,以後爲泰昌元年。〕先生二歲。
十二月初一日,武夷先生誕辰,是日極寒。
天啟元年辛酉,先生三歲。
是年武夷先生鄕試中副榜,赴京師國子監〔家世節錄云:...〕

輸出結果

### 明萬厯四十七年己未,先生一歲
九月初一日子時。
先生生〔家譜云:生萬厯己未九月初一日。〕

### 萬厯四十八年庚申,先生二歲
**冬**十二月初一日,武夷先生誕辰,是日極寒。

### 天啟元年辛酉,先生三歲
是年武夷先生鄕試中副榜,赴京師國子監〔家世節錄云:...〕

支援的年份格式

各格式按處理族歸類(對應「演算法」一節的 L1 格式預分類)。出生條目在各格式族下均啟用,用於年號播種。

格式 範例 年譜
1. 有稱謂(先生/公/府君/傳主名+N嵗)
先生年N嵗 八年己巳,先生年五十二 方柏堂先生譜系略
先生N歲(〔〕年齡註解) 十七年辛丑,〔是年先生五歲。〕始入小學 → 短註解展開為錨點:### 成化十七年辛丑(1481年),先生五歲(長註文如諱琛傳記保留) 陳紫峰先生年譜
公年N歲 十八年辛丑,公年十有一 張清恪公年譜
公N歲+雙欄合併殘留(預處理) 五年丙午公二歲六年 → 移「六年」至其干支前:五年丙午,公二歲。六年丁未,公三歲 朱文端公年譜(表格兩欄合併,殘留年份=下一年欄頭)
跨行年份+年齡 康熙十六年\n公七歲 沈端恪公年譜
跨行拆分年份 康熙\n五年\n丙午 → 康熙五年丙午(年號/N年/干支拆三行) 焦南浦先生年譜
前綴+年號 大淸順治元年,先生二十六歲 明清之際年譜
明代年號 明萬厯四十七年己未,先生一歲 明代年譜
傳主名前綴(人名+年N歲) 光緒元年乙亥希濤年十歲 / 中華民國元年希濤年四十七歲 袁觀瀾先生手編年譜
2. 無稱謂(直接附年齡,無先生/公/府君)
直接年齡 十九年甲戌七嵗 萬清軒先生年譜
年N嵗 二十三年癸卯,年二十六 方柏堂變體
無稱謂直接附年齡 十二年癸丑二歲 / 十年,壬子六十一歲 澄懷主人自訂年譜
年號+干支+「年」+N歲 光緖元年乙亥,年七十歳 殷譜經侍郎自定年譜
3. 出生條目(各格式族通用,年號播種)
出生條目 仁宗睿皇帝嘉慶十三年戊辰八月二十四日先生生 通用
出生日期(無生字) 明萬厯四十六年戊午十一月二十一日辰時 施愚山先生年譜
年月日前綴+生於 康熙十一年壬子,是年九月初九日辰時,生於京師 澄懷主人自訂年譜
出生日期+人名+生於 嘉慶十一年丙寅十月一日戌時。兆鏞生於… 殷譜經侍郎自定年譜
4. 近現代公元年/民國
公元年號/民國 公元一八七三年,同治十二年,岁次癸酉,一岁 / 公元一九五零年,岁次庚寅,七十八岁 項蘭生自訂年譜
民國年號 公元一九一二年,民國元年,岁次壬子,四十岁 / 公元一九四七年,民国卅六年,岁次丁亥,七十五岁 項蘭生自訂年譜
民國無干支年份 中華民國元年希濤年四十七歲(有年齡錨點、無干支) 袁觀瀾先生手編年譜
5. 無年齡(純年份)
無年齡純年份 紹興元年辛亥 / 四年甲寅 / 孝宗隆興元年癸未 / 光宗紹熙元年庚戍 紫陽文公先生年譜
6. 行首裸干支
行首裸干支 庚申、 / 己亥春入京 / 丁卯。公九歲 / 戊申在尚寶### 嘉靖十八年己亥(1539年)(依干支週期+當前年號推算年序) 重刻鄭端簡公年譜
7. 干支+直接年齡(裸干支緊接年齡,無年號)
干支+直接年齡 庚子二歲 / 乙酉年四十七歲 / 丙戌,年四十八歲 / 壬寅,康熙元年四歲### 順治十七年庚子(1660年)二歲(依出生年+年齡推算年號年序+公元年,含順治→康熙→雍正年號更替) 李恕谷先生年譜
8. 現代學者整理本(現代學者已編好年份標題,不重新匹配正文)
現代學者整理本 A(年號在前) #### 嘉慶十八年 癸酉 1813年 一岁(已有標題,檢查是否全+統一格式) 劉熙載年譜
現代學者整理本 B(公元在前) #### 一九二三年(民國十二年癸亥)二十三歲 王欣夫先生編年事輯稿
9. 純年齡(僅以年齡紀年,無年號/干支錨點)
純年齡(行首/句末 N歲) 三歲,… / 二十歲嘗曰… / 五十九歲夏六月…### 洪武十一年戊午(1378年)三歲(出生條目為唯一紀年錨點,依虛歲「出生年+年齡-1」推年號年序+公元年,含洪武→建文→永樂→洪熙→宣德更替) 曹月川先生年譜

註:表中 9 組族類中,「出生條目」(第 3 組)是各族通用的子類,只用於年號播種,並非獨立格式族;故 L1 格式預分類只偵測 8 個獨立格式族(見「演算法」一節)。

公元年標註

處理完成後,會在所有含年號+年序的標題干支後自動標註公元年:

### 嘉慶十一年丙寅(1806年)十月一日戌時
### 道光三十年庚戌(1850年)四十五歲
### 光緒元年乙亥(1875年),年七十歳

換算方式:公元年 = 年號元年公元 + 年序 - 1(如 咸豐八年 = 1851 + 8 - 1 = 1858)。

年號與元年的對應表存在 REIGN_START_YEARS 配置(含異體字 萬厯/萬曆、光緖/光緒 等),涵蓋宋代、元代、明代(含南明)、清代、清末宣統、民國百餘個年號。年號不在表中、或標題只有干支無年序(如「丙申,公四十一嵗」)時,保持原樣不標註。

公元年號標題本身也會標註阿拉伯數字### 公元一八七三年(1873年),同治十二年,岁次癸酉,一岁(依中文數字逐位轉換,如 一八七三=1873、一九五零=1950)。

支援的年號

時代 年號
宋代 建隆、乾德、開寶、太平興國、雍熙、端拱、淳化、至道、咸平、景德、大中祥符、天禧、乾興、天聖、明道、景祐、寶元、康定、慶曆、皇祐、至和、嘉祐、治平、熙寧、元豐、元祐、紹聖、元符、建中靖國、崇寧、大觀、政和、重和、宣和、靖康、建炎、紹興、隆興、乾道、淳熙、紹熙、慶元、嘉泰、開禧、嘉定、寶慶、紹定、端平、嘉熙、淳祐、寶祐、開慶、景定、咸淳、德祐、景炎、祥興
元代 中統、至元、元貞、大德、至大、皇慶、延祐、至治、泰定、致和、天曆、至順、元統、至正
明代 洪武、建文、永樂、洪熙、宣德、正統、景泰、天順、成化、弘治、正德、嘉靖、隆慶、萬厯、萬曆、萬厤、泰昌、天啟、崇禎
南明 隆武、永厯、永曆、宏光、弘光、紹武
清代 順治、康熙、雍正、乾隆、嘉慶、道光、咸豐、同治、光緖、光緒、光绪
清末宣統 宣統、宣统
民國 民國、民国

含完整皇帝廟號諡號前綴(世祖章皇帝、聖祖仁皇帝、仁宗睿皇帝、宣宗成皇帝等),以及「大淸」「大清」「明」等前綴。宋代皇帝前綴(宋高宗、孝宗、光宗、寧宗,朱熹年譜)亦已內建;未涵蓋的皇帝前綴(如「宋太祖」「元世祖」)可由自我進化系統自動發現;未涵蓋的年號(如遼、金、唐)也可由自我進化發現後自動加入。

(自我進化系統可自動發現並記錄新年號,經質檢閘門 --verify-learnings 回歸驗證轉正後、且 ≥2 次出現且置信度 ≥0.4,才會加入匹配列表。含 --prune 清理無效學習、--revert 回滾最近一次 learnings 寫入。)

處理流程

讀取檔案
  → 年號字形正規化(光緖→光緒)
  → OCR 錯誤修正(先元年→先生年)
  → 合併跨行年份+年齡(沈端恪格式支援)
  → 查找年份標記(前綴 + N年干支 + 先生N歲 / 直接N歲 / 澄懷主人無稱謂格式)
  → 插入 ### 標題
  → 追蹤並補全年號
  → 合併斷行(含跨年邊界檢測)
  → 嵌入式年份二次掃描(密集年份拆分)
  → 按月份/季節分段(**春正月**)
  → 輸出
  → 自動檢查報告
  → 自我進化學習
  → (選用)標點/斷句:nianpu_biaodian.py --chunk → LLM 逐塊加標點 → --merge → --verify 字符保全校驗
  → (最後一步)歸檔:nianpu_archive.py 複製到 年譜整理本/書名.md 並更新 _清單.md/_清單.tsv

檢查報告

處理完後自動輸出檢查報告,例如:

============================================================
年譜整理檢查報告
============================================================

原始年份+年齡組合:96 個
輸出 ### 標題:63 個
覆蓋率:65.6%
遺漏:7 個

── 以下年份條目未被切分 ──
  年齡 28歲→咸豐元年辛亥,
  ...

── 年齡空缺 ──
  缺 7-13 歲

── 年號切換記錄 ──
  年號切換:道光 → 咸豐
  年號切換:咸豐 → 同治
  年號切換:同治 → 光緒
============================================================

報告後會附加自我進化報告,顯示本次發現的新年號、字形變體及處理統計。

程式碼結構(nianpu_core 包)

v3.37 起,3338 行的單檔 nianpu_processor.py 機械拆分為 nianpu_core/ 包(13 個模塊,函數體逐字保留、行為零變化,A/B 對比+回歸 9/9 驗證);nianpu_processor.py 保留為薄門面(from nianpu_core import *),所有命令、參數、import nianpu_processor 用法完全不變。模塊依賴單向無循環:

constants ← base ← expand ← preprocess ← anchors ← fixes ← modern
                                  ← patterns ← segment/learnings ← verify ← process ← cli
模塊 職責
constants.py 資料表與常量:年號、干支、季節、字形修正、學習路徑
base.py 底層轉換與模式工具:中文數字↔整數、干支↔公元、年份模式、年號提取、稱謂偵測
expand.py 標題擴展:裸干支/干支+年齡/純年齡 標題 → 年號年序+公元年
preprocess.py 文本預處理:OCR 修正、年號字形歸一、跨行合併、嵌入式年份、去重補缺
anchors.py 標題錨點解析、出生年共識與三錨點一致性驗證
fixes.py 年號誤配自動修正(--fix)與 CBDB 生卒年核驗
modern.py 現代學者年譜(已有年份標題)支援:解析、格式統一、完整性檢查
patterns.py 格式族分類(classify_format)與全文匹配模式構建(_build_full_pattern
segment.py 年份內容按月份/季節分段
learnings.py 自我進化系統:新年號/前綴/字形發現、修正記錄、學習管理
verify.py 輸出核對:遺漏條目、年齡連續性、年號切換、三錨點報告
process.py 主管線:年份切分與標題化(process_nianpu)、公元年標註(annotate_ad_years
cli.py 命令列入口(main:處理/--check--fix--status--prune 等)

自訂配置

如需增加年號或調整年齡格式,修改 nianpu_core/constants.py(資料表集中於此):

# 含宋(建隆…祥興)、元(中統…至正)、明(洪武…崇禎)、南明、清(順治…光緒)
REIGNS = ['洪武', '建文', '永樂', '洪熙', '宣德', '正統', '景泰', '天順', '成化',
          '弘治', '正德', '嘉靖', '隆慶', '萬厯', '萬曆', '萬厤', '泰昌', '天啟', '崇禎',
          '隆武', '永厯', '永曆', '宏光', '弘光', '紹武',
          '中統', '至元', '元貞', '大德', '至大', '皇慶', '延祐', '至治', '泰定',
          '致和', '天曆', '至順', '元統', '至正',
          '建隆', '乾德', '開寶', '太平興國', '雍熙', '端拱', '淳化', '至道',
          '咸平', '景德', '大中祥符', '天禧', '乾興', '天聖', '明道', '景祐',
          '寶元', '康定', '慶曆', '皇祐', '至和', '嘉祐', '治平', '熙寧', '元豐',
          '元祐', '紹聖', '元符', '建中靖國', '崇寧', '大觀', '政和', '重和',
          '宣和', '靖康', '建炎', '紹興', '隆興', '乾道', '淳熙', '紹熙', '慶元',
          '嘉泰', '開禧', '嘉定', '寶慶', '紹定', '端平', '嘉熙', '淳祐', '寶祐',
          '開慶', '景定', '咸淳', '德祐', '景炎', '祥興',
          '順治', '康熙', '雍正', '乾隆', '嘉慶', '道光', '咸豐', '同治', '光緖', '光緒']

EMPEROR_PREFIXES = [
    ('世祖章皇帝','順治'),
    ('聖祖仁皇帝','康熙'),
    ('大淸',''),
    ('明',''),
    # ...
]

PERSON_PREFIXES = ['先生', '公', '府君']
AGE_SUFFIXES = '嵗歲歳𡻕'
AGE_SUFFIX_REQUIRED = '[' + AGE_SUFFIXES + ']'  # 無稱謂直接年齡格式:後綴必備,避免誤切「六月」等

# 年號元年→公元年(含異體字),用於標題標註公元年(可擴展,已含宋/元/明/清)
REIGN_START_YEARS = {
    '建隆': 960, '開寶': 968, '淳化': 990, '咸平': 998, '景德': 1004,
    '天禧': 1017, '天聖': 1023, '慶曆': 1041, '嘉祐': 1056, '熙寧': 1068,
    '元祐': 1086, '崇寧': 1102, '宣和': 1119, '靖康': 1126, '建炎': 1127,
    '紹興': 1131, '乾道': 1165, '淳熙': 1174, '嘉定': 1208, '咸淳': 1265,
    '至元': 1264, '至正': 1341,
    '洪武': 1368, '永樂': 1403, '嘉靖': 1522, '萬厯': 1573, '萬曆': 1573, '萬厤': 1573,
    '天啟': 1621, '崇禎': 1628,
    '隆武': 1645, '永厯': 1647, '永曆': 1647, '宏光': 1645, '弘光': 1645, '紹武': 1646,
    '順治': 1644, '康熙': 1662, '雍正': 1723, '乾隆': 1736, '嘉慶': 1796,
    '道光': 1821, '咸豐': 1851, '同治': 1862, '光緖': 1875, '光緒': 1875,
}

# OCR 容錯規則(可擴展)
_OCR_FIXES = [
    (r'先元年', '先生年'),
    (r'十年九', '十九'),
]

# 年號字形正規化(可擴展)
_REIGN_NORMALIZATIONS = {
    '光緖': '光緒',
    '萬厯': '萬曆',
    '萬厤': '萬曆',
    '永厯': '永曆',
}

演算法

預處理

年譜文字在切分前經過三層清理:

  • 年號字形正規化光緖→光緒萬厯/萬厤→萬曆永厯→永曆康熈(U+7188)→康熙 等異體字統一為標準字形,避免因字形變體導致年號匹配遺漏。
  • OCR 錯誤修正先元年→先生年十年九→十九宏治→弘治 等常見古籍 OCR 誤讀自動替換。
  • HTML 註解剝離 — 移除分頁標記 <!-- 第X頁 --> 等干擾。
  • 跨行合併 — 年份與年齡因排版斷行分處兩行時(康熙十六年\n公七歲),自動接合為一條完整年份條目。

L1 格式預分類

classify_format() 在匹配前先掃描全文,偵測八種格式族,只啟動相關的正則子集,從源頭降低誤配:

格式族 偵測條件 適用年譜
person 含「先生/公/府君〔年〕N嵗」 方柏堂、張清恪、府君風格
no_person 含「N年干支…N嵗」(無稱謂) 萬清軒、澄懷主人、顧亭林風格
ad 含「公元N年」 項蘭生等近現代年譜
bare ≥5 個行首/句末「N年干支」(無年齡) 紫陽(朱熹)等無年齡純年份年譜
bare_gz ≥5 個行首裸干支,後不接干支 鄭端簡公等行首干支逐年標記年譜
gz_age ≥5 個「干支緊接N歲」(優於 bare_gz) 李恕谷先生年譜
pure_age ≥5 個行首/句末「N歲」+出生條目可年號播種;與其他族互斥 曹月川先生年譜
modern ≥2 行可解析的已有年份標題 劉熙載、王欣夫等現代學者整理本

出生 pattern 在所有格式族下均啟用,以確保年號播種。modern 格式(現代學者整理本)不經正則匹配,只走「統一標題格式+完整性檢查」流程。

年份匹配

正則匹配按優先級從嚴到寬依次嘗試,共分為 有稱謂、無稱謂、無年齡、公元年、行首裸干支 五大類。

有稱謂(含傳主名前綴):

  • birth — 出生:[前綴]N年[干支]...先生生/公生/府君生,中間不跨句號
  • entry_sb — 有干支:[前綴]N年干支 + [最多120字] + 先生[年]N嵗,中間不跨句號
  • entry_no_sb — 無干支:[前綴]年號N年...先生N嵗,年號前綴必需
  • entry_sb_direct — 行首干支:干支, + [最多30字] + 先生N嵗,標點必需

無稱謂:

  • birth_no_person — 出生:N年[干支]...生於,中間禁止冒號(防止「治亂生於人心」誤判),可跨一句號
  • entry_sb_no_person — 直接年齡:N年[,]干支[,][年]N嵗,年齡後綴必需

無年齡:

  • entry_bare(前綴)?(年號)?N年干支,限行首/句末,干支必備,放 alternation 末尾避免搶佔有年齡條目

近現代公元年:

  • ad_entry公元NNNN年,[年號N年,][岁次干支,]N岁,年齡後綴必需

行首裸干支(bare_gz 格式):

  • entry_bare_gz — 行首裸干支:庚申、 / 己亥春入京 / 丁卯。公九歲
  • entry_bare_ls — 行首完整年標:隆慶元年丁卯(僅卷首/年號更替處)
  • entry_bare_se_yuan — 句末元年:元年干支(僅年號更替處)

三種 bare_gz pattern 匹配後不直接生成標題,而是由 _expand_bare_gz_heading 依「干支 60 年週期 + 當前年號」推算年號年序與公元年,補全為 ### 嘉靖十八年己亥(1539年)

年號補全與追蹤

掃描過程中維護一個當前年號狀態。遇到無年號前綴的條目(如 二年乙酉,先生二十七歲),自動補上當前年號變為 順治二年乙酉,先生二十七歲。年號切換時自動更新當前年號。行首裸干支格式則依干支週期推算年序,不直接補年號。

後處理鏈

匹配完成後依次執行:

  1. 合併斷行 — 將因排版斷開的行重新接合,檢測跨年邊界防止誤合
  2. 嵌入式年份二次掃描 — 合併後段落中隱藏的密集年份(如 八年戊子五歲。九年己丑六歲)拆出為獨立標題
  3. 月份/季節分段 — 每一年內按 春/夏/秋/冬 及月份拆分,標記格式:季節+月份(**春正月**)、僅季節(**春**)、「是」前綴(**是春**);歲末標記(是歲/是年)歸入前段不另分段;季節複合詞(秋闈、冬至)不切分
  4. 公元年標註 — 對所有含年號+年序的標題,在干支後插入 (YYYY年),換算公式 公元年 = 年號元年 + 年序 - 1

自我進化(v3.38 起帶質檢閘門)

每次處理後自動掃描文本,發現不在已知列表中的年號、皇帝前綴、字形變體,存入 learnings.json已納入版本管理,隨案例里程碑一併 commit,換機不丟失)。新發現的年號/前綴一律 status='pending'——未經回歸驗證不會自動應用

self_learn 發現(pending)→ python tools/regression.py --verify-learnings
  → 逐條臨時套用 → 跑全部回歸案例 vs 基線
  → PASS:轉正 status='verified',此後 apply 才會採用(年號另需 ≥2 次出現且置信度 ≥0.4)
  → FAIL:維持 pending,列出首個失敗案例與原因(疑為假陽性;--record 回饋作廢或人工刪除)

每次 learnings.json 覆寫前自動備份 .bak(驗證轉正/修正錄入/統計更新皆可回滾):python nianpu_processor.py --revert 回滾最近一次寫入。

python tools/regression.py --run 尾段附帶學習帳本報告(只讀,不改檔):①pending 未驗證條目數與名單;②已驗證(verified)學習複驗——把生效集臨時套用重跑九案例 vs 未套用基線,輸出須無變化;變化即「已驗證學習 × 現行代碼」漂移(代碼改動或學習穿透),會在 --run 綠燈旁直接 WARN 並列受影響案例。這補上「verified 只在轉正那一刻被驗證過、之後無任何回歸覆蓋」的長期缺口。

手動修正可通過 --record "錯" "對" [來源] 回饋到學習系統:干支形近字(單字替換,如 順治乙亥→己亥)累積為 OCR 候選規則(帶上下文+來源),--status 列出出現 ≥2 次的候選供人工複核後手動升級 _OCR_FIXES不自動晉升,年序推論錯誤屬校勘不沉澱為字形規則);年號/前綴/字形類修正自動標記相關學習為無效。--prune 命令批量清理已無效的學習記錄。

L2 三錨點一致性檢查

verify_anchors() 對每條標題交叉驗證三個錨點:

  • 年號年→公元 vs 干支→公元 vs 年齡→公元;出生年以「干支+年齡」餘類多數決推定(_consensus_birth_year:一致率 ≥60% 且樣本 ≥5),年號年序多數決落於該餘類內時互相佐證,否則以文本年號 span 解出唯一絕對年——對「年號年序系統性誤刻」(許敬菴尾部錯一年、尙友堂掉十)魯棒
  • 相鄰標題的年齡序列是否逐年遞增

不一致者輸出「⚠ 可疑標題」清單供人工複核。--check <已整理.md> 可對既有整理檔唯讀複查。

CBDB 生卒年核驗與年號誤配自動修正

--cbdb <傳主名> 以中國歷代人物傳記資料庫(CBDB)的生卒年為錨,自動從卷首提取傳主名(或提供別稱映射),帶本地快取,斷網時回退。

  • 出生年核驗:比對三錨點多數決推定與 CBDB(差 ≤1 年為虛歲/源文本之別);年譜最大年份 < CBDB 卒年−2 時標註「自訂/自編年譜止於卒前 N 年」。
  • 年號誤配自動修正:對 L2 標記的年號年序誤標,以「虛歲→公元」推定真年、干支佐證,依 REIGN_END_YEARS 年號終年表判定正確年號年序(如崇禎止於 1644,故 1645 切換為順治二年)。--fix 一鍵改寫標題年號年序+公元註記,干支/年齡保留。CBDB 缺席(查無/斷網/無生卒日期)時,--fix 回退到內部「干支+年齡」共識出生年(_consensus_birth_year),冷門傳主仍可自動修(陳紫峰「正德三年戊寅→十三年戊寅」實例)。

L2 衝突 LLM 仲裁(nianpu_arbitrate.py)

--check 標出的衝突 --fix 無法判定(無年齡/干支歧義)時,nianpu_arbitrate.py 仿標點 chunk→LLM→merge→verify 模式:

  1. --request <已整理.md>:收集三錨點衝突+鄰近標題上下文+推定出生年 → <名>_仲裁請求.md
  2. LLM 讀請求逐條判定(每行:{標題} → {修正後標題}→ 不改
  3. --apply <已整理.md> <仲裁結果.md>:保守套用——只動年號年序(含公元註記),干支/年齡/正文/前綴一律保留;修正後年號年須與干支自洽((ad−4)%60 == 干支索引),不滿足的判定直接拒絕;套用後復驗三錨點並報剩餘衝突。

語義槽位模型(--slots)

slot_model.py 將「每年譜改正則」抽象為「填槽位表」。LLM 以 schema + few-shot 範例讀取新年譜開頭,輸出槽位 JSON(紀年形式、年齡前綴、後綴、字形變體等),工具直接套用覆蓋格式分類與傳主名前綴,使新格式不需改正則(v3.29 補 gz_age 槽位,李恕谷式「干支+直接年齡」小書亦可用 --slots 表達)。--slots <slots.json> 輸入。

常見問題

Q: 輸出亂碼?

A: 確認輸入文件為 UTF-8 編碼。若非 UTF-8,腳本會自動嘗試 GBK/Big5。

Q: 年份未被切分?

A: 可能原因:

  • 年份與年齡相隔超過 120 字(中間有超長註文)
  • 缺少干支且無年號前綴
  • 使用的年號不在支援列表中(自我進化系統可自動發現)
  • OCR 錯誤導致年份模式無法匹配(如「先元年」→工具已內建修正)

Q: 某個年份被誤切?

A: 註文中的年份+年齡組合(如「按武夷先生卒於丁亥,年七十八」)因不含干支且「年七十八」格式不匹配 先生N歲,一般不會誤切。若仍有誤匹配,可調整 entry_sb 的 120 字限制。

Q: 光緖和光緒有什麼區別?

A: 兩者是同一年號的不同字形(緖=緒的異體),工具會自動將 光緖 正規化為 光緒

Q: 首年正文開頭漏了「生於」/「生于」/「生」等字?

A: 這是把出生日期併入標題(### 嘉慶十一年丙寅十月一日戌時)時常見的誤刪。標題只該「借用」日期顯示,正文的出生句({名}生於{地})必須原樣保留。整理首年後,檢查正文首句是否仍以「{名}生於/生于/生/誕」開頭——若正文直接以地點(如「平望鎭東溪湖第時…」)或家屬年齡開頭,即為漏刪,應對照原稿補回人名+動詞。

已成功處理的年譜

以下 45 部年譜已使用本工具成功整理、46 部已歸檔至 年譜整理本/

年譜 格式 年代跨度 備註
陳碩甫先生年譜 無稱謂直接附年齡 1786~1863(乾隆~同治) 清·管慶祺編(據陳奐自撰《師友淵源記》),主體+附錄(戴望行狀/張星鑑·黃景仁傳/王大隆跋);78 條標題、覆蓋率 98.7%、推定出生年 1786、三錨點無可疑;9 處 OCR 年序/年齡誤差以干支+年齡校正(五十二一年→五十二年、十一年丁卯→十二年丁卯、道光一年壬午→二年壬午、道光十七年丁酉五十一→五十二歲、道光二十七年丁未六十一→六十二歲、咸豐七年丁巳七十一→七十二歲 等);中縫/書口殘留(石下全言、頁碼單字、大清乾隆御製寶貞)與 PaddleOCR-VL 誤判為表格的密集案注頁(依表格格序重建豎排文字)均已清理;已全文標點定稿並歸檔(25 處 OCR 誤字校正記於改字記錄)
陳紫峰先生年譜 先生N歲(〔〕年齡註解) 1477~1545(成化~萬曆) 明·陳琛(紫峰,蔡清弟子),六世從孫陳元鍚重梓,卷首/序/卷一/卷二/後跋;49 條標題、覆蓋率 100%、推定出生年 1477、三錨點無可疑;〔先生N歲〕短註解展開為年齡錨點、長註文(諱琛傳記)保留;出生條目跨句號(成化十三年丁酉十月十六日…。先生生);明代皇帝前綴 憲宗/武宗/穆宗/神宗 等+年號承續(成化→弘治→正德→嘉靖→隆慶→萬曆);OCR 修正 兀年→元年、卞五年→十五年、一十八年→二十八年(庚子=1600)、𠕆→有、𡮢→嘗、亐→於、冡→冢、靣→面;死後追述(隆慶六年立墓祠、萬曆元年建祠、二十八年議謚、三十三年請謚)完整保留;22 處校勘後歸檔入整理本
李恕谷先生年譜 干支+直接年齡(無年號) 1659~1733(順治~雍正) 李塨(恕谷,1659-1733,顏李學派),淸苑馮辰纂、惲鶴生訂、孫鍇重修,卷首+五卷;75 條標題(出生+逐年 2~75 歲)、覆蓋率 100%、推定出生年 1659、三錨點無可疑、CBDB 核驗 1659–1733(#33498);新格式族「干支+直接年齡」(v3.28):逐年條目為裸干支緊接年齡(庚子二歲/乙酉年四十七歲/丙戌,年四十八歲),無年號前綴,依「出生年+年齡」推算年號年序+公元年(含順治→康熙→雍正更替);年號更替點「壬寅,康熙元年四歲」、〔康熙N年/雍正N年〕註文保留正文;OCR 修正:順治乙亥→順治己亥、乙亥六十一歲→己亥六十一歲、四土三歲→三十四歲(壬申)、戊子年五十一歲→五十歲;正文保留「先生生」,〔〕錯置(戊申七十歲雍〔正六年〕)修復;季節分段關閉(逐年短敘散文,季節字多為正文用語)
二曲先生年譜 無稱謂直接附年齡 1627~1705(天啟~康熙) 李顒(二曲先生),吳懷淸編《關中三李年譜》卷一~卷二正文、卷三~卷四附錄;65 條年譜標題、覆蓋率 100%、推定出生年 1627;卷首 4 篇序+卷末附錄 45 篇序跋/傳記/詩標題化(附錄上 13 傳記、附錄下 32 序跋);誤切注解標題(長先生/少先生X歲)7 處還原、出生句「先生生」補回;CBDB 有李顒但無生卒日期(跳過核驗);已知瑕疵:崇禎七年乙亥九歲(依出生年應八歲,年譜內部歲差)
警石府君年譜 府君年N歲 乾隆~同治 長註文/引文密集,含月份分段
殷譜經侍郎自定年譜 無稱謂直接附年齡 嘉慶~光緒 自定年譜,含「,年N歲」前綴與「{日時}。{名}生於」出生條目
文貞公年譜 公年N歲 崇禎~康熙 明清之際,含月份分段
施愚山先生年譜 先生年N嵗 明末清初 4卷+附錄,混合嵗/歲字形
涇舟老人洪琴西先生年譜 先生年N歲 晚清 光緖/光緒混用
羅忠節公年譜 先生年N歳 嘉慶~咸豐 50年,OCR錯誤密集
萬清軒先生年譜 直接年齡型 清代 無先生前綴
張清恪公年譜 公年N歲 清代 跨行年份+年齡支援
沈端恪公年譜 跨行年份+年齡 雍正 跨行格式典型
澄懷主人自訂年譜 無稱謂直接附年齡 清代 自訂年譜,6卷
桐溪達叟自編年譜 直接年齡型 清代 自編年譜,多卷
王船山先生年譜 先生年N歲 明末清初 卷上+卷下
方柏堂先生譜系略 先生年N嵗 清代 譜系略格式
鼎甫府君年譜 府君年N歲 清代 府君格式,1卷
吳竹如先生年譜 先生年N歲 清代 卷首+正文
先考松生府君年譜 府君年N歲 清代 府君格式,4卷
魏貞庵先生年譜 先生年N歲 清初 1卷
小酉腴山館主人自著年譜 直接年齡型 清代 自著年譜
項蘭生自訂年譜 公元年號/民國 1873~1957 同治~民國~人民共和國,簡體,廿/卅混用,含「岁次干支」,民國以後無年號
顧亭林先生年譜一卷 直接年齡型(年號年干支+N歲) 1613~1682 車持謙增纂吳映奎重輯本(識典數據),明末清初(萬曆~康熙),出生/卒年為「日期+生/卒+年齡」格式;明清之際崇禎→順治→康熙年號更替修正(甲申後裸年標「二年乙酉~十八年辛丑」補「順治」);補萬曆四十八年八歲錨點、年齡序列 1–70 連續;70 條標題、覆蓋率 100%、推定出生年 1613、三錨點無可疑;已歸檔整理本
黃黎洲先生年譜 公N嵗 1610~1695 明萬曆~清康熙,三卷+卷首/跋;含「萬厤→萬曆」OCR 變體與干支句號斷裂(v3.10 自動切分),出生正文補「公生」,順治二年/康熙十五年源文本缺字處人工補正
紫陽文公先生年譜 無年齡純年份(年號+N年+干支) 1130~1200 朱熹年譜,宋高宗建炎四年(1130)生至慶元六年(1200)卒,71 條標題、覆蓋率 100%;宋代皇帝前綴(宋高宗/孝宗/光宗/寧宗)與干支「戍」OCR 變體,出生條目標題併入日期、正文保留「朱子生」
唐一庵先生年譜 無稱謂直接附年齡(年號N年干支N歲) 1497~1574 明代唐樞(一庵先生)年譜,弘治~萬曆,65 條標題、覆蓋率 97.0%(3 條遺漏皆為卷末按語/碑記的正文年份引用假陽性);「宏治→弘治」全譜正規化、「嘉靖十不年己亥→十八年」OCR 修正;出生正文保留「先生生於」,碑記引文內「嘉靖十六年丁酉」誤切已人工還原
傅青山先生年譜 無稱謂直接附年齡(年號N年干支N歲) 1607~1684 傅山年譜(丁寶銓輯),萬曆~康熙,78 條標題、覆蓋率 100%;明清之際崇禎→順治雙年號過渡(甲申=順治元年),其後無年號條目(二年乙酉~十八年辛丑)人工補「順治」17 條並更正公元註記(L2 曾大規模誤報);版心/書口碎片(年譜字/普/左言/巨/三普 等頁碼字)全譜清除、「崇禎三年庚午一十四歲→二十四歲」「干四/干五→十四/十五」OCR 修正;出生條目標題併入日期、正文保留「先生生一歲」
蕺山先生年譜 先生年N嵗(萬曆~崇禎~弘光~順治) 1578~1645 劉宗周年譜(明·劉汋編),卷前+卷上+卷下+錄遺,54 條標題、覆蓋率 100%;CBDB 核驗 1578–1645(#34748);人工修正:天啓十年→天啓五年乙丑、崇𥛄/禎年已巳→崇禎元年戊辰/二年己巳、乙丣→乙卯(萬厯四十三年)、卒年補弘光元年乙酉(尊重南明遺民紀年)、順治八年跋日期還原正文、萬厯三十七年年齡三十二、首年標註公元(1578年)
朱文端公年譜 公N歲(康熙~乾隆,表格兩欄合併殘留預處理) 1665~1736 朱軾年譜(六世孫瀚原編、六世族孫船補訂),康熙四年乙巳八月十一日生至乾隆元年九月十八日薨,72 條標題、覆蓋率 100%、推定出生年 1665、三錨點無可疑;「公N歲M年。」雙欄合併殘留年份 20 處預處理移至對應干支前(M=下一年欄頭)、跨行「十六年\n丁巳」接合;干支 OCR 誤字 丙中→丙申;出生條目標題借日期「八月十一日」、正文保留「公以八月十一日生於艮溪里」;案註引文「雍正元年癸卯恩科」誤切標題人工還原
桐城吳先生年譜 公年N歲(道光~光緒) 1840~1903 吳汝綸年譜(淸苑郭立志編纂),卷一+卷二主體 64 年全部標題化、覆蓋率 100%、三錨點無可疑、CBDB 核驗 1840–1903(#54451);「_完整」檔含兩套重複 OCR,以較乾淨的第二版(卷四/五/六)去重為主體;人工修正:補回光緒十二年丙戌47歲條目(第二版 OCR 整體遺漏年份標題)、十一年乙未→二十一年乙未、二十五己亥→二十五年己亥;箋證附錄內 4 處誤切標題人工還原正文
劉熙載年譜 現代學者整理本 A(已有標題:年號N年 干支 公元年 年齡) 1813~1881(嘉慶~光緒) 現代學者整理本,60 條年份標題全部識別、格式統一為 #### 嘉慶十八年 癸酉 1813年 一岁、推定出生年 1813、三錨點無可疑;缺年 10 年(1817/1820/1825/1826/1831/1833/1834/1840/1841/1842,該年無事可記)由完整性檢查列出供人工確認;卒於光緒七年辛巳(1881),源文本 1882 條目為身後追述(奉旨入《國史·儒林傳》、建祠)
王欣夫先生編年事輯稿 現代學者整理本 B(已有標題:公元年(年號年干支)年齡) 1901~1966(光緒~民國~共和國) 近現代編年事輯稿,66 條年份標題識別、層級統一為 ####、推定出生年 1901、三錨點無可疑;標題層級 ##/###/#### 參差歸一,正文非年份標題(詩題/頁碼/按語)原樣保留;卒於 1966(源文本卷首「王欣夫(1901—1966)」)
袁觀瀾先生手編年譜 傳主名前綴(名+N歲)+ 民國無干支 1866~1930(同治~民國) 袁希濤年譜(弟袁希洛增輯並補注),同治五年生至民國十九年歿,62 條標題、覆蓋率 100%、三錨點無可疑、推定出生年 1866;「希濤年N歲/希濤N歲」傳主名前綴自動偵測、中華民國N年(干支)民國標題(無干支者經 age-anchor 切分)、跨空行年份+年齡合併、中華民國前綴支援;民國五/七/九年源文本缺年(序列空缺屬正常);出生年(同治五年丙寅九月三日)標題已含出生日期,正文「九月三日希濤生時我…」語義自足,不需強補「希濤生」;來源為《新中華》復刊第四卷第九期 61-63 頁+第十期 58-61 頁+續篇 PDF(續完與續為同一篇重複掃描,取一份);全譜已標點並歸檔(62 條標題、14524 字,全部 7 塊標點後 merge+verify 差異僅為 OCR 修正與字形歸一)
袁觀瀾〔人際網絡數據提取〕 已整理定稿 → hyperextract 1866~1930 對上一部定稿的結構化延伸(nianpu-social-network skill):約 200 餘位人物、300 餘條關係;產出 persons/relations/dataset_meta 三份統一 TSV(class_axis 六軸:業緣/血緣姻親/學緣/政治/社交/經濟),附同構知識圖譜與《整理稿》。已知待改進:實體消解不徹底——同一人分散於多個節點(如「袁希洛/希洛/三弟」各成一行)、生卒年與 attrs(職官/師承等)多為空
陽明先生年譜 先生年N嵗(明,含皇帝前綴) 1472~1529(成化~嘉靖) 明·錢德洪編、羅洪先考訂,四卷;成化八年壬辰(1472)生至嘉靖八年己丑(1529)卒,41 條標題、覆蓋率 100%、推定出生年 1472、三錨點無可疑;〔〕註文密集(羅洪先考訂補注);出生條「明憲宗成化八年壬辰九月丁亥,先生生」;皇帝前綴 明憲宗/孝宗 弘治 由自我進化發現;人工修正「一十二年丙午→二十二年丙午」(L2 標出後依干支丙午=1486+生年1472=15歳仲裁);槽位配置(--slots)與自動檢測結果一致,證明配置驅動機制可跑通;已知瑕疵:卷首序落款「嘉靖四十二年癸亥」被誤切為標題、正德七年「七年。壬申」句號斷行致標題丟「七年」
重刻鄭端簡公年譜 行首裸干支(公N歲稀疏) 1499~1567(弘治~隆慶) 明·鄭曉年譜(子履淳編、孫心材重校,萬曆丁未重刻),十卷;弘治十二年己未(1499)生至嘉靖四十五年丙寅(1566)卒、隆慶元年丁卯(1567)卹典,72 條標題、覆蓋率 100%、推定出生年 1499(CBDB 核驗 1499–1566,#29589)、三錨點無可疑;全譜以行首裸干支逐年標記(年號僅卷首與更替處),新能力「行首裸干支年標」(v3.21)依干支週期+當前年號推算年序與公元年;--slots(year_style=ganzhi_only)與自動檢測結果完全一致;OCR 修正:内申→丙申、内午→丙午、壬戍→壬戌;正文散文干支日期(永樂十九年辛丑、二十六年甲申、隆慶……)經 entry_bare 收緊為「僅行首+句末元年」後不再誤切;出生條目預處理分行、正文保留「公生於」;卷前目録(己未~丁卯逐年 公N歲 概況)與卷之八~十附録(䘏典疏、墓誌銘、祭文、輓詩)原文照錄,另生成本整理目録
關中李二曲先生履歷紀略 無年齡純年份(年號+N年+干支) 1645~1689(順治~康熙) 李顒(二曲先生)年譜(惠靇嗣摭次、馬稢土等仝錄),順治二年乙酉(1645)起至康熙二十八年己巳(1689),44 條標題、覆蓋率 100%、三錨點無可疑;全譜以「順治/康熈N年干支」逐年標記、無年齡;康熈(U+7188)→康熙 年號字形正規化(v3.22,原僅康煕 U+714F)、birth_no_person 中間段禁冒號防「治亂生於人心」誤判出生(v3.22);OCR 預處理:道治六年→順治六年、卜年→十年、乙□→乙巳、□十八年→順治十八年、泣别□□熈九年→泣别。康熈九年、返□→返。;順治八年無事未記(序列空缺正常)、崇禎壬午追敘留正文、無出生年條目(推定無法);CBDB 有「李顒」但無生卒日期,跳過核驗
許敬菴先生年譜存稿 先生年N嵗(年號年干支+先生+N嵗) 1535~1604(嘉靖~萬曆) 許孚遠(敬菴)年譜清稿本,嘉靖十四年乙未十一月二日(1535)生至萬曆三十二年甲辰(1604)七十嵗,末附《明史本傳》;53 條標題、覆蓋率 100%、三錨點無可疑、CBDB 核驗 1535–1604(#29721);稿本尾部年號年序自「二十七年庚子」起整體較干支/年齡錯位一年(稿本一貫筆誤),以干支+年齡雙錨點校正(二十七年庚子→二十八年庚子…三十一年甲辰→三十二年甲辰),出生條原題「嘉靖十三年乙未」依干支乙未+全譜年歲更正為「嘉靖十四年乙未」;OCR 把豎排標題拆多行(年/先生/N嵗/歲各成行)致 4 條年齡落入正文,手動併回標題;OCR 誤讀:一十八年→二十八年己酉、萬曆二年甲申→十二年甲申、萬曆二十一年甲辰→三十二年甲辰;稿本漏「年」字條目正常化(四十丙子→四年丙子、二十七歲己亥→二十七年己亥);穆宗/神宗廟號併入次年標題;頁內重複行去重 2 處
尙友堂年譜(滄柱公年譜) 直接年齡型(年號+N年干支+N歲,抄本) 1644~1717(順治~康熙) 仇兆鰲(滄柱)自訂年譜清抄本,崇禎十一年戊寅(1638)生至康熙五十六年丁酉(1717)八十歲卒,末附廷桂、廷模《附識》;74 條標題(含缺載之順治六年己丑十二歲作占位)、覆蓋率 100%、三錨點無可疑、推定出生年 1638(與傳主史實合:康熙二十四年乙丑二甲八名進士、著《杜詩詳註》);稿本/OCR 康熙年號年序大量掉位(掉「十/二十/三十/四十/五十」),全譜以干支+年齡雙錨點校正 20 餘處(四年乙丑→二十四年乙丑、三年甲寅→十三年甲寅、一十一年壬戌→二十一年壬戌、二十四年乙亥→三十四年乙亥…);OCR 誤字:卻→邵(先室邵淑人)、右今→古今、莪→義(立就六義)、段日→逐日、易栽→易裁;豎排副注誤切標題(甲戌殿元/丁丑進士/甲戌進士三條改回正文小注);康熙二十七年戊辰分校禮闈門生名單、康熙三十三年甲戌同徵小注等豎排錯亂段落手工還原;稿本原缺/漫漶處以□標記待校
焦南浦先生年譜 無年齡純年份+跨行拆分年份+府君年N歲(正文) 1661~1736(順治~乾隆) 焦袁熹(南浦先生)年譜,清·焦以敬編、焦以恕校訂,光緒二十三年刻本,末附行狀(張照)、墓誌銘(張廷玉)等;62 條標題、覆蓋率 100%、推定出生年 1661、三錨點無可疑;OCR 豎排標題拆三行(康熙/五年/丙午、乾隆/元年/丙辰)由 v3.25 直接合併;年號年序誤讀 康熙二十一年癸亥→二十二年癸亥、三十一年癸酉→三十二年癸酉,以干支校正;補雍正十二年甲寅(OCR 漏年標,七十四歲文原混入十一年);OCR 誤字:一十→二十(康熙二十年/二十五年)、父集→文集、二干→二千、舌今→古今、渙→漢、舉以鄉→舉於鄉;書口噪聲(雲間聚/珍版印)清除;全文標點整理
楓山章文懿公年譜:二卷 無稱謂直接附年齡(明代年號逐年) 1436~1521(正統~正德~嘉靖) 明·章懋(楓山先生)年譜,門人方太古敘、楊應詔錄、阮鶚續撰,識典數據(guji.nlc.cn metadataId 1012971);71 條標題、覆蓋率 100%、推定出生年 1436、三錨點無可疑;「先生年十𡻕/二十歲/三十歲/四十/五十/六十/七十/八十/八十六」年齡稀疏錨點;年號承續 正統→景泰→天順→成化→弘治→正德→嘉靖;「七年,辛邜《夏六月三載考績》」型條目(無年齡、干支異體 邜=卯、後接書名)人工補題「### 成化七年辛邜(1471年)」並 --record 回饋;卒年「享年八十有六」(正德十六年 1521)與謚文懿、嘉靖諭祭葬等後事完整保留
馬端敏公年譜 無稱謂直接附年齡(直接年齡型) 1821~1870(道光~咸豐~同治) 馬新貽(端敏)年譜,弟馬新祐編次,識典數據(CADAL 全卷:卷首+卷一);49 條標題、覆蓋率 100%、推定出生年 1821、三錨點無可疑、CBDB 核驗 1821–1870(#60761);卷首(諭賜祭文/碑文)原樣保留於卷首部;道光板塊(二年壬午二嵗~三十年庚戌三十嵗)無年號前綴,依出生年補「道光」並標註公元年;咸豐/同治逐年標題自動註公元年;干支 OCR 誤字 咸豐九年巳未→己未(1859)已修正並 --record 回饋;年齡序列 2–50 連續無空缺,卒於同治九年庚午(1870)五十嵗(刺馬案);正文已含完整標點,無需另行斷句
曹月川先生年譜 純年齡(行首/句末 N歲,無年號/干支錨點) 1376~1434(洪武~宣德) 明·曹端(月川先生,字正夫)年譜,韶陽張信民纂(識典數據,中華古籍智慧平台 metadataId 1014791,無頁碼版);34 條標題(出生+三歲~五十九歲,年齡稀疏)、覆蓋率 100%、推定出生年 1376、三錨點無可疑;新格式族「純年齡」(v3.33):全譜僅以「N歲,」紀錄、無任何紀年錨點,出生條目(洪武九年丙辰春正月十三日午時生)為唯一年號播種,依虛歲「出生年+年齡−1」推各條目年號年序+干支+公元年(洪武→建文→永樂→洪熙→宣德更替);卒年宣德九年甲寅(1434)=五十九歲與 CBDB 曹端 1376–1434 一致;行首「N歲」不需後接標點(二十歲嘗曰/二十七歲時)、句中「N歲」需標點/季節(五十二歲);「六月六日戌時,子琇生」無年齡段落保留為正文待人工歸屬;已歸檔整理本
余孝惠先生年譜 直接年齡型(年號N年干支+N歲) 1809~1874(嘉慶~同治) 清·吳師澄編,余治(翼廷,號蓮村,私諡孝惠,清代善人/慈善家),國圖中華古籍智慧平台(guji.nlc.cn metadataId 1015783)刻本重印無頁碼版;卷首應寶時、沈秉成二序,卷末墓志銘(俞樾)、墓表(彭慰高)、私諡議、附祭文、校訂姓氏等附錄俱在;66 條標題、覆蓋率 100%、推定出生年 1809、三錨點無可疑、CBDB 核驗 1809–1874(#78914);出生條目正文保留「十一月十九日先生生」;年號承續 嘉慶→道光→咸豐→同治;校正 2 處誤字:丙中→丙申(道光十六年干支,修復缺 28 歲條目)、蕙日→蕙田(本生父名),已 --record 回饋學習;已歸檔整理本

年譜擴展利用:人際網絡數據提取

整理好的年譜不只做 RAG/文本分析,還能再往下游「提取為結構化數據」——人際/社交網絡。

由另一獨立 skill nianpu-social-network 提供:把已整理的年譜按年通讀,用 hyperextract(he parse,LLM + 自訂模板) 抽出「誰和誰、是什麼關係、哪一年、原文依據」,整理成統一 persons / relations / dataset_meta 三個 TSV(含 class_axis/relation_class 分類、aliases、evidence、year),為多人譜合併、跨人物分析、知識圖譜做底座。

首個落地案例:〔袁觀瀾(袁希濤)先生手編年譜及續〕——約 200 餘位人物、300 餘條關係;產出三份結構化 TSV 之外,另附同構知識圖譜(data.json+nodes/edges.csv)與一份按關係分類的人際網絡《整理稿》。

延展建議(詳見「常見問題/後續」):本工具改造為「整理 → 標點 → 歸檔 → 再餵給 nianpu-social-network 提取數據」的完整管線;兩 skill 共用同一份定稿 .md,年份標題+有標點的正文,正是提取出可靠 year/evidence 的前置條件。

更新日誌

版本 要點
v3.39 --run 附帶學習帳本報告(信任鏈收口):化解「每日\--run 綠燈無法告知學習帳本狀態、verified 只在轉正那一刻被驗證過」的操作缺口。tools/regression.py --run 尾段附帶 learnings.py 新增 verified_learnings()(已轉正全量,鏡像 pending_learnings)派生的帳本報告:①pending 摘要——未驗證條目數與名單,提示 --verify-learnings 轉正;②verified 複驗——把 apply_learnings 的生效集臨時套用(就地變異,與閘門同款)重跑 manifest 全部案例 vs 本次基線,full 案例比對歸一化全文、其餘比對指標;輸出無變化即淨 PASS,變化逐一列受影響案例(並會火力全開抓到「正文竄改但標題數不變」等級的穿透)。只讀不改 learnings.json;evaluate_case 返回值新增 result_text(full 案例基線全文快照)支撐複驗。負向實測:注入假 OCR 規則「歲→歲X」被複驗抓出 6 案例失守(含王欣夫 titles 74→24+全文)。回歸 9/9 PASS
v3.38 學習質檢閘門(自我進化可信化):化解「自我進化發現的假陽性年號/前綴會被直接套用、污染後續處理」的信任缺口。①條目狀態機:learnings.json 年號/前綴條目一律帶 status(舊數據遷移為 pending);apply_learnings 只應用 verified 條目(年號另需 ≥2 次出現且置信度 ≥0.4),pending 不生效,apply 報告列「待驗證未應用」提示。②閘門命令 python tools/regression.py --verify-learnings:逐條 pending「臨時套用(原地變異)→ 跑全部回歸案例 vs 基線 → PASS 轉正 / FAIL 維持 pending 並列首個失敗案例與原因」;無操作條目(已被基座涵蓋)直接轉正。③可回滾:每次 learnings.json 覆寫前自動備份 .bakpython nianpu_processor.py --revert 回滾最近一次寫入(轉正/--record 錄入/統計更新皆可回滾)。負向實測:注入假年號「二十」被閘門攔截(74 處內容差異、FAIL 且不轉正);既有 4 條真實 pending 條目(年號 咸丰/康熈、前綴 祖章皇帝/世宗皇帝)驗證轉正。回歸 9/9 PASS
v3.37 單檔拆包(nianpu_core,行為零變化的機械拆分):化解「3338 行單檔、93% 為管線邏輯」的可維護性問題——不動任何函數體,按功能把 nianpu_processor.py 切分為 nianpu_core/ 包 13 模塊(constants/base/expand/preprocess/anchors/fixes/modern/patterns/segment/learnings/verify/process/cli,依賴單向無循環),原檔保留為薄門面(from nianpu_core import *),命令/參數/import nianpu_processor__file__ 路徑解析全部不變;外部腳本(regression/biaodian/arbitrate/coverage/bare_review)零改動直接兼容。拆分自檢:行覆蓋率 100%(8 處漏行修正)+刪除唯一死代碼(被後定義覆蓋的第一版 _int_to_chinese_year)。等價性驗證:A/B 對比舊單檔 vs 新包(9 案例輸出全文+格式分類+標題數+出生年+可疑數逐項一致);回歸 9/9 PASS(6 full 全文鎖定殘差零變化)。README 新增「程式碼結構」章、安裝說明改為整目錄
v3.36 行内嵌入式年份補缺(重刻鄭端簡 1546 缺口收口=72 標題與黃金一致):前版本已知缺口「嘉靖二十五年丙午(1546年)缺標題」——主叙事該年行首裸干支被 OCR 併進前一句(内午→丙午,如「…撫卷長嘆也已。丙午三月,再疏乞致仕…」)。新增 _fill_missing_bare_year_title(bare_gz 專用):在某標題塊正文的「句界(行首/。!?;」』))」後掃「干支X月」,僅當該干支恰解碼為塊年份的次年、且次年確無標題時,才在該處拆出次年新標題(_reign_label_of_ad 由 AD 推「年號N年」標籤);截點前行尾內容(如「讀陶集四八目…撫卷長嘆也已。」)保留在當年塊,只去干支、留下「三月」作次年正文開頭。安全閾杜絕誤切祭文/記日中的干支X月(干支非次年或次年已有標題)。結果:重刻鄭端簡 71→72 標題(x=黃金),1545(讀陶集)/1546/1547 三塊逐字鎖定;回歸 9/9 PASS
v3.35 回歸測試升級:全文內容鎖定(full 模式)=黃金語料半步交付:化解「回歸是指標級而非全文 diff、『輸出變了但指標不變』會漏網」的取捨。tools/regression.py 新增 full 模式=exact 全部指標斷言+全文內容鎖定:①歸一化層(剔標點/空白/markdown 標記+異體歸一 熈→熙、戍→戌)消除黃金輸出因 biaodian 標點與異體字造成的假陽性;②以「管線輸出 vs 黃金」的內容殘差存入基線(content_residual),零殘差=正文逐字鎖定;③零假陽性——既有人工修正殘差(陳紫峰「正德三年→十三年」年份校正、警石府君補「府君生」)免試,僅「基線未見的新殘差」報 FAIL,抓到文字指標級看不到的 bug(已負向實測:僅篡改正文一字符、標題數不變即觸發「全文內容鎖定失守」)。六案例升 full(文貞公/陳紫峰/警石府君/殷譜經/紫陽文公/王欣夫),其中四例零殘差全文鎖定、兩例含已入基線的人工修正殘差;方柏堂/萬清軒/重刻鄭端簡維持 metric 哨兵。詳見 docs/回歸測試.md。回歸 9/9 PASS
v3.34 兩處既有缺口修復(紫陽不可能年份+鄭端簡〔〕注文雙匹配)+述畧重複去重:①年號年序長度檢驗——_expand_bare_gz_heading 推算年序須落在該年號實際起訖(REIGN_END_YEARS)內,超長(隆慶十年、慶元五十二年、紹熙三十七年)判為非年份條目而不展開;裸干支推算失敗時不再以當前年號前綴硬造標題、改保留原文。②**〔〕注文排除**——行首裸干支(bare_gz)格式譜的卷前/述畧常以「干支、〔年號N年,公N歲。〕」重複彙總全文年份,insert 對與〔〕註文重疊的匹配不成標題(限定 bare_gz,person 格式〔〕內年份如警石「〔…。道光六年丙戌旣裝潢」仍保留為合法條目)。③述畧同年去重_dedupe_repeated_year_headings,bare_gz):主內容行首裸干支展開後必含干支、述畧無干支,故對同一公元年同時含干支與無干支標題者,保留含干支主內容、將述畧重複降回正文;含干支多緼(嘉靖三十三/三十六年)不誤合。配合既有「bare 優先於 bare_gz」規則,結果:紫陽文公 79→75(x=黃金,升 exact);重刻鄭端簡 145→76→71,推定出生年 1499→None(x=黃金 None)。嘉靖二十五年丙午(1546年)仍缺——主文本中行「丙午三月」無年齡後綴,安全自動拆不可行(黃金為人工插補),故鄭端簡維持 metric 哨兵。回歸 9/9 PASS
v3.33 純年齡格式族(曹月川先生年譜,明·曹端 1376–1434):新格式「行首/句末 N歲」——全譜僅以「N歲,」紀年、無任何年號/干支錨點,出生條目(年號N年干支…生)為唯一紀年錨點;classify_format 新增 pure_age 判定(≥5 個行首/句末「N歲」且出生條目可年號播種,與其他格式族互斥),新增 entry_pure_age_birth(出生「年號N年干支」原子化、日期與「生」動詞留正文)與 entry_pure_age(行首「N歲」不需後接標點、可選吞標點;句中「N歲」需後接標點/季節);_expand_pure_age_heading 依虛歲「出生年+年齡−1」推年號年序+干支(_ad_to_reign+干支週期),annotate_ad_years 補公元年;與 gz_age 同關閉季節分段;_merge_broken_lines 加「- 」標記列表項不併行(卷首 metadata 清單)。曹月川先生年譜:34 條標題、覆蓋率 100%、推定出生年 1376、三錨點無可疑、年號更替 洪武→建文→永樂→洪熙→宣德、卒年宣德九年甲寅(1434)=五十九歲;已歸檔「年譜整理本」。回歸 9/9 PASS
v3.32 工程硬化(可復現性+文檔單源化):①learnings.json(discovered_reigns/prefixes、corrections、lessons、ocr_candidates 等持久知識)與 cbdb_cache.json(已核驗人名→CBDB id 映射)結束 gitignore、納入版本管理——換機不再丟失自我進化經驗與核驗結果;②路徑參數化:nianpu_archive.py 預設整理本目錄與 regression.py --full 掃描根改由環境變數 NIANPU_ROOT 解析(未設時行為不變),README 新增「路徑配置」章;③文檔單源化:SKILL.md 由 67KB 全文收縮為約 6KB 入口頁(管線命令+自主執行策略+基本操作規則+文檔地圖),功能清單/格式表/年號表/更新日誌/已處理清單等易變事實只存於本 README——結構性消除雙軌漂移(原「兩份文檔同步更新」規則改為「只更新 README」);④tmp_* 暫存工作檔加入 .gitignore。回歸 9/9 PASS
v3.31 回歸測試自動化(tools/regression.py):新增 tools/regression.py 回歸套件(stdlib 零依賴,改動腳本後一條命令驗證歷史成績不退化)。tools/testdata/ 收錄 9 對「源+黃金輸出」(文貞公 75/方柏堂 40/萬清軒 82/陳紫峰 49/警石府君 74/殷譜經 79/紫陽文公 79/重刻鄭端簡 145/王欣夫 74,覆蓋 公N歲、先生年N嵗、直接年齡、〔〕註解、府君N歲、無稱謂、無年齡純年份、行首裸干支、現代整理本 9 格式族);regression_manifest.json 記案例模式(exact/metric/smoke)、regression_baseline.json--selfcheck 從黃金輸出實測基線(不手寫、防漂移);--run 重跑管線 vs 基線出 PASS/FAIL 表+自動生成 changelog 回歸行--full 掃 E: 識典數據全庫、--update 人工審核後刷新基線、--smoke 冒煙(33/33)。首建基線即暴露兩處既有缺口:重刻鄭端簡〔〕注文被當標題展開(145 vs 黃金 72,含「正德十七年」錯題)、紫陽文公不可能年份誤切(慶元十年/紹熙三十七年,79 vs 75)——均列 metric 哨兵案例,由黃金差異 WARN 誠實記錄待修。回歸標的為基礎規則集(不走 apply_learnings),learnings 演化不在回歸範圍。詳見 docs/回歸測試.md
v3.30 年譜擴展利用(數據提取延伸,首例:袁觀瀾):與 nianpu-social-network 聯動——把已定稿並標點的 袁觀瀾先生手編年譜 交由 hyperextract(he parse,社會網絡模板)按年抽出人際網絡,產出 persons/relations/dataset_meta 三份統一 TSV(約 204 位人物、313 條關係,class_axis 業緣/血緣姻親/學緣/政治/社交/經濟,全部關係帶 year+evidence)+同構知識圖譜(data.json)與《整理稿》;README 新增「年譜擴展利用」章節與工具腳本欄目。已知待改進(交接給 nianpu-social-network 繼續優化):①實體消解不徹底——同一人因稱謂/代詞分散多節點(袁希洛/希洛/三弟 各一行;袁希濂/希濂/希泳),alias 僅機械列出未歸並,`
v3.29 共識出生年回退+L2仲裁管線+干支OCR候選(陳紫峰先生年譜):①_consensus_birth_year 以 (干支,年齡) 餘類多數決(≥60%+樣本≥5)推定出生年、年號年序多數決佐證,--fix 在 CBDB 缺席時回退到此共識(拔外部依賴),許敬菴/尙友堂式「年號年序系統性誤刻」可自動修(陳紫峰「正德三年戊寅→十三年戊寅」);②--record 錄入手動修正,干支形近字(單字替換)累積 OCR 候選規則(帶上下文+來源),--status 提示手動升級 _OCR_FIXES(不自動晉升、年序推論錯誤不沉澱);③新增 nianpu_arbitrate.py:L2 衝突+上下文→LLM 仲裁請求→保守套用(只動年號年序、與干支自洽)→復驗;④slot_model 補 gz_age 槽位(李恕谷式小書可用 --slots 表達);⑤陳紫峰年譜支援:出生 pattern 跨一句號(先生生分句)、明代皇帝前綴(憲宗..思宗+皇帝變體,與宋代同名靠後接年號分辨)、_make_heading 清未閉合〔、OCR(兀年→元年/一十八年→二十八年/卞五年→十五年)、classify_format 改判定表;陳紫峰先生年譜(1477-1545,先生N歲+〔〕年齡註):49 條標題、覆蓋率 100%、推定出生年 1477、三錨點無可疑、歸檔入整理本;回歸:文貞公 75/涇舟老人 64/警石府君 74/殷譜經 79 標題數不變
v3.28 李恕谷先生年譜(1659-1733,干支+直接年齡,清·馮辰纂):新格式族「干支+直接年齡」(gz_age)——逐年條目為裸干支緊接年齡(庚子二歲乙酉年四十七歲丙戌,年四十八歲壬寅,康熙元年四歲),無年號前綴,classify_format 新增 gz_age 判定(干支緊接年齡 ≥5 且優於 bare_gz),_build_full_pattern 新增 entry_gz_age,由新函式 _find_gz_age_birth_ref(出生條目 己亥順治十六年…先生生)取參照+_expand_gz_age_heading(出生年+年齡→公元年,干支交叉驗證;無年齡時退回干支週期)推算年號年序,_ad_to_reign_REIGN_SERIES(朝代年號序列,含順治→康熙→雍正更替)映射公元年→年號,出生標題補回干支(順治十六年己亥(1659年));_gz_age_connector 統一「干支→年齡」連接(無/年/,年/,康熙元年),前瞻防貪吃年齡數字;gzip_age 格式關閉季節分段(逐年短敘散文,季節字多為正文用語如《春秋》「春正月無氷」);OCR 修正:順治乙亥→順治己亥、乙亥六十一歲→己亥六十一歲、四土三歲→三十四歲(壬申)、戊子,年五十一歲→五十歲、〔〕錯置(戊申七十歲雍〔正六年〕);75 條標題、覆蓋率 100%、推定出生年 1659、三錨點無可疑、CBDB 核驗 1659–1733(#33498);歸檔為 36 部;回歸:文貞公 75/涇舟老人 64/警石府君 74/殷譜經 79 標題數不變(6 案例與 v3.27 輸出差異=0)
v3.27 歸檔/整理本同步:新增 nianpu_archive.py(複制定稿→年譜整理本/書名.md+同步 _清單.md 表格與部數+_清單.tsv;同書再版更新既有列、部數自動刷新、來源路徑相對/絕對自適)。實例:焦南浦先生年譜定稿(清掉書口噪聲「雲間聚」後與整理本副本一致)歸檔為 35 部,清單 md/tsv 同步
v3.26 標點/斷句(LLM 驅動):新增 nianpu_biaodian.py(--chunk 按年份塊切分 → LLM 逐塊依 docs/標點規則.md 加標點 → --merge 合併成定稿 → --verify 字符保全校驗:去標點逐字比對、只插標點不改原文、OCR 誤字修正列內容差異、改動年份標題/半形標點單獨告警);標點約定:書名《》、引語「」/『』、()注公元年/字號、全形標點;新增 docs/標點規則.md;回歸:袁觀瀾先生手編年譜 chunk1(同治五年~光緒十九年)標點後合併 verify 零差異;焦南浦先生年譜全文標點為範本
v3.25 焦南浦先生年譜(1661-1736,無年齡純年份+跨行拆分年份,清·焦以敬編):62 條標題、覆蓋率 100%、推定出生年 1661、三錨點無可疑;_merge_multi_line_years 新增「跨行拆分年份」合併(影印本 OCR 把豎排標題拆成 年號/N年/干支 三行:康熙/五年/丙午→康熙五年丙午、乾隆/元年/丙辰→乾隆元年丙辰,含新輔助 _next_nonempty);年號年序誤讀 康熙二十一年癸亥→二十二年癸亥、三十一年癸酉→三十二年癸酉,以干支+年齡校正;補雍正十二年甲寅條(OCR 漏年標,七十四歲文原混入十一年條);OCR 誤字:一十→二十(康熙二十年辛酉/二十五年丙寅)、父集→文集、二干→二千、十一百→一千一百、舌今→古今、渙→漢、舉以鄉→舉於鄉;書口噪聲(雲間聚/珍版印)清除;回歸:文貞公 75/涇舟老人 64/警石府君 74/殷譜經 79 標題數不變
v3.24 尙友堂年譜(滄柱公年譜,1644-1717,直接年齡型,清仇兆鰲編、清抄本):74 條標題、覆蓋率 100%、三錨點無可疑、推定出生年 1638(傳主史實合:康熙二十四年乙丑二甲八名進士);稿本/OCR 康熙年號年序大量掉位(掉「十/二十/三十/四十/五十」)——原整理檔「康熙四年乙丑(1665年)四十八歲」「康熙十三年甲申(1674年)六十七歲」等年號年序與干支/年齡明顯錯位,全譜以「干支+年齡」雙錨點校正 20 餘處(四年乙丑→二十四年乙丑、三年甲寅→十三年甲寅、一十一年壬戌→二十一年壬戌、二十四年乙亥→三十四年乙亥、十二年癸巳→五十二年癸巳…),並補缺載年份(順治六年己丑十二歲、康熙十一年壬子三十五歲、康熙十七年戊午四十一歲、康熙二十年辛酉四十四歲);OCR 誤字:卻→邵(先室邵淑人)、右今→古今、莪→義(立就六義)、段日→逐日、易栽→易裁;豎排副注誤切標題(甲戌殿元/丁丑進士/甲戌進士三條由標題改回正文小注);康熙二十七年戊辰分校禮闈門生名單、康熙三十三年甲戌同徵小注等豎排錯亂段落手工還原;稿本原缺/漫漶處以□標記待校;回歸:文貞公 75/涇舟老人 64/警石府君 74/殷譜經 79 標題數不變
v3.23 許敬菴先生年譜存稿(1535-1604,先生年N嵗,明·許孚遠,清稿本):53 條標題、覆蓋率 100%、三錨點無可疑、CBDB 核驗 1535–1604(#29721);稿本尾部年號年序自「二十七年庚子」起整體較干支/年齡錯位一年、出生條「嘉靖十三年乙未」亦如是(稿本存稿一貫筆誤),以干支+年齡雙錨點校正年號年序(二十七年庚子→二十八年庚子、二十八年辛丑→二十九年辛丑、二十九年壬寅→三十年壬寅、三十年癸卯→三十一年癸卯、三十一年甲辰→三十二年甲辰、十三→十四年),CBDB 獨立驗證無誤;OCR 把豎排標題拆成多行(年/先生/N嵗/歲各成行)導致 4 條年齡落入正文,手動併回標題;OCR 誤讀:一十八年→二十八年己酉、萬曆二年甲申→十二年甲申、萬曆二十一年甲辰→三十二年甲辰;稿本「四十丙子」(漏「年」)「二十七歲己亥」(誤用「歲」)正常化為「四年丙子」「二十七年己亥」;穆宗/神宗廟號併入次年標題;頁內重複行去重 2 處;回歸:文貞公 75/涇舟老人 64/警石府君 74/殷譜經 79 標題數不變
v3.22 關中李二曲先生履歷紀略(1645-1689,無年齡純年份,順治~康熙):全譜以「順治/康熈N年干支」逐年標記、無年齡。①_REIGN_NORMALIZATIONS 新增 康熈(U+7188)→康熙(原僅有 康煕 U+714F),康熙年標題由全數遺漏→100% 覆蓋;②birth_no_person 中間段禁冒號(:/:),修復「…有感嘆曰:治亂生於人心」的「生於」(義為「起於」)被誤當出生條目、標題吞噬正文的 bug;③44 條標題、覆蓋率 100%、三錨點無可疑(推定出生年無法推定——無出生條目,CBDB 有李顒但無生卒日期);④OCR 預處理:道治六年→順治六年、康熈卜年→康熈十年(卜=十)、康熙四年乙□→乙巳、□十八年→順治十八年、泣别□□熈九年→泣别。康熈九年(補「康」+句讀)、返□康熙二十年→返。康熙二十年;順治八年無事未記(序列空缺正常)、崇禎壬午追敘(太翁襄城殉難)留正文、康熙九年庚戌「治亂生於人心」不再誤切;回歸:文貞公 75/涇舟老人 64/警石府君 74/殷譜經 79 標題數不變(改前 vs 改後 差異=0)
v3.21 行首裸干支年標(重刻鄭端簡公年譜,1499-1567,明·鄭曉):全譜以行首「干支」逐年標記(庚申、/己亥春入京/丁卯。公九歲/戊申在尚寶),年號僅卷首與更替處。classify_format 新增 bare_gz 判定(行首裸干支 ≥5 且後不接干支),_build_full_pattern 新增 entry_bare_gz(行首裸干支)+ entry_bare_ls(行首完整年標)+ entry_bare_se_yuan(句末元年,年號更替用)——bare_gz 格式下 entry_bare 收緊,排除正文散文干支日期(永樂十九年辛丑/二十六年甲申)誤切;_expand_bare_gz_heading 依「干支週期+當前年號」推算年序與公元年(### 嘉靖十八年己亥(1539年));_int_to_chinese_year 整數年序→中文;_make_heading 標題正規化「十有」→「十」、去尾「、」;OCR 修正 内申→丙申/内午→丙午/壬戍→壬戌;slot_model 槽位 year_style: ganzhi_only → bare_gz(--slots 亦套用 ocr_variants),與自動檢測結果一致;出生條目預處理分行、正文保留「公生於」;72 條標題、覆蓋率 100%、CBDB 核驗 1499–1566(#29589)、三錨點無可疑;回歸:文貞公 75/涇舟老人 64/警石府君 74/殷譜經 79 標題數不變(改前 vs 改後 差異=0)
v3.20 朱文端公年譜(1665-1736,公N歲,康熙~乾隆):72 條標題、覆蓋率 100%、推定出生年 1665、三錨點無可疑;表格兩欄合併殘留(「公N歲M年。」M=下一年欄頭、「M年。干支」斷裂)由人工預處理修復——殘留年份移到對應干支前、跨行「十六年\n丁巳」接合,entry_sb 即可匹配出完整「康熙N年干支(公元年),公N歲」標題;干支 OCR 誤字 丙中→丙申;出生條目標題借日期、正文保留「公以八月十一日生於艮溪里」;已知瑕疵:案註引文「雍正元年癸卯恩。科㑹元卷」被無年齡純年份 pattern 誤切標題(人工還原,與陽明年譜卷首序落款同類)
v3.19 陽明先生年譜(1472-1529,先生年N嵗,明·錢德洪編、羅洪先考訂):41 條標題、覆蓋率 100%、推定出生年 1472、三錨點無可疑;語義槽位模型首個真實案例——LLM 讀開頭輸出槽位配置、--slots 與自動檢測結果完全一致(證明配置驅動機制可跑通,不需改正則);L2+LLM 仲裁修正「一十二年丙午→二十二年丙午」(干支丙午=1486、生年1472=15歳自洽);〔〕註文密集、皇帝前綴 明憲宗/孝宗 弘治 由自我進化發現;已知瑕疵:卷首序落款「嘉靖四十二年癸亥」誤切標題、正德七年「七年。壬申」斷行致標題丟「七年」
v3.18 傳主名前綴自動偵測(袁觀瀾先生手編年譜):近代年譜以傳主名為年齡前綴(光緒元年乙亥希濤年十歲希濤三歲),detect_person_prefixes() 偵測「緊接 (年號)N年干支 之後」且非全由年齡數字構成的 2 漢字反覆前綴(≥3 次),並 threading 到 classify_format/_build_full_pattern/verify_output/_split_embedded_years/_merge_multi_line_years;出生條目擴展為「名+生」(同治五年丙寅九月三日希濤生);中華民國 前綴支援(entry_sb/entry_no_sb/entry_bare/annotate_ad_years/extract_reign/_merge_multi_line_years 的跨空行年份+年齡合併);L2 _parse_heading_anchors 顯式公元加 (?<!\d) 防部分匹配((1866年)不再誤報「顯式公元 866」);處理前剝離 HTML 註解(分頁標記);回歸:文貞公 75/涇舟老人 64/警石府君 74/殷譜經 79 標題數不變
v3.17 現代學者年譜支援(劉熙載年譜 A/王欣夫編年事輯稿 B):已有年份標題(#### 嘉慶十八年 癸酉 1813年 一岁#### 一九二三年(民國十二年癸亥)二十三歲)的現代學者編年譜,classify_format 新增 modern 判定(≥2 條可被 try_parse_modern_heading 解析的標題),process_modern_nianpu 不套傳統匹配、只統一標題格式(含標題層級取多數決)+check_modern_headers 完整性檢查(推定出生年、年號年/干支/公元/年齡 四錨點交叉驗證、缺年清單供人工確認);_parse_heading_anchors/verify_anchors 支援 #### 標題與顯式公元年錨點;清代簡體年號(顺治/乾隆/嘉庆/咸丰)入 REIGNS 與公元換算表;try_parse_modern_heading(allow_plain=True) 亦把無 # 前綴的純文字獨立年份行(如 一九三六年(民國二十五年丙子)三十六歲)提升為 #### 標題——「四錨點覆蓋整行」(錨點之外餘留僅括號/空白)+行短,確保是獨立年份標題而非正文敘述(王欣夫檔由 16 條增至 66 條、覆蓋率 100%)
v3.16 桐城吳先生年譜(1840-1903,公年N歲):行首「N年干支,公年N歲」被 entry_bare 搶先匹配、年齡遺留正文的 bug 修復(entry_bare 負向 lookahead 與 _split_embedded_years 均支援帶稱謂年齡);「_完整」檔含兩套重複 OCR 時以較乾淨的第二版去重;第二版整體遺漏年份標題(光緒十二年丙戌)時對照另一版補回
v3.15 蕺山先生年譜(1578-1645):南明遺民紀年(弘光元年=1645,REIGN_START_YEARS 弘光/宏光 1644→1645)、「十有」文言數字前綴排除、崇𥛄/乙丣/天啓十年 OCR 修正
v3.14 CBDB 生卒年核驗 + 年號誤配自動修正(--cbdb/--fix
v3.13 entry_bare 年齡竊取修復、宏治/十不年 OCR(唐一庵)
v3.12 異體字正規化擴充(依文津學志,年號字形/干支)
v3.11 無年齡純年份格式(紫陽/朱熹)+ 宋代皇帝前綴
v3.10 覆蓋率真實化(正文引用過濾)+ 干支句號斷裂自動切分
v3.9 黃黎洲「公N嵗」格式 + 萬厤 OCR 變體
v3.8 L1 格式預分類 + L2 三錨點一致性檢查 + L3 自我進化收緊
v3.7 顧亭林直接年齡型 + 明清之際年號延續
v3.6 公元年號/民國格式,擴展至民國以後
v3.5 宋/元/明年號擴充
v3.4 首年出生句保留規則
v3.3 公元年標註
v3.2 「年」前綴/跨句號出生條目(殷譜經)
v3.1 嵌入式年份拆分、防跨句號吞噬(警石)
v3 自我進化升級(置信度/假陽性過濾/--prune
v2 OCR 容錯、年號字形正規化、季節分段、跨年邊界
v1 初始:年份標題化、年號補全、段落整理

許可證

MIT

About

中国古代年谱整理工具:自动按年份切分、补全年号、标注公元年、整理段落。支援宋元明清年号,具备自我进化能力。为历史人物研究搭建结构化数字文本。 A processor for Chinese chronological biographies (年谱)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages