要做「AI 讀財報」,第一步不是挑模型,而是搞清楚一件事:你手上的 PDF,機器到底讀不進去。 很多人把年報丟給 AI 之後對結果失望,問題往往不在 AI 不夠聰明,而在文件根本沒有以機器可讀的形式進入模型。這篇把「從 PDF 到結構化數據」的路徑完整拆開:三種讀取方式、財報表格為什麼特別難、OCR 之後為什麼必須人工校對,以及最後應該輸出成什麼格式。
三種路徑:先判斷你的 PDF 是哪一種
先建立一個基本觀念:PDF 是「版面描述格式」,不是「數據格式」。 它記錄的是「在這一頁的這個座標畫哪個字」,而不是「這個數字是營業收入」。機器要讀懂財報,得先把版面還原成有意義的結構。
按這個標準,年報 PDF 分成三種,處理路徑完全不同:
| PDF 類型 | 特徵 | 讀取路徑 | 難度 |
|---|---|---|---|
| 文字層 PDF(數位原生) | 游標可以直接選取文字,複製出來是正確字元 | 直接抽取文字層,不需要 OCR | 低 |
| 掃描檔 PDF(圖像) | 游標選不到文字,每一頁本質上是一張圖片 | 必須先 OCR:從圖像辨識出文字 | 高 |
| 混合型 | 部分頁面可選取、部分不可 | 逐頁判斷,分別走兩條路徑 | 中 |
判斷方法很簡單:打開 PDF,試著用游標選取一段文字。選得到、複製出來正確,就是有文字層;選不到,是掃描檔;選得到但複製出來是亂碼,代表內嵌字體缺少正確的編碼對應表,實務上也要當掃描檔處理(轉圖像後 OCR)。港股年報三種都有:近年的報告多數是文字層,年代較久的報告掃描檔比例明顯更高,所以做歷史數據時更要逐份檢查。
三個技術名詞,一次講清楚:
| 名詞 | 回答的問題 | 說明 |
|---|---|---|
| 文字層抽取 | 「這頁有哪些字?」 | 直接讀 PDF 內嵌的文字資訊,速度快、準確率高,但只給你字,不給你結構 |
| OCR(光學字元辨識) | 「這張圖片上有哪些字?」 | 從圖像辨識文字,會輸出每個字的內容與信心度;辨識錯誤無法完全避免 |
| 版面分析 | 「這些字是什麼關係?」 | 判斷一塊文字是標題、內文還是表格儲存格,屬於表格的哪一列哪一欄。財報以表格為主,缺了版面分析,抽出來的數字就是一堆散沙 |
為什麼財報表格特別難
文字抽取只是入門。真正的難點在於,財報表格幾乎集中了所有讓機器頭痛的版面問題:
| 難點 | 具體形態 | 機器處理不好時的後果 |
|---|---|---|
| 跨頁表格 | 附註裡的長表被切成兩頁,第二頁表頭可能只剩「(續)」兩個字 | 第二頁的數字失去行標籤與列標籤,張冠李戴 |
| 合併儲存格 | 「其中:」下面的子項共用一個大類標籤 | 機器把子項當獨立行,數字層級錯亂 |
| 附註編號 | 報表本體寫「見附註 18」,真正的數字在幾十頁之後 | 只抽報表頁拿不到完整資訊,抽錯附註更危險 |
| 單位與幣別 | 表頭寫著「人民幣千元」「港幣百萬元」 | 漏讀這一行,所有數字錯幾個數量級 |
| 負數表示 | 財務報表慣例用括號表示負數,不用減號 | 括號被丟掉,方向整個相反 |
| 多年度欄位 | 本期與上期欄位並排,有的還加比較附註 | 欄位錯位,把上一年的數字當成本期 |
| 腳註與星號 | 數字後面跟著上標 a、b、c,對應頁底說明 | 上標在抽取時丟失,或被誤讀成數字的一部分 |
其中最陰險的是跨頁表格與單位。跨頁表格的錯誤是「看起來完全正常」的:每一行都有數字,只是配錯了標籤,除非你回去看原始頁面,否則不會發現。單位的錯誤則是系統性的:表頭一個「千元」沒讀到,整張表全部放大或縮小一千倍,而且表內部的加總關係依然成立,勾稽檢查也抓不出來——這類錯誤只能靠「錨點數字對帳」防住(下文與 300 頁年報轉結構化 JSON:三表與分部數據 會展開)。
工具選型:三代技術路線
讀財報的工具大致經歷了三代路線,選型時按手上的文件類型匹配,而不是追新:
| 路線 | 適用場景 | 優點 | 主要風險 |
|---|---|---|---|
| 版面解析函式庫 | 文字層 PDF | 快、便宜、結果確定(同樣輸入永遠同樣輸出) | 依賴 PDF 內部結構,版面稍特殊就容易解析失敗 |
| OCR+版面分析引擎 | 掃描檔、混合文件 | 通吃所有文件類型,開源方案成熟 | 辨識錯誤不可完全避免,必須配校對環節 |
| 多模態大模型(VLM) | 快速原型、版面極複雜的文件 | 省事:頁面圖像進去、結構化結果出來 | 幻覺:讀不到時可能「憑常識」補一個而不是承認讀不到;逐頁成本較高 |
第一代路線的常見選擇是開源的 PDF 解析函式庫(例如 pdfplumber、PyMuPDF 這類工具),按座標與線框把文字和表格抽出來。第二代路線以 PaddleOCR 等開源引擎為代表,本站對港股年報做過完整的端到端實測,見 PaddleOCR 實戰:83 秒提取港股年報財務數據。第三代路線目前最活躍,也最需要警惕:「什麼都能讀」的模型,同時也是「什麼都敢編」的模型——用它時必須搭配下文的人工校對與勾稽機制,而且數字類產出一律回查原頁。
三代路線並不互斥,實務上常混用:文字層頁面走解析函式庫,掃描頁面走 OCR,兩條路結果分歧的頁面才交給人工或多模態模型裁定。這樣成本最低,而且每一頁的處理路徑都有記錄可查。
OCR 之後:為什麼還需要人工校對
OCR 引擎會對每個辨識結果給出一個信心度(confidence,介於 0 與 1 之間的數值,代表引擎對自己這次辨識的把握)。信心度高不等於正確,但在財務場景,辨識錯誤的代價結構非常不對稱:錯誤率很低,但單個錯誤的代價極高。
| 錯誤類型 | 辨識錯誤示例 | 後果 |
|---|---|---|
| 形近字元混淆 | 1 與 7、0 與 8、5 與 6 互認 | 單一數字差數倍 |
| 千分位符號 | 逗號被誤讀成 1 或小數點 | 數量級錯誤 |
| 小數點位置 | 小數點漏認或錯位 | 十倍、百倍偏差 |
| 負號遺失 | 括號或減號沒被當成數字的一部分 | 方向反轉,資產變負債 |
| 行列錯位 | 版面分析把數字配到隔壁科目 | 數字本身對,意義全錯 |
所以實務上不是「要不要校對」,而是「怎麼校對才劃算」。四條策略:
- 分級校對:三大報表與關鍵附註全量校對;董事會報告、業務回顧等文字頁抽樣即可。
- 先錨點、後明細:先核對「應該平」的數字——各表的合計、小計、勾稽關係(例如資產總計是否等於負債加權益)。錨點全對,代表大結構沒塌;再抽查明細項。
- 雙引擎比對:同一頁用兩個不同的 OCR 引擎(或不同模型)各跑一次,結果一致的自動通過,不一致的才進人工。人力集中在分歧點,效率最高。
- 低信心優先:保留每個數字的信心度,按信心度由低到高排序人工核對,把時間花在刀刃上。
結構化輸出:JSON schema 的概念
抽取的終點不是「一堆文字」,而是「可查詢、可校驗、可比對的數據」。這裡需要兩個名詞:
- JSON:一種用鍵值對儲存資料的文字格式,機器與人都讀得懂,是結構化數據的事實標準。
- Schema(綱要):對「這份 JSON 應該有哪些欄位、每個欄位是什麼型別、哪些必填」的書面約定。可以理解成一張制式表格的模板:先定好格子,資料只能填進格子裡。
財報結構化最重要的設計原則只有一條:每個數字都要帶著三樣東西一起存——數值本身、來源座標(第幾頁)、處理狀態(校對過沒有)。 以下為教學用假設數字,非任何真實公司:
{
"meta": {
"company": "教學用假設公司",
"fiscalYear": "2025",
"currency": "HKD",
"unit": "thousand",
"sourceFile": "ar2025.pdf"
},
"incomeStatement": {
"revenue": {
"value": 1000000,
"page": 88,
"ocrConfidence": 0.99,
"humanVerified": true
},
"grossProfit": {
"value": 300000,
"page": 88,
"ocrConfidence": 0.97,
"humanVerified": false
}
}
}
注意範例裡的細節:幣別與單位寫在 meta 而不是靠人記憶;每個數值都掛著頁碼;humanVerified 明確標出哪些數字還沒人看過。這樣的設計帶來三個好處:
| 好處 | 說明 |
|---|---|
| 可校驗 | 欄位缺失、單位未宣告,程式可以直接報錯,不靠自覺 |
| 可比對 | 多份年報用同一套 schema,就能直接合併成多年數據表 |
| 可回溯 | 三個月後質疑任何一個數字,都能沿著頁碼回到原始文件 |
完整的 schema 設計、欄位對應與勾稽校對機制,在 300 頁年報轉結構化 JSON:三表與分部數據 有端到端的實作。
AI 會在這裡出錯
最後照本站慣例,把這一環節的典型錯誤與驗證方法整理成清單:
| 出錯形態 | 為什麼危險 | 驗證方法 |
|---|---|---|
| 把掃描檔直接丟給對話模型要數字 | 模型讀不到圖像內容時,可能「憑常識」編一個合理數字給你,而不是告訴你讀不到 | 先確認 PDF 類型;要求模型回報「無法讀取」而不是猜測 |
| 單位假設錯誤 | 模型不看表頭的「千元」「百萬元」,用預設單位輸出 | 每個抽取結果強制帶單位與幣別欄位 |
| 跨頁表格靜默配錯 | 輸出看起來完全正常,錯誤無法從結果本身發現 | 對照原始頁面抽查跨頁表格的接續處 |
| 把信心度當準確率 | 信心度 0.99 只代表引擎自認有把握,不代表對 | 關鍵數字一律人工回看原頁,不信任何單一指標 |
發布前的最終檢查清單:
- 已確認每份 PDF 的類型(文字層/掃描/混合)
- 每張表的單位與幣別都已記錄在結構化數據中
- 錨點數字(各表合計與勾稽關係)已對帳通過
- 關鍵數字已抽樣回看原始頁面
- 每個數字都保留來源頁碼與校對狀態
下一步
- PaddleOCR 實戰:83 秒提取港股年報財務數據:用開源 OCR 引擎 PaddleOCR 對港股年報做端到端實測,包含環境搭建與實作細節。
- 300 頁年報轉結構化 JSON:三表與分部數據:把本文的概念做成完整管線——300 頁年報到三表與分部數據的 JSON。
- 港股調研資訊源地圖:披露易、年報與第三方數據:年報與公告要去哪裡拿?港股調研的資訊源地圖。
- AI 在金融場景的幻覺風險:三種最貴的錯誤:為什麼「模型讀不到就編一個」是金融場景最貴的錯誤,以及四道防線。