一鍵處理原始古籍刻本 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/_清單.tsv(nianpu_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 <輸入檔案> [輸出檔案]將此目錄放入任一 skill 目錄(如 ~/.claude/skills/nianpu-processor/、.opencode/skills/ 等,隨 runtime 而定)後,支援 Agent Skills 標準的智能體會自動載入此 skill,直接用自然語言下達命令即可:
/nianpu-processor <輸入檔案路徑> [輸出檔案路徑] # 或直接說:「整理這個年譜」
「把《顧亭林先生年譜》整理成 Markdown」
「補全年號並標註公元年」
「用 CBDB 核驗傳主生卒年,並修正年號誤標」
不依賴特定 runtime:不採用該標準的環境可直接執行底層腳本(見上方「直接執行」)。
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 歲
── 年號切換記錄 ──
年號切換:道光 → 咸豐
年號切換:咸豐 → 同治
年號切換:同治 → 光緒
============================================================
報告後會附加自我進化報告,顯示本次發現的新年號、字形變體及處理統計。
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公七歲),自動接合為一條完整年份條目。
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年)。
掃描過程中維護一個當前年號狀態。遇到無年號前綴的條目(如 二年乙酉,先生二十七歲),自動補上當前年號變為 順治二年乙酉,先生二十七歲。年號切換時自動更新當前年號。行首裸干支格式則依干支週期推算年序,不直接補年號。
匹配完成後依次執行:
- 合併斷行 — 將因排版斷開的行重新接合,檢測跨年邊界防止誤合
- 嵌入式年份二次掃描 — 合併後段落中隱藏的密集年份(如
八年戊子五歲。九年己丑六歲)拆出為獨立標題 - 月份/季節分段 — 每一年內按
春/夏/秋/冬及月份拆分,標記格式:季節+月份(**春正月**)、僅季節(**春**)、「是」前綴(**是春**);歲末標記(是歲/是年)歸入前段不另分段;季節複合詞(秋闈、冬至)不切分 - 公元年標註 — 對所有含年號+年序的標題,在干支後插入
(YYYY年),換算公式公元年 = 年號元年 + 年序 - 1
每次處理後自動掃描文本,發現不在已知列表中的年號、皇帝前綴、字形變體,存入 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 命令批量清理已無效的學習記錄。
verify_anchors() 對每條標題交叉驗證三個錨點:
- 年號年→公元 vs 干支→公元 vs 年齡→公元;出生年以「干支+年齡」餘類多數決推定(
_consensus_birth_year:一致率 ≥60% 且樣本 ≥5),年號年序多數決落於該餘類內時互相佐證,否則以文本年號 span 解出唯一絕對年——對「年號年序系統性誤刻」(許敬菴尾部錯一年、尙友堂掉十)魯棒 - 相鄰標題的年齡序列是否逐年遞增
不一致者輸出「⚠ 可疑標題」清單供人工複核。--check <已整理.md> 可對既有整理檔唯讀複查。
--cbdb <傳主名> 以中國歷代人物傳記資料庫(CBDB)的生卒年為錨,自動從卷首提取傳主名(或提供別稱映射),帶本地快取,斷網時回退。
- 出生年核驗:比對三錨點多數決推定與 CBDB(差 ≤1 年為虛歲/源文本之別);年譜最大年份 < CBDB 卒年−2 時標註「自訂/自編年譜止於卒前 N 年」。
- 年號誤配自動修正:對 L2 標記的年號年序誤標,以「虛歲→公元」推定真年、干支佐證,依
REIGN_END_YEARS年號終年表判定正確年號年序(如崇禎止於 1644,故 1645 切換為順治二年)。--fix一鍵改寫標題年號年序+公元註記,干支/年齡保留。CBDB 缺席(查無/斷網/無生卒日期)時,--fix回退到內部「干支+年齡」共識出生年(_consensus_birth_year),冷門傳主仍可自動修(陳紫峰「正德三年戊寅→十三年戊寅」實例)。
當 --check 標出的衝突 --fix 無法判定(無年齡/干支歧義)時,nianpu_arbitrate.py 仿標點 chunk→LLM→merge→verify 模式:
--request <已整理.md>:收集三錨點衝突+鄰近標題上下文+推定出生年 →<名>_仲裁請求.md- LLM 讀請求逐條判定(每行:
{標題} → {修正後標題}或→ 不改) --apply <已整理.md> <仲裁結果.md>:保守套用——只動年號年序(含公元註記),干支/年齡/正文/前綴一律保留;修正後年號年須與干支自洽((ad−4)%60 == 干支索引),不滿足的判定直接拒絕;套用後復驗三錨點並報剩餘衝突。
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 覆寫前自動備份 .bak,python 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