2026年10月22日 星期四

Claude Code 學習筆記 : 將文件製作成網站發布到 Vercel

上週四上完 Karen 的直播課程後一直在忙, 都沒時間完成作業, 今天晚上要上第二堂課了, 趕緊來把作業寫完吧! 我已經在筆電安裝好 Vercel CLI 與 Vercel 佈署技能包 agent-skills, 參考 : 


先到 Claude Console 儀錶板查看目前的儲值餘額, 目前帳上有 9.8 美元 (上回安裝沒有進 Claude Code 啊, 奇怪哪裡用掉 0.2 美元?), 方便專案完成後計算花了多少錢 :




第一堂課的作業是用 Claude Code 將一個文件製作成網站, 並發佈到 Vercel 平台上. 

首先建立一個專案資料夾, 然後切換到此資料夾下開啟 claude : 

D:\claude_code\projects\mkdir karen_class_1 
D:\claude_code\projects\cd karen_class_1      
D:\claude_code\projects\karen_class_1\clasude 

接下來準備網站素材, 剛好我今天用 agy 製作了 11 月底京都奈良賞楓之旅的行程規劃書, 那就用這個 pdf 檔作為素材, 把這次的旅遊行程製作成一個 Web app 吧! 參考 :


這份行程規畫書我放在 GitHub :


將此 pdf 檔放在專案目錄 karen_class_1 下後在 Claude Code 輸入提示詞即可 : 

>請讀取專案資料夾下的行程規劃書 "20261123-28京都大阪奈良賞楓之旅行程規劃_v1.pdf", 根據此文件內容幫我設計一個京都大阪 6 日家族賞楓旅遊的一頁式行程網站。採用溫暖的秋日楓紅配色,包含出發倒數計時、Day 1 到 Day 6 的時間軸切換頁籤、每個景點的交通與長輩友善提示卡片,以及一個使用 LocalStorage 記錄勾選狀態的行前打包清單,介面需針對手機瀏覽最佳化。




然後 Claude 就開始進行讀檔與網頁設計, 只用了 4 分鐘左右就完成了 :




這時專案目錄下就多了一個 index.html 檔 (因為是一頁式網頁), 點擊用瀏覽器開啟, 發現效果真不錯哩, 功能非常完整, 布局也很俐落, 可以發布到 Vercel 交差啦 :




回到 Clude Code, 直接叫它幫我佈署 :

> 請幫我佈署到 Vercel 




只花了一分鐘就搞定了 : 




點中間的預覽網址 (preview link) 會開啟瀏覽器顯示此 Web app, 但若分享給別人則會要求登入 Vercel, 因為這是非正式網址, Vercel 專案預設開啟了部署保護機制, 必須登入開發者的 Vercel 帳號才能看到網站. 

取得正式網址須進入 Vercel 儀錶板後點擊專案 :





在 Domain 項目下就可以找到正式網址了 :





Google Antigravity 學習筆記 : 自助旅遊規劃 (四)

1123~11/28 京都奈良賞楓之旅行程, 經過與 Gemini 的兩輪討論後大致已定案, 參考 :


今天以 v2 版的規劃, 用 agy 撰寫 Word 格式的行程規劃書.


1. 建立專案資料夾與準備行程檔案 : 

首先建立一個專案資料夾 kyoto_maple_trip 並啟動 agy :

D:\antigravity_cli\projects\mkdir kyoto_maple_trip   
D:\antigravity_cli\projects\cd kyoto_maple_trip   
D:\antigravity_cli\projects\kyoto_maple_trip\agy 

然後到 GitHub 下載行程規劃書的參考範本 pdf 檔 :


將下載的 pdf 範本檔放到專案資料夾下, 然後將 v2 的行程規劃複製到記事本, 儲存到專案資料夾下的 "行程規劃.txt" 檔裡 :

航班 : 
去程 : 虎航 IT284 高雄 KHH 06:55 ~ 10:40 大阪 KIX
回程 : 虎航 IT285 大阪 KIX 11:30 ~ 14:00 高雄 KHH

住宿 : 
11/23~11/25 : 東福寺民宿 Private Villa Tofukuji (京都市福稲柿本町17−11) 
11/25~11/28 : 日和飯店(Hiyori Hotel Osaka Namba Station, 大阪市浪速區難波 3-1-2 )


行程規劃 : 
Day 1:11/23(週一)抵達關西 ➔ 入住東福寺民宿
航班與交通:高雄直飛關西機場,搭乘 JR 特急 Haruka 直達京都車站,轉搭 JR 奈良線(1 站、2 分鐘)抵達東福寺站,步行至民宿辦理入住。
備註:當天為日本三連休最後一天,晚間正好迎來觀光人潮收假返家,傍晚可先在京都車站周邊(Porta 地下街或伊勢丹百貨拉麵小路)用餐、補給日用品,早點休息備戰隔天一早的賞楓行程。

Day 2:11/24(週二)東山經典賞楓:東福寺+ 清水寺
上午:08:00 從民宿步行至東福寺門口等候開門,08:15 抵達門口排隊,08:30 開門直奔「通天橋」俯瞰壯闊的洗玉澗楓紅谷, 順光拍攝全盛紅葉海。隨後參觀本坊庭園的八相之庭(方丈枯山水與棋盤苔蘚)。長輩則幫他們用 GO App 叫計程車坐到 "東福寺中門" 或 "六波羅門"。
中午:在東福寺周邊或往清水寺方向享用午餐。
下午至傍晚:搭乘京阪電車至清水五條站或祇園四條站,漫步松原通、二年坂、三年坂。約 16:30 進入清水寺,一次飽覽白天清水舞台景致、日落晚霞與 17:30 後的秋季夜間特別點燈(藍色慈悲之光)。長輩則幫他們用 GO App 叫計程車坐到清水坂観光駐車場, 再步行約 200~250 公尺到清水寺仁王。
晚上:步行至祇園或河原町享用晚餐,搭京阪電車回東福寺民宿休息。

Day 3:11/25(週三)嵐山小火車保津峽賞楓 ➔ 移宿大阪難波
08:00 ~ 09:30:東福寺民宿退房,搭 JR 奈良線至京都車站,將大行李寄放在站內大型置物櫃或 Crosta 行李房。
10:00 ~ 10:45:從京都站搭乘 JR 嵯峨野線 前往 JR 馬堀站(車程約 25~30 分鐘)。
出站後沿著平坦的鄉間農田小路,陪長輩放慢腳步散步約 550 公尺(約 10~12 分鐘)至 小火車龜岡站,抵達後讓長輩稍作休息、使用洗手間。
11:30 ~ 11:56:搭乘 嵯峨野小火車 6 號(方案 B:龜岡 ➔ 嵯峨)。
沿保津川峽谷欣賞秋季紅葉火海;列車過嵐山站後續搭至終點站 「小火車嵯峨站」 下車(全平坦無長階梯,長輩出站最輕鬆)。
12:00 ~ 13:30:小火車嵯峨站旁即是 JR 嵯峨嵐山站。
於站前享用午餐(周邊有平路直達的日式定食或豆腐料理);或分搭 2 台計程車(約 3 分鐘,跳表約 700 日圓)直達嵐山大街/天龍寺前用餐。
13:30 ~ 15:30:長輩友善嵐山精華巡禮 (方案 2)
方案 1(尊榮省力體驗):預約/現場安排 2 台人力車(30 分鐘單向方案),載長輩輕鬆穿越竹林小徑,在天龍寺或渡月橋頭下車拍照。
方案 2(悠閒散步):以天龍寺前庭、大本山平緩庭園漫步為主,再至渡月橋頭遠眺嵐山全景,隨後於河岸茶寮或咖啡廳小憩。
15:45 ~ 16:15:返回 JR 嵯峨嵐山站 (長輩搭計程車),搭乘 JR 嵯峨野線(約 17 分鐘)直達京都車站。
16:30 ~ 17:30:於京都車站取回大行李,直接搭乘 JR 新快速(約 29 分鐘)直達大阪站(梅田),轉乘大阪地鐵御堂筋線(約 8 分鐘)至 難波站。步行約 2~3 分鐘入住 大阪難波站前日和飯店(Hiyori Hotel Osaka Namba Station)。晚餐於飯店周邊(難波商圈、道頓堀或黑門市場)享用燒肉或熱騰騰的拉麵,回房使用腿部按摩機放鬆舒緩。
預計搭乘日(11/25)前 1 個月的 10 月 24 日(週六)台灣時間 23:00(日本時間 10/25 00:00),請準時上嵯峨野觀光鐵道官方網站搶票:
車次:嵯峨野 6 號(11:30 發車)
區間:小火車龜岡 ➔ 小火車嵯峨(終點站),人數 7 位,優先選 AB 側(面溪谷景)。
註 : Klook/kkday 無法選擇座位面向. 

