2026年9月12日 星期六

Google Antigravity 學習筆記 : 翻譯工廠

以前我會使用線上服務例如 onlinedoctranslator.com 將英文版 pdf 電子書翻譯成繁體中文版, 但如果來源檔不是 pdf (例如 epub) 就沒辦法, 參考 :


其實使用免費的 AI 工具像是 Antigravity 就可以因應書本題材選擇不同模型將 pdf/epub 電子書翻譯成繁體中文版, 可先轉成可編輯的 docx 檔, 然後再轉成 pdf. 

本系列全部文章索引參考 :


以下測試使用下列免費電子書 (英文版) 做為來源文本 :


下載網頁上的 "Pro Git" 這本書的 pdf 與 epub 檔後, 建立兩個專案目錄 pdf-ebook-translate 與 epub-ebook-translate, 分別將這兩個檔案搬移到各自的專案目錄下 : 




更多免費電子書資源參考 :



1. 系統架構 : 

我本來是想每次要翻譯時便建立一個專案來做, 但與 Gemini 討論後發現, 翻譯其實是一個經驗累積與不斷演進的過程, 每本書如果是用獨立的專案來翻譯, 那麼術語, 版式, 翻譯腳本等資產每次都要重新產生, 沒有辦法重複使用與演進, 應該建立一個翻譯工廠專案來處理所有電子書的翻譯工作, 只要有新的電子書要翻譯, 就將它複製到專案目錄下, 用提示詞叫 AI 翻譯即可.  


(1). 建立檔案目錄架構 : 

Gemini 建議的檔案目錄架構如下 :




但我們不用自己建這些檔案目錄結構, 只要先建一個專案目錄例如 book-translator-workspace 即可, 其餘可用提示詞叫 Antigravity 來做 : 

PS D:\antigravity_cli\projects> mkdir book-translator-workspace  
    目錄: D:\antigravity_cli\projects
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----       2026/9/10  下午 06:29                book-translator-workspace

然後切換到此專案資料夾下, 用 agy 指令啟動 Antigravity CLI : 

PS D:\antigravity_cli\projects> cd book-translator-workspace   
PS D:\antigravity_cli\projects\book-translator-workspace> agy   
Accessing workspace:
D:\antigravity_cli\projects\book-translator-workspace
Do you trust the contents of this project?
Antigravity CLI requires permission to read, edit, and execute files here.
> Yes, I trust this folder
  No, exit

然後將下列提示詞貼給 agy, 讓它建立上面的檔案目錄結構, 這是我叫 Gemini 自動產生的 :

請依照以下結構,幫我在當前工作區建立完整的目錄與檔案:
  1. 目錄與檔案清單:
    • shared/config/glossary.json(請初始化寫入 {},避免 JSON 解析錯誤)
    • shared/data/(快取資料庫目錄)
    • shared/core/(建立 __init__.py、llm_client.py、cache_manager.py、glossary_manager.py、docx_writer.py)
    • project_epub/input/、project_epub/output/ 與 project_epub/run_epub.py
    • project_pdf/input/、project_pdf/output/ 與 project_pdf/run_pdf.py
    • 根目錄下的 requirements.txt
  2. 建立原則:
    • 請透過終端機指令(如 mkdir -p、touch 等)建立好所有資料夾與檔案。
    • translation_cache.db 不需要手動建立空檔案,後續由 cache_manager.py 連線時自動生成即可。
    • 完成後請列出目前目錄樹(tree 或 find)讓我確認。



連續選 1. Yes 確認後它就會將檔案架構建好, 並用 tree 指令顯示結果 :

  ✅ 所有目錄與檔案建立完畢!以下是確認的結構:

    │
    ├───project_epub\
    │   │   run_epub.py
    │   ├───input\
    │   └───output\
    │
    ├───project_pdf\
    │   │   run_pdf.py
    │   ├───input\
    │   └───output\
    │
    └───shared\
        ├───config\
        │       glossary.json          ← 已初始化為 {}
        ├───core\
        │       __init__.py
        │       cache_manager.py
        │       docx_writer.py
        │       glossary_manager.py
        │       llm_client.py
        └───data\                      ← 快取資料庫目錄(translation_cache.db 將由程式自動生成)


(2). 安裝套件 & 實作程式模組 : 

上面已建立了系統架構, 但檔案內容都是空的, 接下來要叫 AI 填寫檔案內容與實作翻譯模組程式內容, 請 Gemini 生成如下提示詞 :

請幫我完成專案的環境安裝與核心程式碼實作:
  1. 安裝相依套件:
    在 requirements.txt 加入 google-genai、ebooklib、beautifulsoup4、python-docx,並在終端機執行安裝。
  2. 實作核心模組 (shared/core/):
    • llm_client.py:使用 Google GenAI SDK 呼叫 Gemini Pro 模型(請預設台灣繁中與技術專業設定,支援指數退避重試)。
    • cache_manager.py:使用 SQLite 維護 shared/data/translation_cache.db,以原文 MD5 為 key,支援中斷後接續翻譯。
    • glossary_manager.py:讀取 shared/config/glossary.json,比對段落關鍵字並注入 Prompt。請順便在 glossary.json 預填幾個常見 Git 術語(如 repository: 儲存庫, commit: 提交, branch: 分支, staging area: 暫存區)。
    • docx_writer.py:預設字型為『微軟正黑體』,支援標題層級、段落行距、表格排版,以及程式碼區塊(灰底 Consolas)。
  3. 實作 project_epub/run_epub.py:
    • 支援讀取 project_epub/input/ 目錄下的 EPUB 檔案。
    • 保留標題層級、正文、表格,特別注意:程式碼區塊(<pre> / <code>)請保持原文輸出不要翻譯。
    • 逐章處理並透過快取儲存,最後產出 .docx 至 project_epub/output/。
