July
17th,
2026
蔡桑說怪
日本神話與靈界怪談,有時還有臺灣
共 73 人評分
作者: 蔡亦竹 出版社:圓神出版
買書推薦網址:
Readmoo: 由此去購買。
前言:
這是 2026 年第 1 本讀完的書。今年上半年都沒有寫讀書心得,因為許多書籍都只有看一點點。這一本書也讀了蠻久的,是在找書的時候偶爾看到這一本書,結果整本書到了後半段卻是相當的好看,我一口氣最後就看完。
大綱
沒有最ㄎㄧㄤ,只有更ㄎㄧㄤ!蔡亦竹a.k.a.民俗學中二教授的鬼話連篇大解放!
◆日本初代神明家庭是如何天天上演八點檔狗血劇?
◆日本神話是怎麼把各種「性隱喻」藏在故事裡?
◆妖怪不是統統都是害人精,哪些妖怪可以讓你發大財、上天堂?
◆妖怪界裡也有霸凌現象?只是變老變醜就可以是一種妖怪?
◆玉皇大帝其實不是CEO?觀世音菩薩其實是外籍人士?
◆臺灣也可以有「師公手錶」「妖怪寶可夢」?
臺灣人怕鬼,日本人怕鬼,全世界的人都怕鬼……
沒有看過《鬼話連篇》沒關係,來這裡聽蔡桑練肖話、說鬼神,讓你心裡不再「毛毛der」!
大多數人對日本的印象是──參拜不完的寺廟、超萌超宅的coser、AV女優……威!一定還有靈異故事、貞子、妖怪,以及各種都市傳說!
聽蔡桑如何把毛骨悚然的撞鬼經驗結合流傳千古的歷史故事,看蔡桑如何用超接地氣語法,揭露日本神話背後的文化意涵!
日本民俗學博士蔡亦竹集結多年對民俗學的研究,以神話鬼話做媒介,用輕鬆易懂的鄉民語言,帶讀者進入日本的「神鬼傳奇」。其中包括日本神明的家譜、妖怪與文化的關聯以及其中所蘊藏的寓意等,同時也讓臺灣的眾神明可以臺日友好大串聯地活躍於文字中,讓你懂鬼話、迷鬼神!看完保證媽媽還會問你,為什麼要跪著看這本書?
因為《蔡桑說怪》會讓你跪地大喊:「日本神話到底是嗑了什麼?我也想要來一點!」
這本書可不是那種硬梆梆的學術論文,而是筑波大學民俗學博士蔡亦竹(蔡桑),用超接地氣的「鄉民用語」與爆笑風格,把日本神話和靈界怪談扒開給你看的文化解析書!最精妙的是,他不僅講日本,還會時不時拉回臺灣的民俗視角做對比。
以下為你精煉出這本書的三大核心板塊與重點整理:
核心三大板塊重點整理
板塊分類
核心研究焦點
蔡桑的「台味白話解讀」與亮點
1. 日本的神話原型
日本初代神明家庭(伊邪那岐、伊邪那美、天照、須佐之男)的誕生,以及歷史上的怨靈信仰。
用「色情與暴力、獵奇與SOD大集合」來吐槽日本神話極度放飛自我的荒謬劇情。介紹日本古代史的「怨靈同好會」及天狗等特有種。
2. 妖怪與都市怪談
鄉野鬼怪如何隨著時代演變成現代的都市傳說(如裂口女、超高速阿婆)。
妖怪是「都市化的新寵物」,背後折射出的是現代人的集體焦慮、孤單,以及媒體對靈異風潮的推波助瀾。
3. 有時還有臺灣
臺灣與日本之間信仰的跨海交涉與文化對照(如長崎媽祖與台南飛虎將軍)。
展現「臺日友好大串聯」。透過觀看日本的怪談,反思臺灣人自己的文化根源與主體性。
一、 日本神話:比本土劇還超展開的第一家庭
初代家庭的愛恨情仇:日本的創世神明(伊邪那岐與伊邪那美)決裂過程荒謬又驚悚(老婆在黃泉變腐屍、老公嚇到逃跑離婚),後代的太陽神天照大神和弟弟須佐之男也是相愛相殺。蔡桑笑稱這些情節放到現代來看,簡直是種種驚悚與獵奇情節的大集合。
怨靈同好會:日本歷史上許多被膜拜的高階神明(如學問之神菅原道真、崇德天皇),其實生前都是「死得很慘的政治鬥爭受害者」。因為後人害怕他們變成怨靈報復,才趕緊蓋神社把他們當神拜,形成了日本獨特的怨靈信仰文化。
二、 妖怪與都市傳說:現代人的集體焦慮
妖怪是都市的新寵物:以前的妖怪(如河童、山姥)住在深山樹林,代表人類對大自然的敬畏;都市化之後,妖怪也「搬進城裡」,演變成裂口女、超高速阿婆等都市怪談。
反映現實社會的孤獨:這些現代怪談的誕生,表面上是恐怖故事,骨子裡其實折射出都市人的疏離感與集體焦慮。同時書中也回顧了八〇、九〇年代日本大眾媒體(電視靈異節目)為了收視率推波助瀾的「靈異熱潮興衰史」。
三、 有時還有臺灣:臺日神鬼的奇妙連結
講日文的媽祖與日本神明:書中特別提及臺日信仰的交織。例如日本長崎有多間媽祖廟,那裡的媽祖因為在地化而會「說日文」;而臺灣台南則有「飛虎將軍廟」,供奉的是二戰時為了保護臺灣村民而犧牲的日本飛行員杉浦茂峰。
民俗學的本質是「人的研究」:蔡桑強調,無論是研究日本神話還是臺灣的靈異現象,恐怖或荒謬的終究不是鬼怪,而是背後的人類社會。信仰能撫慰人心,是因為它反映了當代人的思考邏輯。
本書核心精神金句:
「了解人就會理解鬼,妖怪、幽靈都是依據現實的想像。」
我們必須去發現每一個現象背後為何形成的主因。當我們透過日本怪談這面鏡子,深刻理解了民俗傳說的運作,才能帶著更清晰的眼光,回頭發現並認同屬於「臺灣自己」的文化形貌。
心得
這一本書是充滿了相當多的鄉間傳奇,並且最後跟著一篇他的研究報告與實際發生過的事情會讓你覺得驚訝萬分。首先整本書會開始分享著日本鬼怪的一些故事,並且去思考著許多日本神話背後鬼怪故事由來。 並且也會根據著日本色情與暴力跟他們許多鬼怪故事的牽連。
第二話就一些台灣相關故事的分享,並且也會講到「膽大黨」裡面的超高速婆婆的由來,裂嘴女的相關故事。這些都會讓你很想要一口氣閱讀完。隨著最近好像鬼月又要到了,似乎這一系列的書又會變得開始熱門。大家也也可以看看。
繼續閱讀
July
8th,
2026
(圖片來源: 數位憑證皮夾官方網站) 前提: 上一篇入門版做了一個 HR 員工卡系統:同仁自己申請一張員工卡,然後拿它去申請「運動補助」跟「育兒補助」。那一篇的重點是「發卡(Issuer)」跟「驗證(Verifier)」兩個角色分開來看。 這一篇想再往前走一步:如果一個場景要同時扮演驗證方跟發行方,串成一條完整的 DID 生態鏈,會長什麼樣子?我挑的場景是「訪客背書發證」——這也是我在腦力激盪五個檢驗方應用時,覺得最能展示「全鏈」的一個。 順便,這篇會很誠實地把開發過程中踩到的三個坑寫下來,因為那些才是 TIL 真正有價值的部分。 程式碼在這裡:https://github.com/kkdai/did-usecase-visitor 線上體驗:https://did-usecase-visitor-660825558664.asia-east1.run.app 場景:員工門禁 + 訪客背書發證 這個大廳證件台有兩個模式: 員工門禁 / 活動報名:員工用數位皮夾出示員工卡,系統只驗證「是不是有效員工」,驗過就開門 / 報名成功。姓名、生日、子女數這些欄位一律不揭露,留在皮夾裡——這就是選擇性揭露。 訪客背書發證(這篇的主角):由一位在職員工出示員工卡「背書」,驗證通過之後,系統當場核發一張帶到期時間的臨時訪客通行證到訪客的皮夾。 第二個模式的價值在於,它把兩個角色接起來了: 先當 Verifier(驗員工卡)→ 驗過才當 Issuer(發訪客卡) 比起傳統的紙本訪客簿(抄身分證、押證件影本、一堆個資堆在櫃台還要人工回收),數位背書只留下「哪位員工背書」這一筆可追責的資訊,訪客資料留在訪客自己的皮夾,通行證還可以設到期時間。 架構決策:為什麼不直接改上一個專案 這次我開了一個全新的專案、部署到獨立的 Cloud Run 服務,而不是在原本的 HR 專案上加頁面。幾個考量: 靜態前端 + JSON API:原專案用 jade 樣板 server-side render,這次改成 public/ 靜態頁 + 幾支 JSON API(/api/access/qrcode、/api/access/status),前後端分得比較乾淨。 把皮夾 API 呼叫抽成 lib/wallet.js:原專案的 issuer / verifier 呼叫是內嵌在路由裡、而且重複。這次抽成三個函式:requestPresentationQRCode()、getPresentationResult()、issueCredential(),好維護也好測。 狀態改用記憶體:原專案把資料寫進單一 record.js 檔案,在 Cloud Run 這種無狀態環境上寫檔會有問題。這次用簡單的記憶體物件(重啟歸零,展示用途足夠)。 權杖沿用同一個沙盒帳號:issuer / verifier 的 access token 跟上一篇是同一組,直接重用。 驗證「持有員工卡」的部分,我先沿用既有的運動補助 verifier ref 當 fallback(VERIFIER_ACCESS_REF 沒設就用 VERIFIER_SPORT_REF),這樣不用等後台設定就能先跑起來。 踩坑紀錄一:出示成功了,畫面卻一直卡住 這是最經典的一個。手機掃碼、皮夾也完成出示了,但桌面的頁面就是不往下走,一直在輪詢。 第一步先看 Cloud Run 的日誌,發現 /api/access/status 每 3 秒回一次、每次都回「未驗證」。我在後端加了一行把驗證方原始回應印出來的 log,重新部署後再測一次,就抓到真相了: { "data": [ { "credentialType": "0028680530_line_school", "claims": [ { "ename": "english_name", "cname": "英文名字", "value": "Lub" }, { "ename": "join_company", "cname": "入職時間", "value": "2018-10-05" } ] } ], "verifyResult": true, "resultDescription": "success", "transactionId": "8cd7f37b-..." } 看到問題了嗎?回應裡的欄位是 verifyResult(camelCase),而且根本沒有 code 這個欄位。但我沿用上一篇的舊寫法,判斷式是: // 舊的(對不上現在的回應) const verified = data.code === 0 && data.verify_result === true; data.code 是 undefined、data.verify_result 也是 undefined(人家叫 verifyResult),所以永遠 false,永遠 pending。其實驗證早就成功了(verifyResult: true、resultDescription: "success"),只是我判斷的欄位名對不上——看起來沙盒...
繼續閱讀
July
7th,
2026
痛點:同一個專案內的 Gemini API 費用如何精準分攤? 在開發企業級 LLM 服務或是經營多租戶 (Multi-tenant) 平台時,最常被財務與維運團隊問到的問題就是: 「我們同一個 GCP 專案內接了許多不同的業務與 LINE Bot,每天的 Gemini Key 費用都會統統出現在 Gemini API 的範圍,我們有辦法根據不同的 Gemini Key 或不同的使用者來拆分費用嗎?」 直接回答你的問題: 在 Google Cloud 帳單(Cloud Billing)報告中,無法直接「根據不同的 API Key 金鑰名稱」來分開顯示費用。 Google Cloud 的帳單報表最小的歸屬維度是到「專案 (Project)」、「服務 (Service)」和「SKU (產品細項)」,系統並不會把個別的 API Key 字串當作獨立的計費項目。對帳單系統來說,同一個專案內不論你建了 10 把還是 100 把 API Key,通通都會被揉在一起算成一筆 Gemini API 的總帳。 山不轉路轉:Vertex AI 的「請求標籤 (Labels)」救星 如果因為架構限制非得塞在同一個專案,最推薦的做法就是:切換至 Vertex AI 呼叫,並使用「請求標籤 (Labels)」。 如果你目前使用的是 Google AI Studio 的 API Key,它在單一專案內是無法傳遞計費標籤的。但如果你將程式碼改為呼叫 Vertex AI 的 Gemini API(一樣在同一個專案內),Vertex AI 支援在每次發送請求時,動態帶入自訂的 labels(標籤)。 原理與流程 在每次發送請求(例如呼叫 generateContent)時,於 API Request 中帶入特定的 Metadata: { "contents": { ... }, "labels": { "client_id": "info_helper", "api_key_group": "marketing_team" } } 這些自訂標籤會直接被傳遞到 GCP 的帳單系統。之後當你到 GCP 帳單報告中,在「分組依據 (Group by)」選擇你設定的標籤鍵(例如 client_id),就能在同一個專案內,把不同標籤(代表不同服務、客戶或使用者)的費用算得一清二楚! 專案實戰改造:全面導入 Labels 機制 為了完成這個需求,我們盤點了目前 LINE Bot 專案的 API 呼叫架構,並進行了以下重構。 1. 專案 API 呼叫盤點 經由掃描,我們發現專案中絕大部分都是使用 Vertex AI 進行呼叫(17 個 Client 中有 14 個使用 vertexai=True),只有少數例外: Vertex AI 呼叫:包括 GitHub 摘要、多個 Google Maps Grounding 工具、文字摘要、圖片分析、語音轉文字等(共 11 個檔案、19 處呼叫點)。 Gemini API Key 呼叫:main.py 的 Live API、batch_service.py 的 Batch 服務,以及 tts_tool.py 的 TTS...
繼續閱讀
July
1st,
2026
寫在前面:第二回合,換一把利器 在上一篇文章中,我們用 AGY CLI (Antigravity) 從零打造了一個 macOS 即時會議翻譯 App:透過 ScreenCaptureKit 擷取 Zoom / Google Meet 的音訊,送入 Gemini Live API 進行即時翻譯,並在 App 視窗中顯示繁體中文雙語字幕。 App 上線後,開發者在實際開會中發現了幾個讓人皺眉的問題,同時也有了更多功能想法。這一次,我們換上了 Anthropic 的 Claude Code,在終端機中展開了第二回合的深度打磨。 以下記錄這場協作的完整對話流程,還原每一個關鍵決策點。 階段一:揭露隱藏危機 — 10 分鐘後自動停住的 WebSocket 謎團 App 看似完美運作,但開發者在一場真實的長會議後帶著疑問回來了: User: 查一下這個程式碼,為什麼大概即時翻譯大概十多分鐘就會停住,幫我查看可能會有的原因。 閱讀了全部五個 Swift 原始檔,並結合內建的 Gemini Live API 技能文件,精準指出問題根源: Gemini Live API 的 WebSocket 連線有約 10 分鐘的 Session 上限。時間一到,伺服器會主動關閉連線並送出 GoAway 信號。然而原始程式碼對這個情境毫無防備,造成三層失效: 斷線後不重連:didCloseWith 回呼只更新了 UI 上的狀態文字,沒有任何重連邏輯。 音訊靜默丟棄:isConnected = false 之後,每一個來自麥克風的音訊 chunk 都被 guard isConnected else { return } 無聲地吃掉,使用者毫無察覺。 isRunning 狀態錯誤:主視窗的「翻譯中」圖示仍在閃爍,但實際上什麼都沒有發生。 隨即重構了 GeminiLiveConnection.swift,在不改變任何外部介面的前提下,引入三道防線: GoAway 信號提前偵測:在 parseServerResponse() 中解析伺服器發出的 goAway JSON 訊息,不等連線真正斷掉,就提前主動重連,實現無縫接續翻譯。 指數退避自動重連:斷線後以 2s → 4s → 6s 的間隔遞增重試,最多 10 次;重連成功後計數歸零,確保下一次斷線同樣有完整的重試機會。全程靜默,使用者無感。 30 秒 Ping 保活:連線成功後啟動 Timer,每 30 秒向伺服器發送 sendPing,防止中間網路設備因閒置而切斷連線。 修改完成後,開發者執行了 bash build_app.sh 並推送至 GitHub: Build 成功,commit 完成,push 上去了。之後即時翻譯應該可以長時間持續運作,Session 到期時自動靜默重連,使用者不會察覺中斷。 階段二:功能訪談 — 五個問題鎖定兩大優先開發方向 穩定性解決之後,開發者開始思考 App 能走得更遠: User: 幫我仔細研究後給我三個新功能推薦 仔細閱讀程式碼後,先提出一個定向問題,而非直接給出清單: 這三個新功能的方向你比較傾向哪一類? A. 實用性 / UX — 讓日常使用更方便(字幕匯出、快捷鍵、會議記錄) B. 翻譯品質 — 更準確、更自然(多語言偵測、說話人辨識) C. 系統整合 — 與其他工具串接(Notion、Zoom overlay) User: A 三個 UX 功能隨即出爐:懸浮字幕視窗、會議記錄自動匯出、全域快捷鍵。開發者的回應很直接: User: 1 跟 2 都要 接下來是一場簡短的需求訪談,一次只問一個最關鍵的問題: 懸浮視窗要顯示幾行?→...
繼續閱讀
June
20th,
2026
緣起:聊天打到一半,那張梗圖到底在哪? 每個重度聊天的人手機與電腦裡都存了一堆迷因圖,但真正要用的時候——對話進行到一半、想丟一張「謝謝再聯絡」或「我就爛」——卻怎麼也翻不到。檔名是 IMG_4821.jpg,相簿沒有分類,搜尋更是無從下手。 我先看到一個很棒的開源專案 ShiQu1218/MemeTalk,它用 Python + Streamlit + SQLite 打造了一套本地迷因語意搜尋系統,會掃描你本機的迷因資料夾、用 OCR 與向量嵌入建立索引,再做多路召回。功能完整,但偏研究取向、要開瀏覽器跑 Streamlit。 我想要的是更貼近「日常順手工具」的東西: 一個原生 Mac App,一個搜尋框,打我想找的內容,就跳出相關的梗圖,點一下直接複製到剪貼簿。 於是有了 MemeFinder。這篇文章紀錄它從零到「選單列常駐 + 全域快捷鍵」的開發過程,以及途中幾個很有代表性的坑。 系統設計與架構 核心概念很單純:指定一個本機迷因資料夾 → 用 Gemini 幫每張圖建立索引 → 打字做語意搜尋 → 點圖複製。 技術選型上我做了三個關鍵決定: 原生 SwiftUI App,而不是 Electron。剪貼簿複製圖片、全域快捷鍵、選單列常駐,這些用 AppKit 都是一級公民。 Gemini 負責兩件事:用視覺模型 gemini-3-flash-preview 讀出圖中文字、生成繁中描述與情緒標籤;用 gemini-embedding-2 把這些語意轉成 768 維向量。 語意向量 + 關鍵字混合搜尋。純關鍵字對中文召回太差;語意向量才能做到「打相關敘述就找到圖」。 系統架構流向 graph TD A[使用者指定迷因資料夾] -->|掃描 jpg/png/webp| B[Indexer 索引器] B -->|每張圖| C[Gemini 視覺模型 gemini-3-flash-preview] C -->|OCR文字 + 描述 + 標籤 + 情緒| D[Gemini 嵌入 gemini-embedding-2] D -->|768 維向量| E[本機索引檔 index.json] F[使用者打字查詢] -->|⌃⌘M 選單列浮窗| G[Gemini 嵌入查詢字串] G -->|cosine 相似度 + 關鍵字加權| E E -->|排序結果| H[縮圖牆] H -->|點圖| I[NSPasteboard 複製到剪貼簿] 整個專案刻意拆成兩個 Swift Package target: Target 類型 內容 MemeFinder library 邏輯、模型、服務、ViewModel(全部有單元測試) MemeFinderApp executable SwiftUI 畫面 + 選單列殼(薄殼,依賴上面的函式庫) 這個拆分不是裝飾——它直接決定了測試能不能順利跑,後面「踩坑二」會講到為什麼。 核心實作 1. 用 Gemini 視覺模型自動標註迷因圖 索引時,每張圖會送進視覺模型,要求它只輸出 JSON:圖中文字、繁中描述、標籤、情緒。responseMimeType 設成 application/json 來穩定輸出格式: public static func annotateRequest(apiKey: String, imageData: Data, mimeType: String) -> URLRequest { let prompt = """ 你是迷因圖標註助手。請閱讀這張圖,輸出 JSON,欄位: ocr_text(圖中所有文字), description(用繁體中文描述畫面與梗), tags(3-8 個繁體中文關鍵字陣列), emotion(單一情緒詞)。只輸出 JSON。 """ let...
繼續閱讀
June
13th,
2026
異步處理的利器:Gemini Batch API & Webhooks 在開發基於 LLM 的應用程式時,我們常常需要處理大量的數據分析任務——例如一次性分析數十家餐廳的評論、對大量文章進行分類、或是批次生成翻譯。如果採用傳統的同步 API(即時呼叫),不僅會面臨嚴重的 Rate Limit (速率限制) 阻塞,更會因為網路連線逾時(Timeout)與極高的運算成本而宣告失敗。 為了打破這個限制,Google 推出了 Gemini Batch API 與 Webhook API: Gemini Batch API:允許開發者將大量的請求打包成一個 JSONL 檔案一次性上傳。Gemini 會在後台進行非同步的排程運算,不佔用您日常的即時 API 額度(Rate Limits),且其運算成本通常只有即時 API 的一半,是處理非緊急大數據的完美選擇。 Webhook API:傳統的 Batch 任務需要我們在本機不斷寫輪詢(Polling)去檢查狀態。而透過 Webhook,當 Gemini 完成 Batch 運算後,會主動向您指定的 URL 發送一個 HTTP POST 回呼,即時通知任務已完成,讓系統架構變得更加優雅與節能。 這篇文章將紀錄我們如何將這兩項強大的 API 整合進我們的 LINE Bot 餐廳分析助手,實現在行動端一鍵對特定餐廳進行深度評論與招牌菜大數據分析的開發經歷。 系統設計與優化架構 原本的餐廳分析功能是當用戶發送位置時,Bot 會列出附近餐廳,並提供一個通用的「深度評論分析 (Batch)」按鈕,點下去會一次性把附近所有餐廳送去分析。然而這帶來了不好的 UX:分析所有餐廳耗時過長,且用戶往往只想針對他感興趣的某一家特定餐廳進行深挖。 因此,我們將功能優化為動態 Quick Reply 按鈕: 用戶傳送定位,Bot 透過 Google Maps Grounding 搜尋附近餐廳。 用戶端獲得餐廳純文字列表後,Bot 自動以 Gemini 擷取評分最高的前 3 家餐廳名稱。 產生 3 個客製化的 Quick Reply 按鈕(例如:🍴 分析 鼎泰豐)。 用戶點擊特定餐廳按鈕後,Bot 立即回覆「處理中」以避免 LINE 逾時,並在背景提交該單一餐廳的 Batch 任務,待 Gemini 運算完畢後主動推播專屬大數據報告。 系統架構流向 graph TD A[用戶傳送定位] -->|Location Message| B[Google Maps Grounding 搜尋] B -->|餐廳純文字列表| C[Gemini-2.5-flash 擷取前三名餐廳] C -->|動態生成 Quick Reply| D[LINE Bot 回覆 3 個客製化分析按鈕] D -->|用戶點擊特定分析| E[FastAPI Background Task] E -->|立即 Reply ACK| F[LINE 聊天室訊息] E -->|打包 JSONL 並上傳| G[Gemini Batch API 提交] G -->|運算完成 Webhook/Polling 回呼| H[主動 Push 深度報告給用戶] 核心實作 1. 使用 Gemini 從 Grounding 文字中精準提取餐廳名 在 tools/maps_tool.py 中,地圖搜尋返回的是一段富含格式與說明的純文字。我們使用 Gemini-2.5-flash 的...
繼續閱讀