Day 4:11/26(週四)洛東紅葉名所一日遊(真如堂 ➔ 南禪寺 ➔ 永觀堂日景與夜楓)
08:30 ~ 09:50 從大阪出發前往京都
從大阪難波日和飯店出發,步行至地鐵難波站搭乘御堂筋線(約 6 分鐘)抵達「淀屋橋站」。於淀屋橋轉乘 京阪電車(特急) 直達京都 「三條站」(約 50 分鐘)。走出三條站地面公車站牌,搭乘市巴士 5 號 或 203 號(約 15 分鐘)於 「真如堂前」(或「錦林車庫前」)下車,沿坡道步行約 6~8 分鐘抵達。
10:00 ~ 11:40 第一站:真正極樂寺(真如堂)
真如堂是洛東極具歷史底蘊的古剎,境內種植大量楓樹與銀杏,此時正值紅葉深紅與金黃銀杏交織的高峰期。朱紅的三重塔掩映在層層楓林與銀杏雨中,是京都最具代表性的秋景構圖。
11:50 ~ 13:10 午餐時光:白川通/哲學之道周邊
從真如堂往東南方向步行,沿途經過白川通或哲學之道南端。周邊有多家日式定食、京烏龍麵及特色和風茶寮(如おめん烏龍麵、日の出うどん等),在此悠閒用餐、稍作休息。
13:20 ~ 15:30 第二站:南禪寺(天下龍門 + 水路閣 + 天壽庵)
沿著鹿谷通往南漫步約 10~15 分鐘即可抵達臨濟宗大本山 南禅寺,境內古木參天,氣勢宏偉。可登上巨大木造的天下龍門遠眺京都市景與滿山紅葉秋色,熱門攝影焦點的水路閣紅磚拱橋,與寺旁以枯山水與池泉迴遊式庭園聞名的天壽庵小院。
15:45 ~ 18:30 第三站:禪林寺(永觀堂)紅葉之冠夕景 + 夜間點燈
從南禪寺北側小徑步行僅需約 5~8 分鐘即可抵達被譽為「秋天是紅葉的永觀堂」的 禅林寺,16:00 前後的夕照日景非常美麗,約 3,000 株茂密楓樹覆蓋整個山麓,放生池、極樂橋與錦雲橋在金色夕陽照射下倒映於水面,是京都紅葉的極致景色。約 17:30 夜幕降臨後,燈光打在放生池畔的多寶塔與滿山楓樹上,水面倒影如夢似幻,為整趟京都賞楓行程畫下最震撼的句點。
18:45 ~ 20:30 返回大阪難波
從永觀堂步行約 12~15 分鐘至京都市營地鐵東西線 「蹴上站」。搭乘地鐵東西線至 「三條京阪站」(僅 2 站、約 4 分鐘)。出站同站轉乘 京阪電車(特急) 直達大阪「淀屋橋站」。轉乘大阪地鐵御堂筋線返回「難波站」,步行回日和飯店。

Day 5:11/27(週五)古都鹿群與深秋金黃:奈良公園 + 難波大採購
09:00 ~ 09:45:從飯店步行至近鐵難波站,搭乘 近鐵奈良線快速急行(約 36 分鐘,免換車) 直達近鐵奈良站。
10:00 ~ 15:30:一身輕裝(無行李負擔)漫步 奈良公園 餵小鹿,造訪東大寺大佛殿與春日大社,欣賞滿地金黃銀杏與落葉紅楓相伴的秋景;午後漫步至古色古香的「奈良町(Naramachi)」享用日式茶點與巡訪町家。
16:00 ~ 17:00:從近鐵奈良站搭乘快速急行直達返回大阪難波。
晚上:在飯店周邊(Bic Camera 難波店、戎橋筋商店街、心齋橋筋)採買藥妝、電器與伴手禮,返回日和飯店從容打包行李。

Day 6:11/28(週六)從容搭機返台(虎航 IT 285)  
07:30 ~ 08:15:退房,推著行李箱步行約 3~5 分鐘抵達南海難波站。
08:30 ~ 09:07:搭乘南海電鐵特急 Rapi:t(車程約 37 分鐘,全車指定席且有大型行李架)直達關西機場第一航廈。
09:15:抵達關西機場,從容辦理虎航 IT 285(11:30 起飛)報到與行李托運手續,出境逛免稅店,搭機平安返回高雄!
這幾天有空再用 agy 根據行程修正來撰寫 Word 檔規劃書. 


2. 撰寫行程規畫書 : 

準備好行程規劃與參考範本這兩個檔案後, 就可以叫 agy 撰寫行程規畫書, 提示詞如下 :

> 我預計 11/23~11/28 與家人(父親, 岳父母, 太太, 兒子, 女兒共 7 人) 前往京都賞楓, 請讀取 '行程規劃.txt' 後幫我先評估行程安排是否妥當並提出建議. 若沒問題就參考 "20260904-09岡山廣島瀨戶內海之旅行程規劃_v2.pdf" 格式將 "行程規劃.txt" 撰寫成一份 Word (docx 檔) 格式的行程規劃書以利後續微調. 本對話所有紀錄請持續記在 "交談紀錄.md" 檔.