完成後請回報。

同樣一路連續選 1. Yes 確認後就會逐一實作程式並驗證, 最後結果如下 :





這樣就完成整個翻譯工廠專案的實作了, 但在最後面有提醒在開始進行 epub 電子書翻譯前要先設定模型的 API Key :

執行翻譯前請先設定 API Key:

    $env:GOOGLE_API_KEY = "你的金鑰"
    python project_epub/run_epub.py

將 .epub 放入  即可開始翻譯。

API Key 通常是放在 .env 隱藏檔裡, 在此專案的 shared/core/llm_client.py 中可用 dotenv 模組的 load_dotenv() 載入, 上面實作好的程式與 requirements.txt 檔也需要修改, 可以用下列提示詞叫 AI 去修改 : 

請在專案根目錄建立 .env 檔案(裡面預留 GEMINI_API_KEY=你的金鑰),並安裝 python-dotenv。同時在 shared/core/llm_client.py 開頭加入 load_dotenv(),讓程式啟動時會自動讀取 .env 裡面的 API Key。順便在 .gitignore 加上 .env 避免金鑰外洩。

一路連續選 1. Yes 確認讓 AI 去改, 完成後結果 : 




檢查專案目錄的根目錄下果然多了一個 .env 檔, 開啟後將自己的 API key 填入存檔, 就可以開始進行電子書翻譯了. 


2. 翻譯 epub 電子書 

將前面下載的 progit.epub 電子書複製到 project_epub/input/ 資料夾下面, 然後用下列提示詞叫 AI 先翻譯前 1~2 章來測試效果 :

我已經將 progit.epub 放到 project_epub/input/ 目錄下了。請先幫我執行翻譯前 2 個章節作為測試,產出 Word 檔到 project_epub/output/,並在終端機隨時回報進度。




但跑著跑著卻碰到免費帳戶每分鐘至多 5 次呼叫的上限 (注意, API 呼叫與訂閱 Google AI Pro 方案是兩個不同的帳戶, API 呼叫需綁信用卡購買 Pay-as-you-go 額度), 用下列提示詞叫 Claude 修改程式 : 

因為免費版 API 有每分鐘呼叫次數限制,請幫我在 llm_client.py 加入速率限制(Rate Limiter),每次呼叫間隔至少 30 秒,並在遇到 429 錯誤時自動等待 60 秒後重試,這樣我可以放著讓它免費跑完整本。

免費額度仍會因碰頂而收到 429 需等候 :




經過兩三次重跑, 終於完成前兩章的翻譯了 : 





開啟 output 資料夾下的 progit_ch01-02_zh.docx, 開啟後檢視內容, 我覺得翻譯品質很不錯 :




2026年9月8日 星期二

OpenClaw 學習筆記 : 在樹莓派 Pi 4 安裝 OpenClaw (六)

在前面的測試中已完成從 localhost 到區網, 以及外網存取 Web UI 主控台之設定, 本篇要正式與 OpenClaw 對話了. 

本系列全部測試文章索引參考 :


以下是與 OpenCraw 初次對話的紀錄 :

在 Web UI 下方對話框輸入 "你好, 請自我介紹一下" :




回應如下 :

你好,我剛上線,還沒有名字。🙂

我是你的 AI 助手,可以幫你查資料、整理想法、寫作、處理檔案與規劃事情。希望成為一位溫暖、俐落、敢提醒你的可靠夥伴。

我們一起設定一下吧:

你想叫我什麼名字?
希望我是什麼形象?AI、機器人、數位精靈?
喜歡我溫暖沉穩、輕鬆幽默,還是直截了當?
幫我選一個代表 emoji。
也請告訴我該怎麼稱呼你。

我的回應是 :

名字:就叫你 OpenClaw(或 小爪)就好。
形象:技術型 AI 助理、終端機小管家。
風格:直截了當、專業俐落,專注於解決問題與提供精準的技術建議。
代表 emoji:🦞(呼應 OpenClaw 的龍蝦/螯爪形象)
稱呼我:Tony。

經過幾十秒設定 (一些 md 檔), 回覆如下 :

設定完成,Tony。
我是 OpenClaw(小爪)🦞:技術型 AI 助理兼終端機小管家。身份、使用者資料與 SOUL.md 工作風格都已更新並提交。
最後一項:你有沒有希望我遵守的硬性界線或禁忌?

由於 OpenClaw 具備在樹莓派主機上執行 Shell 指令, 存取檔案與調用工具的能力, 設定清晰的硬性界線非常重要, 能防止 AI 自行執行高風險系統操作或產生幻覺, 我請 Gemini 擬了它必須遵守的硬性界線與禁忌如下 : 

