name: paper-summarize-pdf-to-feishu version: 2.0.0 author: yy-fan license: MIT homepage: https://github.com/openclaw/openclaw description: | 總結論文 PDF 為飛書文件(含圖表)。採用主控 - 子代理 (Orchestrator-Subagents) 架構處理長流程。 支援學術論文、技術報告的自動去重、總結、配圖、真實比對稽核與人工確認。 觸發場景:傳送 PDF 附件、"總結這個 PDF"、"把 PDF 寫成飛書文件"、"論文總結"。 metadata: clawdbot: emoji: "📄" requires: bins: - pdftotext - pdfinfo - pdfimages - pdftoppm - tesseract - jq install: - id: apt-poppler kind: apt package: poppler-utils bins: ["pdftotext", "pdfinfo", "pdfimages", "pdftoppm"] label: "Install poppler-utils (PDF tools)" - id: apt-tesseract kind: apt package: tesseract-ocr bins: ["tesseract"] label: "Install tesseract-ocr (OCR)" - id: apt-jq kind: apt package: jq bins: ["jq"] label: "Install jq (JSON processor)"
本技能採用多 Agent 協作模式。作為主控 Agent,你的核心職責是:
❌ 請不要試圖自己在單次對話中完成所有長文本閱讀和細節比對。
收到 PDF 後,第一步必須做:
1. ✅ 完整閱讀本 SKILL.md(不要跳過!)
2. ✅ 檢查前置依賴(which pdftotext pdfinfo ...)
3. ✅ 建立日誌目錄(階段零)
❌ 禁止直接開始處理!
| 原則 | 說明 |
|---|---|
| 不要自己讀長文本 | 必須派生 Reader 子 Agent |
| 不要自己上傳圖片 | 必須派生 Vision 子 Agent |
| 不要自我稽核 | 必須派生 Reviewer + 真實資料注入 |
| 必須等使用者確認 | 階段四必須掛起 |
| 必須用佔位符 | Reader 必須插入 【FIGURE_X】 |
確保以下工具可用:pdftotext, pdfinfo, pdfimages, pdftoppm, tesseract, jq。
如果缺失,通過以下命令安裝:
# PDF 處理工具
sudo apt-get install -y poppler-utils
# OCR 工具
sudo apt-get install -y tesseract-ocr tesseract-ocr-eng tesseract-ocr-chi-sim
# JSON 處理工具(指令碼中大量使用)
sudo apt-get install -y jq
快速檢查:
which pdftotext pdfinfo pdfimages pdftoppm tesseract jq
# 所有命令都應該返回路徑
在階段零開始時,主控 Agent 必須建立以下目錄結構:
mkdir -p "$PAPER_DIR/logs/scripts"
mkdir -p "$PAPER_DIR/progress"
mkdir -p "$PAPER_DIR/errors"
目錄說明:
| 目錄 | 用途 | 內容 |
|------|------|------|
| $PAPER_DIR/logs/ | 統一日誌目錄 | 所有 Agent 和指令碼的日誌 |
| $PAPER_DIR/logs/scripts/ | 指令碼日誌 | extract_metadata.log, locate_figures.log 等 |
| $PAPER_DIR/progress/ | 進度報告 | Markdown 格式的子 Agent 完成報告 |
| $PAPER_DIR/errors/ | 錯誤報告 | 錯誤日誌和堆疊跟蹤 |
優點: - ✅ 每篇論文獨立,不會覆蓋 - ✅ 多人使用不會衝突 - ✅ 清理論文時一起清理 - ✅ 符合"工作目錄"的概念
日誌目錄建立:
mkdir -p "$PAPER_DIR/logs/scripts"
mkdir -p "$PAPER_DIR/progress"
mkdir -p "$PAPER_DIR/errors"
log_master "✅ 日誌目錄已建立"
目標:檢查論文是否已處理,避免重複工作。
提取後設資料:
bash
scripts/extract_metadata.sh <input.pdf> "$PAPER_DIR/metadata.json" "$PAPER_DIR"
檢查去重: ```bash scripts/check_duplicate.sh "$PAPER_DIR/metadata.json" "$PAPERS_DIR" result=$? # 儲存退出碼
# 檢查指令碼輸出中的 RESULT 變數 if echo "$output" | grep -q "RESULT=duplicate"; then echo "❌ 完全重複:該論文已處理過" echo "📋 飛書文件:$(cat $PAPER_DIR/feishu_doc_token.txt)" exit 1 # 停止任務 elif echo "$output" | grep -q "RESULT=possible_duplicate"; then echo "⚠️ 可能重複:已存在飛書文件,但 PDF 檔案未找到" echo "📋 請使用者確認是否繼續" # 等待使用者確認 fi
# 檢查退出碼 if [[ $result -eq 1 ]]; then echo "❌ 去重檢查失敗,停止任務" exit 1 fi ```
$PAPER_DIR,複製 PDF,進入階段一⚠️ 重要:主控 Agent 必須檢查指令碼的退出碼和 RESULT 變數,如果檢測到重複(RESULT=duplicate 或退出碼 1),必須立即停止任務,不得繼續執行後續階段!
日誌要求: - 所有日誌輸出到 $PAPER_DIR/progress/reader.log - 使用標準格式:[YYYY-MM-DD HH:MM:SS] [級別] 訊息 - 關鍵步驟必須記錄(開始、完成、錯誤) - 完成後生成進度報告到 $PAPER_DIR/progress/reader_report.md
目標:提取 PDF 文本並生成結構化總結初稿。
提取文本(主控 Agent 執行):
bash
scripts/extract_pdf_text.sh "$PAPER_DIR/paper.pdf" "$PAPER_DIR/paper.txt" "$PAPER_DIR"
派生閱讀子 Agent(主控 Agent 呼叫 sessions_spawn):
```bash sessions_spawn task="你是一個專業的學術閱讀助手 (Reader)。
任務: 1. 分段讀取 $PAPER_DIR/paper.txt 的完整內容(不要跳過任何部分)。 2. 嚴格按照 summary_template.md 的結構要求,提取以下內容: - 研究背景與動機 - 研究設計 - 方法/系統架構 - 核心結果(包含所有關鍵資料:百分比、p 值、置信區間、樣本量) - 討論與侷限性 - 結論 3. 必須將最終生成的 Markdown 文本儲存到 $PAPER_DIR/summary.md 中。
資料精度要求: - 百分比:28.7%(不要四捨五入) - P 值:P < 0.001 或 P = 0.005 - 樣本量:n=691 或 2,069 人
圖片佔位符要求(重要!):
- 在相關章節內容後插入佔位符標記:【FIGURE_X】
- 佔位符單獨一行,不要與正文混排
- 必須用中文方括號 【】,因為飛書會過濾 HTML 註釋 <!-- -->
- 新增預期描述(幫助 Vision Agent 匹配圖片):
```markdown
## 研究設計
本研究採用隨機對照試驗設計...
【FIGURE_1】
<!-- 預期:流程圖/試驗設計,展示參與者分組和隨訪流程 -->
## 核心結果
LLM 單獨表現優異...
【FIGURE_2】
<!-- 預期:柱狀圖/資料對比,展示主要結局指標 -->
```
進度日誌(必須寫入):
1. 開始任務時,立即寫入 $PAPER_DIR/progress/reader.log:
[YYYY-MM-DD HH:MM:SS] Reader 子 Agent 啟動
[YYYY-MM-DD HH:MM:SS] 開始讀取 paper.txt (共 XXX 行)
2. 每完成一個章節,追加進度:
[YYYY-MM-DD HH:MM:SS] ✅ 完成:研究背景與動機
[YYYY-MM-DD HH:MM:SS] ✅ 完成:研究設計
...
3. 完成後寫入最終報告:
[YYYY-MM-DD HH:MM:SS] ✅ Reader 任務完成
[YYYY-MM-DD HH:MM:SS] 輸出檔案:$PAPER_DIR/summary.md (XXX KB)
[YYYY-MM-DD HH:MM:SS] 總耗時:X 分鐘
完成後彙報(向我報告): ```markdown ## Reader 子 Agent 完成報告
開始時間: YYYY-MM-DD HH:MM
完成時間: YYYY-MM-DD HH:MM
耗時: X 分鐘
### 執行結果 - ✅ 成功生成 summary.md
### 輸出檔案
- $PAPER_DIR/summary.md (XXX KB, XXX 行)
- $PAPER_DIR/progress/reader.log (進度日誌)
### 論文關鍵資訊 - 研究型別: <如 RCT、佇列研究等> - 樣本量: <如 2,069 人> - 主要結局: <如 問診時長減少 28.7%>
### 問題與備註 <如有問題,在此說明;如無問題,填寫"無"> ```
確認後向我(主控 Agent)報告。" ```
$PAPER_DIR/summary.md 已生成。目標:建立飛書文件並插入圖表。
建立飛書文件(主控 Agent 執行):
bash
feishu_doc action=create title="總結:<論文標題>"
獲取 doc_token 並儲存到 $PAPER_DIR/feishu_doc_token.txt。
寫入初稿(主控 Agent 執行):
bash
# ⚠️ 注意:必須使用 Reader 生成的完整 summary.md,不要手動修改或精簡
feishu_doc action=write doc_token="<token>" content="$(cat $PAPER_DIR/summary.md)"
定位圖表(主控 Agent 執行):
bash
scripts/locate_figures.sh "$PAPER_DIR/paper.pdf" "$PAPER_DIR/paper.txt" "$PAPER_DIR/images"
輸出說明:指令碼使用 pdfimages 提取 PDF 中所有嵌入圖片,生成 fig_01.png, fig_02.png 等檔案。
注意:提取的圖片可能包含圖示、線條等小檔案(<10KB),Vision 子 Agent 需要篩選真正的 Figure(通常 >100KB)。
# 如果找不到支援圖片的模型,使用主模型 if [[ -z "$VISION_MODEL" || "$VISION_MODEL" == "null" || "$VISION_MODEL" == "" ]]; then VISION_MODEL=$(jq -r '.agents.defaults.model.primary' "~/.openclaw/openclaw.json") echo "⚠️ 未找到支援圖片的模型,使用主模型:$VISION_MODEL" else echo "👁️ Vision 模型(自動識別):$VISION_MODEL" fi ```
sessions_spawn):```bash sessions_spawn task="你是一個視覺處理專家 (Vision)。
任務: 1. 逐個讀取 $PAPER_DIR/images 下的圖片,確認圖中包含正確的 Figure/Table 標題及內容。 2. 使用 feishu_doc action=upload_image 上傳圖片到飛書文件 (token: $DOC_TOKEN)。 3. 精確定位插入:使用 parent_block_id + index 引數將圖片插入到對應章節。
🚨 飛書操作關鍵規則(必須遵守,否則失敗):
1. 防限流:
- 每次 upload_image 後必須 sleep 3 秒
- 嚴重限流時等待 10 秒後重試
2. 智慧匹配佔位符(修正版流程) ⭐:
- 步驟 1:list_blocks 獲取所有 blocks,從 root block 的 children 陣列中查詢佔位符的位置
**關鍵**:佔位符的 `index` 是它在 root block 的 `children` 陣列中的位置(0-based)
```
1. 獲取 root block(第一個 block)
2. 讀取 root_block.children 陣列
3. 遍歷 children 陣列,找到佔位符 block_id 的位置
4. 該位置就是 index(0-based)
```
**記錄**:每個佔位符的 `block_id` 和 `index`(在 children 陣列中的位置)
步驟 2:對每張圖片執行(必須按順序執行,嚴格遵守):
2a. OCR 提取文字:
bash
tesseract image.png stdout --psm 6
提取 Figure 編號和標題。
2b. 視覺模型理解(重要!OCR 失敗時必須執行):
``
使用read` 工具讀取圖片檔案(路徑:$PAPER_DIR/images/xxx.png)
讀取時附帶問題(讓模型分析圖片): "請分析這張圖片: - 這是什麼型別的圖表?(流程圖/柱狀圖/森林圖/表格/其他) - 圖中有什麼關鍵詞或標題? - 能否識別 Figure 編號或 Table 編號?
請用簡潔的格式回覆,例如: 型別:柱狀圖 關鍵詞:條件識別率,GPT-4o, Llama 3, 94.7% Figure 編號:Figure 2" ```
說明:
- 你的 model 引數已設定為支援圖片的模型(如 qwen3.5-plus)
- 使用 read 工具讀取圖片後,模型會自動"看到"並分析
- 從模型回覆中提取:圖表型別、關鍵詞、Figure 編號
2c. 匹配佔位符:
- 根據 OCR 結果 + 視覺模型提取的關鍵詞 + 佔位符預期描述,匹配最合適的佔位符
- 記錄佔位符的 block_id 和 index
步驟 3:先刪除佔位符,再上傳圖片 ⭐
a. delete_block(block_id: 佔位符的 block_id)
b. 記錄原 index = N
c. sleep 1 秒(讓飛書處理刪除)
d. upload_image(..., parent_block_id: 文件根 ID, index: N)
e. 【關鍵驗證】檢查 file_token:
- 如果 file_token 為空字串 → 上傳失敗,等待 10 秒後重試
- 如果 file_token 不為空 → 上傳成功
f. sleep 3 秒(防限流,必須執行!)
g. 記錄:圖片上傳成功,block_id = xxx
匹配原則:
【FIGURE_1】)步驟 4:最終驗證
list_blocks 檢查 Image block (block_type 27) 數量
應該等於上傳的圖片數量
3. 精確定位引數:
- parent_block_id: 文件根 ID(和 doc_token 相同)
- index: 佔位符 block 的 index(在佔位符位置插入)
- 不填 parent_block_id 則追加到末尾
4. 上傳後驗證:
- 檢查 file_token 不為空字串
- 執行 read 檢視文件,確認圖片數量正確
- 開啟飛書文件確認圖片顯示(不轉圈)
5. 失敗處理(重置法):
- 觸發條件:
- delete_block 返回 404(block 不存在)
- 連續 2 次 upload_image 返回空 file_token
- 文件結構混亂(block IDs 失效)
- 操作步驟:
1. 向主控 Agent 報告需要重置
2. 主控 Agent 執行:feishu_doc action=write doc_token="$DOC_TOKEN" content="$(cat $PAPER_DIR/summary.md)"(使用完整檔案,不要精簡)
3. 重新從步驟 1 開始(list_blocks → 找佔位符 → 上傳圖片)
- 注意:重置後所有佔位符會恢復,需要重新上傳所有圖片
操作流程:
1. 用 write 寫入 summary.md(含佔位符 【FIGURE_X】 和預期描述)
2. list_blocks 獲取所有 blocks,讀取佔位符預期描述
3. 對每張圖片執行智慧匹配(詳細步驟):
```
a. OCR 提取:tesseract image.png stdout --psm 6
b. 視覺模型理解(OCR 失敗時必需):
呼叫 read 工具讀取圖片,附帶問題:
"請分析這張圖片的型別、關鍵詞、Figure 編號"
示例模型回覆:
"型別:柱狀圖
關鍵詞:條件識別率,GPT-4o, 94.7%
Figure 編號:Figure 2"
c. 匹配佔位符:
- 如果 OCR 識別到"Figure 2"→匹配 `【FIGURE_2】`
- 如果 OCR 失敗,用關鍵詞匹配:
"柱狀圖" + "條件識別率" → 匹配預期描述為"柱狀圖,展示條件識別率"的佔位符
d. 獲取佔位符的 index(從 list_blocks 結果中)
```
index 位置 upload_imagedelete_block 刪除佔位符圖片驗證: - 如果 pdfimages 提取的圖片數量 < 文件中 Figure 數量,使用截圖備選方案 - 驗證每張截圖是否包含'Figure X'或'Table X'標題文字 - 純文字頁面不要使用,檢查相鄰頁面(±3 頁範圍)
進度日誌(必須寫入):
1. 開始任務時,立即寫入 $PAPER_DIR/progress/vision.log:
[YYYY-MM-DD HH:MM:SS] Vision 子 Agent 啟動
[YYYY-MM-DD HH:MM:SS] 飛書文件 token: <token>
[YYYY-MM-DD HH:MM:SS] 待上傳圖片:X 張
2. 寫入文本後:
[YYYY-MM-DD HH:MM:SS] ✅ 寫入 summary.md(含佔位符和預期描述)
[YYYY-MM-DD HH:MM:SS] ✅ list_blocks 獲取 blocks 列表
[YYYY-MM-DD HH:MM:SS] ✅ 找到佔位符:【FIGURE_1】(index: X, 預期:流程圖)
3. 每上傳一張圖片,追加進度:
[YYYY-MM-DD HH:MM:SS] 📸 處理圖片:figure_1.png
[YYYY-MM-DD HH:MM:SS] 🔍 OCR 結果:Figure 1, 流程圖
[YYYY-MM-DD HH:MM:SS] 👁️ 視覺模型分析:型別=流程圖,關鍵詞=研究設計,分組
[YYYY-MM-DD HH:MM:SS] 🎯 匹配佔位符:【FIGURE_1】(index: 4, 預期:流程圖)
[YYYY-MM-DD HH:MM:SS] ✅ Fig. 1 上傳成功 (file_token: xxx, 527 KB, index: 4)
[YYYY-MM-DD HH:MM:SS] ✅ 刪除佔位符【FIGURE_1】
[YYYY-MM-DD HH:MM:SS] ⏳ 等待 3 秒(防限流)...
[YYYY-MM-DD HH:MM:SS] 🔍 OCR 結果:失敗(無文字)
[YYYY-MM-DD HH:MM:SS] 👁️ 視覺模型分析:型別=柱狀圖,關鍵詞=條件識別率,GPT-4o, 94.7%
[YYYY-MM-DD HH:MM:SS] 🎯 匹配佔位符:【FIGURE_2】(index: 13, 預期:柱狀圖,展示條件識別率)
[YYYY-MM-DD HH:MM:SS] ✅ Fig. 2 上傳成功 (file_token: xxx, 442 KB, index: 13)
...
4. 完成後寫入最終報告:
[YYYY-MM-DD HH:MM:SS] ✅ Vision 任務完成
[YYYY-MM-DD HH:MM:SS] 成功上傳:X/ Y 張圖片
[YYYY-MM-DD HH:MM:SS] 智慧匹配成功:X 張(命中率 XX%)
[YYYY-MM-DD HH:MM:SS] 總耗時:X 分鐘
完成後彙報(向我報告): ```markdown ## Vision 子 Agent 完成報告
開始時間: YYYY-MM-DD HH:MM
完成時間: YYYY-MM-DD HH:MM
耗時: X 分鐘
### 執行結果 - ✅ 成功建立飛書文件 - ✅ 寫入 summary.md(含佔位符) - ✅ 上傳 X 張圖片(使用佔位符定位) - ✅ 刪除所有佔位符
### 輸出檔案
- 飛書文件連結:https://feishu.cn/docx/$PAPER_DIR/progress/vision.log (進度日誌)
### 圖片上傳詳情 | Figure | 大小 | 佔位符 index | file_token | 匹配方式 | 狀態 | |--------|------|-------------|------------|----------|------| | Fig. 1 | 527 KB | 4 | MsRLbdZbVo9... | OCR | ✅ | | Fig. 2 | 442 KB | 13 | NjuFbqaz8oT... | 視覺模型 | ✅ |
### 匹配統計 - OCR 成功:X 張 - 視覺模型輔助:Y 張 - 匹配成功率:XX%
### 問題與備註 <如有問題,在此說明;如無問題,填寫"無"> ```
確認後向我(主控 Agent)報告。" model="$VISION_MODEL" ```
日誌要求: - 所有日誌輸出到 $PAPER_DIR/progress/reviewer.log - 使用標準格式:[YYYY-MM-DD HH:MM:SS] [級別] 訊息 - 關鍵步驟必須記錄(開始、完成、錯誤) - 完成後生成進度報告到 $PAPER_DIR/progress/reviewer_report.md - 稽核報告儲存到 $PAPER_DIR/progress/audit_report.md
目標:通過注入真實資料防止稽核幻覺。
核心防幻覺機制:必須將原始文本的切片直接餵給稽核模型,不能讓它空對空稽核。
讀取 Fallback 模型(主控 Agent 執行):
bash
FALLBACK_MODEL=$(jq -r '.agents.defaults.model.fallbacks[0]' "~/.openclaw/openclaw.json")
如果沒有配置,則使用當前主模型。告知使用者正在啟動交叉稽核。
派生稽核子 Agent(帶真實資料注入)(主控 Agent 呼叫 sessions_spawn):
```bash sessions_spawn task="你是一個嚴苛的學術稽核員 (Reviewer)。
【原始論文關鍵資料提取】: $(cat $PAPER_DIR/paper.txt | grep -E '%|p<|p=|CI|n=' | head -n 30)
【生成的總結內容】: $(cat $PAPER_DIR/summary.md)
請重點核查: 1. 飛書文件中的百分比、p 值、置信區間、樣本量是否與原始資料存在偏差? 2. 結論是否有無依據的誇大? 3. 格式是否完全符合 summary_template.md 的精度要求?
進度日誌(必須寫入):
1. 開始任務時,立即寫入 $PAPER_DIR/progress/reviewer.log:
[YYYY-MM-DD HH:MM:SS] Reviewer 子 Agent 啟動
[YYYY-MM-DD HH:MM:SS] 稽核模型:<模型名稱>
[YYYY-MM-DD HH:MM:SS] 開始資料一致性核對
2. 完成後寫入最終報告:
[YYYY-MM-DD HH:MM:SS] ✅ Reviewer 任務完成
[YYYY-MM-DD HH:MM:SS] 稽核結果:通過 / 需要修改
[YYYY-MM-DD HH:MM:SS] 總耗時:X 分鐘
輸出要求: 請直接輸出一份詳盡的《稽核報告及修改建議清單》,格式如下:
```markdown ## 稽核報告
### 一致的內容 - <列出哪些地方與原文一致>
### 需要修改的內容 - <列出哪些地方需要修改,具體修改建議>
### 格式問題 - <列出格式不符合要求的地方>
### 總體評價 <通過/需要修改> ```
完成後彙報(向我報告): ```markdown ## Reviewer 子 Agent 完成報告
開始時間: YYYY-MM-DD HH:MM
完成時間: YYYY-MM-DD HH:MM
耗時: X 分鐘
稽核模型: <模型名稱>
### 執行結果 - ✅ 稽核通過 / ⚠️ 需要修改
### 稽核統計 - 一致的內容:X 處 - 需要修改的內容:Y 處 - 格式問題:Z 處
### 輸出檔案
- $PAPER_DIR/progress/reviewer.log (進度日誌)
- $PAPER_DIR/audit_report.md (稽核報告全文)
### 關鍵問題 <如有嚴重問題(如資料錯誤、結論誇大),在此說明>
### 修改建議清單 1. <具體修改建議 1> 2. <具體修改建議 2> ... ```
確認後向我(主控 Agent)報告。" model="$FALLBACK_MODEL" ```
收集稽核報告,準備提交使用者確認。
應用稽核修改(主控 Agent 執行) ⭐:
步驟 4a:讀取稽核報告 ```bash # 讀取稽核報告 AUDIT_REPORT="$PAPER_DIR/progress/audit_report.md"
# 提取修改建議清單 MODIFY_LIST=$(grep -A 20 "修改建議清單" "$AUDIT_REPORT") ```
步驟 4b:逐項應用修改
bash
# 對每個修改建議:
# 1. 使用 list_blocks 找到需要修改的 block_id
# 2. 使用 update_block 修改文本塊
# 3. 使用 insert/append 新增缺失內容
# 4. 記錄修改日誌
修改原則:
- 資料錯誤 → 使用 update_block 修改對應文本塊
- 缺失資料 → 使用 insert 在相應位置新增
- 格式問題 → 使用 update_block 調整格式
- 每次修改後驗證 success: true
步驟 4c:驗證修改
bash
# 使用 read 檢視飛書文件
# 確認所有修改已應用
# 記錄驗證結果到 progress/audit_apply.log
目標:讓使用者確認稽核報告並決定是否修改。
主控 Agent 收集 Reviewer 的《稽核報告及修改建議清單》。
向用戶傳送以下內容:
```
📄 飛書初稿連結:
## 稽核報告摘要
<稽核報告內容>
## 修改建議清單
<具體修改建議>
⏳ 請確認是否採納以上修改建議:
| 回覆 | 操作 |
|---|---|
| 【確認】 | 自動應用修改,輸出最終版 |
| 【修改 xxx】 | 進行微調(告訴我具體修改內容) |
| 【跳過】 | 保留現狀,輸出最終版 |
| ``` |
目標:應用修改並輸出最終版。
如果使用者回覆【確認】: ```bash # 1. 讀取稽核報告中的修改建議清單 AUDIT_REPORT="$PAPER_DIR/progress/audit_report.md"
# 2. 對每個修改建議執行: # a. 使用 list_blocks 找到目標 block_id # b. 使用 update_block 修改內容 # c. 驗證修改成功 (success: true) # d. 記錄修改日誌
# 3. 使用 read 驗證所有修改已應用 # 4. 記錄驗證結果到 progress/audit_apply.log ```
修改方法:
| 修改型別 | 使用工具 | 說明 |
|----------|---------|------|
| 修改文本 | update_block | 需要提供正確的 block_id |
| 新增內容 | insert / append | insert 在指定位置,append 追加到末尾 |
| 修改表格 | write_table_cells | 修改表格單元格內容 |
| 新增表格行 | insert_table_row | 在表格中新增新行 |
驗證流程:
bash
# 1. 使用 read 檢視飛書文件
# 2. 確認所有修改已應用
# 3. 如果有遺漏,重新執行修改
# 4. 記錄最終驗證結果
如果使用者回覆【修改 xxx】:根據使用者具體要求修改。
如果使用者回覆【跳過】:保持現狀,記錄"使用者選擇跳過修改"。
summary_template.md 的表格要求):```markdown ## 📝 文件資訊
| 專案 | 資訊 |
|---|---|
| 撰寫人 | Lux(qwencode/qwen3.5-plus) |
| 稽核狀態 | ✅ 已稽核 / ⏭️ 已跳過 |
| 稽核模型 | <稽核模型名稱> |
| 生成時間 | |
| 文件版本 | v1.0(最終版) |
稽核修改記錄: - ✅ 核實接受日期:已確認 - ✅ 關鍵資料已核對(X 處一致,Y 處已補充) - ✅ 圖片已上傳(X 張) ```
更新本地後設資料:
儲存最終狀態到 $PAPER_DIR/final_metadata.json。
向用戶交付最終版連結,流程結束。
記錄修改日誌 ⭐:
bash
# 儲存修改記錄到 progress/audit_apply.log
# 包含:修改項、修改前、修改後、修改時間、驗證結果
如果在【階段零】判定傳入的 PDF 為補充材料:
主控 Agent 讀取已有的飛書文件 token:
bash
DOC_TOKEN=$(cat "$PAPER_DIR/feishu_doc_token.txt")
執行合併指令碼:
bash
scripts/merge_supplement.sh "$PAPER_DIR" "<supplement.pdf>" "$DOC_TOKEN"
主控 Agent 呼叫 feishu_doc action=append 將補充摘要追加到主文件的"📎 補充材料"章節中。
無需走完整生成和稽核流程。
原則:每個階段完成後,立即清理已完成的子 Agent,只保留主控 Agent
實現:
1. 派生子 Agent 時記錄 session_key
2. 等待子 Agent 完成(sessions_yield)
3. 獲取子 Agent 結果
4. 立即清理:subagents action=kill target="$session_key"
示例:
# 階段一:Reader Agent
reader_session=$(sessions_spawn task="Reader..." label="Reader-Agent")
sessions_yield # 等待完成
summary_md=$(cat "$PAPER_DIR/summary.md") # 獲取結果
subagents action=kill target="$reader_session" # ← 清理 Reader
# 階段二:Vision Agent
vision_session=$(sessions_spawn task="Vision..." label="Vision-Agent")
sessions_yield
doc_token=$(cat "$PAPER_DIR/feishu_doc_token.txt")
subagents action=kill target="$vision_session" # ← 清理 Vision
# 階段三:Reviewer Agent
reviewer_session=$(sessions_spawn task="Reviewer..." label="Reviewer-Agent")
sessions_yield
audit_report=$(cat "$PAPER_DIR/audit_report.md")
subagents action=kill target="$reviewer_session" # ← 清理 Reviewer
# 最終:只保留主控 Agent
好處: - ✅ 只保留主控 Agent,降低記憶體佔用(節省 ~300-400MB/每個階段) - ✅ 避免子 Agent 堆積 - ✅ 明確的資源管理
sessions_spawn 派生子 Agent與使用者溝通確認
❌ 不應該做的:
核心原則:
📌 通用工具用法參考
feishu-doc技能文件 📌 本節只記錄本業務特有的糾偏規則和易錯點
規則:任何涉及 upload_image 的迴圈操作,必須:
feishu_doc action=upload_image ...
sleep 3 # 必須間隔 3 秒
feishu_doc action=upload_image ...
sleep 3 # 必須間隔 3 秒
違反後果:
- file_token 為空字串
- 圖片 block 建立但圖片轉圈不顯示
- 需要刪除所有空 token block 重新上傳
嚴重限流時: - 等待 10 秒後重試 - 增加間隔到 5 秒
適用場景:
- delete_block 返回 404(block 不存在)
- 文件結構混亂,需要清理
- Block IDs 失效,無法定位
- 連續 2 次 upload_image 返回空 file_token
操作步驟:
# 1. 使用 Reader 生成的完整 summary.md(不要精簡)
# 2. 全量覆蓋(清除所有舊 blocks)
feishu_doc action=write doc_token="$DOC_TOKEN" content="$(cat $PAPER_DIR/summary.md)"
# 3. 重新 upload_image 上傳圖片
# 4. read 檢視文件確認結果
效果:清除所有舊 blocks,恢復到乾淨狀態。
方案對比:
| 場景 | 方案 | 地位 |
|------|------|------|
| 文件結構混亂、block IDs 失效 | 重置法(write 全量覆蓋) | 兜底方案 |
| 圖片精確定位 | 佔位符法(【FIGURE_X】) | 首選方案 |
歷史經驗:
- 2026-03-26/27:遇到 delete_block 404 錯誤,使用重置法成功
- 2026-03-28:佔位符方案驗證成功,成為首選方案
任何飛書文件修改操作前,必須:
1. list_blocks 獲取最新 blocks 列表
2. 確認目標 blocks 存在(檢查 block IDs)
3. 逐個呼叫工具(不批次)
4. 操作後再次 list_blocks + read 驗證
引數說明:
- parent_block_id: 文件根 ID(和 doc_token 相同)
- index: 從 list_blocks 的 children 陣列獲取(0-based)
- 不填 parent_block_id 則自動追加到末尾
定位方法:
# 從 list_blocks 返回中找到章節標題的 block_id
# 計算其 index(在 children 陣列中的位置)
# 上傳圖片時 index = 章節 index + 1
插入策略: - 從文件末尾往前插(倒序),避免索引偏移 - Fig. 1 插入到 4.1 章節後,Fig. 2 插入到 4.2 章節後
必須檢查:
- [ ] upload_image 返回的 file_token 不為空字串
- [ ] read 檢視文件,確認圖片數量正確
- [ ] 開啟飛書文件確認圖片顯示(不轉圈)
驗證命令:
feishu_doc action=read doc_token="$DOC_TOKEN"
# 檢查 "Image" 數量是否正確
# 如果 "Image": 7,說明 7 張圖片都已成功上傳
不要混淆:
| 操作 | 用途 | 常見錯誤 | 解決方案 |
|------|------|----------|----------|
| feishu_doc delete_block | 刪除文件塊 | 404(block 不存在) | 用重置法(write 全量覆蓋) |
| feishu_drive delete | 刪除雲空間檔案 | 400(許可權問題) | 檢查檔案許可權 |
子 Agent 錯誤報告機制:
子 Agent 錯誤報告機制:
如果子 Agent 執行失敗,必須寫入錯誤報告:
# 錯誤報告格式 ($PAPER_DIR/errors/<agent>.log)
## 錯誤報告
**子 Agent**: Reader/Vision/Reviewer
**錯誤型別**: 指令碼執行失敗 / API 限流 / 檔案不存在 / 超時 / ...
**錯誤資訊**: <具體錯誤內容>
**發生時間**: YYYY-MM-DD HH:MM:SS
**重試次數**: X/3
### 建議操作
<主控 Agent 應該採取的行動,如:重試、跳過、人工介入等>
主控 Agent 響應流程:
$PAPER_DIR/errors/<agent>.log常見錯誤處理:
| 錯誤型別 | 錯誤程式碼 | 處理方案 |
|---|---|---|
| 飛書 API 限流 | 429 | 等待 10 秒後重試,增加 sleep 時間到 5 秒 |
| Block 不存在 | 404 | 重新獲取 blocks 列表,或使用重置法 |
| PDF 無法提取文本 | - | 檢查是否為掃描版,建議使用 OCR |
| 子 Agent 超時 | - | 增加 timeoutSeconds,或拆分任務 |
| 檔案不存在 | - | 檢查路徑,重新執行前置指令碼 |
| jq 解析失敗 | - | 檢查 JSON 格式,手動修復 metadata.json |
| OCR 識別失敗 | - | 檢查 tesseract 是否安裝,語言包是否存在 |
| 圖片上傳失敗 | - | 檢查圖片檔案是否存在,大小是否超過限制 |
重試機制示例:
# 飛書 API 呼叫重試
max_retries=3
retry_count=0
while [[ $retry_count -lt $max_retries ]]; do
result=$(feishu_doc action=upload_image ...)
if echo "$result" | grep -q '"success": true'; then
echo "✅ 上傳成功"
break
elif echo "$result" | grep -q "429"; then
retry_count=$((retry_count + 1))
echo "⚠️ API 限流,等待 10 秒後重試 ($retry_count/$max_retries)"
sleep 10
else
echo "❌ 上傳失敗:$result"
break
fi
done
if [[ $retry_count -eq $max_retries ]]; then
echo "❌ 達到最大重試次數,任務失敗"
# 寫入錯誤日誌
echo "錯誤型別:API 限流" >> "$PAPER_DIR/errors/vision.log"
echo "重試次數:$max_retries" >> "$PAPER_DIR/errors/vision.log"
echo "建議操作:等待 5 分鐘後重試,或聯絡使用者" >> "$PAPER_DIR/errors/vision.log"
fi
| 子 Agent | 職責 | 關鍵技能 | 進度日誌 |
|---|---|---|---|
| Reader | 長文本閱讀、總結生成 | 分段讀取、資訊提取、結構化輸出 | progress_reader.log |
| Vision | 圖片稽核、飛書上傳 | 圖片識別、upload_image、限流規避 |
progress_vision.log |
| Reviewer | 資料一致性核對 | 資料比對、格式檢查、報告生成 | progress/reviewer.log |
每個子 Agent 執行時都會生成進度日誌檔案,便於除錯和審計:
| 檔案 | 說明 | 生成時機 |
|---|---|---|
$PAPER_DIR/progress/reader.log |
Reader 子 Agent 進度 | 閱讀論文時 |
$PAPER_DIR/progress/vision.log |
Vision 子 Agent 進度 | 上傳圖片時 |
$PAPER_DIR/progress/reviewer.log |
Reviewer 子 Agent 進度 | 稽核資料時 |
$PAPER_DIR/errors/<agent>.log |
錯誤報告 | 發生錯誤時 |
[YYYY-MM-DD HH:MM:SS] <Agent> 子 Agent 啟動
[YYYY-MM-DD HH:MM:SS] 開始 <任務描述>
[YYYY-MM-DD HH:MM:SS] ✅ 完成:<步驟 1>
[YYYY-MM-DD HH:MM:SS] ✅ 完成:<步驟 2>
[YYYY-MM-DD HH:MM:SS] ✅ <Agent> 任務完成
[YYYY-MM-DD HH:MM:SS] 輸出檔案:<檔案路徑>
[YYYY-MM-DD HH:MM:SS] 總耗時:X 分鐘
## 錯誤報告
**子 Agent**: <Agent 名稱>
**錯誤型別**: <錯誤型別>
**錯誤資訊**: <具體錯誤>
**發生時間**: YYYY-MM-DD HH:MM:SS
**重試次數**: X/3
### 建議操作
<主控 Agent 應該採取的行動>
## Reader 子 Agent 完成報告
**開始時間**: YYYY-MM-DD HH:MM
**完成時間**: YYYY-MM-DD HH:MM
**耗時**: X 分鐘
### 執行結果
- ✅ 成功生成 summary.md
### 輸出檔案
- `$PAPER_DIR/summary.md` (XXX KB, XXX 行)
- `$PAPER_DIR/progress/reader.log` (進度日誌)
### 論文關鍵資訊
- **研究型別**: <如 RCT、佇列研究等>
- **樣本量**: <如 2,069 人>
- **主要結局**: <如 問診時長減少 28.7%>
### 問題與備註
<如有問題,在此說明;如無問題,填寫"無">
### 詳細進度
| 步驟 | 狀態 | 耗時 |
|------|------|------|
| 讀取 paper.txt | ✅ 完成 | X 秒 |
| 提取研究背景 | ✅ 完成 | X 秒 |
| 提取研究設計 | ✅ 完成 | X 秒 |
| 提取核心結果 | ✅ 完成 | X 秒 |
| 生成 summary.md | ✅ 完成 | X 秒 |
## Vision 子 Agent 完成報告
**開始時間**: YYYY-MM-DD HH:MM
**完成時間**: YYYY-MM-DD HH:MM
**耗時**: X 分鐘
### 執行結果
- ✅ 成功上傳 X/Y 張圖片
### 圖片上傳清單
| Figure | file_token | 大小 | 插入位置 | 狀態 |
|--------|------------|------|----------|------|
| Fig. 1 | `xxx...` | XXX KB | 4.1 章節後 | ✅ |
### 輸出檔案
- `$PAPER_DIR/progress/vision.log` (進度日誌)
### 問題與備註
<如有問題,在此說明>
### 詳細進度
| 步驟 | 狀態 | 耗時 |
|------|------|------|
| 獲取 blocks 列表 | ✅ 完成 | X 秒 |
| 上傳 Fig. 1 | ✅ 完成 | X 秒 |
| 上傳 Fig. 2 | ✅ 完成 | X 秒 |
| 上傳 Fig. 3 | ✅ 完成 | X 秒 |
| 驗證圖片數量 | ✅ 完成 | X 秒 |
## Reviewer 子 Agent 完成報告
**開始時間**: YYYY-MM-DD HH:MM
**完成時間**: YYYY-MM-DD HH:MM
**耗時**: X 分鐘
**稽核模型**: <模型名稱>
### 執行結果
- ✅ 稽核通過 / ⚠️ 需要修改
### 稽核統計
- 一致的內容:X 處
- 需要修改的內容:Y 處
- 格式問題:Z 處
### 輸出檔案
- `$PAPER_DIR/progress/reviewer.log` (進度日誌)
- `$PAPER_DIR/audit_report.md` (稽核報告全文)
### 關鍵問題
<如有嚴重問題,在此說明>
### 修改建議清單
1. <具體修改建議 1>
2. <具體修改建議 2>
...
### 詳細進度
| 步驟 | 狀態 | 耗時 |
|------|------|------|
| 讀取原始資料 | ✅ 完成 | X 秒 |
| 讀取總結內容 | ✅ 完成 | X 秒 |
| 資料一致性核對 | ✅ 完成 | X 秒 |
| 格式檢查 | ✅ 完成 | X 秒 |
| 生成稽核報告 | ✅ 完成 | X 秒 |
# 關鍵步驟確認函式
confirm_step() {
local step_name=$1
local log_file=$2
log_master "🔍 確認步驟:$step_name"
if [[ ! -f "$log_file" ]]; then
log_master "❌ 日誌檔案不存在:$log_file"
return 1
fi
# 檢查是否有 ERROR
if grep -q "\[ERROR\]" "$log_file"; then
log_master "❌ 檢測到錯誤,檢視錯誤日誌"
cat "$log_file" | grep "\[ERROR\]"
return 1
fi
# 檢查是否完成
if grep -q "✅ 完成\|\[SUCCESS\]" "$log_file"; then
log_master "✅ 步驟確認成功:$step_name"
return 0
else
log_master "⚠️ 步驟未完成:$step_name"
return 1
fi
}
# 使用示例(在每個階段完成後呼叫)
# confirm_step "Reader 完成" "$PAPER_DIR/logs/reader.log" || exit 1
# confirm_step "Vision 完成" "$PAPER_DIR/logs/vision.log" || exit 1
# confirm_step "Reviewer 完成" "$PAPER_DIR/logs/reviewer.log" || exit 1
小蔥技能站7w4.net發現了升級外掛。
技能會自動從 ~/.openclaw/openclaw.json 中查詢支援圖片輸入的模型:
# 自動識別邏輯
VISION_MODEL=$(jq -r '
.models.providers | to_entries[] |
.value.models[] |
select(.input and (.input | index("image"))) |
.id |
first
' "~/.openclaw/openclaw.json")
識別邏輯:
1. 遍歷所有 provider 的 models
2. 查詢 input 欄位包含 "image" 的模型
3. 使用找到的第一個模型
4. 如果找不到,回退到 model.primary
如何判斷模型是否支援圖片:
檢視 models.providers[].models[] 中的 input 欄位:
{
"models": {
"providers": {
"qwencode": {
"models": [
{
"id": "qwen3.5-plus",
"name": "Qwen3.5 Plus",
"input": ["text", "image"] ← 支援圖片
}
]
}
}
}
}
優點: - ✅ 無需手動配置 - ✅ 自動選擇支援圖片的模型 - ✅ 向後相容(無配置也能用) - ✅ 符合"約定優於配置"原則
這是一款高質量的論文總結工具,能夠自動讀取 PDF 論文、提取關鍵資訊、生成結構清晰的總結文件,並支援將圖表圖片上傳到飛書文件。採用了多 Agent 協作模式,讓不同 Agent 分別負責閱讀理解、圖片處理、內容稽核,流程嚴謹且不容易出錯,還有人工確認環節把關質量。優點是總結規範、資料準確、帶圖片,缺點是依賴外部工具處理 PDF,對掃描版論文效果可能有限。