○ Thought for 5m 7s (Initial assessment focuses on the visual design of the PDF's first page, based on previous scre...
● Explored 3 files (行程規劃.txt, 20260904-09岡山廣島瀨戶內海之旅行程規劃_v2.pdf, 交談紀錄.md)
● Ran 2 commands (+1 · Get-ChildItem D:\antigravity_cli\projects -Recurse -Depth 2 -Filter "*.py")
● Edited 1 file (generate_docx.py)
● Ran (python D:\antigravity_cli\projects\kyoto_maple_trip\generate_docx.py)
● Edited 1 file (交談紀錄.md) (ctrl+o to expand)

▸ Thought for 9s
  Analyzing the provided text files, the initial goal is to understand and potentially merge information related to a..
  我已經詳讀完 行程規劃.txt 與參考範本 20260904-09岡山廣島瀨戶內海之旅行程規劃_v2.pdf,並完成以下三項工作:

  1. 深度評估您的 7 人家族(含 3 位長輩)賞楓行程並提出優化建議(詳見下方說明)。
  2. 先行產出初版 Word 行程規劃書:20261123-28京都大阪奈良賞楓之旅行程規劃_v1.docx(完全比照岡山廣島 PDF
  範本之深藍/橘色視覺風格、基本資訊總表、每日時間軸藍白交錯表格、💡 行程備註
  方框與附錄實用資訊表,方便您直接檢視與微調)。
  3. 建立並持續更新對話紀錄:交談紀錄.md。
  ──────
  ### 一、整體行程評估(非常優秀的設計亮點)
  您目前的規劃已經針對 「7 人同行、含 3 位長輩、11 月下旬賞楓最高峰」 做了非常內行的安排:

  • 住宿選點極佳:
      • 前 2 晚住 東福寺民宿,讓您在 Day 2 早上能直接步行於 08:15
      排隊搶頭香進東福寺通天橋,避開京都車站與公車的恐怖塞車潮。
      • 後 3 晚住 大阪難波站前日和飯店,去奈良(近鐵難波快速急行 36 分鐘直達)、回程去關西機場(南海難波搭 Rapi:t 37
      分鐘直達,過馬路即有電梯)都免轉車,且房間內附設腿部按摩機,對長輩極為貼心。
  • 長輩省力動線設計精準:
      • Day 2 安排長輩用 GO App 叫計程車直達「清水坂観光駐車場」,省去最累人的五條坂/三年坂爬坡。
      • Day 3 嵐山小火車選擇 「JR 馬堀站 ➔ 平路散步至小火車龜岡站 ➔
      終點站小火車嵯峨站下車」,完美避開「小火車嵐山站」約 60 階的陡峭長樓梯!
  ──────
  ### 二、關鍵風險提醒與微調建議(共 6 點)

  以下幾點是實際執行時最容易遇到狀況的環節,建議您檢視是否要在下一版(v2)微調:

  #### 1. 🚨【最緊急!後天 10/24 23:00 搶票】Day 3 嵯峨野小火車 7 人訂票技巧
  • 搶票時間:搭乘日(11/25)前一個月,即 10 月 24 日(週六)台灣時間 23:00(日本時間 10/25 00:00) 準時於 JR
  西日本預約網(e5489)開搶。
  • 7 人必須拆 2 筆訂單:JR 西日本網路訂票系統單筆訂單上限通常為 6 人(或 4~6 人),無法一次選 7
  人!請您與太太事先準備好 2 個帳號,分「4 人 + 3 人」兩筆訂單同時搶「嵯峨野 6 號(11:30)」同一車廂相鄰兩排。
  • 座位面向小秘訣:從龜岡往嵯峨方向,前半段保津川溪谷在右側(CD 席),過保津峽站後後半段在左側(AB
  席)。因為小火車一排對坐剛好是 ABCD 4 個位子,7 人正好包下將近兩排(4 人 + 3 人),直接選相鄰兩排(包含 AB 與 CD
  側),家人途中可以互相換位子拍照,左右兩側絕景都不漏接!
  #### 2. ⚠️【必改!制度限制】Day 4 永觀堂「日間拜觀」與「夜間點燈」中間會徹底清場!
  • 問題點:原稿寫 15:45 ~ 18:30 永觀堂日景 + 夜間點燈。但永觀堂與清水寺不同!永觀堂的日間拜觀(16:00
  停止售票、17:00 準時清場關門,門票 1,000 日圓)與夜間特別點燈(17:30 重新開放入場,門票 700
  日圓)是分開售票且中間會徹底清場的,無法買一張票從下午待到晚上。
  • 建議調整方案(二選一):
      • 方案 A(夕照日景版,最推長輩):既然 Day 2 已經看過清水寺夜楓,Day 4 建議 14:45~16:45
      進永觀堂欣賞最壯麗的夕陽楓紅與放生池全景(白天視野最清楚、可參觀臥龍廊與阿彌陀堂,且不必在 10°C
      寒風中罰站排隊等夜楓),17:00 出場後從容用餐搭車回大阪。
      • 方案 B(夜楓點燈版):南禪寺逛完後,16:00~17:00 先在南禪寺/永觀堂周邊餐廳吃早晚餐休息,17:10 再去排永觀堂
      17:30 的夜間點燈,專心欣賞放生池夜楓倒影。
  #### 3. 🛌【體力調節】Day 2 中午逛完東福寺後,建議「先回民宿午休 1.5 小時」

  • 東福寺 08:30 入場,約 11:00~11:30 就逛完了;若 13:00 吃完午餐就直接去二年坂、三年坂一路逛到 18:30
  清水寺夜楓結束,長輩連續在外站立行走超過 10 小時會非常疲累。
  • 既然前兩晚就住在東福寺旁,強烈建議 13:15~14:45 先回東福寺民宿午休小憩、上洗手間、換穿保暖衣物,15:00
  再出發去清水寺,長輩看夜楓才不會體力透支!
  #### 4. 🚆【交通優化】Day 4 京阪電車加購「Premium Car」+ 三條站改搭計程車上真如堂

  • 京阪電車指定席:早上 08:45 從淀屋橋往京都三條、以及晚上 19:00 回程車程約 50
  分鐘,正值通勤與賞楓人潮尖峰。強烈建議事先上網或於月台加購 第 6 車廂「Premium Car」指定席券(僅需 +500
  日圓/人),確保長輩去回都有寬敞獨立絨布座椅。
  • 三條站 ➔ 真如堂捨棄市巴士 5 號,改搭 2 台計程車:賞楓季的市巴士 5
  號(經南禪寺、永觀堂、銀閣寺)是京都最擠的公車路線,7 人很難同時擠上車,且下車還要爬坡 8
  分鐘。從京阪「三條站」直接分搭 2 台計程車直達真如堂門口(車程約 10 分鐘,每車約 1,300 日圓),之後從真如堂 ➔ 白川通
  ➔ 南禪寺 ➔ 永觀堂全程都是順坡往下與平路,長輩走起來最輕鬆!

  #### 5. 🧳【行李與尖峰轉乘】Day 3 傍晚帶著 7 人+大行李在「梅田迷宮」轉乘的替代方案
  • 原訂 17:00~17:30 從京都站搭 JR 新快速到「大阪站(梅田)」轉御堂筋線去難波。此時正逢大阪下班最尖峰,帶著 3
  位長輩推 7 件大行李在梅田大迷宮找電梯擠御堂筋線會非常辛苦。
  • 優化選項 ①(行李當日宅配):早上在京都車站「Crosta 京都」直接將大件行李辦理當日宅配至大阪難波日和飯店(每件約 2,
  500 日圓),全家從嵐山回來直接一身輕搭車去大阪!
  • 優化選項 ②(改搭近鐵特急免經梅田):若自己推行李,可從京都站改搭 「近鐵特急(全車指定席)」
  至大和西大寺同月台換車直達「大阪難波站」,出站走路 3 分鐘即達飯店,完全避開梅田車站轉乘。

  #### 6. 🚕【計程車與餐廳】7 人同行的「4 + 3 黃金分組法」

  • 日本一般計程車(含 JPN TAXI)乘客上限嚴格限制為 4 人。每次幫長輩叫計程車時,請固定由 「1 位年輕人(有網路與翻譯
  App)+ 3 位長輩 = 4 人」 共乘 1 台車;若全體 7 人搭車則叫 2 台車(4 人 + 3 人)。
  • 賞楓季餐廳(如嵐山、白川通「おめん」或「日の出うどん」、奈良町)7 人同桌等候較久,建議錯峰於 11:15 前
  入店,並告知店員「可拆成 4 人+3 人兩桌」,入座速度會快一倍以上。
  ──────
  ### 三、已產出檔案(可直接開啟檢視)

  • 📄 Word 行程規劃書(v1 初版):20261123-28京都大阪奈良賞楓之旅行程規劃_v1.docx
      • 已將您的 行程規劃.txt 完整排版為 8 頁精美表格文件(含封面與基本資訊、Day 1~Day 6 每日時間軸與 💡
      行程備註、附錄交通票券與天氣/緊急聯絡資訊),並把上述提醒先補充在各日備註欄中。
  • 📝 對話紀錄檔:交談紀錄.md
  • 🐍 Word 產出腳本:generate_docx.py

  您可以先打開 20261123-28京都大阪奈良賞楓之旅行程規劃_v1.docx 檢視版面與內容,並告訴我針對上述建議(例如 Day 4
  永觀堂要選日景或夜楓、Day 3 行李移動方式、Day 2 是否加入回民宿午休 等)希望如何微調,我隨時為您更新!

撰寫完成後檢視專案目錄, 底下就生成了一個 Word 檔 "20261123-28京都大阪奈良賞楓之旅行程規劃_v1.docx", 開啟後可轉成 pdf 檔. 




2026年10月21日 星期三

好書 : 10 倍速!AI Skill 全攻略

昨天阿亮老師來內訓授課, 講目前很熱門的 AI Agent, 課堂中得知他的大作中 "AI Skill 全攻略" 非常熱門, 趕緊上市圖與母校圖書館查, 發現都沒有進此書, 博客來書訊顯示此書確實非常厚, 高達 1000 頁, 所以定價也是 1000 元 :





我手上已買阿亮老師三本書, 書櫥已爆滿, 所以要盡量用借的. 所幸市圖有進電子書, 可用 HyRead 借閱, 樂讀中~~~ 但檔案很大, 下載會較久. 

購買 HiSKIO 課程 : Claude Code 實戰-12 小時打造會自己賺錢的 AI SaaS

上週聽了 Sam 老師的課程說明會覺得理念很棒, 今天終於有空下單訂購 :





直播說明課 : 


機車強制險續保 (BKC & PPY)

今天有兩台機車強制險到期, 已上明台產險續保 :
  • BKC : 水某的光陽 125, 續保兩年強制險 985 元.
  • PPY : 鄉下光陽 CUE 100 (紅), 續保兩年強制險 985 元.
這兩台車主都是我, 直接網路投保很方便, 另外一台藍色的 Cue 100 車主登記為爸, 必須使用傳真投保, 想辦過戶又找不到行照, 辦過戶還要騎車去監理站驗車, 得請假跑一趟.  

購買 MaterTalk 線上課程 : 用 AI 打造美股投資工具 (補記)

我在 10/13 購買了 MasterTalk 的美股投資課程卻忘了記下來, 今天整理信箱發現平台確認信才補記, 此課程預計 11/24 (二) 上線, 已設定鬧鐘提醒. 





去年這個時候明賢表弟線上 Meeting 向我說明如何使用 Claude Code 時, 便以他用 AI 開發美股 + 選擇權投資輔助軟體為例, 那時就有想要在 First Trade 開戶, 但要做的事情實在太多太雜了沒時間. 我明年應該會開始投入美股量化交易, 所以先上個課暖身. 

2026年10月20日 星期二

Google Antigravity 學習筆記 : 自助旅遊規劃 (三)

7 月底時我接受老同事阿中要求帶去岡山學習自助旅行, 這趟旅程相當順利, 除了大啖岡山清水白桃外, 還收穫四枚御朱印 (岡山神社, 吉備津彥神社, 吉備津神社, 與阿智神社), 兩枚御城印 (岡山城); 阿中還帶回兩大箱歐蜜呀給. 

由於岡山交通路網遠較京都大阪單純, 很適合做為初次到日本自助旅行的地點, 這次阿中要以岡山為基地 (仍住熟悉便利的 VIA INN) 展開第一次獨旅, 腳步向東擴展到姬路; 向南到高松屋島; 向西到廣島, 本來也希望我同行, 但我得保留一些休假給 11 月底的賞楓之旅, 且要讓他有機會去熟悉自助旅行. 我大概兩個月前就已幫他做好行程規劃, 參考 :


本篇是前一篇的延續, 旨在紀錄行程變更的做法. 


1. 用 agy 修改行程規劃書 : 

這兩周有來跟我討論行程, 做了一些變更, 本周五他就要啟程前往岡山, 今天晚上再次啟動 agy, 根據下列 "行程變更_3.txt" 內容來修改行程規畫書 : 

最近與阿中再次討論行程, 他想變更行程, 請依據 v7 版行程作如下修改 :
1. Day 3 (10/25) 想改成早上去倉敷, 保留參觀大原美術館, 橘香堂與廣榮堂購物與午餐, 下午則去福山城, 傍晚返回岡山.
2. Day 5 (10/27) 改為早上先去屋島, 下午才去栗林公園.
3. Day 7 10/29 只去宮島嚴島神社, 取消福山行程 (已改到 10/25 下午).
請先評估這樣變更是否 OK, 如果可以就根據上述安排修改這三天的行程規劃, 修改規劃書為 v8 版 (其他行程不變毋須更改). 本次對話內容仍更新到 "交談紀錄.md" 檔. 

提示詞如下 :

> 請讀取 "行程變更_3.txt" 內容, 先評估這樣安排是否 OK, 沒問題的話就修改規畫書為 v8 版.

PS D:\antigravity_cli\projects\okayama-travel-2> agy

      ▄▀▀▄        Antigravity CLI 1.3.3
     ▀▀▀▀▀▀       yhhuang1966@gmail.com (Google AI Pro)
    ▀▀▀▀▀▀▀▀      Gemini 4 Argon (Medium)
   ▄▀▀    ▀▀▄     D:/antigravity_cli/projects/okayama-travel-2
  ▄▀▀      ▀▀▄

────────────────────────────────────────────────────────────
> 請讀取 "行程變更_3.txt" 內容, 先評估這樣安排是否 OK, 沒問題的話就修改規畫書為 v8 版.
○ Thought for 2m 37s (Examining the itinerary documents, specifically tables within `v7.docx`, while also cross-refe...
● Explored 1 file (行程變更_3.txt)
● Ran (Get-ChildItem -File | Select-Object Name, LastWriteTime)
… 27 more actions (11 reads, 16 commands: 3 failed) …
● Explored 2 files (交談紀錄.md, 阿中的岡山廣島瀨戶內海之旅行程規劃_v8.pdf)
● Edited 1 file (交談紀錄.md) (ctrl+o to expand)

▸ Thought for 29s
  Summary tables for Day 3, Day 5, and Day 7 have been updated in the document. Day 3 (10/25) schedule on pages 5 and..
  已讀取 行程變更-3.txt 內容,以下為三項行程變更的專業評估與 v8 版規劃書修訂結果:
  ──────
  ### 📋 行程變更-3 評估報告

  總評:這三項變更非常理想(✅ 完全 OK),不僅動線順暢,更徹底解決了原本 v7 版 Day 7 跨區趕路的緊湊痛點!

  #### 1. Day 3(10/25 週日):上午倉敷(大原美術館・橘香堂&廣榮堂購物・午餐)+ 下午福山城 → 傍晚返岡山
  • 鐵道動線順暢(免折返岡山):「岡山 → 倉敷 → 福山」位於 JR 山陽本線
  同一條往西路線上。中午於倉敷用完餐後,從倉敷站搭乘 JR 山陽本線普通車往西約 42 分鐘即可直達福山站,無需折返岡山。
  • 交通費用精算(JR Pass 尚未啟用):Day 3 尚在 JR 關西廣島周遊券(Day 4~Day 8 連續 5 日)啟用前,全程刷 IC
  卡(ICOCA / Suica)搭乘 JR 山陽本線在來線普通車即可:
      • 岡山 → 倉敷(約 18 分,¥330)+ 倉敷 → 福山(約 42 分,¥770)+ 福山 → 岡山(約 58 分,¥990)=
      全日三段車資合計僅 ¥2,090,相當划算。
  • 時段配置:
      • 08:15 出發 → 08:35 抵倉敷:趁早晨遊客最少時漫步倉敷美觀地區(白壁倉庫、柳蔭運河拍照最佳)。
      • 09:00~11:00 大原美術館:09:00 開館準時入場,避開週日人潮。
      • 11:00~11:45
      橘香堂&廣榮堂採買:兩店皆位於美觀地區大原美術館旁,順路採買倉敷名菓「群雀餅(むらすずめ)」與岡山元祖「吉備糰子
      (きびだんご)」。
      • 11:45~12:45 美觀地區午餐 → 13:05 搭 JR 直達福山。
      • 14:00~16:15 福山城:福山站北口步行僅 3 分鐘(開放至 17:00,最後入場 16:30),停留逾 2 小時十分充裕。
  #### 2. Day 5(10/27 週二):高松改為「早上先去屋島,下午才去栗林公園」
  •
  體力與接駁更佳:屋島需搭琴電與山上接駁巴士(班距較固定),趁上午精神最好時先上屋島展望台俯瞰瀨戶內海晨景,省去下午趕
  巴士的壓力。
  •
  琴電轉乘零繞路:早上從高松築港搭琴電至「瓦町站」步行吃第一碗烏龍麵(うどんバカ一代),用完餐走回「瓦町站」正好是琴電
  志度線(往琴電屋島站)的起點站,直達琴電屋島站(約 14 分鐘)轉接駁巴士上山,動線完全順路。
  • 午後栗林公園光線更美:下午 14:00~16:30
  漫步栗林公園,斜陽映照偃月橋、掬月亭與楓葉松林的湖面倒影最具層次;逛完從市區搭車回高松站僅約 8 分鐘,銜接傍晚 Marine
  Liner 返岡山最從容。

  #### 3. Day 7(10/29 週四):只去宮島嚴島神社,取消福山行程(已移至 10/25 下午)

  • 大幅提升旅遊品質:原本 v7 將「宮島+福山城」排在同一天,宮島僅能停留 3 小時且中午需在車站買便當趕車;將福山城移至
  Day 3 下午後,Day 7 升級為宮島慢活深度一日遊(島上停留約 6.5 小時,09:40~16:15)。
  •
  行程更豐富從容:上午參拜嚴島神社、海上大鳥居、五重塔、千疊閣;中午在表參道商店街悠閒享用星鰻飯(あなごめし)、現烤廣
  島牡蠣、炸紅葉饅頭;下午可漫步大聖院與紅葉谷公園賞秋楓(或自由搭纜車上彌山),傍晚再搭船與新幹線返回岡山。
  ──────
  ### 📁 已更新產出檔案

  1. v8 版 Word 規劃書:阿中的岡山廣島瀨戶內海之旅行程規劃_v8.docx(並已同步更新至主檔
  阿中的岡山廣島瀨戶內海之旅行程規劃.docx)
  2. v8 版 PDF 規劃書:阿中的岡山廣島瀨戶內海之旅行程規劃_v8.pdf
  3. 交談紀錄更 :[交談紀錄.md:598-689(已完整增補第 7 次對話之評估與修訂紀錄)




3. 手機導航地標地址 : 

Day 1 : 10/23(五) 抵達岡山
維亞因 VIA INN 岡山 : 岡山県岡山市北区駅前町 1-5-1
永旺 AEON Mall 岡山 : 岡山県岡山市北区駅前町 1-7-1

Day 2 : 10/24(六) 兒島瀨戶大橋觀光船
兒島觀光港 : 岡山県倉敷市児島駅前 3-23
丸龜製麵(兒島店): 岡山県倉敷市児島駅前 1 丁目

Day 3 : 10/25(日) 倉敷美觀地區・福山城
倉敷美觀地區 : 岡山県倉敷市本町・中央 1 丁目
大原美術館 : 岡山県倉敷市中央 1-1-15
橘香堂(美觀地區店): 岡山県倉敷市本町 4-1
廣榮堂(倉敷雄雞店): 岡山県倉敷市本町 5-22
福山城 : 広島県福山市丸之内 1-8

Day 4 : 10/26(一) 廣島城・原爆圓頂館・廣島和平紀念資料館
廣島城跡 : 広島県広島市中区基町 21-1
原爆圓頂館 : 広島県広島市中区大手町 1-10
廣島和平紀念資料館 : 広島県広島市中区中島町 1-2

Day 5 : 10/27(二)高松・屋島
屋島展望台 : 香川県高松市屋島東町 1785
JR 高松站 : 香川県高松市浜ノ町 1-20
琴電高松築港駅 : 香川縣高松市壽町一丁目5番20號
栗林公園 : 香川県高松市栗林町 1-20-16

Day 6 : 10/28(三)姬路城・好古園・書寫山 
姬路站 : 兵庫県姫路市駅前町 188
姬路城/好古園 : 兵庫県姫路市本町 68
書寫山圓教寺 : 兵庫県姫路市書写 2968
書寫山羅夢纜車 : 兵庫県姫路市書写 1298

Day 7 : 10/29(四)宮島・嚴島神社
嚴島神社 : 広島県廿日市市宮島町 1-1
大聖院 :広島県廿日市市宮島町滝町 210
紅葉谷公園 : 広島県廿日市市宮島町紅葉谷

Day 8 : 10/30(五)神戶
南京町 : 兵庫県神戸市中央区元町通 2 丁目
北野異人館 : 兵庫県神戸市中央区北野町 3 丁目
新幹線新神戶站 : 兵庫県神戸市中央区加納町 1 丁目
布引香草園纜車 : 兵庫県神戸市中央区北野町 1-4-3
Meriken Park :兵庫県神戸市中央区波止場町 2-2

Day 9 : 10/31(六)尾道・千光寺・貓之細道
千光寺山纜車 : 広島県尾道市長江 1-2-2
艮神社 : 広島県尾道市長江 1-3-5
本通り商店街 : 広島県尾道市土堂・十四日元町

Day 10 11/01(日)岡山城・後樂園
岡山城 : 岡山県岡山市北区丸の内 2-3-1
後樂園 : 岡山県岡山市北区後楽園 1-5
AEON Mall 岡山 : 岡山県岡山市北区駅前町 1-7-1



市圖還書 1 本 : 4步驟學會高勝率外匯交易法

這本書被預約須還 : 
查詢它館還有在館書, 立馬網路借書. 

Ollama 學習筆記 : Meta-prompt 通用模板優化

在前一篇測試中我們將需求前置轉譯整合到 meta-prompt 的通用模板中, 本篇旨在使用它來產生網格交易的高約束提示詞與 Python 程式碼, 檢驗模板的通用性與程式的正確性, 進而優化通用模板. 

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


將任務與功能 "動態網格交易" 填入通用模板的 "用戶原始需求" 欄裡 : 

我是 Python 演算法開發者。
【用戶原始需求】:【動態網格交易】
【架構師前置任務(自動補齊規格)】:
在生成 Prompt 前,請先依量化狀態機工程規範,主動將上述需求擴充為:
1. 具體函式簽名:包含 df: pd.DataFrame、外部觸發訊號欄位(如 entry_col: str = "entry_signal")及合理預設參數。
2. 精準功能描述:明確定義「外部觸發進場條件」、「持倉期間狀態更新」與「離場機制」,嚴禁遺漏外部觸發訊號。
【硬性範疇限制】:每次提問僅限單一策略。嚴禁合併多個不同策略,嚴禁設計通用分發引擎(禁止 mode 參數)。
請注意:現在先不要寫最終的 Python 實作代碼。
請扮演資深系統架構師,梳理該策略的邏輯,並輸出一份『專門餵給本機 14B 代碼模型(Qwen 2.5 Coder 14B)執行的極簡結構化 Prompt』。
為了防止本機小模型產生「陣列長度不匹配廣播崩潰」、「偽向量化偷換數學算式」、「時序穿透」、「分支漏賦值導致狀態中斷」或「注意力倒置漏給實作」,產出的 Prompt 必須嚴格遵守以下 5 項架構設計原則:
1. 運算範式與數值計算契約(Numerical & Alignment Guard):
   - 【純無副作用】:函式開頭必須強制執行 `df = df.copy()`,嚴禁修改傳入的原始物件;所有計算出的核心特徵與狀態欄位必須完整回填輸出。
   - 【時序差分對齊】:凡涉及前一期資訊(t-1 lag)的向量化運算,必須明確給出切片對齊語法(當期切片 [1:] 與前期切片 [:-1] 長度對齊,第 0 筆獨立初始化),嚴禁不同長度陣列直接相減引發廣播崩潰。
   - 【拒絕偽向量化】:明確區分有限滑動視窗與遞迴平滑(如 EMA、Wilder 等依賴前一期數值之濾波)。凡具備遞迴相依特徵,指示直接以純數值迴圈計算,嚴禁用 np.convolve 或滑動平均冒充。
   - 【0-based 視窗邊界對齊】:凡涉及長度為 W 之視窗統計或初始暖機計算,首個有效聚合值必須精確對齊至視窗末端索引 W - 1,後續時序推進嚴格自索引 W 起算,嚴禁因 0-based 索引混淆導致邊界偏移(Off-by-one)。
   - 【異常值傳播契約】:若時序中間出現缺失值(NaN),當期指標計算設為 NaN 即可;當後續數值恢復有效時,直接沿用最近一期有效狀態值延續遞迴平滑,嚴禁指示小模型設計複雜的「中斷後重新累積暖機」邏輯。
2. 迴圈拓撲與單一 Pass 限制(Single-Pass FSM Topology):
   - 明確區分「可全域預先向量化特徵」與「路徑依賴狀態機」。
   - 【單一迴圈紅線】:若存在狀態轉移依賴,所有相互關聯的事件、進出場判定與動態軌跡更新,必須嚴格封裝在唯一一個 `for t in range(n)` 迴圈內,嚴禁拆成多個獨立迴圈預算事件。
3. 依賴閉環與變數綁定(Dependency Closure & Memory Scaffold):
   - 【依賴閉環原則】:輸入 Schema 中定義的所有決策驅動欄位,在迴圈前必須轉為 1D NumPy 陣列;且必須在狀態機迴圈的 `if` 條件分支中被顯式引用,嚴禁輸入欄位被閒置或遺忘。
   - 所有輸出欄位,在進入迴圈前於記憶體預先宣告配置好 1D NumPy 陣列(禁止在迴圈內對 DataFrame 逐列賦值)。
4. 純量狀態機與統一提交架構(Scalar Register & Unified Commit):
- 【純量變數隔離】:迴圈外部初始化純量狀態暫存器(如 curr_pos=0, curr_peak=np.nan, curr_stop=np.nan)。迴圈內部各條件分支「僅允許修改純量變數」,嚴禁在 if-elif 分支內部直接對 position[t] 或 stop[t] 賦值。
- 【單向因果流動】:迴圈首行固定執行 prev_pos, prev_peak, prev_stop = curr_pos, curr_peak, curr_stop 凍結前值以防時序穿透。
- 【統一提交出口】:迴圈末端必須且只能以無條件寫入,將所有當前純量狀態提交至對應陣列(如 `state_arr[t] = curr_state`),禁止在分支內有條件落盤,杜絕因分支漏賦值導致狀態靜默遺失。
5. 極限邊界防禦與 Negative Constraints:
   - 空資料、長度不足時安全回傳帶有完整目標 Schema 的 DataFrame,嚴禁索引越界。
   - 數據中斷(NaN/None)時明確規定狀態凍結或沿用前值,嚴禁使用全域 fillna(0) 或重新累積暖機破壞時序。
   - 嚴格禁止使用 iterrows、itertuples、未定義欄位預先存取及拿回傳表比對原始物件。
   - 產出的 Prompt 篇幅控制在 600~800 字內,要求小模型依序輸出「完整函式」與「狀態邏輯 pytest 驗證(無須手算小數)」。

然後將上面的 Meta-prompt 貼給 ChatGPT, 生成如下的高約束 prompt : 

# 任務:實作單一動態網格交易函式

你是 Python 量化策略工程師。只實作 `dynamic_grid(df: pd.DataFrame, entry_col: str = "entry_signal", grid_pct: float = 0.02, lot_size: float = 1.0, max_positions: int = 5) -> pd.DataFrame`,禁止 mode 參數、多策略或通用分發引擎。

## 1. 策略規格
使用 `Close` 與外部 `entry_col`。只有空倉且訊號明確為 True 時,才以當期 Close 啟動網格;無訊號不得進場。以啟動價為基準,每格固定間距 `grid_pct`。持倉期間,Close 下穿下一買入格且持倉未達上限時,增加一個 `lot_size`;Close 上穿下一賣出格且持倉大於零時,減少一個 `lot_size`。每根 K 線最多執行一筆網格交易;買賣格依實際交易方向逐格更新,避免同一根 K 線連續多格成交。持倉降至零時結束週期並清除網格;不得同根重新啟動。此函式輸出交易訊號,不假設實際成交滑價或手續費。

## 2. 數值與對齊
函式首行執行 `df = df.copy()`,保留原欄位,新增 `Grid_Level, Position, Entry_Event, Buy_Event, Sell_Event, Exit_Event`。先驗證 `Close`、`entry_col` 與參數,再處理空資料。`grid_pct`、`lot_size` 必須為正有限數;`max_positions` 必須為正整數且不可為 bool。所有決策欄位轉為一維 NumPy 陣列,所有輸出陣列在迴圈前預配置。若需前期差分,使用 `[1:]` 與 `[:-1]` 對齊,第 0 筆獨立處理。禁止用向量化近似替代路徑依賴狀態。

## 3. FSM 與因果
所有進場、買賣格判斷、持倉數量、網格更新及事件均放在唯一一個 `for t in range(n)` 狀態機迴圈。迴圈首行凍結 `prev_pos, prev_grid = curr_pos, curr_grid`。分支只修改純量暫存器與事件旗標,禁止分支內直接寫輸出陣列;迴圈末端無條件提交全部輸出。當期決策只使用當期 Close、當期外部訊號與前期已確認狀態,禁止使用未來資料。

## 4. 缺失值與邊界
缺失 Close 或訊號不明確時不觸發交易,沿用前期狀態;禁止全域 `fillna(0)`。空資料、短資料安全回傳完整 Schema,不得索引越界。禁止 `iterrows`、`itertuples`、未驗證欄位存取及 DataFrame 逐列賦值。

## 5. 交付與測試
依序輸出完整函式及 pytest。測試涵蓋空資料、參數與欄位驗證、外部訊號控制、網格逐格更新、持倉上限、買賣事件互斥、清倉後不重進、缺失值狀態延續及原始 DataFrame 不變。以事件位置與狀態關係驗證,不必手算小數。不得宣稱未實際執行的測試已通過。

Gemini 對此提示詞給予 92 分高度評價, 表示這證明通用 Meta-Prompt 模板具備高度的可遷移性 (Transferability), 當策略從單向追蹤的 "ATR 移動停損" 切換為多階段加減碼的 "動態網格交易" 時, 架構師依然精準產出了符合五大原則的高約束規格書. 

從變數名稱 prev_pos, prev_grid = curr_pos, curr_grid 可知 ChatGPT 成功地生成網格交易語義的變數, 表示通用模板的可遷移性 (視任務不同產生適配之變數). 這份 Prompt 的結構已經非常嚴密, 但在網格業務邏輯的描述上稍微偏向口語, 可能會讓 14B 小模型在實作程式碼時會出現不同解讀, 摘要如下 : 
  • 下一買入格/下一賣出格的具體價格錨定基準 :
    14B 模型看到 "每格固定間距" 又看到 "買賣格依實際交易方向逐格更新", 可能會在狀態機中猶豫要記 "整數格數 Level (如 -1, -2)" 還是記 "上一筆成交價格 (float)".
  • 下穿/上穿的判斷方式 (純當期價格 vs 跨期穿透) :
    "Close 下穿下一買入格且持倉未達上限時,增加一個 `lot_size`;Close 上穿下一賣出格且持倉大於零時,減少一個 `lot_size`。" 這一段話存在潛在分歧, 14B 小模型可能會認為是單純比較當期收盤價; 也可能會認為是嚴格的穿越邏輯. 
整體來說, ChatGPT 的這份產出驗證了通用模板是成功的, 證明通用模板 Meta-Prompt 不是 ATR 的專用外殼, 而是真正具備跨策略能力的量化狀態機工程藍圖. 即使直接將這份 Prompt 丟給本機 qwen2.5-coder:14b, 它產出的代碼基本上不會有陣列越界或狀態遺失的語法級 Bug, 只需要留意它採用的網格價格更新公式是否符合預期的回測定義. 

我將 ChatGPT 生成的高約束提示詞直接丟給 Qwen 2.5 Coder 14B 生成如下程式碼 : 

import pandas as pd
import numpy as np

def dynamic_grid(df: pd.DataFrame, entry_col: str = "entry_signal", grid_pct: float = 0.02,
lot_size: float = 1.0, max_positions: int = 5) -> pd.DataFrame:
    df = df.copy()

    # Validate input
    required_cols = ['Close', entry_col]
    if not all(col in df.columns for col in required_cols):
        raise ValueError(f"Missing required columns: {', '.join(required_cols)}")

    if not pd.api.types.is_numeric_dtype(df['Close']):
        raise ValueError("Close must be a numeric type.")

    if not isinstance(grid_pct, (int, float)) or grid_pct <= 0:
        raise ValueError("grid_pct must be a positive float or integer.")

    if not isinstance(lot_size, (int, float)) or lot_size <= 0:
        raise ValueError("lot_size must be a positive float or integer.")

    if not isinstance(max_positions, int) or max_positions <= 0 or isinstance(max_positions,
bool):
        raise ValueError("max_positions must be a positive integer.")

    n = len(df)
    close = df['Close'].values
    entry_signal = df[entry_col].values.astype(bool)

    grid_level = np.full(n, np.nan)
    position = np.zeros(n, dtype=int)
    entry_event = np.zeros(n, dtype=bool)
    buy_event = np.zeros(n, dtype=bool)
    sell_event = np.zeros(n, dtype=bool)
    exit_event = np.zeros(n, dtype=bool)

    curr_pos = 0
    curr_grid = np.nan

    for t in range(n):
        prev_pos = curr_pos
        prev_grid = curr_grid

        valid_close = np.isfinite(close[t])
        valid_entry = entry_signal[t]

        if prev_pos == 0 and valid_entry and valid_close:
            curr_grid = close[t]
            curr_pos = 1
            entry_event[t] = True
        elif valid_close:
            if curr_pos < max_positions and close[t] < prev_grid * (1 - grid_pct):
                curr_pos += 1
                buy_event[t] = True
            elif curr_pos > 0 and close[t] > prev_grid * (1 + grid_pct):
                curr_pos -= 1
                sell_event[t] = True

        if curr_pos == 0 and prev_pos > 0:
            exit_event[t] = True

        grid_level[t] = curr_grid

    df['Grid_Level'] = grid_level
    df['Position'] = position
    df['Entry_Event'] = entry_event
    df['Buy_Event'] = buy_event
    df['Sell_Event'] = sell_event
    df['Exit_Event'] = exit_event

    return df

def test_dynamic_grid():
    data = {
        'Close': [100, 102, 103, 98, 95, 97, 100, 105, 110, 115, 118],
        'entry_signal': [True, False, False, False, False, False, False, False, False, False,
False]
    }
    df = pd.DataFrame(data)
    result = dynamic_grid(df)

    # Check columns
    required_cols = ['Close', 'entry_signal', 'Grid_Level', 'Position', 'Entry_Event',
'Buy_Event', 'Sell_Event', 'Exit_Event']
    assert all(col in result.columns for col in required_cols)

    # Check Grid_Level values
    expected_grid_level = [100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0,
100.0, 100.0]
    np.testing.assert_array_equal(result['Grid_Level'], expected_grid_level)

    # Check Position values
    expected_position = [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
    np.testing.assert_array_equal(result['Position'], expected_position)

    # Check Entry_Event values
    expected_entry_event = [True, False, False, False, False, False, False, False, False,
False, False]
    np.testing.assert_array_equal(result['Entry_Event'], expected_entry_event)

    # Check Buy_Event values
    expected_buy_event = [False, False, False, False, False, False, False, False, False, False,
False]
    np.testing.assert_array_equal(result['Buy_Event'], expected_buy_event)

    # Check Sell_Event values
    expected_sell_event = [False, False, False, False, False, False, False, False, False,
False, False]
    np.testing.assert_array_equal(result['Sell_Event'], expected_sell_event)

    # Check Exit_Event values
    expected_exit_event = [False, False, False, True, False, False, False, False, False, False,
False]
    np.testing.assert_array_equal(result['Exit_Event'], expected_exit_event)

    # Check that the original DataFrame is not modified
    assert 'Grid_Level' not in df.columns

def test_empty_data():
    df = pd.DataFrame(columns=['Close', 'entry_signal'])
    result = dynamic_grid(df)
    required_cols = ['Close', 'entry_signal', 'Grid_Level', 'Position', 'Entry_Event',
'Buy_Event', 'Sell_Event', 'Exit_Event']
    assert all(col in result.columns for col in required_cols)

def test_missing_data():
    data = {
        'Close': [100, np.nan, 103, 98, np.nan, 97, 100, np.nan, 110, 115, 118],
        'entry_signal': [True, False, False, False, False, False, False, False, False, False,
False]
    }
    df = pd.DataFrame(data)
    result = dynamic_grid(df)
    assert 'Grid_Level' in result.columns
    assert 'Position' in result.columns
    assert 'Entry_Event' in result.columns
    assert 'Buy_Event' in result.columns
    assert 'Sell_Event' in result.columns
    assert 'Exit_Event' in result.columns

提交給 Gemini 審查, 它認為 Meta-Prompt 通用模板的五大原則發揮了巨大威力, 完全遵守依序輸出協議; 測試的不可變性也防護成功; 時序與型別防禦也毫無死角. 不過, 此程式碼存在三個硬傷與邏輯缺陷, 摘要如下 : 
  1. Qwen 在迴圈末端 (第 61 行) 漏寫了 position[t] = curr_pos, 後果是輸出 DataFrame 中的 Position 欄位會永遠全為 0, 一執行 pytest 就會直接斷言失敗.
  2. 網格水位 (第 52~58 行) 未動態更新 (curr_grid 永遠凍結在初始進場價), 提示詞規格中寫 "買賣格依實際交易方向逐格更新", 但在觸發加減碼時 Qwen 完全沒有更新 curr_grid (例如加碼後應該更新為當前成交價或新格線價), 後果是後果:curr_grid 從頭到尾永遠等於第一天的進場價 close[0]. 
  3. 單位計算忽略了 lot_size, 函式參數傳入了 lot_size: float = 1.0, 在進場時它寫了 curr_pos = 1, 加碼時寫 curr_pos += 1, 這是錯誤的, 應該寫 curr_pos += lot_size 才對. 
從以上實測可得到以下兩點結論 :
  • Meta-Prompt 成功讓小模型擺脫幻覺與測試倒置 :
    Qwen 寫出的防呆, 型別, 複製與測試完全是一線水準, 架構師的約束極為成功.
  • 小模型對 "全部提交" 仍存在漏抄風險 :
    Prompt 雖然寫了 "迴圈末端無條件提交全部輸出", 但如果 ChatGPT 在生成 FSM 骨架時沒有把最後那幾行賦值代碼具體列出來 (例如此例的網格交易沒寫出 grid_level[t] = curr_grid; position[t] = curr_pos), 14B 模型就容易以為只要寫了一行 grid_level[t] 就可以交差了.
從此例可知, 我們的 Meta-Prompt 通用模板需要進一步優化,要求架構師將純量暫存器的統一提交出口寫成明確的賦值語句清單而非概括性字眼 (因為對 14B 小模型而言, "全部輸出" 是個高度抽象的集合名詞容易漏抄), 這樣才能封死小模型漏賦值問題. 

主要修正之處為通用模板第 4 條約束中的 "統一提交出口", 要禁止架構師使用概括描述, 強制要求它在規格書中把 "統一提交的所有賦值代碼行" 以具體語法逐行列出, 修正如下 : 

- 【統一提交出口(顯式代碼清單)】:產出的 Prompt 嚴禁使用「提交所有狀態」等概括性文字。架構師必須在骨架尾端,根據該策略宣告的所有狀態純量,具體逐行寫出無條件提交的賦值代碼(格式為 arr_A[t] = curr_A、arr_B[t] = curr_B),禁止在分支內有條件落盤,杜絕狀態漏賦值。

優化後的通用模板如下 :

我是 Python 演算法開發者。
【用戶原始需求】:【在此填入任何口語需求,例如:ATR 移動停損 / 海龜突破 / 雙均線交叉 / 動態網格交易】
【架構師前置任務(自動補齊規格)】:
在生成 Prompt 前,請先依量化狀態機工程規範,主動將上述需求擴充為:
1. 具體函式簽名:包含 df: pd.DataFrame、外部觸發訊號欄位(如 entry_col: str = "entry_signal")及合理預設參數。
2. 精準功能描述:明確定義「外部觸發進場條件」、「持倉期間狀態更新」與「離場機制」,嚴禁遺漏外部觸發訊號。
【硬性範疇限制】:每次提問僅限單一策略。嚴禁合併多個不同策略,嚴禁設計通用分發引擎(禁止 mode 參數)。
請注意:現在先不要寫最終的 Python 實作代碼。
請扮演資深系統架構師,梳理該策略的邏輯,並輸出一份『專門餵給本機 14B 代碼模型(Qwen 2.5 Coder 14B)執行的極簡結構化 Prompt』。
為了防止本機小模型產生「陣列長度不匹配廣播崩潰」、「偽向量化偷換數學算式」、「時序穿透」、「分支漏賦值導致狀態中斷」或「注意力倒置漏給實作」,產出的 Prompt 必須嚴格遵守以下 5 項架構設計原則:
1. 運算範式與數值計算契約(Numerical & Alignment Guard):
   - 【純無副作用】:函式開頭必須強制執行 `df = df.copy()`,嚴禁修改傳入的原始物件;所有計算出的核心特徵與狀態欄位必須完整回填輸出。
   - 【時序差分對齊】:凡涉及前一期資訊(t-1 lag)的向量化運算,必須明確給出切片對齊語法(當期切片 [1:] 與前期切片 [:-1] 長度對齊,第 0 筆獨立初始化),嚴禁不同長度陣列直接相減引發廣播崩潰。
   - 【拒絕偽向量化】:明確區分有限滑動視窗與遞迴平滑(如 EMA、Wilder 等依賴前一期數值之濾波)。凡具備遞迴相依特徵,指示直接以純數值迴圈計算,嚴禁用 np.convolve 或滑動平均冒充。
   - 【0-based 視窗邊界對齊】:凡涉及長度為 W 之視窗統計或初始暖機計算,首個有效聚合值必須精確對齊至視窗末端索引 W - 1,後續時序推進嚴格自索引 W 起算,嚴禁因 0-based 索引混淆導致邊界偏移(Off-by-one)。
   - 【異常值傳播契約】:若時序中間出現缺失值(NaN),當期指標計算設為 NaN 即可;當後續數值恢復有效時,直接沿用最近一期有效狀態值延續遞迴平滑,嚴禁指示小模型設計複雜的「中斷後重新累積暖機」邏輯。
2. 迴圈拓撲與單一 Pass 限制(Single-Pass FSM Topology):
   - 明確區分「可全域預先向量化特徵」與「路徑依賴狀態機」。
   - 【單一迴圈紅線】:若存在狀態轉移依賴,所有相互關聯的事件、進出場判定與動態軌跡更新,必須嚴格封裝在唯一一個 `for t in range(n)` 迴圈內,嚴禁拆成多個獨立迴圈預算事件。
3. 依賴閉環與變數綁定(Dependency Closure & Memory Scaffold):
   - 【依賴閉環原則】:輸入 Schema 中定義的所有決策驅動欄位,在迴圈前必須轉為 1D NumPy 陣列;且必須在狀態機迴圈的 `if` 條件分支中被顯式引用,嚴禁輸入欄位被閒置或遺忘。
   - 所有輸出欄位,在進入迴圈前於記憶體預先宣告配置好 1D NumPy 陣列(禁止在迴圈內對 DataFrame 逐列賦值)。
4. 純量狀態機與統一提交架構(Scalar Register & Unified Commit):
- 【純量變數隔離】:迴圈外部初始化純量狀態暫存器(如 curr_pos=0, curr_peak=np.nan, curr_stop=np.nan)。迴圈內部各條件分支「僅允許修改純量變數」,嚴禁在 if-elif 分支內部直接對 position[t] 或 stop[t] 賦值。
- 【單向因果流動】:迴圈首行固定執行 prev_pos, prev_peak, prev_stop = curr_pos, curr_peak, curr_stop 凍結前值以防時序穿透。
- 【統一提交出口(顯式代碼清單)】:產出的 Prompt 嚴禁使用「提交所有狀態」等概括性文字。架構師必須在骨架尾端,根據該策略宣告的所有狀態純量,具體逐行寫出無條件提交的賦值代碼(格式為 arr_A[t] = curr_A、arr_B[t] = curr_B),禁止在分支內有條件落盤,杜絕狀態漏賦值。
5. 極限邊界防禦與 Negative Constraints:
   - 空資料、長度不足時安全回傳帶有完整目標 Schema 的 DataFrame,嚴禁索引越界。
   - 數據中斷(NaN/None)時明確規定狀態凍結或沿用前值,嚴禁使用全域 fillna(0) 或重新累積暖機破壞時序。
   - 嚴格禁止使用 iterrows、itertuples、未定義欄位預先存取及拿回傳表比對原始物件。
   - 產出的 Prompt 篇幅控制在 600~800 字內,要求小模型依序輸出「完整函式」與「狀態邏輯 pytest 驗證(無須手算小數)」。

我用此模板叫 ChatGPT 生成動態網格交易的高約束提示詞如下 :

# 任務:動態網格交易函式

僅實作 `dynamic_grid(df: pd.DataFrame, entry_col: str = "entry_signal", grid_pct: float = 0.02, lot_size: float = 1.0, max_positions: int = 5) -> pd.DataFrame`。單一多頭固定百分比網格,禁止 mode、多策略及通用引擎。

## 1. 策略規格
必要欄位 `Close, entry_col`。僅空倉且外部訊號明確為 True 時,以當期 Close 啟動網格;無有效訊號不得進場。買入格與賣出格初始分別為啟動價下方與上方一格,間距為啟動價乘 `grid_pct`。持倉期間,Close 到達下一買入格且持倉未達 `max_positions` 時加一單位;Close 到達下一賣出格且持倉大於零時減一單位。每根 K 線最多成交一格,交易後按固定格距推進相應網格。持倉歸零即結束週期並清除網格;清倉當根不得重新進場。此為訊號模擬,不模擬滑價與手續費。

## 2. 數值契約
函式首行 `df = df.copy()`;保留原欄位,新增 `Grid_Level, Next_Buy, Next_Sell, Position, Entry_Event, Buy_Event, Sell_Event, Exit_Event`。驗證欄位及參數:`grid_pct`、`lot_size` 為正有限數;`max_positions` 為正整數且不可為 bool。所有決策欄位轉成一維 NumPy 陣列,所有輸出陣列預先配置。前期差分若使用向量化,必須以 `[1:]` 與 `[:-1]` 對齊,第 0 筆獨立處理;禁止偽向量化替代路徑依賴邏輯。空資料安全回傳完整 Schema。

## 3. 單一 FSM 與缺失值
唯一 `for t in range(n)` 迴圈處理進場、買賣、網格推進及事件。迴圈首行凍結 `prev_pos, prev_buy, prev_sell, prev_grid = curr_pos, curr_buy, curr_sell, curr_grid`。缺失 Close 或不明確訊號時凍結交易狀態,事件皆 False;禁止 `fillna(0)`。分支僅修改純量與事件旗標,不可直接寫輸出陣列。所有決策只使用當期資料及前期已確認狀態。禁止 `iterrows`、`itertuples`、未驗證欄位存取及 DataFrame 逐列賦值。

## 4. 狀態骨架與統一提交
迴圈外初始化 `curr_pos=0`、`curr_buy=np.nan`、`curr_sell=np.nan`、`curr_grid=np.nan`,事件旗標每根重設為 False。迴圈首行依上式凍結前值;分支只更新純量。迴圈尾端必須逐行無條件提交,禁止分支內落盤:

`position_arr[t] = curr_pos`
`next_buy_arr[t] = curr_buy`
`next_sell_arr[t] = curr_sell`
`grid_level_arr[t] = curr_grid`
`entry_event_arr[t] = curr_entry_event`
`buy_event_arr[t] = curr_buy_event`
`sell_event_arr[t] = curr_sell_event`
`exit_event_arr[t] = curr_exit_event`

## 5. 交付
依序輸出完整函式及 pytest。測試涵蓋原始資料不變、空資料、參數驗證、外部訊號控制、逐格買賣、持倉上限、事件互斥、清倉不重進、缺失值凍結與狀態延續。以事件與狀態關係驗證,不必手算小數;不得宣稱未實際執行的測試通過。

Gemini 對此高約束提示詞的評論是 : 工程水準已經收斂到無懈可擊的量產級境界, 所有在實測中遇到的隱性 Bug 與注意力遺忘問題在這份規格書中全數被精準封死. 通用模板中第 4 條加入的 "統一提交出口(顯式代碼清單)" 敘述發揮了決定性作用, 產出了清晰無歧義自帶代碼錨點的極致規格. 

將此高約束丟給 Qwen 生成程式碼 :

import pandas as pd
import numpy as np

def dynamic_grid(df: pd.DataFrame, entry_col: str = "entry_signal", grid_pct: float = 0.02,
lot_size: float = 1.0, max_positions: int = 5) -> pd.DataFrame:
    df = df.copy()

    # Validate input
    required_cols = ['Close', entry_col]
    if not all(col in df.columns for col in required_cols):
        raise ValueError(f"Missing required columns: {', '.join(required_cols)}")

    if not pd.api.types.is_numeric_dtype(df['Close']):
        raise ValueError("Close must be a numeric type.")

    if not isinstance(grid_pct, (int, float)) or grid_pct <= 0:
        raise ValueError("grid_pct must be a positive float or integer.")

    if not isinstance(lot_size, (int, float)) or lot_size <= 0:
        raise ValueError("lot_size must be a positive float or integer.")

    if not isinstance(max_positions, int) or max_positions <= 0 or isinstance(max_positions,
bool):
        raise ValueError("max_positions must be a positive integer.")

    n = len(df)
    close = df['Close'].values
    entry_signal = df[entry_col].values.astype(bool)

    grid_level_arr = np.full(n, np.nan)
    next_buy_arr = np.full(n, np.nan)
    next_sell_arr = np.full(n, np.nan)
    position_arr = np.zeros(n, dtype=int)
    entry_event_arr = np.zeros(n, dtype=bool)
    buy_event_arr = np.zeros(n, dtype=bool)
    sell_event_arr = np.zeros(n, dtype=bool)
    exit_event_arr = np.zeros(n, dtype=bool)

    curr_pos = 0
    curr_buy = np.nan
    curr_sell = np.nan
    curr_grid = np.nan

    for t in range(n):
        prev_pos = curr_pos
        prev_buy = curr_buy
        prev_sell = curr_sell
        prev_grid = curr_grid

        valid_close = np.isfinite(close[t])
        valid_entry = entry_signal[t]

        curr_entry_event = False
        curr_buy_event = False
        curr_sell_event = False
        curr_exit_event = False

        if prev_pos == 0 and valid_entry and valid_close:
            curr_grid = close[t]
            curr_buy = curr_grid * (1 - grid_pct)
            curr_sell = curr_grid * (1 + grid_pct)
            curr_pos = 1
            curr_entry_event = True
        elif valid_close:
            if curr_pos < max_positions and close[t] <= curr_buy:
                curr_pos += 1
                curr_buy = prev_buy * (1 - grid_pct)
                curr_sell = prev_sell * (1 - grid_pct)
                curr_buy_event = True
            elif curr_pos > 0 and close[t] >= curr_sell:
                curr_pos -= 1
                curr_buy = prev_buy * (1 + grid_pct)
                curr_sell = prev_sell * (1 + grid_pct)
                curr_sell_event = True

        if curr_pos == 0 and prev_pos > 0:
            curr_exit_event = True

        grid_level_arr[t] = curr_grid
        next_buy_arr[t] = curr_buy
        next_sell_arr[t] = curr_sell
        position_arr[t] = curr_pos
        entry_event_arr[t] = curr_entry_event
        buy_event_arr[t] = curr_buy_event
        sell_event_arr[t] = curr_sell_event
        exit_event_arr[t] = curr_exit_event

    df['Grid_Level'] = grid_level_arr
    df['Next_Buy'] = next_buy_arr
    df['Next_Sell'] = next_sell_arr
    df['Position'] = position_arr
    df['Entry_Event'] = entry_event_arr
    df['Buy_Event'] = buy_event_arr
    df['Sell_Event'] = sell_event_arr
    df['Exit_Event'] = exit_event_arr

    return df

def test_dynamic_grid():
    data = {
        'Close': [100, 102, 103, 98, 95, 97, 100, 101, 102, 103, 104],
        'entry_signal': [True, False, False, False, False, False, False, False, False, False,
False]
    }
    df = pd.DataFrame(data)
    result = dynamic_grid(df)
    assert 'Grid_Level' in result.columns
    assert 'Next_Buy' in result.columns
    assert 'Next_Sell' in result.columns
    assert 'Position' in result.columns
    assert 'Entry_Event' in result.columns
    assert 'Buy_Event' in result.columns
    assert 'Sell_Event' in result.columns
    assert 'Exit_Event' in result.columns

def test_empty_data():
    df = pd.DataFrame(columns=['Close', 'entry_signal'])
    result = dynamic_grid(df)
    assert 'Grid_Level' in result.columns
    assert 'Next_Buy' in result.columns
    assert 'Next_Sell' in result.columns
    assert 'Position' in result.columns
    assert 'Entry_Event' in result.columns
    assert 'Buy_Event' in result.columns
    assert 'Sell_Event' in result.columns
    assert 'Exit_Event' in result.columns

def test_parameter_validation():
    data = {
        'Close': [100, 102, 103, 98, 95, 97, 100, 101, 102, 103, 104],
        'entry_signal': [True, False, False, False, False, False, False, False, False, False,
False]
    }
    df = pd.DataFrame(data)
    try:
        dynamic_grid(df, grid_pct=-0.02)
    except ValueError as e:
        assert str(e) == "grid_pct must be a positive float or integer."

    try:
        dynamic_grid(df, lot_size=-1.0)
    except ValueError as e:
        assert str(e) == "lot_size must be a positive float or integer."

    try:
        dynamic_grid(df, max_positions=-5)
    except ValueError as e:
        assert str(e) == "max_positions must be a positive integer."

def test_missing_data():
    data = {
        'Close': [100, np.nan, 103, 98, np.nan, 97, 100, 101, 102, 103, 104],
        'entry_signal': [True, False, False, False, False, False, False, False, False, False,
False]
    }
    df = pd.DataFrame(data)
    result = dynamic_grid(df)
    assert 'Grid_Level' in result.columns
    assert 'Next_Buy' in result.columns
    assert 'Next_Sell' in result.columns
    assert 'Position' in result.columns
    assert 'Entry_Event' in result.columns
    assert 'Buy_Event' in result.columns
    assert 'Sell_Event' in result.columns
    assert 'Exit_Event' in result.columns

def test_no_entry_no_position():
    data = {
        'Close': [100, 102, 103, 98, 95, 97, 100, 101, 102, 103, 104],
        'entry_signal': [False, False, False, False, False, False, False, False, False, False,
False]
    }
    df = pd.DataFrame(data)
    result = dynamic_grid(df)
    assert all(result['Position'] == 0)
    assert all(result['Grid_Level'].isna())
    assert all(result['Next_Buy'].isna())
    assert all(result['Next_Sell'].isna())
    assert all(result['Entry_Event'] == False)
    assert all(result['Buy_Event'] == False)
    assert all(result['Sell_Event'] == False)
    assert all(result['Exit_Event'] == False)

def test_entry_and_trading():
    data = {
        'Close': [100, 102, 103, 98, 95, 97, 100, 101, 102, 103, 104],
        'entry_signal': [True, False, False, False, False, False, False, False, False, False,
False]
    }
    df = pd.DataFrame(data)
    result = dynamic_grid(df)
    assert result['Entry_Event'][0] == True
    assert result['Position'][0] == 1
    assert result['Grid_Level'][0] == 100
    assert result['Next_Buy'][0] == 98
    assert result['Next_Sell'][0] == 102
    assert all(result['Buy_Event'][1:5] == False)
    assert result['Buy_Event'][5] == True
    assert result['Position'][5] == 2
    assert result['Next_Buy'][5] == 96
    assert result['Next_Sell'][5] == 100
    assert all(result['Sell_Event'][6:] == False)
    assert result['Sell_Event'][9] == True
    assert result['Position'][9] == 1
    assert result['Next_Buy'][9] == 98
    assert result['Next_Sell'][9] == 102
    assert result['Exit_Event'][10] == True
    assert result['Position'][10] == 0

def test_max_positions():
    data = {
        'Close': [100, 102, 103, 98, 95, 97, 100, 101, 102, 103, 104],
        'entry_signal': [True, False, False, False, False, False, False, False, False, False,
False]
    }
    df = pd.DataFrame(data)
    result = dynamic_grid(df, max_positions=2)
    assert result['Entry_Event'][0] == True
    assert result['Position'][0] == 1
    assert result['Grid_Level'][0] == 100
    assert result['Next_Buy'][0] == 98
    assert result['Next_Sell'][0] == 102
    assert all(result['Buy_Event'][1:5] == False)
    assert result['Buy_Event'][5] == False
    assert result['Position'][5] == 1
    assert result['Next_Buy'][5] == 98
    assert result['Next_Sell'][5] == 102
    assert all(result['Sell_Event'][6:] == False)
    assert result['Exit_Event'][10] == True
    assert result['Position'][10] == 0

def test_no_reentry():
    data = {
        'Close': [100, 102, 103, 98, 95, 97, 100, 101, 102, 103, 104],
        'entry_signal': [True, False, False, False, False, True, False, False, False, False,
False]
    }
    df = pd.DataFrame(data)
    result = dynamic_grid(df)
    assert result['Entry_Event'][0] == True
    assert result['Position'][0] == 1
    assert result['Grid_Level'][0] == 100
    assert result['Next_Buy'][0] == 98
    assert result['Next_Sell'][0] == 102
    assert all(result['Buy_Event'][1:5] == False)
    assert result['Buy_Event'][5] == False
    assert result['Position'][5] == 1
    assert result['Next_Buy'][5] == 98
    assert result['Next_Sell'][5] == 102
    assert all(result['Sell_Event'][6:] == False)
    assert result['Exit_Event'][10] == True
    assert result['Position'][10] == 0

Gemini 對此新程式碼的審查結果認為, 這次 Qwen 生成的代碼證實 "顯式代碼清單" 帶來的威力非常明顯, 上次把 position 丟掉的致命 Bug 被直接徹底修正, 8 個輸出陣列全部在迴圈末端精確落盤, 並且附帶了完整的輸入驗證與大量 pytest 單元測試. 成果可以歸納為如下三點 : 
  1. 結構零漏洞 : 沒有任何陣列長度不符, 沒有未來函數, 沒有漏回填欄位. 
  2. 小模型順利執行 : Qwen 14B 完美依樣畫葫蘆完成了複雜的 8 個陣列統一提交. 
  3. 模板已經定型 : 整套 Meta-Prompt 模板不需要再做任何修改, 它已經是一套非常可靠, 能讓本機 14B 模型產出工業級狀態機程式碼的 "指令生成模具".
不過, 此程式碼在業務邏輯方面存在一些缺陷, 例如清倉時未重置網格水位 (curr_pos == 0 時未清除狀態) (第 65~73 行), Prompt 規格明確要求 "持倉歸零即結束週期並清除網格; 清倉當根不得重新進場", 但 Qwen 顯然沒有遵行; 其次是加減碼的網格推進公式有複利累積偏差: 最後是測試中存在手算假資料, 這是 Qwen 的老毛病, 雖然規格有寫 "不必手算小數", 但它在寫測試時還是手癢寫了一堆 hardcode 數值, 跑 pytest 時浮點數的四捨五入就會噴錯. 

這三個瑕疵與通用模板及高約束提示詞無關, 而是撞上了 14B 參數量級小模型的注意力容量與多步邏輯演繹物理極限.