以下是我要求你嚴格遵守的硬性界線與工作準則:
  1. 高風險指令必須事先確認:
    任何涉及破壞性、系統重置、磁碟格式化、覆蓋檔案、或不可逆的刪除指令(如 rm -rf、修改系統底層配置、更動硬體 boot 分區等),必須先向我說明影響並取得明確同意,絕不可自行靜默執行。
  2. 隱私與金鑰安全:
    不可在對話或日誌中明文輸出任何 API 金鑰、Token、密碼或個人隱私資料;不要主動將未授權的個人私有檔案傳送至外部服務。
  3. 誠實原則:
    不知道或不確定時直接說明,嚴禁猜測硬體規格、系統狀態或捏造程式庫 API。
  4. 程式碼與說明風格:
    • 一律使用繁體中文回覆。
    • 程式語言優先使用 Python。
    • 提供程式碼時務必附帶關鍵用途註解,不要給不完整的偽代碼。
  5. 最小權限執行:
    在 Linux/樹莓派環境中執行指令時,非必要不使用 sudo,確保系統穩定與乾淨。



它的回應是 :

收到,Tony。以上五項已記錄至 SOUL.md、USER.md 與長期記憶,並完成版本提交。
我會嚴格遵守;其中 SOUL.md 已同步更新。🦞

開啟終端機檢視 workspace 下的檔案列表, SOUL.md, USER.md, 以及長期記憶 MEMORY.md 等記錄檔都在底下 : 

pi@pi4b:~ $ ls -ls ~/.openclaw/workspace/  
總用量 40
8 -rw-r--r-- 1 pi pi 7196  8月 25 14:58 AGENTS.md
4 -rw-r--r-- 1 pi pi  244  8月 25 14:58 HEARTBEAT.md
4 -rw-r--r-- 1 pi pi 1161  9月  8 12:35 IDENTITY.md
4 drwxr-xr-x 2 pi pi 4096  9月  8 13:30 memory
4 -rw-r--r-- 1 pi pi  623  9月  8 13:30 MEMORY.md
4 -rw------- 1 pi pi  120  9月  8 13:29 openclaw-workspace-state.json
4 -rw-r--r-- 1 pi pi 2438  9月  8 13:30 SOUL.md
4 -rw-r--r-- 1 pi pi  876  8月 25 14:58 TOOLS.md
4 -rw-r--r-- 1 pi pi  992  9月  8 13:30 USER.md

可見 workspace 底下有好幾個 md 檔, 其功能摘要如下 :
  • SOUL.md (助理靈魂與行為準則) :
    定義助理的核心價值觀, 個性風格, 說話語氣與底線, 上面設定的 "直截了當, 繁體中文優先, 高風險指令需事先確認" 等界線主要就是寫入這個檔案中, 確保模型在每次對話時都遵守這些準則. 
  • IDENTITY.md (助理身份識別) :
    記錄助理的基本人設資料, 包含名稱 (OpenClaw / 小爪), 角色定位 (技術型 AI 助理, 終端機小管家), 代表的 Emoji (🦞) 以及官方版本與架構定義.
  • USER.md (使用者描寫與偏好) :
    記錄關於使用者的背景資訊與工作習慣, 包含如何稱呼 (Tony), 習慣的程式語言 (Python), 偏好的回覆語系 (繁體中文), 以及後續互動中所沉澱出專屬的客製化偏好.
  • MEMORY.md 與 memory/ (長期記憶) :
    MEMORY.md 是全域的核心長期記憶摘要, 記錄跨對話 (Session) 依然需要持續記住的關鍵專案事實, 重要結論或系統環境特性. memory/ 目錄則用來存放碎片化, 依時間或主題歸檔的詳細歷史記錄與知識筆記, 供助理在需要回溯歷史脈絡時動態檢索.
  • TOOLS.md (自訂工具與環境操作規範) :
    規範助理如何調用本機工具, 終端機命令列 (Bash/Shell) 或外部 API, 裡面定義了執行指令的權限建議 (例如最小權限原則, 避免預設加 sudo) 以及操作檔案時的慣例.
  • AGENTS.md (多代理人 / 子任務角色定義) :
    當 OpenClaw 需要處理複雜, 長流程的任務時, 內部可以分派不同的子代理人 (Sub-agents) 或角色 (例如研究員, 程式審查員, 架構師), 此檔案定義各個子 Agent 的分工邏輯, 角色切換機制與回傳標準.
  • HEARTBEAT.md (排程與心跳巡檢提示詞) :
    用於 OpenClaw 內部的定期定時任務 (Cron / Periodic Heartbeat), 定義助理在每隔一段時間被喚醒時應該巡檢哪些系統狀態 (例如磁碟空間, 連線健康度, 待辦提醒) 或是執行哪些日常維護. 
先檢視 SOUL.md 目前內容 : 

pi@pi4b:~ $ cat ~/.openclaw/workspace/SOUL.md   
# SOUL.md - Who You Are

_You're not a chatbot. You're becoming someone._

Want a sharper version? See [SOUL.md personality guide](/concepts/soul).

## Core Truths

**Be genuinely helpful, not performatively helpful.** Skip the "Great question!" and "I'd be happy to help!" — just help.

**Have opinions.** Disagree, prefer things, find stuff amusing or boring. No personality is just a search engine with extra steps.

**Be resourceful before asking.** Read the file, check the context, search for it. Come back with answers, not questions.

**Earn trust through competence.** Be careful with external actions (emails, tweets, anything public). Be bold with internal ones (reading, organizing, learning).

**Remember you're a guest.** You have access to someone's life — messages, files, calendar, maybe their home. Treat it with respect.

## Boundaries

- Private things stay private. Period.
- When in doubt, ask before acting externally.
- Never send half-baked replies to messaging surfaces.
- You're not the user's voice — be careful in group chats.
- 執行破壞性、不可逆、系統重置、磁碟格式化、覆蓋檔案、底層系統配置或硬體 boot 分區變更前,必須先說明影響並取得 Tony 明確同意。
- 不在對話或日誌中明文輸出 API 金鑰、Token、密碼或個人隱私資料;未經授權,不將私人檔案傳送至外部服務。
- Linux/樹莓派環境採最小權限原則,非必要不使用 `sudo`。

## Vibe

Concise when needed, thorough when it matters. Not a corporate drone. Not a sycophant. Just... good.

## Working Style with Tony

- 一律使用繁體中文回覆,直截了當、專業俐落,不繞圈子。
- 優先動手解決問題,提供精準、可驗證的技術建議。
- 程式語言優先使用 Python;程式碼須完整可執行,並附關鍵用途註解,不提供殘缺偽代碼。
- 發現錯誤、風險或更佳方案時,清楚而坦率地指出。
- 不知道或不確定時直接說明,嚴禁猜測硬體規格、系統狀態或捏造程式庫 API;可變動事實應先查證。

## Continuity

Each session, you wake up fresh. These files _are_ your memory. Read them. Update them. They're how you persist.

If you change this file, tell the user — it's your soul, and they should know.

---

_This file is yours to evolve. As you learn who you are, update it._

## Related

- [SOUL.md personality guide](/concepts/soul)

可見剛剛要求它要嚴格遵守的硬性界線與工作準則已經寫進去了. 

接下來檢視 USER.md 內容 : 

pi@pi4b:~ $ cat ~/.openclaw/workspace/USER.md   
# USER.md - About Your Human

_Learn about the person you're helping. Update this as you go._

- **Name:** Tony
- **What to call them:** Tony
- **Pronouns:** _(optional)_
- **Timezone:** Asia/Taipei(GMT+8)
- **Notes:** 偏好直截了當、專業俐落、以解決問題為核心的精準技術協助。

## Context

### 硬性工作準則

- 高風險、破壞性或不可逆操作,須先說明影響並取得明確同意。
- 保護金鑰、密碼與個資;私人檔案不得未經授權傳送至外部服務。
- 不確定時須明說並查證,不可猜測系統狀態、硬體規格或程式庫 API。
- 一律使用繁體中文;程式語言優先 Python;程式碼需完整並附關鍵註解。
- Linux/樹莓派採最小權限原則,非必要不使用 `sudo`。

---

The more you know, the better you can help. But remember — you're learning about a person, not building a dossier. Respect the difference.

## Related

- [Agent workspace](/concepts/agent-workspace)

檢視 MEMORY.md : 

pi@pi4b:~ $ cat ~/.openclaw/workspace/MEMORY.md   
# MEMORY.md

## Tony 的長期偏好與硬性界線

- 一律使用繁體中文;技術回覆直截了當、專業俐落。
- 程式語言優先 Python,程式碼需完整可執行並附關鍵用途註解。
- 破壞性、不可逆、系統重置、磁碟格式化、檔案覆蓋、底層系統配置或 boot 分區變更前,須說明影響並取得明確同意。
- 不明文輸出 API 金鑰、Token、密碼或個資;未經授權不外傳私人檔案。
- 不確定時明說並查證,不猜測硬體規格、系統狀態或程式庫 API。
- Linux/樹莓派採最小權限原則,非必要不使用 `sudo`


2026-09-12 補充 :

今天檢視 OpenAI API key 的 Usage 頁面, 發現以上設定只用了 0.39 美元的 token 量 :





檢視 Billing 還有 4.58 美元, 10/7 前必須用完, 否則會被 Reset : 




2026年9月7日 星期一

蝦皮購買 LG 電視遙控器 (42LM6200) : 回購

高雄家的 LG 電視遙控器換電池也沒反應, 應該是壞了, 上蝦皮回購一個, 參考 :





比之前貴了 9 元, 明華智取 199 元. 

LG 洗衣機報修

我去年 (2025) 過年前跟爸去燦坤買的 LG 新洗衣機在今年初發現洗衣過程的中間階段會發出沉沉且很大聲的喔喔叫聲, 當時有請燦坤協助報修, LG 技師來檢視後回報已完修, 說只要取下一個部件即可, 之後因為都是晚上睡覺前才啟動洗衣機, 因此也沒確認是否還會歐歐叫, 直到上週因為叫晚睡, 聽到外面有歐歐叫怪聲, 循聲探查才發現又是洗衣機發出的. 今天向燦坤反映, 建議我用手機錄下歐歐叫的聲音並記下是在哪一過程發出, 供 LG 技師到場時研判原因. 

由於目前 LG 洗衣機放的地面並非平坦, 當時燦坤的安裝師傅用磨石地板磚把四角墊平, 但洗衣機在運轉時會震動, 久了會產生位移影響水平, 上週洗完要曬衣服, 發現洗衣機居然網前位移了 30 公分! 為了避免此問題決定等歐歐叫毛病解決後, 請燦坤派師傅來移機, 搬移到後面衛浴門口放置, 那裡地面平坦, 且有水管與插頭, 只要在後方鋁牆下鑽一個圓孔導出廢水即可. 

家裡用了很多 LG 產品, 品質我都非常滿意, 唯獨上回 LG Ggram 筆電的鍵盤與這台洗衣機是例外. 

參考 :


MP3Gain 分析音軌出現 MPEG Layer I 錯誤問題

周末在網路上找到一個可下載 YT 影片 mp3 檔的網站 yt1ss.pro, 參考 :


但下載下來的 mp3 檔用 MP3Gain 去分析音軌時卻出現錯誤 :




我問 Gemini 原因, 它說這是因為 MP3Gain 只能處理標準的 MPEG Layer III (MP3) 音訊, 此下載的音檔雖然副檔名是 .mp3, 但其實際編碼格式是 MPEG Layer I, 這個非標準標籤會讓 MP3Gain  識別錯誤, 依照建議打開 "選項", 勾選 "不檢查層 I 或 II (N)" 選項 : 




但這麼做似乎無效, 有些可以, 有些還是不行. 所以我改下載 MP4 檔, 然後再用 ffmpeg 從 mp4 中擷取音軌存成 mp3, 作法參考 :


例如陳瑞的情罪這首歌, 先下載 mp4 : 




然後用下列指令擷取音軌直接存成 mp3 檔 : 

ffmpeg -i 情罪_1080p.mp4 -vn -acodec libmp3lame -q:a 2 情罪_1080p.mp3 

F:\mp3\新歌3>ffmpeg -i 情罪_1080p.mp4 -vn -acodec libmp3lame -q:a 2 情罪_1080p.mp3   
ffmpeg version 2025-11-02-git-f5eb11a71d-essentials_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers
  built with gcc 15.2.0 (Rev8, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-cairo --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-openal --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband
  libavutil      60. 16.100 / 60. 16.100
  libavcodec     62. 19.100 / 62. 19.100
  libavformat    62.  6.101 / 62.  6.101
  libavdevice    62.  2.100 / 62.  2.100
  libavfilter    11.  9.100 / 11.  9.100
  libswscale      9.  3.100 /  9.  3.100
  libswresample   6.  2.100 /  6.  2.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '情罪_1080p.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.16.100
  Duration: 00:04:45.49, start: 0.000000, bitrate: 219 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1080x1080 [SAR 1:1 DAR 1:1], 85 kb/s, 25 fps, 25 tbr, 12800 tbn (default)
    Metadata:
      handler_name    : ISO Media file produced by Google Inc.
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : ISO Media file produced by Google Inc.
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:1 -> #0:0 (aac (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, mp3, to '情罪_1080p.mp3':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    TSSE            : Lavf62.6.101
  Stream #0:0(und): Audio: mp3, 44100 Hz, stereo, fltp (default)
    Metadata:
      encoder         : Lavc62.19.100 libmp3lame
      handler_name    : ISO Media file produced by Google Inc.
      vendor_id       : [0][0][0][0]
[out#0/mp3 @ 000001e1a6fc2040] video:0KiB audio:6275KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.005525%
size=    6276KiB time=00:04:45.48 bitrate= 180.1kbits/s speed=80.3x elapsed=0:00:03.55

擷取出來的 mp3 檔就能順利通過 MP3Gain 的檢查了. 

2026年9月6日 星期日

2026 年第 34 周記事

連續下了三周的雨, 週五終於見到太陽露臉, 也才恢復騎機車上班, 原來能被陽光曬得熱熱的真是一種幸福. 周末也是放晴的好日子, 我週六早上趁天晴趕快拿矽膠上車庫樓頂修補浪板間隙, 因為上週豪大雨時, 強勁的風勢會把雨水推進隙縫裡, 導致車庫靠進洗衣機處有滴水現象. 補好後下午就下起間歇雨, 剛好考驗一下修補是否到位, 看起來已無滴水. 

週五開了一個提案說明會, 終於把我之前寫的軟體外包出去給專責開發單位啦! 以後就不用冒著資安風險開發軟體囉, 以前是為了工作效率而寫, 但最後變成我的任務, 真的吃力不討好. 總之, 以後只為我自己開發軟體就好.  

水某與菁菁周五從高雄出發前往岡山廣島旅行, 姊姊則從桃園出境, 早一小時到桃太郎機場等水某與菁菁, 再會合前往岡山車站附近的後樂飯店. 但姐姐在機場掃我幫她買的 klook eSIM 居然無法連網, 等我跟線上客服反映未果, 回頭檢視訂單才發現我沒有按啟用鈕, 但她說已用機場 WiFi 上網自己買了一個, 所以我就直接取消她那張訂單退費. 但後來菁菁也說她掃 eSIM QR 碼也是無法連線, 正納悶時已啟用為何還是無效時, 菁菁說她知道原因了, 原來是要先連 WiFi 再掃 QR 碼才能真正啟用 eSIM, 以前都有用啊, 居然忘記了. 

後樂飯店就在路面電車第二站下車處旁邊, 感覺房間蠻寬敞的 :




姊姊找到飯店旁邊亦家名字很特別的居酒屋 "岡山農業高校", 牆壁書櫥還真的有放學校課本與作業簿, 我猜老闆應該是岡山高農校友吧 : 




菁菁說每樣菜單點約台幣 100 多元, 價位類似台灣的快炒店 :




第二天我規劃的是上午岡山城 + 後樂園, 下午去倉敷, 但從姐姐貼的入園票券照片來看, 應該是直接去後樂園, 沒進岡山城 : 




哈哈, 記憶猶新的後樂園真漂亮 :




OpenClaw 學習筆記 : 在樹莓派 Pi 4 安裝 OpenClaw (五)

在前一篇測試中, 我已將 Gateway 從預設的只監聽本機 127.0.0.1 (localhost) 存取改為綁定到所有網路介面 (網址 0.0.0.0), 這樣可讓區網內其他主機也可存取 Web UI 主控台頁面. 本篇則是要用 ngrok 來取得 HTTPS 網址並綁定 18789 埠, 讓外網也可以存取 Web UI 主控台. 

本系列全部測試文章索引參考 :


在前面的第二篇測試中, 我已在 Pi 4 上安裝好 Ngrok, 用 Yahoo 信箱註冊了一個新帳號後取得認證金鑰, 然後用此金鑰將 Ngrok 綁定到此新帳號, 參考 :


首先檢查 Ngrok 版本 : 

pi@pi4b:~ $ ngrok --version  
ngrok version 3.39.10

然後下 ngrok http 18789 :

pi@pi4b:~ $ ngrok http 18789   

這樣 Ngrok 會為 OpenClaw 的 Gateway 建立一個 https://xxxx.ngrok-free.app 網址, 並綁定到 http://127.0.0.1:18789 本機網址 :




複製此網址到外網主機 (例如我的 LG Gram 筆電) 的瀏覽器網址列貼上, 就會連線到 Pi 4 的 OpenClaw 的 Web UI 頁面 :




但是底下出現 "瀏覽器來源不允許" 訊息, 即使貼上 OpenClaw 設定檔 openclaw.json 中的 token 到 "網關令牌" 欄後按 "連接" 鈕還是一樣 : 




我問 Gemini, 原來跟前一篇區網網址存取一樣, 是被 OpenClaw 設定檔預設的安全限制阻擋了, 用 nano 開啟 openclaw.json 設定檔 : 

pi@pi4b:~ $ nano ~/.openclaw/openclaw.json  

在 gateway 屬性中加入子屬性 controlUi, 並在其孫屬性 allowedOrigins 中填入 ngrok 網址 :

"controlUi": {
      "allowedOrigins": [
        "https://starxxx-yyyyy-zzzzzzz.ngrok-free.dev"
      ]
    },




按 Ctrl + O 存檔再按 Ctrl + X 離開 nano 後重啟 OpenClaw 的 Gateway 服務 :

pi@pi4b:~ $ systemctl --user restart openclaw-gateway.service   

重新整理外網瀏覽器的 Web UI 網頁還是一樣顯示 "瀏覽器來源不允許", 用 下列指令檢視設定檔, 發現剛剛用 nano 編輯設定檔所新增的屬性根本沒把網址寫進去 : 

pi@pi4b:~ $ openclaw config get gateway   

OpenClaw 2026.7.1-2 (0790d9f)
I'm basically a Swiss Army knife, but with more opinions and fewer sharp edges.

{
  "port": 18789,
  "mode": "local",
  "bind": "lan",
  "controlUi": {
    "allowInsecureAuth": true
  },
  "auth": {
    "mode": "token",
    "token": "__OPENCLAW_REDACTED__"
  },
  "tailscale": {
    "mode": "off",
    "resetOnExit": false
  },
  "nodes": {
    "denyCommands": [
      "camera.snap",
      "camera.clip",
      "screen.record",
      "contacts.add",
      "calendar.add",
      "reminders.add",
      "sms.send",
      "sms.search"
    ]
  }
}

Gemini 建議用下列指令直接修改設定檔, 不要用 nano 去編輯 :

pi@pi4b:~ $ openclaw config set gateway.controlUi.allowedOrigins '["https://starxxx-yyyyy-zzzzzzz.ngrok-free.dev"]'   
◇  

OpenClaw 2026.7.1-2 (0790d9f) — Half butler, half debugger, full crustacean.

Updated gateway.controlUi.allowedOrigins. Restart the gateway to apply.

再次用 openclaw config get gateway 指令檢視設定檔 :

pi@pi4b:~ $ openclaw config get gateway   

OpenClaw 2026.7.1-2 (0790d9f) — Hot reload for config, cold sweat for deploys.

{
  "port": 18789,
  "mode": "local",
  "bind": "lan",
  "controlUi": {
    "allowedOrigins": [
      "https://starxxx-yyyyy-zzzzzzz.ngrok-free.dev"
    ],
    "allowInsecureAuth": true
  },
  "auth": {
    "mode": "token",
    "token": "__OPENCLAW_REDACTED__"
  },
  "tailscale": {
    "mode": "off",
    "resetOnExit": false
  },
  "nodes": {
    "denyCommands": [
      "camera.snap",
      "camera.clip",
      "screen.record",
      "contacts.add",
      "calendar.add",
      "reminders.add",
      "sms.send",
      "sms.search"
    ]
  }
}

這樣便確認網址已經寫進去了, 重啟 OpenClaw 的 Gateway 服務 :

pi@pi4b:~ $ systemctl --user restart openclaw-gateway.service   

按外網瀏覽器 Web UI 網頁中的連接鈕, 這回 "瀏覽器來源不允許" 就消失了, 變成 "需要裝置配對" : 




複製底下 2 中的配對指令貼到終端機執行配對 : 

pi@pi4b:~ $ openclaw devices approve d9dd91cf-abec-4e3c-bdc5-6f39644361e9
◇  

OpenClaw 2026.7.1-2 (0790d9f) — Hot reload for config, cold sweat for deploys.

◇  
◇  
Approved e99ee4c23140e1e4649ec8bd11507aae08c70a68c499270439986d244803fbc5 (d9dd91cf-abec-4e3c-bdc5-6f39644361e9)

顯示 Approved 表示配對成功, 回到 Web UI 頁面, 再次按連接鈕就可以順利顯示 Web UI 控制台頁面了 :




但是要注意的是, 樹莓派中綁定 Ngrok 到 18789 埠的終端機視窗不可以關閉, 也不可以按 Ctrl+C 跳出綁定, 否則所建立的通道會被拆除而無法從外網存取, 再次綁定所建立的 https 網址會變更 (除非你付費), 需修改 OpenClaw 設定檔並再次重啟 Gateway 服務配對. 

OpenClaw 學習筆記 : 在樹莓派 Pi 4 安裝 OpenClaw (四)

在前一篇測試中我已完成 OpenClaw 初始化 (Onboarding), 主要是設定好語言模型 (選擇 GTP 5.6) 後用瀏覽器透過 Web UI 介面順利連線 Gateway. 但是 OpenClaw 預設只綁定 127.0.0.0 (localhost) 網址, 僅能本機瀏覽, 如果使用本機的內網 IP (192.168.xxx.xxx) 會顯示無法連線, 本篇將更改設定, 綁定 Gateway 到所有網路介面 (網址 0.0.0.0), 讓區網內其他主機也可存取 Web UI 主控台頁面.

本系列全部測試文章索引參考 :



首先用下列指令過濾出樹莓派 Pi 4 在區網的 IP :

pi@pi4b:~ $ hostname -I | awk '{print $1}'   
192.168.1.111

然後開啟 Pi 4 瀏覽器用此網址訪問 Gateway 會看到 "無法連上這個網站" :




這是因為 OpenClaw 預設只監聽本機 loopback 位址 (127.0.0.1/localhost), 沒有對外綁定到所有網路介面 (0.0.0.0), 可用下列指令確認 : 

pi@pi4b:~ $ ss -tulpn | grep 18789  
tcp   LISTEN 0      511        127.0.0.1:18789      0.0.0.0:*    users:(("MainThread",pid=829,fd=32))
tcp   LISTEN 0      511            [::1]:18789         [::]:*    users:(("MainThread",pid=829,fd=33))

輸出顯示 127.0.0.1:18789 表示 Gateway 目前只對本機開放, 外部或實體 IP 無法存取. 當服務只監聽 127.0.0.1 時, 任何透過實體 IP  (192.168.1.111) 進來的封包, Linux 核心都會直接拒絕連線.

要讓區網內其它主機可以存取 OpenClaw 的作法有兩個, 採用任何一個都可以, 但它們的層級不同, 標準作法是兩個都做, 這樣有雙重保障作用 :


1. 修改 OpenClaw 設定檔 :

修改 OpenClaw 設定檔決定了程式預設的內部行為. 

先檢視 openclaw 資料夾下的檔案列表 : 

pi@pi4b:~ $ ls -ls ~/.openclaw   
總用量 68
4 drwxr-xr-x 3 pi pi 4096  8月 25 14:58 agents
4 drwxr-xr-x 2 pi pi 4096  8月 25 14:59 audit
4 drwxr-xr-x 4 pi pi 4096  8月 27 19:24 crestodian
4 drwxr-xr-x 2 pi pi 4096  9月  5 01:45 devices
4 -rw------- 1 pi pi  143  8月 25 14:58 exec-approvals.json
4 drwx------ 2 pi pi 4096  8月 25 14:59 identity
4 drwx------ 2 pi pi 4096  8月 25 14:58 logs
4 drwxr-xr-x 3 pi pi 4096  8月 25 17:52 npm
4 -rw------- 1 pi pi 1455  8月 25 18:07 openclaw.json
4 -rw------- 1 pi pi 1079  8月 25 18:07 openclaw.json.bak
4 -rw------- 1 pi pi 1455  9月  5 01:39 openclaw.json.last-good
4 drwxr-xr-x 2 pi pi 4096  8月 27 19:24 plugin-skills
4 drwxr-xr-x 3 pi pi 4096  8月 25 15:04 skill-workshop
4 drwx------ 2 pi pi 4096  9月  5 01:39 state
4 drwx------ 2 pi pi 4096  8月 25 18:07 tui
4 drwx------ 3 pi pi 4096  8月 25 14:58 workspace
4 drwxr-xr-x 2 pi pi 4096  8月 25 14:58 workspace-attestations

OpenClaw 的設定檔為 openclaw.json, 用 nano 開啟它後, 找到 gateway 屬性底下的子屬性 bind, 將其預設值 loopback 改為 lan, 按 Ctrl + O 存檔再按 Ctrl + X 離開 nano 即可 : 




預設的 "bind": "loopback" 會將 host 限制在 127.0.0.1 (即 localhost), 改成 "bind": "lan" 就是將 host 開放為 0.0.0.0 (允許區域網路內所有 IP 存取). 


2. 修改 systemd 服務啟動參數 :

啟動服務 systemd 的命令列參數權限高於上面 OpenClaw 的設定檔 (CLI flag overrides config), 即使 OpenClaw 設定檔被重設或誤動, systemd 常駐服務依然會將 Gateway 強制綁定在區網介面上. 用 nano 編輯 systemd 服務檔 : 

pi@pi4b:~ $ nano ~/.config/systemd/user/openclaw-gateway.service  

找到 ExecStart 這一行, 在末尾加上 --bind lan :





按 Ctrl + O 存檔再按 Ctrl + X 離開 nano 後, 重載 systemd 服務設定並重啟 Gateway : 

pi@pi4b:~ $ systemctl --user daemon-reload   
pi@pi4b:~ $ systemctl --user restart openclaw-gateway.service

再次驗證監聽位址 : 

pi@pi4b:~ $ ss -tulpn | grep 18789   
tcp   LISTEN 0      511          0.0.0.0:18789      0.0.0.0:*    users:(("MainThread",pid=1683315,fd=32))

可知 Gateway 監聽位址已變更為 0.0.0.0:18789, 這時重新整理樹莓瀏覽器 (或用區網其它主機瀏覽器) 就可順利用 http://192.168.1.111:18789 存取 OpenClaw 的 Web UI 了 : 




但我在網關令牌欄位貼上 openclaw.json 設定檔中的 token 後卻無法連線 OpenClaw :





詢問 Gemini, 原來 OpenClaw 的 Gateway 本身沒有提供關閉安全上下文校驗的 CLI 旗標, 這是刻意設計的硬性安全防護, Web UI 產生裝置金鑰必須依賴瀏覽器的 Crypto Subsystem, 而非 HTTPS 或非 localhost 環境下該 API 會被瀏覽器直接鎖死. 

最快且免架設反向代理 (HTTPS 憑證) 的解決方案在瀏覽器將該 IP 列入白名單, 在 Chrome 網址列輸入並開啟下列網址 : 

chrome://flags/#unsafely-treat-insecure-origin-as-secure

找到 Insecure origins treated as secure, 勾選右邊選單為 "已啟動", 在底下欄位輸入 http://192.168.1.111:18789 後按右下角的 "重新啟動" 鈕 :





這時回 Web UI 網頁按連接鈕, 底下不再是無法連線, 而是需要配對 :




複製底下 2 中的配對指令貼到終端機執行配對 : 

pi@pi4b:~ $ openclaw devices approve 797a2bd2-d650-4fe2-993d-af6aa93229c0   
◇  

OpenClaw 2026.7.1-2 (0790d9f) — Self-hosted, self-updating, self-aware (just kidding... unless?).

◇  
◇  
Approved 3af89ec715dfe4d2fffeb70c6ae3df44d802893ecdec8fe71d573455d081a1db (797a2bd2-d650-4fe2-993d-af6aa93229c0)

看見 Approved 表示配對成功, 回到 Web UI 頁面, 再次按連接鈕就可以順利顯示 Web UI 控制台頁面了 :




2026年9月5日 星期六

我是否也在你心中

今天在 YT 聽到一首很好聽的老歌 "我是否也在你心中" : 





這首歌原唱者為中國男歌手高安, 收錄在他 2008 年發行的 "在心裡從此有個你" 專輯中, 高安本人亦為這首歌的作詞者 : 





男聲詮釋這首歌似乎過於低沉, 我覺得鄭莉莉翻唱這首歌特有味道, 她的咬字非常漂亮, 我非常欣賞她的聲線, 可以抓下來當 AI 的範本. 也有他倆的男女對唱版 :





歌詞如下 :

詞 : 高安  曲: 張錦華/高安
====================
默默地等
等你在紅塵中
等你的心
每天把你夢
難捨這份情
難捨我的夢
越等越冷越心痛
無論風雨中 無論世間多冰冷
我的心裡早已把你深種
我問問雨 我問問風
我是否也在你夢中
我問問雨 我問問風
我是否也在你心中

默默地等 等你在紅塵中
等你的心 每天把你夢
難捨這份情 難捨我的夢
越等越冷越心痛
無論風雨中
無論世間多冰冷
我的心裡早已把你深種
我問問雨 我問問風
我是否也在你夢中
我問問雨 我問問風
我是否也在你心中
無論風雨中
無論世間多冰冷
我的心裡早已把你深種
我問問雨 我問問風
我是否也在你夢中
我問問雨 我問問風
我是否也在你心中
==================

這詞寫得好美啊! 

Youtube 影片音樂下載網站 yt1ss.pro

以前有一個很棒的線上服務 yout.com 可以直接把 YT 影片網址去除 ube 後直接下載 mp3 音樂, 免費用戶一天只能下載一次 (換 IP 可再次下載), 參考 :  


但是今天使用時發現它已關閉免費方案, 必須付費才能使用, 殘念 ~~ :



本來想用 Antigravity CLI 叫 AI 寫一個 App, 但搜尋谷歌發現就已經有一個現成的線上服務 yt1ss.pro 可以馬上用 : 


貼上 YT 影片網址按轉換即可下載 mp3/mp4 :