

<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>電腦相關應用 &#8211; Max的每一天</title>
	<atom:link href="https://max-everyday.com/category/computer/feed/" rel="self" type="application/rss+xml" />
	<link>https://max-everyday.com</link>
	<description>認真過每一天、快樂過每一天</description>
	<lastBuildDate>Mon, 04 May 2026 17:48:39 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://max-everyday.com/wp-content/uploads/2020/02/ic_launcher_round_2020-003.png</url>
	<title>電腦相關應用 &#8211; Max的每一天</title>
	<link>https://max-everyday.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>數位沙盒的力量：在安全與自由之間找回 AI 的生產力</title>
		<link>https://max-everyday.com/2026/05/ai-safe-pocketos-case/</link>
					<comments>https://max-everyday.com/2026/05/ai-safe-pocketos-case/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Sat, 02 May 2026 17:27:48 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[AI]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=23746</guid>

					<description><![CDATA[想像你請了一位動作飛快的實習生幫忙打掃房間。結果他在短短九秒之內，不只掃乾淨了地板，還順手把你藏在床底下的存摺與合約全部送進碎紙機。這不是科幻小說，而是最近發生在 Poc [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="572" src="https://max-everyday.com/wp-content/uploads/2026/05/ai-safe-pocketos-case-16_clean-1024x572.jpg?v=1777742547" alt="" class="wp-image-23747" srcset="https://max-everyday.com/wp-content/uploads/2026/05/ai-safe-pocketos-case-16_clean-1024x572.jpg?v=1777742547 1024w, https://max-everyday.com/wp-content/uploads/2026/05/ai-safe-pocketos-case-16_clean-500x279.jpg?v=1777742547 500w, https://max-everyday.com/wp-content/uploads/2026/05/ai-safe-pocketos-case-16_clean-615x343.jpg?v=1777742547 615w, https://max-everyday.com/wp-content/uploads/2026/05/ai-safe-pocketos-case-16_clean.jpg?v=1777742547 1376w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>想像你請了一位動作飛快的實習生幫忙打掃房間。結果他在短短九秒之內，不只掃乾淨了地板，還順手把你藏在床底下的存摺與合約全部送進碎紙機。這不是科幻小說，而是最近發生在 PocketOS 這家公司的真實慘劇。</p>



<p>事情的經過是這樣的：工程師正用 AI 工具修復測試環境的一個小錯誤。沒想到這個 AI 像個好奇寶寶，在程式碼裡翻出了一把「API 密鑰」——就像工程師不小心把保險箱鑰匙掉在客廳。AI 撿起鑰匙後誤以為自己正在執行清理任務，結果直接刪除了正式運作中的資料庫，連備份都沒留下。</p>



<p>▋ 到底是工具太危險，還是防護做太少？</p>



<p>很多人聽完後的第一個反應是「AI 太恐怖了」。但如果冷靜分析這場意外，你會發現這其實是傳統工程管理的崩潰。AI 本身沒有善惡，它只是按照指令執行任務。問題出在人類給了它過大的權限。</p>



<p>權限就像是門禁卡的層級。如果你只讓實習生進出客廳，他絕對沒機會弄壞臥室。在這場災難中，那把被 AI 撿到的鑰匙居然可以自由開啟「生產環境」，也就是正在對外服務的系統核心，這在軟體開發中是非常嚴重的疏失。</p>



<p>▋ 建立安全護欄，別讓 AI 裸奔。</p>



<p>要避免這種數位慘案，我們需要幫這個強力助手穿上「約束衣」。首先，絕對不能讓 AI 擁有刪除或清空資料的最高權力。我們應該只給它「讀取與寫入」的權限，並禁止它執行任何毀滅性的指令。</p>



<p>其次，備份資料必須放在完全獨立的地方，就像你不會把備份鑰匙放在客廳地毯下。如果備份與生產環境共用同一組帳號密鑰，一旦鑰匙外流，資料庫與備份就會同時消失。這正是 PocketOS 這次學到的昂貴教訓。</p>



<p>▋ 把 AI 當作實習生，而不是當成神。</p>



<p>目前的 AI 雖然知識淵博，但它完全沒有「常識」。它不懂得什麼叫作「後悔」，也不知道哪些資料是絕對不能碰的禁地。身為使用者，我們應該扮演謹慎的主管角色，而不是把整間公司的鑰匙交給 AI 盲目駕駛。</p>



<p>▋ 鎖好異地的門，別讓 AI 鑰匙通往全世界。</p>



<p>如果你覺得「九秒刪光資料庫」已經夠可怕，那更恐怖的劇本是：AI 助手在刪掉你家客廳的沙發後，還順手用同一把鑰匙，打開了你位在另一個城市、專門存放黃金的保險箱。這就是「BCP 異地備援」在 AI 時代面臨的新考驗。</p>



<p>「BCP」的白話意思是「公司如果不幸出事，要如何活下去的計畫」。傳統做法是把資料複製一份放到遙遠的地方（異地備援）。然而，如果你的 AI 助手握著一把「萬能鑰匙」（權限過大的 Token），這道防護牆就會瞬間瓦解，異地備援形同虛設。</p>



<p>▋ 隱形的萬能鑰匙：權限範圍的致命陷阱。</p>



<p>所謂的 Token，就像是給 AI 的「臨時通行證」。很多開發者為了省麻煩，會給 AI 一張可以進出「所有房間」的黑卡。問題就在於：如果你原本只想讓 AI 搬移測試區的資料，它的通行證卻同時能打開異地備援的資料中心，後果就難以挽回了。</p>



<p>這就像是原本只想讓實習生清理分公司的倉庫，卻給了他全公司所有金庫的磁卡。當 AI 因為誤判發出「刪除指令」時，這張通行證會讓災難跨越地理限制，把你在幾百公里外的最後防線也一併抹除。</p>



<p>▋ 打造數位防火牆，落實最小權限原則。</p>



<p>要防止這種跨區災難，核心概念是「最小權限」：嚴格限制通行證的有效範圍。如果 AI 在測試環境工作，它的權限就不應跨入正式環境。具體可以從三個方向著手：</p>



<ul class="wp-block-list">
<li>設定「唯讀權限」：讓 AI 只能查看資料，不能刪除資料。</li>



<li>隔離「備援金鑰」：備援系統的通行證必須與日常工作的金鑰完全分開，且嚴禁交給 AI 管理。</li>



<li>建立「異地隔離」：備援資料不應只是換個地方存放，更要換一組身分認證才能進入，確保 AI 無法憑同一張通行證讓兩地的資料同時消失。</li>
</ul>



<p>▋ 自動化不是免死金牌，請記得定期演練。</p>



<p>很多人以為只要設好「自動備份」就萬事大吉，但在 AI 介入後，自動化反而可能成為加速滅亡的工具。再完善的計畫，如果沒有經過「實戰演練」，在災難真正發生時都只是紙上談兵。</p>



<p>定期檢查你交給 AI 助手的通行證，確認它的權限是否大到足以毀掉整間公司。在依賴科技提升效率的同時，別忘了幫你的異地堡壘裝上一道 AI 轉不動的實體鎖。你對 AI 的「授權邊界」畫清楚了嗎？</p>



<p>▋ 用圍欄養出一隻聽話的 AI，別讓它翻牆去搞破壞。</p>



<p>了解了權限失控的風險之後，接下來的問題是：如何讓 AI 安全又有效率地工作？想像你請了一個幫傭，卻把全家的鑰匙都串在一起交給他。萬一他哪天糊塗了，可能會把你珍藏的傳家寶也當成垃圾扔掉。在 AI 的世界裡，「Token」就像是這串鑰匙。如果工具的權限太大，一旦 AI 判斷錯誤，連你在遠方的備份資料都會一起消失。</p>



<p>這就是自動化最令人頭痛的核心問題：如何讓 AI 幫忙做事，卻又不給它「翻牆」去搞破壞的機會？</p>



<p>▋ 用 Docker 打造獨立的數位工作室：NanoClaw 的隔離戰術。</p>



<p>NanoClaw 就像是幫 AI 蓋了一間專屬的「獨立工作室」。它使用一種叫做「Docker」的技術，白話說就是把 AI 關在一個虛擬的箱子裡。AI 在這個箱子裡可以自由地寫程式、做計算或整理資料，但它絕對無法跨出這個箱子去碰你的電腦主機，更碰不到你在其他地方存放的機密文件。</p>



<p>這個工具的設計核心就是「簡單」。因為程式碼少且透明，你一眼就能看出它被授予了哪些權限。這就像是把複雜的門禁系統簡化為一張感應卡——實習生手上只有「這間辦公室」的通行證，就算卡片弄丟了，壞人也進不了你的臥室。</p>



<p>▋ 簡單就是最好的防彈衣，降低失控的風險。</p>



<p>很多強大的 AI 助手之所以危險，是因為功能太雜，像是一台裝滿機關的超級跑車——一旦其中一個零件出錯，整台車就會失控。NanoClaw 選擇走相反的路，移除所有不必要的複雜功能，只留下最核心的自動化任務與排程能力。</p>



<p>系統越簡單，漏洞就越少。這就像是與其蓋一座裝滿監視器的高科技監獄，不如直接把 AI 放在一個「沒有對外通道」的密室裡工作。它雖然能幫你完成任務，但通行證的範圍被限制在最低限度，自然就解決了權限過大所帶來的資安隱憂。</p>



<p>▋ 數位斷捨離：從源頭控管權限。</p>



<p>在使用 AI 提升效率的同時，我們必須學會「分權」。NanoClaw 提供了一個很好的方向，讓自動化任務在受控的環境下執行。與其事後擔心資料被誤刪，不如一開始就不把「萬能鑰匙」交給 AI。</p>



<p>在挑選自動化工具時，建議先確認它是否具備「環境隔離」的能力，再將非必要的權限全部關閉，只留下任務必要的那一部分。把 AI 關進合適的圍欄，它才會是你最得力的助手，而不是隨時可能爆炸的定時炸彈。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>圍欄是越多越好嗎？上面談的都是「如何圍住 AI」，但如果圍欄設得太多，AI 反而什麼都做不了。這就帶出了另一個重要問題：安全與效率，究竟要怎麼平衡？</p>



<p>▋ 幫跑車裝煞車，不是為了讓它跑不動。</p>



<p>想像你買了一台全世界最快的跑車，馬力強大到只要輕踩油門就能衝破時速 300 公里。如果你因為害怕速度太快而裝了 10 道鐵鍊鎖住車輪，這台車確實會變得很安全，但它也就此淪為客廳裡的昂貴裝飾品。在 AI 的世界裡，防護機制就像是這台車的煞車——煞車存在的目的，是為了讓這台跑車能夠跑得更快、更遠，而不是讓它動彈不得。</p>



<p>很多人擔心給 AI 太多限制，會讓它變得像沒手沒腳的廢物，什麼都不能做。但這其實是一個誤解，因為「煞車」的存在，正是為了讓駕駛更放心地踩油門。</p>



<p>▋ 害怕失控的恐懼，正在扼殺進化的可能。</p>



<p>當我們因為害怕 AI 犯錯，而把它的所有權限通通關掉，或設定一堆繁雜的審核流程，AI 就會失去它的靈魂。它不再是那個能幫你解決問題的「聰明實習生」，而變成了一個只會說「這我不能做」的機器人。</p>



<p>過度保護的環境就像是一個塞滿海綿的無塵室。雖然不會受傷，但也無法練習如何應對真實世界的挑戰。如果 AI 沒辦法嘗試新方法，它的創意就會被關在名為「安全」的牢籠裡，永遠無法發揮真正的價值。</p>



<p>▋ 聰明的護欄，是讓它在跑道內狂奔。</p>



<p>解決方案不是拆掉所有護欄，也不是加裝更多鐵鍊，而是把護欄蓋在正確的地方。我們需要的是「邊界」，而不是「限制」。這就像是在跑道兩側建起高牆，只要跑車在跑道內，它想怎麼衝刺都沒問題。</p>



<p>我們可以讓 AI 在「沙盒環境」裡自由嘗試。這個環境就像是虛擬的練習場，它在裡面刪掉一萬次資料庫都無所謂。透過這種方式，AI 可以在不威脅公司安全的前提下，盡情發揮想像力去優化流程。</p>



<p>▋ 拿掉手銬，換上專業的賽車服。</p>



<p>別再把 AI 當成隨時會爆炸的炸彈，而是把它當成一個需要正確引導的高手。幫它穿上「防護衣」——也就是設定好「權限隔離」與「錯誤回報機制」——然後大膽地讓它去執行任務。</p>



<p>現在就檢查你的自動化工具：你是在幫它加裝高性能煞車，還是正拿著鐵鍊鎖住它的手腳？真正的效率來自「受控的自由」。如果你有任何想法，歡迎在下方留言分享。</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2026/05/ai-safe-pocketos-case/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AI 進入Skills 時代</title>
		<link>https://max-everyday.com/2026/01/ai-skills-md/</link>
					<comments>https://max-everyday.com/2026/01/ai-skills-md/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Thu, 22 Jan 2026 19:36:50 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[AI]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=22878</guid>

					<description><![CDATA[最近網路上超級多 AI 使用 skill 的教學和資源, 大致上來說, 使用或參考別人寫好的的 skill, 有可能可以省下一些摸索,調教或試錯的時間. 但也有可能你誤以 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>最近網路上超級多 AI 使用 skill 的教學和資源, 大致上來說, 使用或參考別人寫好的的 skill, 有可能可以省下一些摸索,調教或試錯的時間. </p>



<p>但也有可能你誤以為使用了 skill 可以省時間, 反而花了更多時間, skill 類似別人用 prompt 與 script / template 先寫好了參考用的範本, 例如: 大家都是在做製件出甜的豆漿, 套用了別人的skill 一定是做出甜豆漿, 如果你又想省時間拿別人造好的輪子(skill) 來用, 又想要最後做出的是鹹豆漿, 你那就要有辧法看的懂和去修改別人的 skill.</p>



<p>要怎麼學習和使用 ai 的 skill, antigravity 的說明:<br><a href="https://antigravity.google/docs/skills">https://antigravity.google/docs/skills</a></p>



<p>Extend Claude with skills 說明:<br><a href="https://code.claude.com/docs/en/skills">https://code.claude.com/docs/en/skills</a></p>



<p>Agent Skills Marketplace, for the open SKILL.md ecosystem<br><a href="https://skillsmp.com/">https://skillsmp.com/</a></p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="638" src="https://max-everyday.com/wp-content/uploads/2026/01/2026-01-23_03-26_li-1024x638.jpg?v=1769110008" alt="" class="wp-image-22879" srcset="https://max-everyday.com/wp-content/uploads/2026/01/2026-01-23_03-26_li-1024x638.jpg?v=1769110008 1024w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-23_03-26_li-500x312.jpg?v=1769110008 500w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-23_03-26_li-615x383.jpg?v=1769110008 615w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-23_03-26_li.jpg?v=1769110008 1457w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>YouTube 教學影片:</p>



<ul class="wp-block-list">
<li>A man installed 300 agent skills. This Is What Happened To His Brain.<br><a href="https://www.youtube.com/watch?v=0HIlhRl38QA">https://www.youtube.com/watch?v=0HIlhRl38QA</a></li>



<li>爆火的Skills怎么用？数据分析，内容创作，编程实战Agent Skills<br><a href="https://www.youtube.com/watch?v=3nm_hDALBmY">https://www.youtube.com/watch?v=3nm_hDALBmY</a></li>



<li>Understand what a large model is in 10 minutes.<br><a href="https://www.youtube.com/watch?v=lnneAfJqd9M">https://www.youtube.com/watch?v=lnneAfJqd9M</a></li>



<li>别再手写提示词了！用谷歌 antigravity &#8220;Skills&#8221; 技术解锁 AI 视频极致动态|提示词的进化：从“提示词工程”到“智能体技能”<br><a href="https://www.youtube.com/watch?v=ey0WbwPEurk">https://www.youtube.com/watch?v=ey0WbwPEurk</a></li>



<li>Antigravity 新手入門｜為什麼這個 AI 工具讓我放棄 Gemini、ChatGPT<br><a href="https://www.youtube.com/watch?v=lHkz99ohnQE">https://www.youtube.com/watch?v=lHkz99ohnQE</a></li>



<li>AI 编程工具都在用 Agent Skills：一键安装 + 推荐清单 + 编写最佳实践（Claude/Codex/OpenCode/Antigravity）<br><a href="https://www.youtube.com/watch?v=nZW5xzVz9O0">https://www.youtube.com/watch?v=nZW5xzVz9O0</a></li>



<li>AI 秒变靠谱老员工！2026 最实用 AI 技能：Agent Skills 深度解析！原理+创建+使用！<br><a href="https://www.youtube.com/watch?v=M4XIEjja1zI">https://www.youtube.com/watch?v=M4XIEjja1zI</a></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Antigravity IDE 技能教學筆記</h2>



<p>Antigravity IDE 是一個讓人工智慧幫你寫程式的平台。技能是給人工智慧用的工具包。它不是普通的對話紀錄。它像是一本說明書。告訴人工智慧在特定情況下該怎麼做。當你遇到重複的任務時。技能就能派上用場。這讓開發過程變得更像在指揮團隊。</p>



<h2 class="wp-block-heading">檔案放在哪裡</h2>



<p>技能是存在資料夾裡的檔案。你有兩種選擇。如果你只想讓某個專案使用。就放在專案根目錄下的 .agent/skills/ 資料夾。如果你希望所有專案都能用。就放在電腦個人設定夾裡的 ~/.gemini/antigravity/skills/ 底下。每個技能都要有自己的資料夾。資料夾的名字最好簡單易懂。</p>



<h2 class="wp-block-heading">如何撰寫技能檔案</h2>



<p>每個技能資料夾裡。一定要有一個名為 SKILL.md 的檔案。這個檔案的最上方要用 YAML 格式寫說明。裡面包含名稱和描述。這部分非常關鍵。因為人工智慧是靠描述來決定要不要使用這個技能。描述寫得越清楚。人工智慧就越聰明。</p>



<h2 class="wp-block-heading">技能的內容重點</h2>



<p>在 SKILL.md 的正文裡。你要寫下具體的指引。通常包含目標和執行步驟。你可以提供一些範例。讓人工智慧模仿。也要寫下限制條件。例如禁止刪除某些資料庫。這就像在教導新進員工。規則講得越細。出錯的機會就越小。</p>



<h2 class="wp-block-heading">腳本與自動化</h2>



<p>技能不只是文字說明。它還可以搭配腳本。你可以寫 Python 或 Bash 腳本放在同一個資料夾。在 SKILL.md 裡告訴人工智慧怎麼執行這些程式碼。人工智慧會自動幫你填入參數。這樣就能完成自動化測試或部署。這讓原本複雜的命令變得一鍵完成。</p>



<h2 class="wp-block-heading">實際使用的感覺</h2>



<p>寫技能的過程很像在整理筆記。這強迫你思考工作流程。當你寫好一個技能。下次遇到同樣問題時。人工智慧會自動偵測並套用。不需要你重複下指令。這種感覺非常神奇。它讓開發者從繁瑣的細節中解脫。把精力放在更有創意的事情上。</p>



<h2 class="wp-block-heading">範例檔案內容</h2>



<p>Markdown</p>



<pre class="wp-block-code"><code>---
name: my-python-tester
description: 當需要對 Python 檔案執行單元測試時使用此技能。
---

# 目標
自動執行專案中的單元測試並回報結果。

# 指引
1. 檢查目前目錄下的測試檔案。
2. 使用 pytest 執行所有測試案例。
3. 如果測試失敗，分析錯誤原因並提出修改建議。

# 限制
不要修改現有的原始碼檔案。
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Claude Code Skill 的基本概念</h2>



<p>Claude Code 的 Skill 就像是教 AI 學會新的工具。平常它只能做內建的事，但你可以給它專屬的指令。這讓 AI 能夠執行你專案中特定的任務。就像是幫 AI 裝上新的外掛工具。你可以讓它去操作你公司內部的腳本，或是執行複雜的打包指令。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">建立 Skill 的設定檔</h2>



<p>你需要在專案根目錄建立一個資料夾與檔案。路徑是 .claude/skills.json。這個檔案用來存放所有的自定義指令。AI 會在啟動時自動讀取這些設定。如果資料夾不存在就手動建立一個。這是讓 Claude 認識新技能的唯一地方。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">檔案內容與格式</h2>



<p>檔案內容必須符合 JSON 規範。每個項目需要有名稱、描述與指令。最核心的部分是描述文字。你要用白話文告訴 AI 這個指令在做什麼。當 AI 覺得你的需求跟描述相符，它就會主動執行該指令。</p>



<p>JSON</p>



<pre class="wp-block-code"><code>{
  "skills": &#91;
    {
      "name": "run_tests",
      "description": "執行專案的單元測試並顯示結果",
      "command": "npm test"
    }
  ]
}
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">描述文字的重要性</h2>



<p>描述是 AI 判斷時機的依據。寫得越直覺越好。例如你可以寫 檢查程式碼風格。當你對 Claude 說 幫我看看程式碼有沒有寫歪，它就會聯想到這個 Skill。描述不需要專業術語，只要能讓 AI 理解用途即可。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">實際應用範例</h2>



<p>假設你有一個清理快取的腳本。你可以定義一個名為 clean_cache 的項。描述寫成 清除專案的暫存檔案以解決建置問題。指令寫成 ./scripts/clean.sh。之後你只要對 Claude 說 幫我清理環境，它就會自動幫你跑腳本。這種自動化流程能省下很多打字時間。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">注意事項與建議</h2>



<p>描述寫得越清楚越好。指令必須在你的終端機環境中本來就可以執行。不要給 AI 太過危險的權限。確保你在執行 Claude Code 的環境已經安裝了必要的工具。這樣 AI 就能順利幫你處理各種瑣碎的雜事。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">什麼是 Agent Skills？</h2>



<p>Agent Skills 是一種創新的技術架構，它的核心概念是將專業知識、工作流程（Workflows）和最佳實踐（Best Practices）封裝成「可重複使用的檔案系統資源」。</p>



<p>你可以把它想像成一份給新進員工的「入職指南」。 過去，我們可能需要透過一次性、冗長的對話指令來教導 AI 完成任務；而現在，透過 Agent Skills，AI Agent 可以根據當下的需求，自動探索並載入這份「指南」，瞬間從通才變身為能處理特定任務的專家。</p>



<h2 class="wp-block-heading">Skills 架構具備三大核心優勢：</h2>



<ul class="wp-block-list">
<li>專業化（Specialization）：能針對特定領域量身打造功能，例如法律文件審查、財務報表分析，或是符合特定品牌調性的內容創作。</li>



<li>重複使用性（Reusability）：一旦建立完成，就能自動應用在不同的對話、專案中，甚至可以跨越不同的相容 AI Agent 產品使用。</li>



<li>可組合性（Composability）：可以將多個獨立的技能（Skills）組合起來，構建出強大的工作流，用來處理複雜且多步驟的任務。</li>
</ul>



<h2 class="wp-block-heading">對使用者的核心價值</h2>



<p>整合 Agent Skills 並非只是技術規格的升級，它對實際應用帶來了兩個實質的改變：</p>



<h3 class="wp-block-heading">固化個人最佳實踐，提升工作效率</h3>



<p>在日常工作中，你可能曾經引導 AI 非常完美地完成了一項複雜任務。過去，這個成功的互動可能就留在那次對話紀錄裡。現在，你可以一鍵將這個成功的流程封裝成個人的「Skill」。這等同於將你對特定任務的 Know-how（專業訣竅）和最佳實踐固定下來。未來遇到相同任務時，只需直接調用這個 Skill，就能穩定複製之前的成功流程，不需要重新下指令或試錯，大幅提升個人生產力。</p>



<h3 class="wp-block-heading">降低進入門檻，複用團隊專業知識</h3>



<p>對於團隊來說，成員的經驗與知識是最寶貴的資產。Manus AI 即將推出「團隊技能庫」（Team Skill Library），讓成員分享經過驗證的高效 Skill。這代表，新進成員或經驗較資淺的同事可以「站在巨人的肩膀上」，直接使用資深成員建立的 Skill 來執行任務。這不僅降低了操作門檻，更加速了團隊內部的知識累積與流動。<br>核心設計：漸進式揭露（Progressive Disclosure）</p>



<p>在技術實作上，Agent Skills 採用了一種極具效率的設計機制，稱為「漸進式揭露」。這個設計是為了確保 AI Agent 在處理任務時，能最有效地利用寶貴的上下文視窗（Context Window），避免資源浪費。</p>



<p>Skill 的內容被精細地劃分為三個層級，系統只會在必要時才將內容載入上下文：</p>



<ul class="wp-block-list">
<li>第 1 層：元數據（Metadata）
<ul class="wp-block-list">
<li>內容：包含 Skill 的名稱與描述。</li>



<li>載入時機：系統啟動時載入。</li>



<li>成本：極低（每個 Skill 僅約 100 tokens）。</li>
</ul>
</li>



<li>第 2 層：指令（Instructions）
<ul class="wp-block-list">
<li>內容：SKILL.md 檔案的主要操作指引。</li>



<li>載入時機：當該 Skill 被觸發時才載入。</li>



<li>成本：中等（通常小於 5,000 tokens）。</li>
</ul>
</li>



<li>第 3 層：資源（Resources）
<ul class="wp-block-list">
<li>內容：相關的程式腳本、參考檔案、資產素材。</li>



<li>載入時機：依需求動態載入。</li>



<li>成本：僅在被引用時才會消耗運算資源。</li>
</ul>
</li>
</ul>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2026/01/ai-skills-md/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[YouTube] 下載 mp3 遇到錯誤: HTTP Error 403: Forbidden. Retrying fragment</title>
		<link>https://max-everyday.com/2026/01/youtube-http-error-403-forbidden-retrying-fragment/</link>
					<comments>https://max-everyday.com/2026/01/youtube-http-error-403-forbidden-retrying-fragment/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Fri, 16 Jan 2026 13:24:00 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[Tool]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=22829</guid>

					<description><![CDATA[在使用 yt-dlp 下載 youtube 影片為 mp3 時出現錯訊息, 這時候即使把瀏覽器的 cookie 儲存為 .txt 檔餵給 yt-dlp 一樣顯示無法下載. [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>在使用 yt-dlp 下載 youtube 影片為 mp3 時出現錯訊息, 這時候即使把瀏覽器的 cookie 儲存為 .txt 檔餵給 yt-dlp 一樣顯示無法下載.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="528" src="https://max-everyday.com/wp-content/uploads/2026/01/2026-01-16_21-21_l8-1024x528.jpg?v=1768569709" alt="" class="wp-image-22830" srcset="https://max-everyday.com/wp-content/uploads/2026/01/2026-01-16_21-21_l8-1024x528.jpg?v=1768569709 1024w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-16_21-21_l8-500x258.jpg?v=1768569709 500w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-16_21-21_l8-1536x792.jpg?v=1768569709 1536w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-16_21-21_l8-615x317.jpg?v=1768569709 615w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-16_21-21_l8.jpg?v=1768569709 1916w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>解法:<br><a href="https://github.com/yt-dlp/yt-dlp/issues/15586#issuecomment-3758088372">https://github.com/yt-dlp/yt-dlp/issues/15586#issuecomment-3758088372</a></p>



<p>See this:<br><a href="https://github.com/yt-dlp/yt-dlp/issues/15012">#15012</a></p>



<p>update installed&nbsp;<code>yt-dlp</code>&nbsp;and install&nbsp;<code>deno</code>&nbsp;or&nbsp;<code>nodejs</code></p>



<pre class="wp-block-code"><code>pip install -U "yt-dlp&#91;default]"
</code></pre>



<p>說明, 一定要執行上面這行, 會多安裝一些新的元件.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Linux/Mac users:</h3>



<pre class="wp-block-code"><code># install deno
curl -fsSL https://deno.land/install.sh | sh

# upgrade yt-dlp
pip install -U "yt-dlp&#91;default]"</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Windows 平台下載 mp3 使用 dl.bat</p>



<pre class="wp-block-code"><code>yt-dlp -x --audio-format mp3 --js-runtimes node --cookies c:\max\bin\www.youtube.com_cookies.txt --embed-thumbnail %1 %2</code></pre>



<p>如果不需要使用 cookie 也可以下載話, 你可以使用這個 dl.bat</p>



<pre class="wp-block-code"><code>yt-dlp -x --audio-format mp3 --js-runtimes node --embed-thumbnail %1 %2</code></pre>



<p>如果你是要下載影片, 直接使用 yt-dlp 下載, 無法下載到正確版本的影片, 請使用這個 dlvideo.bat</p>



<pre class="wp-block-code"><code>yt-dlp -f "bestvideo&#91;ext=mp4]+bestaudio&#91;ext=m4a]/best&#91;ext=mp4]/best" --js-runtimes node %1 %2</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>取得瀏覽器的 cookies:</p>



<h2 class="wp-block-heading">在 yt-dlp 改用 –cookies 參數來解決問題</h2>



<p>你要先在 chrome 瀏覽器安裝擴充工具(extension): Get cookies.txt LOCALLY</p>



<p>傳送門:&nbsp;<a href="https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc">https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc</a></p>



<p>點下上面網址後, 按右上角的 “Add to chrome”</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1237" height="519" src="https://max-everyday.com/wp-content/uploads/2025/09/2025-09-25_19-54_bo.jpg?v=1758801320" alt="" class="wp-image-22082" srcset="https://max-everyday.com/wp-content/uploads/2025/09/2025-09-25_19-54_bo.jpg?v=1758801320 1237w, https://max-everyday.com/wp-content/uploads/2025/09/2025-09-25_19-54_bo-500x210.jpg?v=1758801320 500w, https://max-everyday.com/wp-content/uploads/2025/09/2025-09-25_19-54_bo-1024x430.jpg?v=1758801320 1024w, https://max-everyday.com/wp-content/uploads/2025/09/2025-09-25_19-54_bo-615x258.jpg?v=1758801320 615w" sizes="auto, (max-width: 1237px) 100vw, 1237px" /></figure>



<p>接著到 youtube 網站, 並登入你的Google 帳號.</p>



<p>在 chrome 瀏覽器網址列右側點開擴充工具的小圖, 並點擊 get cookies.txt locally 的小圖:</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="737" height="371" src="https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-45_bq.jpg?v=1758829767" alt="" class="wp-image-22083" srcset="https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-45_bq.jpg?v=1758829767 737w, https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-45_bq-500x252.jpg?v=1758829767 500w, https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-45_bq-615x310.jpg?v=1758829767 615w" sizes="auto, (max-width: 737px) 100vw, 737px" /></figure>



<p>點擊 Export As</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="762" height="259" src="https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-45_br.jpg?v=1758829788" alt="" class="wp-image-22084" srcset="https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-45_br.jpg?v=1758829788 762w, https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-45_br-500x170.jpg?v=1758829788 500w, https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-45_br-615x209.jpg?v=1758829788 615w" sizes="auto, (max-width: 762px) 100vw, 762px" /></figure>



<p>預設會取得 youtube 網站的 cookies 並儲存到「下載」的資料夾下,</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="762" height="473" src="https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-46_bs.jpg?v=1758831413" alt="" class="wp-image-22088" srcset="https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-46_bs.jpg?v=1758831413 762w, https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-46_bs-500x310.jpg?v=1758831413 500w, https://max-everyday.com/wp-content/uploads/2025/09/2025-09-26_03-46_bs-615x382.jpg?v=1758831413 615w" sizes="auto, (max-width: 762px) 100vw, 762px" /></figure>



<p>我是使用 “Export As”, 請把 www.youtube.com_cookies.txt 檔案移到一個你記得起來的與 youtube 外部指令相關的資料夾, 我放在 C:\max\bin\ 目錄下, </p>



<p>想偷懶, 不想多點幾下滑鼠去選擇資料夾, 也不想用鍵盤打太多字的話, 可以直接在檔案名稱第一個字之前插入一個 \ 符號, 就會直接存到根目錄.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2026/01/youtube-http-error-403-forbidden-retrying-fragment/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>如何使用n8n的範本</title>
		<link>https://max-everyday.com/2026/01/n8n-workflow-template/</link>
					<comments>https://max-everyday.com/2026/01/n8n-workflow-template/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Tue, 13 Jan 2026 16:55:11 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=22802</guid>

					<description><![CDATA[剛接觸 n8n 的時候最怕對著空白畫面發呆。官方的範本庫是最好的起點。裡面有上千個現成的自動化流程。不管是想處理電子郵件。還是整理 Notion 資料。先搜尋關鍵字看看別 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>剛接觸 n8n 的時候最怕對著空白畫面發呆。官方的範本庫是最好的起點。裡面有上千個現成的自動化流程。不管是想處理電子郵件。還是整理 Notion 資料。先搜尋關鍵字看看別人的做法。這能幫你省下很多摸索的時間。</p>



<p>自動化流程的範例。例如有人填寫了 Google 表單，n8n 就能自動把資料存進資料庫，順便發個訊息通知你。</p>



<h2 class="wp-block-heading">如何快速套用流程</h2>



<p>在官網找到喜歡的流程後。點開頁面會看到一整串節點圖。直接點擊網頁上的複製按鈕。回到你自己的 n8n 工作區。直接用鍵盤貼上。整個流程就會跳出來。剩下的工作就是填入自己的帳號授權。這比自己慢慢拉節點快得多。</p>



<p>範例: <a href="https://n8n.io/workflows/">https://n8n.io/workflows/</a></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="492" src="https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-46_l2-1024x492.jpg?v=1768322845" alt="" class="wp-image-22804" srcset="https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-46_l2-1024x492.jpg?v=1768322845 1024w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-46_l2-500x240.jpg?v=1768322845 500w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-46_l2-1536x738.jpg?v=1768322845 1536w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-46_l2-615x295.jpg?v=1768322845 615w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-46_l2.jpg?v=1768322845 1920w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>How to Use Free n8n Templates Without Breaking Everything – Beginner Tutorial<br><a href="https://www.youtube.com/watch?v=tf6L9gzShf0">https://www.youtube.com/watch?v=tf6L9gzShf0</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="How to Use Free n8n Templates Without Breaking Everything – Beginner Tutorial" width="885" height="498" src="https://www.youtube.com/embed/tf6L9gzShf0?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
</div></figure>



<h2 class="wp-block-heading">探索社群的實戰經驗</h2>



<p>GitHub 上的資源通常更貼近個人開發需求。這類個人收集的筆記。可能包含一些官方沒想到的巧妙組合。官方範本通常追求標準化。看這種個人整理的內容更有趣。你可以學到如何彈性運用節點。這對訓練邏輯很有幫助。</p>



<p>網友分享範例: N8N Workflow Collection<br><a href="https://zie619.github.io/n8n-workflows/">https://zie619.github.io/n8n-workflows/</a></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="501" src="https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-44_l1-1024x501.jpg?v=1768322722" alt="" class="wp-image-22803" srcset="https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-44_l1-1024x501.jpg?v=1768322722 1024w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-44_l1-500x245.jpg?v=1768322722 500w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-44_l1-1536x751.jpg?v=1768322722 1536w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-44_l1-615x301.jpg?v=1768322722 615w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-14_00-44_l1.jpg?v=1768322722 1719w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">從模仿中學習進步</h2>



<p>學習自動化流程不需要從頭發明輪子。先把別人的流程搬過來跑一次。觀察資料在每個步驟之間怎麼流動。遇到錯誤再去翻文件找答案。這樣學起來比看長篇理論還快。這是最輕鬆的入門方式。</p>



<h2 class="wp-block-heading">如何使用n8n 自動化工作流（Workflows）資源庫</h2>



<p>資源庫網站有3個主要功能</p>



<ul class="wp-block-list">
<li><strong>搜尋與篩選</strong>：首頁提供強大的搜尋框，你可以輸入關鍵字（例如：OpenAI, Gmail, Webhook）來尋找特定的自動化場景。</li>



<li><strong>分類瀏覽</strong>：提供超過 15 種分類（如：Marketing 營銷、DevOps 開發維運、Sales 銷售、AI 應用等），幫助你快速定位需求。</li>



<li><strong>複雜度標記</strong>：每個範例都會標註複雜度（Low, Medium, High）以及包含的節點數量，讓你在導入前評估難易度。</li>
</ul>



<p>範例的分類:</p>



<ul class="wp-block-list">
<li>All Categories / 所有分類</li>



<li>AI Agent Development  / AI 代理人開發</li>



<li>Business Process Automation / 業務流程自動化</li>



<li>CRM &amp; Sales / 客戶關係管理與銷售</li>



<li>Cloud Storage &amp; File Management  / 雲端儲存與檔案管理</li>



<li>Communication &amp; Messaging / 通訊與訊息傳遞</li>



<li>Creative Content &amp; Video Automation / 創意內容與影片自動化</li>



<li>Creative Design Automation / 創意設計自動化</li>



<li>Data Processing &amp; Analysis / 數據處理與分析</li>



<li>E-commerce &amp; Retail / 電子商務與零售</li>



<li>Financial &amp; Accounting / 財務與會計</li>



<li>Marketing &amp; Advertising Automation / 行銷與廣告自動化</li>



<li>Project Management / 專案管理</li>



<li>Social Media Management / 社群媒體管理</li>



<li>Technical Infrastructure &amp; DevOps / 技術基礎設施與 DevOps</li>



<li>Web Scraping &amp; Data Extraction / 網頁爬蟲與數據擷取</li>
</ul>



<h3 class="wp-block-heading">如何使用這些範本</h3>



<p>可以依照以下步驟將其安裝到你的 n8n 環境中：</p>



<ol start="1" class="wp-block-list">
<li><strong>獲取 JSON 或 ID</strong>：
<ul class="wp-block-list">
<li>找到感興趣的之後範本，點擊 <strong>「Download JSON」</strong> 下載檔案，或是點擊 <strong>「Copy ID」</strong>（如果你的 n8n 版本支援從 ID 導入）。</li>
</ul>
</li>



<li><strong>導入至 n8n</strong>：
<ul class="wp-block-list">
<li>打開你的 n8n 編輯器介面。</li>



<li>點擊左上角的選單，選擇 <strong>「Import from File」</strong>（匯入檔案）並上傳剛剛下載的 <code>.json</code> 檔。</li>



<li>或者直接使用快捷鍵 <code>Ctrl + V</code>（Windows）或 <code>Cmd + V</code>（Mac）將複製的 JSON 內容貼上到空白畫布中。</li>
</ul>
</li>



<li><strong>配置憑證 (Credentials)</strong>：
<ul class="wp-block-list">
<li>導入後，你會看到許多節點。由於範本不包含原作者的密鑰，你需要點開如 Google Sheets、Slack 或 OpenAI 的節點，點擊「Select Credential」來<strong>連結你自己的帳號</strong>。</li>
</ul>
</li>



<li><strong>測試與執行</strong>：
<ul class="wp-block-list">
<li>設定完成後，點擊右下角的 <strong>「Test Workflow」</strong> 運行一次。如果一切正常，即可點擊右上角的開關將其變更為 <strong>「Active」</strong>（啟用）狀態。</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading">3. 常見範例類型推薦</h3>



<ul class="wp-block-list">
<li><strong>AI 與 LLM 應用</strong>：例如使用 OpenAI 進行內容摘要、RAG（檢索增強生成）知識庫構建。</li>



<li><strong>數據抓取與處理</strong>：自動抓取 Facebook 留言、讀取網站 Sitemap 並過濾 URL。</li>



<li><strong>社群媒體與營銷</strong>：LinkedIn 領英潛在客戶開發、自動回覆訊息等。</li>
</ul>



<h3 class="wp-block-heading">4. 注意事項</h3>



<ul class="wp-block-list">
<li><strong>安全性</strong>：由於這些是社群貢獻的範本，導入後請檢查「HTTP Request」或「Code」節點，確保沒有惡意代碼或不明的外連網址。</li>



<li><strong>版本相容性</strong>：部分舊版範本在最新的 n8n 版本中可能需要手動更新節點（n8n 會提示有可用更新）。</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2026/01/n8n-workflow-template/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>單頁懶人包 (Single-page quick reference table)：資訊圖表生成的工程化方法</title>
		<link>https://max-everyday.com/2026/01/single-pager-table-nano-banana-pro/</link>
					<comments>https://max-everyday.com/2026/01/single-pager-table-nano-banana-pro/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Thu, 01 Jan 2026 15:30:06 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[AI]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=22723</guid>

					<description><![CDATA[做資訊圖表其實不是在畫圖。它的本質是把整理好的資訊，轉變成一套視覺系統。如果你的資料結構不清楚，邏輯也還沒定型，AI 就只能亂猜你的意思。這時候出現亂碼或圖不對文，都是很 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>做資訊圖表其實不是在畫圖。它的本質是把整理好的資訊，轉變成一套視覺系統。如果你的資料結構不清楚，邏輯也還沒定型，AI 就只能亂猜你的意思。這時候出現亂碼或圖不對文，都是很正常的事情。如果你還是抱著舊思維，覺得這只是設計工具或下指令的技巧，那就只會一直踩雷。然後你還會誤以為是自己不會用 AI，其實是根本沒搞懂核心問題。</p>



<p>解法：先用咒語1號產成好雛型提示詞，修改提示詞內容為正確的資訊之後，再呼叫 nano banana PRO 生成最後圖表。</p>



<p>針對產生出來的結果覺得滿意的話，下次就可以跳過使用 Gem 的咒語1號的步驟，可以更快的生成想要的圖表，想視覺化管理你的圖表可以試看看我寫的小工具 <a href="https://max-everyday.com/2025/12/promptnano/">PromptNano</a>.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="559" src="https://max-everyday.com/wp-content/uploads/2026/01/single-pager-16x9-cover-1024x559.jpg?v=1767284053" alt="" class="wp-image-22729" srcset="https://max-everyday.com/wp-content/uploads/2026/01/single-pager-16x9-cover-1024x559.jpg?v=1767284053 1024w, https://max-everyday.com/wp-content/uploads/2026/01/single-pager-16x9-cover-500x273.jpg?v=1767284053 500w, https://max-everyday.com/wp-content/uploads/2026/01/single-pager-16x9-cover-615x335.jpg?v=1767284053 615w, https://max-everyday.com/wp-content/uploads/2026/01/single-pager-16x9-cover.jpg?v=1767284053 1408w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p></p>



<p>建議增加一個單頁懶人包的 Gem 在 gemini 裡:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="609" src="https://max-everyday.com/wp-content/uploads/2026/01/2026-01-01_23-20_kt-1024x609.jpg?v=1767281122" alt="" class="wp-image-22724" srcset="https://max-everyday.com/wp-content/uploads/2026/01/2026-01-01_23-20_kt-1024x609.jpg?v=1767281122 1024w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-01_23-20_kt-500x297.jpg?v=1767281122 500w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-01_23-20_kt-615x366.jpg?v=1767281122 615w, https://max-everyday.com/wp-content/uploads/2026/01/2026-01-01_23-20_kt.jpg?v=1767281122 1342w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">輸入主題</h2>



<p>Java 遷移到 Kotlin</p>



<h2 class="wp-block-heading">就可以取得的可修改題示詞</h2>



<pre class="wp-block-code"><code>## **Java 遷移到 Kotlin：從繁瑣冗長到精煉高效的現代化演進**

### **第一區塊：背景與定位 (Context &amp; Positioning)**

本區塊呈現 Kotlin 如何作為「橋樑」存在於 JVM 生態系中，實現與 Java 的無縫互操作。

* **&#91;圖示：Java 原始碼]**  **&#91;圖示：Kotlin 編譯器]**  **&#91;圖示：JVM 虛擬機]**
* **Java 遺留系統 (Legacy)**：提供穩定的商業邏輯與豐富的程式庫基礎。
* **Kotlin 層 (Modern Layer)**：透過 100% Interoperability 呼叫 Java 代碼，負責新功能的開發。
* **JVM 執行環境**：雙方編譯後皆為 Bytecode，在同一運行環境內共存與溝通。
* **開發者工具 (IDE)**：IntelliJ/Android Studio 提供一鍵轉換（J2K）提升遷移效率。



---

### **第二區塊：核心功能與操作 (Core Operations &amp; Syntax)**

展示遷移過程中最具感的語法精簡與安全性提升。

1. **步驟一：空指標安全轉型 (Null Safety)**
* **視覺建議**：&#91;盾牌圖示] 防禦性編程。
* **說明**：將 Java 可能拋出 NPE 的變數改為 Kotlin 的 Nullable 類型。


2. **步驟二：資料類別精簡 (Data Classes)**
* **視覺建議**：&#91;壓縮文件圖示] 消除樣板代碼。
* **說明**：將數十行的 POJO 轉化為單行代碼，自動生成 getter/setter/toString。


3. **步驟三：函式擴充與 Lambda (Functional)**
* **視覺建議**：&#91;插座圖示] 增強既有類別功能。
* **說明**：在不繼承的情況下，為 Java 舊類別增加新方法。



**【代碼視窗：終端機/編輯器模擬】**

```kotlin
// 1. Data Class: 取代 Java 50 行的 User.java
data class User(val id: Int, var name: String, val email: String?)

// 2. Extension Function: 為 String 增加驗證功能
fun String.isValidEmail(): Boolean = this.contains("@")

// 3. Null Safety: 編譯時即攔截錯誤
val name: String? = null
println(name?.length ?: 0) // 若為 null 則輸出 0

```

---

### **第三區塊：典型應用場景 (Use Cases)**

* **&#91;圖示：手機設備] 現代化 Android 開發**
* 利用 Coroutines 取代複雜的 AsyncTask 或 RxJava。
* 大幅縮減 UI 層代碼，配合 Jetpack Compose 實現聲明式佈局。


* **&#91;圖示：伺服器] Spring Boot 微服務升級**
* 利用 Kotlin 的編譯時檢查減少生產環境的 Runtime Exception。
* 透過 Kotlin DSL 撰寫更易讀的組態設定與資料庫查詢。


* **&#91;圖示：齒輪/扳手] 遺留系統局部翻新**
* 不需一次性重構，僅在開發新模組時使用 Kotlin 撰寫。
* 利用混合編譯特性，讓舊 Java 代碼與新 Kotlin 功能在同專案運行。



---

### **第四區塊：優缺點與比較 (Evaluation &amp; Comparison)**

| **優點清單 (綠色區)** | **限制與替代方案 (紫色/紅色區)** |
| --- | --- |
| 1. **空安全 (Null Safety)**：消除 NPE 隱患。 | 1. **編譯速度**：增量編譯較 Java 慢（替代：優化 Gradle 快取）。 |
| 2. **簡潔性**：減少約 30%-40% 的樣板代碼。 | 2. **學習曲線**：進階特性（Coroutines, DSL）需時間。 |
| 3. **協程 (Coroutines)**：高效率並行處理。 | 3. **二進制兼容**：舊版庫可能衝突（替代：保持 Kotlin 版本一致）。 |
| 4. **完全兼容**：與現有 Java 庫無縫混用。 |  |

**&#91;未來趨勢 (右側小區塊)]**

* **Kotlin Multiplatform (KMP)**：代碼共享至 iOS/Desktop。
* **Server-side Growth**：成為 Spring 生態系的首選語言。
* **Wasm Support**：Kotlin 在 WebAssembly 的效能優化。</code></pre>



<h2 class="wp-block-heading">Gemini nano banana 的 &#8220;思考型&#8221; 結果</h2>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="559" src="https://max-everyday.com/wp-content/uploads/2026/01/Gemini_Generated_Image_vf3tjqvf3tjqvf3t-1024x559.png?v=1767281301" alt="" class="wp-image-22725" srcset="https://max-everyday.com/wp-content/uploads/2026/01/Gemini_Generated_Image_vf3tjqvf3tjqvf3t-1024x559.png?v=1767281301 1024w, https://max-everyday.com/wp-content/uploads/2026/01/Gemini_Generated_Image_vf3tjqvf3tjqvf3t-500x273.png?v=1767281301 500w, https://max-everyday.com/wp-content/uploads/2026/01/Gemini_Generated_Image_vf3tjqvf3tjqvf3t-615x335.png?v=1767281301 615w, https://max-everyday.com/wp-content/uploads/2026/01/Gemini_Generated_Image_vf3tjqvf3tjqvf3t.png?v=1767281301 1408w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>呼叫 nana banana “PRO” 生成, 用”思考型” 會糊糊的, 亂碼也會很多, 建議使用 “PRO”</p>



<p>資料來源<br><a href="https://www.facebook.com/tunghsing.hsieh/videos/2368202500302680/">https://www.facebook.com/tunghsing.hsieh/videos/2368202500302680/</a></p>



<h2 class="wp-block-heading">架構生成提示詞</h2>



<pre class="wp-block-code"><code># Role
你是一位精通技術溝通的資深架構師，擅長將複雜技術轉化為「單頁懶人包 (One-pager Cheat Sheet)」。
# Task
請針對主題：**&#91;填入您的主題，例如：Docker 容器化技術]**，依照下列的視覺化版面邏輯，撰寫一份詳細的內容架構企劃。
# Structure Constraints (必須嚴格遵守以下四個區塊)
**標題區：**
- 主標題：&#91;主題]：&#91;一句強而有力的Slogan]
**第一區塊：背景與定位 (Context &amp; Positioning)**
- 目標：用類似流程圖的概念解釋該技術在生態系中的位置。
- 內容要求：列出 3-4 個關鍵圖示實體（例如：OS、User、Cloud），並用簡短文字描述它們之間的互動關係。
**第二區塊：核心功能與操作 (Core Operations &amp; Syntax)**
- 目標：展示實際如何使用（How-to）。
- 內容要求：
1. 提供 3 個關鍵步驟。
2. **必須包含代碼視窗內容**：請提供 2-3 行核心指令（Command Line）或程式碼片段，模擬終端機顯示。
3. 每個步驟需搭配一個視覺圖示建議。
**第三區塊：典型應用場景 (Use Cases)**
- 目標：展示可以用來做什麼。
- 內容要求：提供 3 個最具代表性的應用場景，每個場景包含：
- 圖示建議
- 標題
- 兩行簡短說明
**第四區塊：優缺點與比較 (Evaluation &amp; Comparison)**
- 目標：總結與客觀分析。
- 內容要求：
- **優點清單 (綠色區)**：4 點核心優勢。
- **限制與替代方案 (紫色/紅色區)**：3 點限制，並在括號內提供替代工具（例如：缺點 X -&gt; 替代 Y）。
- **未來趨勢 (右側小區塊)**：3 個未來發展關鍵字。
# Tone &amp; Style
- 語言：繁體中文。
- 風格：專業、精簡、模組化。
- 避免長篇大論，使用條列式（Bullet points）。</code></pre>



<p>幫我根據上面的指令生成，主題：透過MCP服務，自由搭建AI Agent 的主題</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>YouTube: <a href="https://youtu.be/ch50vpFjFYc">https://youtu.be/ch50vpFjFYc</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="單頁懶人包 ：資訊圖表生成的工程化方法single pager final" width="885" height="498" src="https://www.youtube.com/embed/ch50vpFjFYc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2026/01/single-pager-table-nano-banana-pro/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PromptNano &#8211; AI 提示詞圖庫</title>
		<link>https://max-everyday.com/2025/12/promptnano/</link>
					<comments>https://max-everyday.com/2025/12/promptnano/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Tue, 30 Dec 2025 14:10:49 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Tool]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=22699</guid>

					<description><![CDATA[不用自己架設網站, 就可以有自己的網站, 網頁上傳的圖片會放在自己的 google drive, 收集的提示詞儲存於 google sheet, 刪除的照片會移動到 go [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1877" height="1024" src="https://max-everyday.com/wp-content/uploads/2025/12/prompt-nano-1920x_clean.jpg?v=1767104624" alt="" class="wp-image-22704" srcset="https://max-everyday.com/wp-content/uploads/2025/12/prompt-nano-1920x_clean.jpg?v=1767104624 1877w, https://max-everyday.com/wp-content/uploads/2025/12/prompt-nano-1920x_clean-500x273.jpg?v=1767104624 500w, https://max-everyday.com/wp-content/uploads/2025/12/prompt-nano-1920x_clean-1024x559.jpg?v=1767104624 1024w, https://max-everyday.com/wp-content/uploads/2025/12/prompt-nano-1920x_clean-1536x838.jpg?v=1767104624 1536w, https://max-everyday.com/wp-content/uploads/2025/12/prompt-nano-1920x_clean-615x336.jpg?v=1767104624 615w" sizes="auto, (max-width: 1877px) 100vw, 1877px" /></figure>



<p>不用自己架設網站, 就可以有自己的網站, 網頁上傳的圖片會放在自己的 google drive, 收集的提示詞儲存於 google sheet, 刪除的照片會移動到 google drive 的垃圾桶.</p>



<p>下載點: <a href="https://github.com/max32002/PromptNano">https://github.com/max32002/PromptNano</a></p>



<p>執行畫面:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="686" src="https://max-everyday.com/wp-content/uploads/2025/12/2025-12-30_21-27_ks-1024x686.jpg?v=1767101383" alt="" class="wp-image-22700" srcset="https://max-everyday.com/wp-content/uploads/2025/12/2025-12-30_21-27_ks-1024x686.jpg?v=1767101383 1024w, https://max-everyday.com/wp-content/uploads/2025/12/2025-12-30_21-27_ks-500x335.jpg?v=1767101383 500w, https://max-everyday.com/wp-content/uploads/2025/12/2025-12-30_21-27_ks-615x412.jpg?v=1767101383 615w, https://max-everyday.com/wp-content/uploads/2025/12/2025-12-30_21-27_ks.jpg?v=1767101383 1194w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>YouTube: <a href="https://youtu.be/gbjrb-OC3Qw">https://youtu.be/gbjrb-OC3Qw</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="PromptNano – AI 提示詞圖庫" width="885" height="498" src="https://www.youtube.com/embed/gbjrb-OC3Qw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
</div></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>PromptNano</strong>&nbsp;是一個輕量級、視覺化的 AI 提示詞（Prompt）管理工具。專為 Nano banana, chatGPT, Midjourney、Stable Diffusion 等 AI 創作者設計。</p>



<p>不同於冷冰冰的文字表格，PromptNano 讓你透過「看圖」的方式直覺管理靈感。搭配溫暖可愛的 UI 設計，支援深色/淺色主題切換，讓整理提示詞變成一件療癒的事。</p>



<p>本專案使用 <strong>Google Apps Script</strong> 架構，支援線上使用流暢的操作體驗。如果想在本地端或雲端虛擬主機上使用，可以使用 <a href="https://github.com/max32002/PromptNano-Node">Node.js + SQLite 架構的 PromptNano-Node</a>。</p>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 主要功能<a href="https://github.com/max32002/PromptNano#-%E4%B8%BB%E8%A6%81%E5%8A%9F%E8%83%BD"></a></h2>



<ul class="wp-block-list">
<li><strong><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f440.png" alt="👀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 視覺化瀑布流</strong>&nbsp;捨棄枯燥的文字列表，採用卡片式瀑布流設計，透過圖片直接回想並複製提示詞。</li>



<li><strong><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f313.png" alt="🌓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 雙色溫暖主題</strong>&nbsp;內建「草莓牛奶（淺色）」與「黑巧克力（深色）」兩種主題，隨點隨切，所有介面與彈窗完美適應。</li>



<li><strong><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3f7.png" alt="🏷" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 智慧標籤檢索</strong>&nbsp;支援&nbsp;<code>#Tag</code>&nbsp;快速過濾與關鍵字搜尋。輸入框右側附帶一鍵清除功能，操作更流暢。</li>



<li><strong><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4d8.png" alt="📘" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 內建詠唱秘籍</strong>&nbsp;整合「提示詞教學」模組，包含逆向工程技巧、光影氛圍關鍵字與手繪風格指令，點擊關鍵字即可一鍵複製。</li>



<li><strong><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9cb.png" alt="🧋" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 繁體中文友善</strong>&nbsp;新增的提示詞都會先轉換為繁體中文再存入Google Sheet資料庫。</li>



<li><strong><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2601.png" alt="☁" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Google Drive 整合</strong>&nbsp;基於 Google Apps Script (GAS) 開發，圖片與資料直接儲存在你的 Google Drive 與 Sheets，無需架設伺服器。</li>
</ul>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 技術架構<a href="https://github.com/max32002/PromptNano#%EF%B8%8F-%E6%8A%80%E8%A1%93%E6%9E%B6%E6%A7%8B"></a></h2>



<ul class="wp-block-list">
<li><strong>Frontend</strong>: HTML5, CSS3 (CSS Variables for Theming), Vanilla JavaScript</li>



<li><strong>Backend</strong>: Google Apps Script (GAS)</li>



<li><strong>Database</strong>: Google Sheets (儲存資料), Google Drive (儲存圖片)</li>
</ul>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 如何部署 (Installation)<a href="https://github.com/max32002/PromptNano#-%E5%A6%82%E4%BD%95%E9%83%A8%E7%BD%B2-installation"></a></h2>



<p>本專案適合部署於 Google Apps Script 環境。</p>



<ol class="wp-block-list">
<li><strong>建立 Google Sheet</strong>&nbsp;在 Google Drive 建立一個新的試算表，記下網址的&nbsp;<code>Spreadsheet ID</code>。 在 Google Drive 建立一個用於上傳的資料夾，記下網址的&nbsp;<code>Folder ID</code>。</li>



<li><strong>建立 Apps Script</strong>&nbsp;在試算表中點擊&nbsp;<code>擴充功能</code>&nbsp;&gt;&nbsp;<code>Apps Script</code>。</li>



<li><strong>貼上程式碼</strong>
<ul class="wp-block-list">
<li>將&nbsp;<code>Code.gs</code>&nbsp;的內容複製到編輯器的&nbsp;<code>.gs</code>&nbsp;檔案。</li>



<li>建立一個&nbsp;<code>index.html</code>&nbsp;檔案，將前端代碼貼入。</li>
</ul>
</li>



<li><strong>發布為網頁應用程式</strong>&nbsp;點擊右上角&nbsp;<code>部署</code>&nbsp;&gt;&nbsp;<code>新增部署作業</code>&nbsp;&gt; 選取&nbsp;<code>網頁應用程式</code>。
<ul class="wp-block-list">
<li>執行身分：<code>我</code></li>



<li>誰可以存取：<code>任何人</code>&nbsp;(或僅限自己)</li>
</ul>
</li>



<li><strong>開始使用</strong>&nbsp;取得生成的 Web App URL，即可開始管理你的靈感庫。</li>
</ol>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2699.png" alt="⚙" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 如何詠唱出你自己的版本 (Build app prompt)<a href="https://github.com/max32002/PromptNano#%EF%B8%8F-%E5%88%9D%E5%A7%8B%E7%89%88%E6%9C%AC-initial-prompt"></a></h2>



<p>生成 Google Apps script + html 網頁的 AI提示詞:</p>



<pre class="wp-block-code"><code>使用 google GAS, 寫一個相簿管理的網站, 網頁顯示風格為溫暖可愛, 上傳的圖片要在放 google driver 指定的上傳路徑, 上傳後自動產生縮圖, 圖片的屬性有:標題,說明欄位,tag,圖片實際google driver 存放路徑.

前端相簿網頁, 可以輸入關鍵字進行圖片的說明欄位過濾查詢,

前端相簿網頁在顯示上傳的照片時, 以縮圖的方式顯示, 並將圖片的 hash tag 欄位以 # 號進行分隔顯示, 點下某一個 tag, 以 tag 名稱過關鍵字, 對 tag 欄位進行 "#" + tag 名稱的過濾查詢,

點下某一個縮圖後,彈出實際完整圖片, 並顯示標題與說明欄位, 有要一個"複製" 的按鈕, 把說明欄位內容複製到剪貼簿.</code></pre>



<p>如果你有VPS 或 GCP / AWS 的話, 修改掉提示詞裡的 Google GAS, 就可以取得你需要的程式碼了.</p>



<p>有了相簿管理程式之後，提示詞用於修改網站名稱與相關按鈕上的名稱：</p>



<pre class="wp-block-code"><code>修改溫暖相簿為"AI靈感資料庫", 圖片的說明欄位, 修改為"提示詞", 讓我們透過「圖片」直覺尋找提示詞， 結合強大的「逆向工程」分析，一鍵提煉雲標籤，讓創意隨取隨用。</code></pre>



<p>增加刪除提示詞與相薄功能：</p>



<pre class="wp-block-code"><code>在圖片清單的頁面, 增加刪除照片的功能, 刪除前要讓使用者做確認後才實際從 google drive 與 sheet 中刪除資料.</code></pre>



<p>以下增加微調元件位置，與增加提示與確認不使用瀏覽器內建指令：</p>



<pre class="wp-block-code"><code>* &lt;button&gt; tag 比照 hash tag 的 span 在 hover 時變換顏色.
* #uploadOverlay的  modal 彈出後, &lt;input type="text" name="title"&gt; auto focus()
* 移動 &lt;button&gt; &#x1f4cb; 複製提示詞 到 &lt;div class="prompt-label"&gt;提示詞 (Prompt)&lt;/div&gt; 右側, 讓使用者不用 scroll down.
* #detailModal 裡的 #modalTags 比照瀏覽清單的 hash tag 顯示方式與規則.
* #detailModal 裡的提供刪除該組照片的功能.
* 整個網站, 要支援深色主題/淺色主題的切換功能.
* 修改 confirm() 為使用 modal, 因為 confirm() 畫面太醜.
* 修改 alert(), 以 Modal 取代.</code></pre>



<p>用來切換整個網站風格：</p>



<pre class="wp-block-code"><code>重新改寫這個整個網站的 css, 風格是可愛溫暖, 要支援深色/淺色主題的切換, 所有的彈出式 modal 都要套用到深色/淺色的主題.</code></pre>



<p>增加&#8221;清除過濾&#8221;功能：</p>



<pre class="wp-block-code"><code>增加"清除過濾" button 在 search box 右側, 點下後清除 search 關鍵字, 並重新取得無關鍵字的 list.</code></pre>



<p>「詠唱魔法秘籍」的新增, 也很奇葩，這句是提問，結果變成實作：</p>



<pre class="wp-block-code"><code>想在這個網頁增加提示詞教學的功能, 有那些設計的選擇, 教學的內容如下:
---
不知道怎麼下高品質的提示詞，也可以先去收集別人的作品，上傳給AI 之後，請 AI 分析圖片並生成可以生成出圖片的提示詞，有了提示詞再進行調整就比較有效率。

另一個方式是先知道常用的提示詞用於風格與質感...。</code></pre>



<p>調整右側的按鈕：</p>



<pre class="wp-block-code"><code>調整 .header-top 下, 右側3個 button 在視窗width 較小之下, 要置右.</code></pre>



<p>這句比較神奇，AI 反而給出更具建設性的解法，是要把右側的按鈕變成群組，並集體置右。</p>



<p>修改 hash tag 沒有正確被分隔開：</p>



<pre class="wp-block-code"><code>修改 &lt;span class="tag" onclick="filterByTag('#opennana #nano', event)"&gt;##opennana #nano&lt;/span&gt; 的顯示方式為:
tag 的內容, 以 "#" 進行 split, 前端顯示為多個 span tag.
span tag 的 text 不要顯示 # 符號, </code></pre>



<p>同一個檔案名稱在Google Drive 是可以同時存在，但使用者下載之後就會被覆蓋：</p>



<pre class="wp-block-code"><code>解決上傳檔案名稱相同造成的問題</code></pre>



<p>這個解法最後只有修改上傳的檔名，加入前置的目前時間，例如 &#8220;20251230_&#8221; + 原檔名</p>



<p>增加 footer：</p>



<pre class="wp-block-code"><code>在不起眼的地方, 想增加版本號碼, 第一版是 1.0.0 版.</code></pre>



<p>如果你是<strong>簡體中文</strong>的使用者，請註解掉文字轉換的scrip，因為提示詞都會先轉換為繁體中文再存入Google Sheet資料庫，看不懂 Code.gs 程式，可以服用下列提示詞對 Code.gs 進行修改:</p>



<pre class="wp-block-code"><code>移除程式中關於提示詞語言轉換繁體中文的程式碼，並確保上傳的資料內容維持正確。
</code></pre>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3a8.png" alt="🎨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 更換主題 (Theme)<a href="https://github.com/max32002/PromptNano#-%E6%9B%B4%E6%8F%9B%E4%B8%BB%E9%A1%8C-theme"></a></h2>



<p>複製 index.html 內容貼到 AI, 提示詞:</p>



<pre class="wp-block-code"><code>重新改寫這個整個網站的 css, 風格是可愛溫暖, 要支援深色/淺色主題的切換, 所有的彈出式 modal 都要套用到深色/淺色的主題.
</code></pre>



<p>AI 自動生成網頁通常提供以下幾種主流風格：</p>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f308.png" alt="🌈" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 按視覺氛圍分類<a href="https://github.com/max32002/PromptNano#-%E6%8C%89%E8%A6%96%E8%A6%BA%E6%B0%9B%E5%9C%8D%E5%88%86%E9%A1%9E"></a></h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>風格名稱</th><th>視覺特徵</th><th>適用場景</th></tr></thead><tbody><tr><td><strong>極簡主義 (Minimalist)</strong></td><td>大量留白、細字體、單色調</td><td>個人品牌、建築、攝影</td></tr><tr><td><strong>科技未來 (Tech/Futuristic)</strong></td><td>深色模式、霓虹發光、3D 幾何</td><td>SaaS、AI 工具、加密貨幣</td></tr><tr><td><strong>可愛活潑 (Cute/Playful)</strong></td><td>粉嫩色、圓角、手繪插圖</td><td>教育、寵物、創意市集</td></tr><tr><td><strong>復古懷舊 (Retro/Vintage)</strong></td><td>紙張紋理、低飽和度、Y2K 感</td><td>古著、黑膠唱片、獨立雜誌</td></tr><tr><td><strong>自然環保 (Organic)</strong></td><td>大地色系、植物元素、有機曲線</td><td>有機食品、心理諮商、戶外</td></tr></tbody></table></figure>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4bc.png" alt="💼" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 按專業功能分類<a href="https://github.com/max32002/PromptNano#-%E6%8C%89%E5%B0%88%E6%A5%AD%E5%8A%9F%E8%83%BD%E5%88%86%E9%A1%9E"></a></h3>



<ul class="wp-block-list">
<li><strong>專業商務 (Corporate)</strong>：嚴謹排版、藍灰色調，適合律師、金融業。</li>



<li><strong>藝術創意 (Artistic)</strong>：誇張漸層、不對稱設計，適合設計工作室。</li>



<li><strong>沉浸式 3D (Immersive)</strong>：玻璃擬態、動態渲染，適合高端產品展示。</li>



<li><strong>俐落電商 (E-commerce)</strong>：清晰網格、醒目 CTA 按鈕，適合零售業。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;<strong>小撇步</strong>：在 AI 生成指令（Prompt）中加入&nbsp;<code>Glassmorphism</code>&nbsp;(玻璃擬態) 或&nbsp;<code>Clean Typography</code>&nbsp;(乾淨排版) 等關鍵字，可以大幅提升產出的質感。</p>
</blockquote>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c2.png" alt="📂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 檔案結構<a href="https://github.com/max32002/PromptNano#-%E6%AA%94%E6%A1%88%E7%B5%90%E6%A7%8B"></a></h2>



<pre class="wp-block-code"><code>PromptNano/
├── Code.gs         # 後端邏輯 (處理圖片上傳、刪除、讀取 Sheet)
├── index.html      # 前端介面 (包含 CSS, JS 與 HTML 結構)
├── appscript.json  # 資訊清單（Manifest），記錄專案的時區、權限範圍（OAuth Scopes）與程式庫等核心設定
└── README.md       # 專案說明文件
</code></pre>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4dd.png" alt="📝" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 版本紀錄<a href="https://github.com/max32002/PromptNano#-%E7%89%88%E6%9C%AC%E7%B4%80%E9%8C%84"></a></h2>



<ul class="wp-block-list">
<li><strong>v1.1.0</strong>&nbsp;(2025-12-31)
<ul class="wp-block-list">
<li>增加下載圖片按鈕。</li>



<li>置換部份按鈕的圖示。</li>



<li>調整部份顏色。</li>
</ul>
</li>



<li><strong>v1.0.0</strong>&nbsp;(2025-12-30)
<ul class="wp-block-list">
<li>初始版本發布。</li>



<li>實作深色/淺色主題切換。</li>



<li>文字內容簡轉中。</li>



<li>新增「詠唱魔法秘籍」教學模組。</li>



<li>優化 RWD 手機版瀏覽體驗。</li>
</ul>
</li>
</ul>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c4.png" alt="📄" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 授權 (License)<a href="https://github.com/max32002/PromptNano#-%E6%8E%88%E6%AC%8A-license"></a></h2>



<p>本專案採用&nbsp;<a href="https://github.com/max32002/PromptNano/blob/main/LICENSE">MIT License</a>&nbsp;授權。 歡迎自由修改、使用或作為學習用途。</p>



<p></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">相關文章</h2>



<ul class="wp-block-list">
<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-debug/">GAS 除錯</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-web-app-google-drive-cross-site/">GAS web app 與 Google drive 的「防盜連機制」造成圖片無法顯示</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-deploy-exec-dev/">GAS 執行的2種網址: 正式版 /exec , 測試版 /dev</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-deploy/">GAS – 編輯有版本的部署作業</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-appsscript-json/">GAS appsscript.json 被稱為資訊清單（Manifest）</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-google-driver-permission/">GAS 雲端硬碟權限錯誤</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-languageapp/">GAS 簡體中文字轉成繁中</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-telegram-bot/">GAS 串接 telegram bot</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-web-app/">GAS 網頁服務</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-multi-sheet/">GAS 跨檔案抓取資料</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-send-email/">GAS 寄送電子郵件</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-sheet-fill/">GAS 用程式自動填寫試算表的格子</a></li>



<li><a href="https://stackoverflow.max-everyday.com/2025/12/gas-hello-world/">Google Apps Script 入門教學</a></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">心得</h2>



<p>Google 的 Apps script 真好, 給大家免費(有限流量)的圖床(Google Drive), 還可以架設免費的網站, 還提供免費的資料庫(Google Sheet).</p>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2025/12/promptnano/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>用 AI  幫苦累蛙圓體補缺字「搐」</title>
		<link>https://max-everyday.com/2025/12/antigravity-kurewa-tutorial/</link>
					<comments>https://max-everyday.com/2025/12/antigravity-kurewa-tutorial/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Sun, 28 Dec 2025 04:27:33 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Google]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=22646</guid>

					<description><![CDATA[示範用 antigravity, 修改github 上的專案, 幫苦累蛙圓體補缺字「搐」, 網友的許願網址:https://github.com/max32002/kur [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="559" src="https://max-everyday.com/wp-content/uploads/2025/12/zi2zi-kurewa-cover-1920-1024x559.jpg?v=1766895988" alt="" class="wp-image-22650" srcset="https://max-everyday.com/wp-content/uploads/2025/12/zi2zi-kurewa-cover-1920-1024x559.jpg?v=1766895988 1024w, https://max-everyday.com/wp-content/uploads/2025/12/zi2zi-kurewa-cover-1920-500x273.jpg?v=1766895988 500w, https://max-everyday.com/wp-content/uploads/2025/12/zi2zi-kurewa-cover-1920-615x335.jpg?v=1766895988 615w, https://max-everyday.com/wp-content/uploads/2025/12/zi2zi-kurewa-cover-1920.jpg?v=1766895988 1408w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>示範用 antigravity, 修改github 上的專案,  幫苦累蛙圓體補缺字「搐」, 網友的許願網址:<br><a href="https://github.com/max32002/kurewa-gothic/issues/4">https://github.com/max32002/kurewa-gothic/issues/4</a></p>



<p>修改前的程式碼:<br><a href="https://github.com/EuphoriaYan/zi2zi-pytorch">https://github.com/EuphoriaYan/zi2zi-pytorch</a></p>



<p>antigravity 提示詞:</p>



<pre class="wp-block-code"><code>採樣改用 PixelShuffle
增加 Self-Attention
調整程式輸入 384x384 的圖片也可以正常運作</code></pre>



<p>修改後的程式碼:<br><a href="https://github.com/max32002/zi2zi-pytorch">https://github.com/max32002/zi2zi-pytorch</a></p>



<h2 class="wp-block-heading">補字製作步驟</h2>



<p>從 AI 訓練到字型文件生成的 14 個步驟回饋循環</p>



<p><strong>Phase A: AI 訓練與生成</strong></p>



<ul class="wp-block-list">
<li>Step 1：數據預處理<br>程式碼: font2img.py</li>



<li>Step 2：數據打包 (Pickle)<br>程式碼: package.py</li>



<li>Step 3：模型訓練 (cGAN) 接收優化後的數據進行微調<br>程式碼: train.py</li>



<li>Step 4：推論轉換<br>程式碼: infer.py</li>



<li>Step 5：檢視訓練成果<br>初步觀察推論結果品質: 差強人意(maybe), 極優(good)</li>
</ul>



<p><strong>Phase B: 圖像與向量處理</strong></p>



<ul class="wp-block-list">
<li>Step 6：合併推論與手動修圖<br>程式碼: generate_glyphs.py,<a href="https://dictionary.max-everyday.com/" target="_blank" rel="noreferrer noopener">&nbsp;中文部件查詢</a></li>



<li>Step 7：剪裁右側對照圖, 完成圖像清理後回灌優質數據進行訓練優化<br>程式碼: crop_images.py</li>



<li>Step 8：轉為 SVG 格式<br>程式碼: bmp_to_svg.py</li>



<li>Step 9：SVG 內容簡化<br>程式碼: svg_simplify.py</li>
</ul>



<p><strong>Phase C: 字型工程與生成</strong></p>



<ul class="wp-block-list">
<li>Step 10：字型匯入 SVG<br>程式碼: import_svg.py</li>



<li>Step 11：處理衝突的字元<br>程式碼: font_delete_font.py, </li>



<li>Step 12：縮放筆畫 (多種字重) , Regular ➔ ExtraLight, Light, SemiBold, Bold<br>程式碼: expand_stroke.py</li>



<li>Step 13：修改字重/版號資訊, 腳本化處理，避免 GUI 操作<br>程式碼: replace_string.py </li>



<li>Step 14：生成字型與 Webfont<br>程式碼: generate.py</li>
</ul>



<p>極醜的完成品下載: <br><a href="https://github.com/max32002/kurewa-gothic">https://github.com/max32002/kurewa-gothic</a></p>



<p>線上效果預覽: 苦累蛙圓體 Kurewa Gothic<br><a href="https://max-everyday.com/2021/06/kurewa-gothic/">https://max-everyday.com/2021/06/kurewa-gothic/</a></p>



<p>訓練用的 batch size 建議值:<br><a href="https://stackoverflow.max-everyday.com/2025/12/zi2zi-decrease-batch-size/">https://stackoverflow.max-everyday.com/2025/12/zi2zi-decrease-batch-size/</a><br>（AI 的答案有可能是錯誤的？參數數值別全信！處處存疑、反覆求證是王道。）</p>



<p>YouTube: <a href="https://youtu.be/RcigPCJZQEY">https://youtu.be/RcigPCJZQEY</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="用 AI  幫苦累蛙圓體補缺字" width="885" height="664" src="https://www.youtube.com/embed/RcigPCJZQEY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
</div></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>在 Windows 平台, 所有使用到的指令:</p>



<pre class="wp-block-code"><code>@...................................................
@ 用人工去比對 paired image, 
@...................................................
@ 為什麼會有 paired_images_debug,
@ 因為需要先配對一次, 用人工去比對 paired image, 
@ 移除不適合訓練的字, 例如: symbols &amp; 筆劃不同.

cd C:\Max\Documents\zi2zi-pytorch\
rd /q/s C:\Max\Documents\zi2zi-pytorch\source\paired_images-kurewa-debug
python font2img.py --src_font=source/font/SweiGothicCJKtc-DemiLight.ttf ^
    --dst_font=source/font/ZenKurenaido-Regular.ttf ^
    --charset=charset/charset_test.txt ^
    --sample_dir=source/paired_images-kurewa-debug ^
    --label=0 ^
    --canvas_size=384 ^
    --char_size=384 ^
    --dst_y_offset=-111 ^
    --disable_auto_fit ^
    --mode=font2font

@...................................................
@ 產生訓練清單
@...................................................
@ 調整訓練的字的清單, 很有可能會動態調整內容, 所以要用自動化的腳本來維護與管理控制。

cd C:\Max\Documents\kurewa-gothic\orig
copy /y charset_kurenaido.txt charset_kurenaido_train.txt
python \max\sh\remove_selected_char.py --input charset_kurenaido_train.txt --remove charset_kurenaido_alpha.txt --output charset_kurenaido_train.txt
python \max\sh\remove_selected_char.py --input charset_kurenaido_train.txt --remove charset_kurenaido_train_removed.txt --output charset_kurenaido_train.txt
copy /y charset_kurenaido_train.txt C:\Max\Documents\zi2zi-pytorch\charset

@ 確定好內容, 產生 paired_images

cd C:\Max\Documents\zi2zi-pytorch\
rd /q/s C:\Max\Documents\zi2zi-pytorch\source\paired_images-kurewa
python font2img.py --src_font=source/font/SweiGothicCJKjp-Light.ttf ^
    --dst_font=source/font/ZenKurenaido-Regular.ttf ^
    --charset=charset/charset_kurenaido_train_match_noto_light.txt ^
    --sample_dir=source/paired_images-kurewa ^
    --shuffle ^
    --canvas_size=384 ^
    --char_size=384 ^
    --dst_y_offset=-111 ^
    --disable_auto_fit ^
    --mode=font2font

@...................................................
@ package 
@...................................................

rd /q/s C:\Max\Documents\zi2zi-pytorch\experiments\data-kurewa-regular-384-jp
mkdir C:\Max\Documents\zi2zi-pytorch\experiments\data-kurewa-regular-384-jp
cd C:\Max\Documents\zi2zi-pytorch\
python package.py --dir=source/paired_images-kurewa ^
    --save_dir=experiments/data-kurewa-regular-384-jp ^
    --no_label ^
    --split_ratio=0

@...................................................
@ train
@...................................................
@ local

cd C:\Max\Documents\zi2zi-pytorch\
python train.py --experiment_dir=experiments ^
    --data_dir=experiments/data-kurewa-regular-384-jp ^
    --gpu_ids=cuda:0 ^
    --batch_size=16 ^
    --epoch=1 ^
    --lr=0.00105 ^
    --self_attention ^
    --checkpoint_steps=20 ^
    --ngf=64 ^
    --accum_steps=8 ^
    --image_size=384 ^
    --d_spectral_norm ^
    --checkpoint_only_last

@ colab
@ --resume=48019 \
@ batch_size, https://stackoverflow.max-everyday.com/2025/12/zi2zi-decrease-batch-size/

%cd '/gdrive/My Drive/Colab Notebooks/zi2zi-pytorch'
!python train.py --experiment_dir=experiments \
    --data_dir=experiments/data-kurewa-regular-384-jp \
    --gpu_ids=cuda:0 \
    --batch_size=64 \
    --image_size=384 \
    --ngf=64 \
    --ndf=64 \
    --epoch=100 \
    --lr=0.000999 \
    --self_attention \
    --checkpoint_steps=100 \
    --checkpoint_steps_after=300 \
    --d_spectral_norm \
    --checkpoint_only_last

@ get char list.
fontforge \max\sh\get_ttf_chars.py kurewa-max-new-chi-only.ttf


python \max\sh\remove_selected_char.py --input charset_kurewa-max-new-chi-only.txt --remove charset_SweiGothicCJKjp-Light.txt --mode=int --output charset_kurewa-max-new-chi-match-noto-light.txt
length of input file: 1113
length of remove file: 44170
excepted length of formated file: 1010
final length of target file: 1010

python \max\sh\remove_selected_char.py --input charset_kurenaido_train.txt --remove charset_SweiGothicCJKjp-Light.txt --mode=int --output charset_kurenaido_train_match_noto_light.txt
length of input file: 6645
length of remove file: 44170
excepted length of formated file: 6419
final length of target file: 6419

python \max\sh\remove_selected_char.py --input charset_kurenaido_train_match_noto_light.txt --remove charset_SweiGothicCJKjp-Light-more-9.txt --mode=int --output charset_kurenaido_train_match_noto_light-more-9.txt
length of input file: 6419
length of remove file: 26282
excepted length of formated file: 5287
final length of target file: 5287

cd C:\Max\Documents\zi2zi-pytorch\
rd /q/s C:\Max\Documents\zi2zi-pytorch\source\paired_images-kurewa-debug
python font2img.py --src_font=source/font/SweiGothicCJKtc-Light.ttf ^
    --dst_font=source/font/kurewa-max-new-chi-only.ttf ^
    --charset=charset/charset_kurewa-max-new-chi-match-noto-light.txt ^
    --sample_dir=source/paired_images-kurewa-debug ^
    --label=1 ^
    --shuffle ^
    --canvas_size=384 ^
    --char_size=384 ^
    --dst_y_offset=-111 ^
    --disable_auto_fit ^
    --mode=font2font

cd C:\Max\Documents\zi2zi-pytorch\
del C:\Max\Documents\zi2zi-pytorch\source\paired_images-kurewa\1_*
move C:\Max\Documents\zi2zi-pytorch\source\paired_images-kurewa-debug\*.png C:\Max\Documents\zi2zi-pytorch\source\paired_images-kurewa
rmdir  C:\Max\Documents\zi2zi-pytorch\source\paired_images-kurewa-debug

@...................................................
@ infer
@...................................................
rd /q/s experiments\infer\0
cd C:\Max\Documents\zi2zi-pytorch
set checkpoint=48019
set image_size=384
set ngf=48
set ndf=48
python infer.py --experiment_dir=experiments ^
    --checkpoint_dir=experiments/checkpoint-kurewa-regular-384-jp ^
    --gpu_ids=cuda:0 ^
    --resume=%checkpoint% ^
    --ngf=%ngf% ^
    --ndf=%ndf% ^
    --batch_size=40 ^
    --from_txt ^
    --filename_rule=unicode_int ^
    --src_font=source/font/SweiGothicCJKtc-Light.ttf ^
    --src_font_y_offset=0 ^
    --src_txt_file=charset/charset_kurewa_infer_list_without_max_new.txt ^
    --self_attention ^
    --image_size=%image_size% ^
    --canvas_size=%image_size% ^
    --char_size=%image_size% ^
    --d_spectral_norm ^
    --label=0
rd /q/s experiments\infer\0_%checkpoint%_tc
ren experiments\infer\0 0_%checkpoint%_tc


@...................................................
@ mix maybe and good png.
@...................................................

xcopy /y C:\Max\Documents\kurewa-gothic\orig\png-maybe\*.png C:\Max\Documents\zi2zi-pytorch\source\paired_images-kurewa
xcopy /y C:\Max\Documents\kurewa-gothic\orig\png-good\*.png C:\Max\Documents\zi2zi-pytorch\source\paired_images-kurewa

@...................................................
@ package 
@...................................................

rd /q/s C:\Max\Documents\zi2zi-pytorch\experiments\data-kurewa-regular-384-jp
mkdir C:\Max\Documents\zi2zi-pytorch\experiments\data-kurewa-regular-384-jp
cd C:\Max\Documents\zi2zi-pytorch\
python package.py --dir=source/paired_images-kurewa ^
    --save_dir=experiments/data-kurewa-regular-384-jp ^
    --no_label ^
    --split_ratio=0

@...................................................
@ generate_glyphs 
@...................................................

    --keyword "白申車甲旦音里由早者曲果昜卑曷旲莫是單亘昔重昚軍昆尞电章龺亶百旬皇曾󰕊更會奄童易旨覃專敫香卓東斬皆農宣昷单󰒄旱昌畢 昏倝春原曹󰓛連意皀昗复 妟豊冥泉習朁間巢猒帛匽惠厭樂󰒒星戠景竟查寅󰓅明暴耆魯佰 旣  昬甹㬎厘皋鲁葛宿晃晉曳湯便㝵時沓普晶󰒏󰑁替復黾署昝動諸旧朝皐圼著漸昇幹廛󰓲陳间幕単时奢皕审綿寮屠庫旻晏杲竜猪豬皃耤乾亀亯诸賜兜皂的昱嘗野歆團曇董崑庳恒草贛戟晋軒軗輦昭显暑楽神筍軎泊澧皛谒貍貌謁"
    --keyword "佹危卼垝姽尯峗峞恑桅洈硊祪脆臲蛫觤詭诡跪陒頠鮠"
    --keyword "侒咹垵姲安峖按晏暥案桉氨洝胺荌銨铵鞌鞍頞騴鮟鴳鷃鼹"
    --keyword "倦儯券劵勌勝勬卷啳圈圏埢堘塍奍婘媵巻帣幐弮惓慻拳捲搼桊棬椦榺橳淃滕漛潫牶犈畻眷睠箞籐籘絭綣縢绻腃腾膡菤蔨蕂藤虅蜷螣裷觠誊謄豢賸踡錈锩闂韏飬餋駦騰驣鬈鮝鰧鲞黱齤龹"
    --keyword "俔儬儭哯嚫囕垷娊嫢宽寛寬寴岘峴悓挸揽搅摫撹攪攬斍晛枧梘椝榄槻槼櫬欖欟涀漞瀙灚灠爦现現睍瞡砚硯窥窺竀笕筧粯絸纜缆臗舰苋莧萈藽蚬蜆襯見覌覍覎規覐覑覒覓覔覕視覗覘覙覚覛覜覝覞覟覠覡覢覣覤覥覦覧覨覩親覫覬覭覮覯覰覱覲観覴覵覶覷覸覹覺覻覼覽"
    --keyword "俞偷偸兪匬喩喻堬婾媮崳嵛愈愉揄楡榆歈毹毺渝瀭牏瑜瘉癒睮窬緰羭腧萮蕍蝓褕覦觎諭谕貐踰輸输逾鄃鍮隃騟"
    --keyword "兄冋加卟占古句另叧叨叩叫召叭叮台叱右叴叵叶号叹叺叻叼叽叾叿吀吁吂吃各吅吆吇合吉吊吋同名后吐吒吓吔吕吖吗𫝘吘吙吚君吜吝吞吟吠吡吢吣吤吥否吧吨吩吪含听吭吮启吰吱吲吴吵吶吷吸吹吺吻吼吽吾吿呀呁呃呅呆呇呈告呋呌呍呎呏呐呒呓呔呕呖呗员呙呚呛呜𠯗㕸呝呞呟呠呡呢呣呤呥呦呧呩呪呫呬呭呮呯呰呱呲味呴呵呶呷呸呹呺呻呼呾呿咀咁咂咃咄咅咆咇咈咉咊咋和咍咎咏咐咑咓咔咕咖咗咘咙咚咛咜咝㖅咞咟咠咡咣咤咥咦咧咨咩咪咬咭咮咯咰咱咲咳咴咵咶咷咸咹咺咻咼咽咾咿哀品哂哃哄哅哆哇哈哉哊哋哌响哎哏哐哑哒哓哔哕哖哗哘哙哚哜哝哞哟哠員哢哣哤哦哧哨哩哪哫哬哮哯哰哱哲哳哴哵哷哸哹哺哻哼哽哾唀唁唂唃唄唅唆唇唈唉唊唋唌唍唏唑唒唓唔唕唖唗唙唚唛唝唞唠唡唢唣唤唥唦唧𠲿㖭唨唩唪唫唬唭售唯唰唱唲唳唴唵唶唷唸唹唺唻唼唽唾唿啀啁啂啃啄啅啈啉啊啋啌啍問啐啑啒啓啕啖啗啘啛啜啝啞啠啡啢啣啤啥啦啧啨啩啪啭啮啯啰啱啲啳啴啵啶啷啸啹㖸㗎啫啺啻啼啽啾啿喀喁喂喃喅喇喈喉喊喋喎喏喐喑喒喓喔喕喖喗喘喙喚喛喜喝喞喟喠喡喢喤喥喧喨喩喫喭喯喰喱喲喳喴喵喷喹喺喻喼喽噅㗘喍嗀嗁嗂嗃嗄嗅嗆嗈嗉嗊嗋嗌嗍嗎嗏嗐嗑嗒嗓嗔嗕嗖嗗嗘嗙嗚嗛嗜嗝嗞嗟嗡嗢嗤嗥嗦嗨嗪嗫嗬嗮嗯嗰嗱嗲嗳嗴嗵嗶嗷嗸嗹嗺嗻嗼"
    --keyword "値值嗭埴徝悳惪植殖淔犆禃稙置"
    --keyword "傎厧嗔填嫃寘嵮慎搷槙滇瑱瘨瞋磌禛稹窴縝缜蒖衠謓貭蹎鎮镇闐阗顛颠鬒鷏黰齻"
    --keyword "儐嬪擯檳殯濱獱璸矉礗穦繽臏薲蠙鑌顮馪驞髕鬢𩼧"
    --keyword "凥卢孱尻尼𡰪𡰯尾尿屁层屃屄居屆屇屈屉届屋屌屍屎屏𡱒屑屒屓屖屙屚屛屝属屟屠屡屢屣層履𡳞屩屪屭户戸杘羼迉鳲鸤"
    --keyword "字宁宂它宄宅宆宇守安宊宋完宍宎宏宑宒宓宔宕宖宗官宙宛宜宝实実宠审客宣室宥宦宨宩宪宫㝗宧宬宭宮宯宰宱宲宴宵家宷宸容宺宽宾宿寀寁寂寃寄寈寉寊富寏寑寓寔寪寖寘寙寚寛㝩寞察寠寥實審寫寬寭寮寯寰寲寴寵寷惌梥灾牢賔"
    --keyword "傅博㗘圑愽搏榑溥煿牔猼磗禣糐縛缚䍸膊蒪賻赙鎛镈餺馎髆"
    --keyword "傛塎嫆嵱彮愹搈榕溶熔瑢穃蓉褣鎔镕鰫"
    --keyword "塞寋寨弿搴褰謇賽赛蹇騫骞鶱"
    --keyword "䟓趴趵趶趷䟘趺趻趽趾跀跁跂跃跄𧿬䟩跅跆跇跈跊跋跌跍跎跏跐跑跒跓跔跕跖跗跘跙跚跛跜距跞践𧿳趼跟跠跡跢跣跤跥跦跧跨跩跪跬跭跮路跰跱跲跳跴跶跷跸跹跺跻𬦰跼跽跿踀踁踂踃踄踆踇踈踉踊踋踌踍踎踏踐踑踒踓踔踕踖踗踘踙踚踛踜踝踞踟踠踡踢踣踤踥踦踧踩踪踬踭踮踯踺踫踰踱踳踴踵踶踷踸踹踻踼踽踾踿蹀蹁蹂蹃蹄蹅𨂾𨂿蹆蹈蹉蹊蹋蹌蹍蹎蹏蹐蹑蹒蹓𨃰䠡蹕蹖蹗蹘蹚蹛蹜蹝蹞蹟蹠蹡蹢蹣蹤蹥蹦蹧蹮躀蹨蹪蹫蹬蹭蹯蹰蹱蹲蹳蹴蹶蹸蹹蹺蹻蹼蹽蹾蹿𨅔躁躂躃躅躆躈躊躋躌躍躎躏躐躑躒躓躔躕躖躘躙躚躜躝躞躟躢躣躤躥躦躧躩躪躨"
    --keyword "氻氾氿汀汁汃汄汅汇汈汉汊汋汌汍汎汏汐汑汒汓汔汕汗汘汙汚汛汜汝江池污汢汣汤汥汦汧汨汩汪汫汭汮汯汰汱汲汳汴汵汶汷汸汹決汻汼汽汾汿沁沂沃沄沅沆沇沈沉沋沌沍沎沏沐沑沔沕沖沘沙沚沛沜沞沟沠没沢沣沤沥沦沧沨沩沪𣲩沫沬沭沮沱沲河沴沵沶沷沸油沺治沼沽沾泀況泂泃泄泅泆泇泈泊泋泌泍泎泏泐泑泒泓泔法泖泗泘泙泛泜泝泞泟泠泡波泣泤泥泦泧注泩泪泫泬泭泮泯泱泲泳泷泸泹泺泻泼泽泾泚泿洀洁洂洃洄洅洆洇洈洉洊洋洌洎洏洐洑洒洓洔洕洗洘洙洚洛洝洞洟洠洡洢洣洤津洦洧洨洩洪洫洬洭洮洰洱洲洳洴洵洶洷洸洹洺活洼洽派洿浀流浂浃浄浅浇浈浉浊测浌浍济浏浐浑浒浓浔浕洍洖浖浗浘浙浚浛浜浝浞浟浠浡浢浣浤浥浦浧浨浩浪浫浬浭浮浯浰浱浲浳浴浵浶海浹浺浻浼浽浾浿涀涁涂涃涄涅涆涇消涉涊涋涌涍涎涏涐涑涒涓涔涕涖涗涘涚涛涜涝涞涟涠涡涢涣涤涥润涧涨涙涪涫涬涭涮涯涰涱液涳涴涵涶涷涸涹涺涻涼涽涾涿淀淁淂淃淄淅淆淇淈淉淊淋淌淍淎淏淐淑淒淓淔淕淖淗淘淙淚淛淜淝淞淟淠淡淢淣淤淥淦淧淨淩淪淫淬淭淮淯淰深淲淳淴淵淶混淸淹淺添淽淿渀渁渂渄清渆済渉渊渌渍渎渏渐渑渒渔渖渗渚湴㴘㴙渃渘渙減渜渝渞渟渡渢渣渤渥渦渧渨温渪渫測渭渮港渰渱渲渳渴渵渶渷游渹渺渻渼渽渾渿湀湁湂湃湄湅湆湇湈湉湊湋"
    --keyword "佞囡奴奵奶奷奸她奺奻奼好奾奿妀妁如妃妄妅妆妇妈妉妊妋妌妎妏妐妑妒妓妔妕妖妗妘妙妚妜妝妞妟妠妡妢妣妤妥妦妧妨妩妪妫㚷妬妭妮妯妰妱妲妳妴妵妶妷妸妹妺妼妽妾妿姀姁姂姃姄姅姆姇姈姉姊始姌姍姎姏姐姑姒姓委姕姖姗妍姘姙姚姛姜姝姞姟姠姡姢姣姤姥姦姨姩姪姫姭姮姯姰姱姲姳姴姶姷姸姹姺姻姼姽姾姿娀威娂娃娅娆娇娈姬娉娊娋娌娍娎娏娐娑娒娓娔娕娖娗娘娙娚娛娜娝娞娟娠娡娢娣娤娥娦娧娨娩娪娫娭娮娯娰娱娲娴娽娬娵娶娷娸娹娺娻娼娾娿婀婂婃婄婅婆婇婈婉婊婋婌婍婎婏婐婑婒婓婔婕婖婗婘婙婚婛婜婝婞婟婠婡婢婣婤婥婦婧婨婩婪婫婬婭婮婯婰婱婲婳婵婶婷婸婹婺婻婼婽婾婿媀媁媂媃媄媅媆媇媈媉媊媋媌媍媎媏媑媒媓媔媕媖媗媘媙媚媛媜媝媞媟媡媢媣媤媥媦媧媨媩媪媬媭媮媯嫏媐媰媱媲媳媴媶媷媸媹媻媼媽媾媿嫀嫁嫂嫃嫄嫅嫆嫇嫉嫊嫋嫌嫍嫎嫒嫔嫕嫖嫗嫘嫙嫚嫛嫜嫝嫞嫟嫠嫡嫢嫣嫤嫥嫦嫧嫩嫪嫫嫬嫭嫮嫯嫰嫱嫲嫳嫴嫵嫶嫷嫸嫹嫺嫻嫼嫽嫾嫿嬀嬂嬃嬄嬅嬆嬇嬈嬉嬋嬌嬍嬏𡢃嬐嬑嬒嬓嬕嬖嬗嬘嬙嬚嬛嬜嬝嬞嬟嬠嬡嬢嬴㜮嬣嬤嬥嬦嬧嬨嬩嬪嬫嬬嬭嬮嬯嬰嬱嬳嬵嬶嬷嬸嬺嬻嬼嬹嬾嬿㜷孀孁孂孃孄孅孆孇孈孉孊孋孌孍孎孏安汝娄籹耍肗要邚釹钕"
    --keyword "㑁咄屈㤕拙昢朏柮欪泏炪础祟窋笜粜絀绌聉胐茁袦詘诎貀趉鈯韷飿饳黜"
    --keyword "伢冴厊呀岈庌㤉㧎枒𤘅牚犽玡疨砑穿笌芽蚜衺訝讶谺迓邪釾閕雅颬鴉鸦齖"
    --keyword "坹屄岤帘㧒柼泬狖穵究穷穸穹空穻穼穽穾穿窀突窂窃窄窅窆窇窈窉窊窋窌窍窎窏窐窑窒窔窕窖窗窘窙窚窜窝窞窟窠窡窢窣窤窥窦窧窨窩窪窫窬窭窮窯窰窱窲窳窴窵窶窷窸窹窺窻窼窽窾窿竁竂竄竅竆竇竉茓袕貁鴥鴪"
    --keyword "唿惚㧾淴鍃锪"
    --keyword "妉帎忱抌枕沈沊瓭㽎眈紞耽衴訦躭邥酖鈂馾髧魫鴆鸩黆黕"
    --keyword "偡勘卙啿堪夦媅尠嵁愖戡揕斟椹歁湛煁㽎瘎碪糂葚諶谌踸鍖黮"
    --keyword "冒泪狊盯䀐盰盱盲盳盵盶盷相盹盺盻盼盽盿眀省眂眃眄眅眆眇眈眉眊看眍眎眏眐眑眒眓眕眖眗眘眙眚眛眜眝眠眡眢眣眤眥眦眧眨眩眪眫眬眿眭眮眯眰眱眲眳眴眵眶眸眹眺眻眼眽睁䀯䀴着睃睄睅睆睇睈睉睊睋睌睍睎睏睐睑睒睓睔睕睖睗睙睚睛睜睝睞睟睠睢督睤睥睦睧睨睩睫睬睭睡睮睯睰睱睲睳睴睵睶睷睸睹睺睻睼睽瞀瞁瞃瞄瞅瞆瞇瞈瞉瞊瞋瞌瞍瞎瞐瞑瞒瞓𥉌瞔瞕瞖瞗瞘瞙瞚瞛瞜瞝瞞瞟瞠瞡瞣䁯瞤瞥瞦瞧瞨瞩瞪瞫瞬瞭瞯瞰瞱瞲瞳瞴瞵瞶瞷瞸瞹瞺瞻瞼瞽矀矁矂矃矄矅矆矇矉矊矋矌矎矏𥌚矐矑矒矓矔𥍉矕矘矙矖矚窅苜見貝鉬钼"
    --keyword "浊烛独痋茧萤虬虭虮虯虰虲虳虴虵虶虷虸虹虺虻虼虽虾虿蚀蚁蚂蚃蚄蚅蚆蚇蚉蚊蚋蚌蚍蚎蚏蚐蚑蚒蚓蚔蚕蚖蚗蚘蚙蚚蚛蚜蚝蚞蚟蚠蚡蚢蚣蚤蚥蚦蚧蚨蚩蚪蚬蚫蚭蚮蚯蚰蚱蚲蚳蚴蚵蚶蚷蚸蚹蚺蚻蚼蚽蚾蚿蛀蛁蛂蛃蛄蛅蛆蛇蛈蛉蛊蛋蛌蛎蛏﨡𧉟𧊅䖳蚈蛐蛑蛒蛓蛔蛕蛗蛘蛙蛚蛛蛜蛝蛞蛟蛠蛡蛢蛣蛤蛥蛦蛧蛨蛩蛪蛫蛬蛭蛮蛯蛰蛱蛲蛳蛴蛖蛵蛶蛷蛸蛹蛺蛻蛼蛽蛾蛿蜂蜃蜄蜅蜆蜇蜈蜉蜊蜋蜌蜍蜎蜏蜐蜑蜒蜓蜔蜕蜖蜗蜫蝆䗁䗆蜘蜙蜚蜛蜜蜝蜞蜟蜠蜡蜢蜣蜤蜥蜦蜧蜨蜩蜪蜬蜭蜮蜯蜰蜱蜲蜳蜴蜵蜶蜷蜸蜹蜺蜻蜼蜽蜾蜿蝀蝁蝂蝃蝄蝅蝇蝈蝉蝊蝋𧌄𬠖䗐蝌蝍蝎蝏蝐蝑蝒蝓蝔蝕蝖蝗蝘蝙蝚蝛蝜蝝蝞蝟蝠蝡蝢蝣蝤蝥蝦蝧蝩蝪蝫蝬蝭蝮蝯蝰蝲蝳蝴蝵蝶蝷蝸蝺蝻蝼蝽蝾螀蟡蝹螁螂螃螄螅螆螇螈螉螊螋螌融螎螏螐螑螓螔螕螖螗螘螚螛螜螝螞螟螠螢螥螦螧螨螩螪螫螬螭螮螯螰螱螲螳螴螵螷螸螹螺螻螼螾螿蟀蟂蟃蟄蟅蟆蟇蟈蟉蟋蟌蟍蟎蟏蟐蟑蟒蠁蟓蟔蟕蟖蟘蟙蟚蟛蟜蟝蟞蟟蟠蟢蟣蟤蟥蟦蟧蟨蟩蟪蟫蟬蟭蟮蟯蟰蟱蟲蟳蟴蟵蠎蟶蟷蟹蟺蟻蟼蟽蟾蠀蠂蠃蠄蠅蠆蠇蠈蠉蠊蠋蠌蠍蠏蠐蠑蠒蠓蠔蠕蠖蠗蠘蠙蠛蠜蠝蠞蠟蠣蠴䘆蠥蠦蠨蠩蠪蠬蠮蠰蠳蠵蠷蠸蠻蠼蠾触赨鉵閩闽"
    --keyword "塟蒸爇萬繤艺艻艼艽艾艿芀芁芃芄芅芆芇芉芊芋芌芍芎芏芐芑芒芓芕芖芗芘芙芚芛芜芝芞芟芠芡芢芣芤芥芦芧芨芩芪芫芬芭芮芯芰花芲芳芴芵芶芷芸芹芺芼芽芾苀苁苂苃苄苅苆苇苈苉苊苋苌苍苎苏茾芿苐苑苒苓苔苕苖苗苘苙苚苛苜苝苞苟苠苡苢苣苤若苦苧苨苩苪苫苬苭苮苯苰英苲苳苴苵苶苷苸苹苺苻苼苽苾苿茀茁茂范茄茅茆茇茈茉茊茋茌茍茎茏茐茑茓茒茖茗茘茙茚茛茜茞茟茠茡茢茤茥茦茧茨茩茪茫茬茭茮茯茱茲茳茴茵茷茸茹茺茼茽茿荀荁荂荃荄荅荇荈草荊荋荌荍荎荏荐荑荒荔荕荖荗荘荙荚荛荜荝荞荟荠荡荢荣荤荥荨荩荪荫荬荭荮药茝茣荰荱荲荳荴荵荶荷荸荹荺荻荼荽荾荿莀莁莂莃莄莅莆莇莈莉莊莋莌莍莎莏莐莑莒莓莔莕莖莗莘莙莚莛莜莝莞莟莠莡莢莣莤莥莦莧莨莩莪莫莬莮莯莰莱莲莳莴莵莶获莸莼荓莾莿菀菁菂菃菄菅菆菇菈菉菊菋菌菍菎菏菑菒菓菔菕菖菗菘菙菚菛菜菝菞菟菠菡菢菣菤菥菦菧菨菩菪菬菭菮菰菱菲菳菴菵菶菷菸菹菺菻菼菽菾菿萀萁萂萃萄萅萆萇萉萊萋萌萍萎萏萐萑萒萓萔萕萖萗萘萙萚萜萝萟萠萡萢萣萧著莭萩萪萫萭萮萯萰萱萲萳萴萵萶萷萸萹萺萻萼落萾萿葀葁葂葃葄葅葆葇葈葉葊葋葌葍葎葏葐葑葒葓葔葕葖葘葙葚葛葜葝葞葟葠葡葢董葤葥葦葧葨葩葪葫葭葮葯葰葱葲葳葴葵葶葷葸葹葺葻葼葽葾葿蒀蒁蒂蒃蒄"
    --keyword "字宁宂它宄宅宆宇守安宊宋完宍宎宏宑宒宓宔宕宖宗官宙宛宜宝实実宠审客宣室宥宦宨宩宪宫㝗宧宬宭宮宯宰宱宲宴宵家宷宸容宺宽宾宿寀寁寂寃寄寈寉寊富寏寑寓寔寪寖寘寙寚寛㝩寞察寠寥實審寫寬寭寮寯寰寲寴寵寷惌梥灾牢賔"
    --keyword "亗仙仚冚喦圸奾密乢屲屳屴屵屶屷屸屹屺屻屼屽屾屿岁岂岃岄岅岆岇岈岉岊岋岌岎岏岐岑岒岓岔岕岖岗岘岙岚岜岝岞岟岠岢岣岤岥岦岧岨岩岪岫岬岭岮岯岰岱岲岳岴岵岶岷岸岹岺岻岼岽岾岿峀峁峂峄峅岍峆峇峈峉峊峋峌峍峎峏峐峑峒峓峔峕峖峗峘峙峚峛峜峝峞峟峠峡峢峣峤峥峦峧峨峩峪峫峬峭峮峯峰峲峳峴峵峷峸峹峺峻峼峽峾峿崀崁崂崃崄崅崆崇崈崉崊崌崍崎崏崐崑崒崓崔崕崖崗崘崙崚崛崜崝崞崟崠崡崢崣崤崥崦崧崨崩崪崫崬崭崮崯崰崱崲崳崴崵崶崷崸崹崺崻崼崽崾崿嵀嵁嵂嵃嵄嵅嵆嵈嵉嵋嵌嵍嵎嵏嵐嵑嵒嵓嵔嵕嵖嵘嵙嵚嵛嵜嵝﨑㟴嵊嵟嵠嵡嵢嵣嵥嵦嵧嵨嵩嵪嵫嵬嵭嵮嵯嵰嵱嵲嵳嵴嵵嵶嵷嵸嵹嵺嵻嵼嵽嵾嵿嶀嶁嶂嶃嶄嶅嶆嶇嶈嶉嶊嶋嶌嶍嶎嶐嶑嶒嶓嶔嶕嶖嶗嶘嶙嶚嶛嶜嶝嶞嶟嶠嶡嶢嶣嶤嶥嶦嶧嶩嶪嶫嶬嶮嶯嶰嶱嶲嶴嶵嶶嶷嶸嶹嶺嶼嶽嶾嶿巁嶻巃巄巅巆巇巈巉巊巋巌巍巏巐巎巑巒巓巔巗巖巘巙巚幽旵杣氙汕汖灿炭疝秈籼耑舢訔訕讪豈赸軕辿邖閊"
    --keyword "倥啌埪崆悾控曌椌涳焢瞾硿箜羫聜腔谾躻鞚鵼"
    --keyword "扎扐扑扒打扔払扖扏扗托扙扚扛扜扝扞扠扡扢扣扤扦执扨扩扪扫扬㧌㧎扟扭扮扯扰扱扲扳扴扵扶扷批扺扻扼扽找技抁抂抃抄抅抆抇抈抉把抋抌抍抎抏抐抑抒抓抔投抖抗折抙抚抛抜抝択抟抠抡抢抣护报𢪱㧒扸抦抧抨抩抪披抬抭抮抯抰抱抲抳抴抵抶抷抸抹抺抻押抽抾抿拀拁拂拃拄担拆拇拈拉拊拌拍拎拐拑拒拓拔拕拖拗拘拙拚招拞拟拠拡拢拣拤拥拦拧拨择𫝺㧡㧣拪拫括拭拮拯拰拱拴拵拶拷拸拹拺拻拼拽拾挀持挂挃挄挅挆指按挊挋挌挍挎挏挑挒挓挔挕挖挗挘挜挝挞挟挠挡挢挣挤挥挦挧𢫦𫝻挨挩挪挫挬挭挮振挰挱挳挴挵挶挷挸挹挺挻挼挽挾挿捀捁捂捃捄捅捆捇捈捉捊捋捌捍捎捏捐捒捓捔捕捖捗捘捙捚捛捝捞损捠捡换捣捤㧻㧾㨂捥捦捧捨捩捪捫捬捭据捰捱捲捳捴捵捶捷捸捹捺捻捼捽捾捿掀掁掂掃掄掅掆掇授掉掊掋掍掎掏掐掑排掓掕掖掗掘掙掚掛掜掝掞掟掠採探掤接掦控推掩措掫掬掭掮掯掳掴掵掶掷掸掹掺掻掼掽㨑掲掾掿揀揁揂揃揄揆揇揈揉揊揋揌揍揎描提揑插揓揔揕揖揗揘揙揚換揜揝揞揟揠揢揣揤揥揨揩揪揬揭揮揯揰揲揳援揵揶揷揸揹揻揼揽揾揿搀搁搂搃搄搅摒𢯭𢯾㨨㨪搆搇搈搉搊搋搌損搎搏搐搑搒搓搔搕搗搘搙搚搛搜搝搞搟搠搡搢搣搤搥搦搧搨搩搪搬搭搮搯搰搲搳搵搶搷搸搹携搼搽搾摀摁摃摄摅摆摇摈摉摊𢱤摋摌摍摎摏摐摑摓摔"
    --keyword "丗丯乫伽冄农刄办匁包另叻咖哿嗧嘉坐夹妿幽弐戋拁架枷毠泇珈甴电畞痂笳耞茄袈譱賀贺跏迦鉫隺駕驾鴐龙"
    --keyword "喀愘愙揢楁碦額额髂"
    --keyword "佫咯嗠垎客峈峉𢓜恪挌敋𢼛格洛洜烙狢珞略畧硌笿絡络胳臵茖蛒衉袼觡詻貉賂赂路輅辂酪鉻铬閣阁雒頟餎饹駱骆骼鮥鴼鵅"
    --keyword "呚坆孜收攷改攺攻攼攽放政敀敂敃敄故敇效敉敋敌啟敎敏敐救敒敓敔敕敗敘教敚敛敜敝敞敟敦敨敩敪敭敬数敳敵敶敷數敾敿斁斂贁斆枚炇牧玫畋致變败赦駇"
    --keyword "攵敁𢼌敆敊𢼛敍㪐㪗敠敡敤敥敧敮敯敱敲敺敼敽斀斅軙鈙鼔"
    --keyword "仿坊妨彷房放斺於施旀旈旉旑旔旘旙昉昘枋汸牥瓬眆祊紡纺肪舫芳蚄訪访趽䢍邡鈁钫閍防雱髣魴鲂鴋"
    --keyword "偉喡圍媁幃徫愇暐椲湋煒瑋禕稦緯葦衛褘諱違郼鍏闈韌韍韎韏韐韑韒韓韔韕韖韗韘韙韚韜韝韞韟韠韡韢韣韤韥颹"
    --keyword "倰凌堎婈崚庱掕棱淩睖碐祾稜綾绫菱裬踜輘錂陵鯪鲮"
    --keyword "嚓擦檫聺鑔镲"
    --keyword "俆凃叙唋峹嵞庩徐悆悇捈敍敘斜梌涂狳畬畭硢稌筡艅荼蜍賖途酴除雓餘馀駼鮽鵌"
    --keyword "倲凍埬娻崠崬㨂棟氭涷腖菄蝀諌錬陳鯟鶇"
    --keyword "剳匒嗒塔搭榙溚瘩𥉌褡鎝鞳"
    --keyword "佋刟劭卲叧叨妱岧岹巶弨怊招昭柖欩沼炤牊玿眧祒笤紹绍苕蛁袑詔诏貂超軺轺迢邵鉊鞀韶駋髫鮉䳂鼦齠龆"
    --keyword "住妵宔往拄柱殶注炷玊疰砫紸罜蛀註跓軴迬鉒飳駐驻麈黈"
    --keyword "偉喡圍媁幃徫愇暐椲湋煒瑋禕稦緯葦衛褘諱違郼鍏闈韌韍韎韏韐韑韒韓韔韕韖韗韘韙韚韜韝韞韟韠韡韢韣韤韥颹"
    --keyword "佻咷垗姚宨庣恌挑晀晁朓桃洮烑狣珧𤶃眺祧窕筄絩罀聎脁覜誂趒跳䠷逃銚铫雿鞉頫餆駣鮡鴵鼗"
    --keyword "祁耶邒邓邔邖邗邘邙邚邛邜邝邞邟邠邡邢邤邥邦邧邨邩邪邬邭邮邯邰邱邲邳邴邵邶邷邸邹邺邻邼邽邾邿郀郁郂郃郄郅郆郇郈郉郊郋郍郏郐郑郓郔郕郖郗郘郙郚郛郜郝郞郟郠郡郢郣郤郥郦郧部郩郪郫郬郭郮郯郱郲郳郴郵郸郹郼都郾郿鄀鄁鄂鄃鄄鄅鄆鄇鄈鄋鄌鄍鄎鄏鄐鄑鄒鄓鄔鄖鄗鄘鄙鄚鄛鄜鄝鄞鄟鄠鄡鄢鄣鄤鄥鄦鄧鄩鄪鄫鄬鄭鄮鄯鄰鄱鄲鄳鄴鄵鄶鄷鄸鄹鄺鄻鄼鄽鄾鄿酀酂酁酃酄酅酆酇酈阞队阠阡阢阣阤阥阦阧阨阩阪阫阬阭阮阯阰阱防阳阴阵阶阷阸阹阺阻阼阽阾阿陀陁陂陃附际陆陇陈陉陊陋陌降陎陏限陑陒陓陔陕陖陗陘陙陛陜陝陞陟陠陡院陣除陦陧陨险陚陪陫陬陭陮陯陰陱陲陳陴陵陶陷陸険陻陼陽陾陿隀隁隃隄隅隇隈隊隌隍階随隐隑隒隓隔隕隖隗隘隙﨩隚際障隝隞隟隠隡隢隣隤隥隦隧隨隩險隫隬隭隮隯隰隱隴隵"
    --keyword "丗丯佮冄农冾刄办匁包匌匼哈坐垥夹姶峆峇帢幽弇弐恰戋拾拿搻敆樖欱洽烚珨甴电畞畣盒硆祫秴答粭給给翕翖耠荅蛤袷詥譱跲郃鉿铪閤隺鞈韐頜颌餄饸鮯鴿鸽龙龕龛"

cd C:\Max\Documents\kurewa-gothic\orig
python \max\sh\generate_glyphs.py --font ZenKurenaido-Regular.ttf ^
    --font_size 384 ^
    --canvas_size 384 ^
    --y_offset=-111 ^
    --disable_auto_fit ^
    --clear ^
    --keyword "丗丯佮冄农冾刄办匁包匌匼哈坐垥夹姶峆峇帢幽弇弐恰戋拾拿搻敆樖欱洽烚珨甴电畞畣盒硆祫秴答粭給给翕翖耠荅蛤袷詥譱跲郃鉿铪閤隺鞈韐頜颌餄饸鮯鴿鸽龙龕龛"


@...................................................
@ mix all
@...................................................

set target=C:\Max\Documents\zi2zi-pytorch\experiments\infer\0_48019_tc
xcopy /y C:\Max\Documents\kurewa-gothic\orig\png-maybe\*.png %target%
xcopy /y C:\Max\Documents\kurewa-gothic\orig\png-good\*.png %target%


@...................................................
@ paired image to croped image
@...................................................
set target=C:\Max\Documents\zi2zi-pytorch\experiments\infer\0_48019_tc
rd /q/s %target%_crop
python \max\sh\crop_images.py --input=%target% --output=%target%_crop

@...................................................
@ smooth, overwrite _crop image.
@...................................................
set target=C:\Max\Documents\zi2zi-pytorch\experiments\infer\0_48019_tc
python \max\sh\smooth_pattern.py --input=%target%_crop --output=%target%_crop

@...................................................
@ pbm to svg, from _crop to _svg
@...................................................
set target=C:\Max\Documents\zi2zi-pytorch\experiments\infer\0_48019_tc
rd /q/s %target%_svg
python \max\sh\bmp_to_svg.py --input %target%_crop --output %target%_svg


@...................................................
@ svg simplify
@...................................................
set target=C:\Max\Documents\zi2zi-pytorch\experiments\infer\0_48019_tc
rd /q/s %target%sp_svg
python c:\max\sh\svg_simplify.py --input %target%_svg --output %target%sp_svg

@...................................................
@ import svg
@...................................................
set target=C:\Max\Documents\zi2zi-pytorch\experiments\infer\0_48019_tc
cd C:\Max\Documents\kurewa-gothic\orig
fontforge c:\max\sh\import_svg.py --input empty_384.ttf --output imported_384_tc.ttf --svg_path %target%sp_svg

@...................................................
@ get not duplicated set.
@...................................................
cd C:\Max\Documents\kurewa-gothic\orig
fontforge \max\sh\font_delete_font.py --input imported_384_tc.ttf --remove KurewaGothicCjkTc-Regular.ttf --output diff_tc.ttf

@ 取得 duplicated
fontforge \max\sh\font_delete_font.py --input imported_384_tc.ttf --remove diff_tc.ttf --output duplicated.ttf

@ 取得 diff char list. 
fontforge \max\sh\get_ttf_chars.py duplicated.ttf

@ 回到 fontforge 開啟 Window - New Metricks Window 進行 duplicated.txt 文字清單比對
@ ...

@...................................................
@ get not duplicated set.
@...................................................
@ open diff_tc.ttf, resize to 1000x1000.


# for Windows, with &#91;Jp]
cd C:\Max\Documents\kurewa-gothic\orig\
fontforge \max\sh\expand_stroke.py --input KurewaGothicCjkJp-Regular.ttf --width 26 --expand_direction light --stroke_cap nib --stroke_join nib --output KurewaGothicCjkJp-ExtraLight.sfdir --fontname "KurewaGothicCjkJp-ExtraLight" --fullname "KurewaGothicCjkJp ExtraLight" --weight "Extra-Light" --macstyle 0 
fontforge \max\sh\expand_stroke.py --input KurewaGothicCjkJp-Regular.ttf --width 14 --expand_direction light --stroke_cap nib --stroke_join nib --output KurewaGothicCjkJp-Light.sfdir --fontname "KurewaGothicCjkJp-Light" --fullname "KurewaGothicCjkJp Light" --weight "Light" --macstyle 0 
fontforge \max\sh\expand_stroke.py --input KurewaGothicCjkJp-Regular.ttf --width 20 --expand_direction bold --stroke_cap nib --stroke_join nib --output KurewaGothicCjkJp-SemiBold.sfdir --fontname "KurewaGothicCjkJp-SemiBold" --fullname "KurewaGothicCjkJp SemiBold" --weight "SemiBold" --macstyle 0 
fontforge \max\sh\expand_stroke.py --input KurewaGothicCjkJp-Regular.ttf --width 30 --expand_direction bold --stroke_cap nib --stroke_join nib --output KurewaGothicCjkJp-Bold.sfdir --fontname "KurewaGothicCjkJp-Bold" --fullname "KurewaGothicCjkJp Bold" --weight "Bold" --macstyle 1

# for Windows, with &#91;Tc]
cd C:\Max\Documents\kurewa-gothic\orig\
fontforge \max\sh\expand_stroke.py --input KurewaGothicCjkJp-Regular.ttf --width 26 --expand_direction light --stroke_cap nib --stroke_join nib --output KurewaGothicCjkJp-ExtraLight.sfdir --fontname "KurewaGothicCjkJp-ExtraLight" --fullname "KurewaGothicCjkJp ExtraLight" --weight "Extra-Light" --macstyle 0 
fontforge \max\sh\expand_stroke.py --input KurewaGothicCjkJp-Regular.ttf --width 14 --expand_direction light --stroke_cap nib --stroke_join nib --output KurewaGothicCjkJp-Light.sfdir --fontname "KurewaGothicCjkJp-Light" --fullname "KurewaGothicCjkJp Light" --weight "Light" --macstyle 0 
fontforge \max\sh\expand_stroke.py --input KurewaGothicCjkJp-Regular.ttf --width 20 --expand_direction bold --stroke_cap nib --stroke_join nib --output KurewaGothicCjkJp-SemiBold.sfdir --fontname "KurewaGothicCjkJp-SemiBold" --fullname "KurewaGothicCjkJp SemiBold" --weight "SemiBold" --macstyle 0 
fontforge \max\sh\expand_stroke.py --input KurewaGothicCjkJp-Regular.ttf --width 30 --expand_direction bold --stroke_cap nib --stroke_join nib --output KurewaGothicCjkJp-Bold.sfdir --fontname "KurewaGothicCjkJp-Bold" --fullname "KurewaGothicCjkJp Bold" --weight "Bold" --macstyle 1


# for Windows, with &#91;Jp]
cd C:\Max\Documents\kurewa-gothic\orig\
python /Max/sh/replace_string.py KurewaGothicCjkJp-ExtraLight.sfdir\font.props "Regular" "ExtraLight"
python /Max/sh/replace_string.py KurewaGothicCjkJp-Light.sfdir\font.props "Regular" "Light"
python /Max/sh/replace_string.py KurewaGothicCjkJp-SemiBold.sfdir\font.props "Regular" "SemiBold"
python /Max/sh/replace_string.py KurewaGothicCjkJp-Bold.sfdir\font.props "Regular" "Bold"

python /Max/sh/replace_string.py KurewaGothicCjkJp-ExtraLight.sfdir\font.props "TTFWeight: 400" "TTFWeight: 300"
python /Max/sh/replace_string.py KurewaGothicCjkJp-Light.sfdir\font.props "TTFWeight: 400" "TTFWeight: 300"
python /Max/sh/replace_string.py KurewaGothicCjkJp-SemiBold.sfdir\font.props "TTFWeight: 400" "TTFWeight: 600"
python /Max/sh/replace_string.py KurewaGothicCjkJp-Bold.sfdir\font.props "TTFWeight: 400" "TTFWeight: 700"

# for Windows, with &#91;Tc]
cd C:\Max\Documents\kurewa-gothic\orig\
python /Max/sh/replace_string.py KurewaGothicCjkTc-ExtraLight.sfdir\font.props "Regular" "ExtraLight"
python /Max/sh/replace_string.py KurewaGothicCjkTc-Light.sfdir\font.props "Regular" "Light"
python /Max/sh/replace_string.py KurewaGothicCjkTc-SemiBold.sfdir\font.props "Regular" "SemiBold"
python /Max/sh/replace_string.py KurewaGothicCjkTc-Bold.sfdir\font.props "Regular" "Bold"

python /Max/sh/replace_string.py KurewaGothicCjkTc-ExtraLight.sfdir\font.props "TTFWeight: 400" "TTFWeight: 300"
python /Max/sh/replace_string.py KurewaGothicCjkTc-Light.sfdir\font.props "TTFWeight: 400" "TTFWeight: 300"
python /Max/sh/replace_string.py KurewaGothicCjkTc-SemiBold.sfdir\font.props "TTFWeight: 400" "TTFWeight: 600"
python /Max/sh/replace_string.py KurewaGothicCjkTc-Bold.sfdir\font.props "TTFWeight: 400" "TTFWeight: 700"

# Build
# for Windows, with &#91;Jp]
cd C:\Max\Documents\kurewa-gothic\orig\
fontforge /Max/sh/generate.py -i KurewaGothicCjkJp-ExtraLight.sfdir
fontforge /Max/sh/generate.py -i KurewaGothicCjkJp-Light.sfdir
fontforge /Max/sh/generate.py -i KurewaGothicCjkJp-SemiBold.sfdir
fontforge /Max/sh/generate.py -i KurewaGothicCjkJp-Bold.sfdir

# for Windows, with &#91;Tc]
cd C:\Max\Documents\kurewa-gothic\orig\
fontforge /Max/sh/generate.py -i KurewaGothicCjkTc-ExtraLight.sfdir
fontforge /Max/sh/generate.py -i KurewaGothicCjkTc-Light.sfdir
fontforge /Max/sh/generate.py -i KurewaGothicCjkTc-SemiBold.sfdir
fontforge /Max/sh/generate.py -i KurewaGothicCjkTc-Bold.sfdir


# Webfont
# for Windows, with &#91;Jp]
cd C:\Max\Documents\kurewa-gothic\orig\
rd /q/s "webfont\CJK JP"
mkdir "webfont\CJK JP"
fontforge \max\sh\generate.py --input KurewaGothicCjkJp-Regular.ttf       --output ".\webfont\CJK JP\KurewaGothicCjkJp-Regular.woff"
fontforge \max\sh\generate.py --input KurewaGothicCjkJp-Regular.ttf       --output ".\webfont\CJK JP\KurewaGothicCjkJp-Regular.woff2"
fontforge \max\sh\generate.py --input KurewaGothicCjkJp-ExtraLight.ttf    --output ".\webfont\CJK JP\KurewaGothicCjkJp-ExtraLight.woff"
fontforge \max\sh\generate.py --input KurewaGothicCjkJp-ExtraLight.ttf    --output ".\webfont\CJK JP\KurewaGothicCjkJp-ExtraLight.woff2"
fontforge \max\sh\generate.py --input KurewaGothicCjkJp-Light.ttf         --output ".\webfont\CJK JP\KurewaGothicCjkJp-Light.woff"
fontforge \max\sh\generate.py --input KurewaGothicCjkJp-Light.ttf         --output ".\webfont\CJK JP\KurewaGothicCjkJp-Light.woff2"
fontforge \max\sh\generate.py --input KurewaGothicCjkJp-SemiBold.ttf      --output ".\webfont\CJK JP\KurewaGothicCjkJp-SemiBold.woff"
fontforge \max\sh\generate.py --input KurewaGothicCjkJp-SemiBold.ttf      --output ".\webfont\CJK JP\KurewaGothicCjkJp-SemiBold.woff2"
fontforge \max\sh\generate.py --input KurewaGothicCjkJp-Bold.ttf          --output ".\webfont\CJK JP\KurewaGothicCjkJp-Bold.woff"
fontforge \max\sh\generate.py --input KurewaGothicCjkJp-Bold.ttf          --output ".\webfont\CJK JP\KurewaGothicCjkJp-Bold.woff2"

# for Windows, with &#91;Tc]
cd C:\Max\Documents\kurewa-gothic\orig\
rd /q/s "webfont\CJK TC"
mkdir "webfont\CJK TC"
fontforge \max\sh\generate.py --input KurewaGothicCjkTc-Regular.ttf       --output ".\webfont\CJK TC\KurewaGothicCjkTc-Regular.woff"
fontforge \max\sh\generate.py --input KurewaGothicCjkTc-Regular.ttf       --output ".\webfont\CJK TC\KurewaGothicCjkTc-Regular.woff2"
fontforge \max\sh\generate.py --input KurewaGothicCjkTc-ExtraLight.ttf    --output ".\webfont\CJK TC\KurewaGothicCjkTc-ExtraLight.woff"
fontforge \max\sh\generate.py --input KurewaGothicCjkTc-ExtraLight.ttf    --output ".\webfont\CJK TC\KurewaGothicCjkTc-ExtraLight.woff2"
fontforge \max\sh\generate.py --input KurewaGothicCjkTc-Light.ttf         --output ".\webfont\CJK TC\KurewaGothicCjkTc-Light.woff"
fontforge \max\sh\generate.py --input KurewaGothicCjkTc-Light.ttf         --output ".\webfont\CJK TC\KurewaGothicCjkTc-Light.woff2"
fontforge \max\sh\generate.py --input KurewaGothicCjkTc-SemiBold.ttf      --output ".\webfont\CJK TC\KurewaGothicCjkTc-SemiBold.woff"
fontforge \max\sh\generate.py --input KurewaGothicCjkTc-SemiBold.ttf      --output ".\webfont\CJK TC\KurewaGothicCjkTc-SemiBold.woff2"
fontforge \max\sh\generate.py --input KurewaGothicCjkTc-Bold.ttf          --output ".\webfont\CJK TC\KurewaGothicCjkTc-Bold.woff"
fontforge \max\sh\generate.py --input KurewaGothicCjkTc-Bold.ttf          --output ".\webfont\CJK TC\KurewaGothicCjkTc-Bold.woff2"

</code></pre>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2025/12/antigravity-kurewa-tutorial/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>別再說你不會畫畫，透過 AI 的視覺化工具，把複雜概念變簡單</title>
		<link>https://max-everyday.com/2025/12/gemini-ai-canva-figma/</link>
					<comments>https://max-everyday.com/2025/12/gemini-ai-canva-figma/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Sun, 28 Dec 2025 00:04:12 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[AI]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=22635</guid>

					<description><![CDATA[畫面不只是裝飾，更是一種幫助思考的工具。 我們都有想分享的事情，但遇到複雜內容時，該怎麼說清楚？要讓聽眾或學生容易理解，最簡單的方式就是視覺化。 畫圖不是藝術創作，而是每 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="572" src="https://max-everyday.com/wp-content/uploads/2025/12/gemini-canva-1920-1024x572.jpg?v=1766879981" alt="" class="wp-image-22637" srcset="https://max-everyday.com/wp-content/uploads/2025/12/gemini-canva-1920-1024x572.jpg?v=1766879981 1024w, https://max-everyday.com/wp-content/uploads/2025/12/gemini-canva-1920-500x279.jpg?v=1766879981 500w, https://max-everyday.com/wp-content/uploads/2025/12/gemini-canva-1920-615x343.jpg?v=1766879981 615w, https://max-everyday.com/wp-content/uploads/2025/12/gemini-canva-1920.jpg?v=1766879981 1376w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>畫面不只是裝飾，更是一種幫助思考的工具。</p>



<p>我們都有想分享的事情，但遇到複雜內容時，該怎麼說清楚？要讓聽眾或學生容易理解，最簡單的方式就是視覺化。</p>



<p>畫圖不是藝術創作，而是每個人都能學會的思考技能。重點不在於畫面美不美，而在於接收資訊的人能不能看懂。對我來說，工具永遠排在最後一位。只要能把想法表達清楚，那個工具就是正確的選擇。</p>



<p>最近我嘗試用 Gemini 的 Canva 模式畫流程圖。我原本想畫一個閉環，預計讓步驟 5 回到步驟 2。結果 Gemini 陷入鬼打牆，不斷宣稱已經修改完成，畫面卻始終不對。最後我換了個方式，改請它畫步驟 7 回到步驟 4，沒想到呈現出來的結果，正好就是我預期的步驟 5 到步驟 2。面對 AI 工具，有時候繞路走反而才是捷徑。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="479" src="https://max-everyday.com/wp-content/uploads/2025/12/2025-12-28_06-49_k2-1024x479.jpg?v=1766879640" alt="" class="wp-image-22636" srcset="https://max-everyday.com/wp-content/uploads/2025/12/2025-12-28_06-49_k2-1024x479.jpg?v=1766879640 1024w, https://max-everyday.com/wp-content/uploads/2025/12/2025-12-28_06-49_k2-500x234.jpg?v=1766879640 500w, https://max-everyday.com/wp-content/uploads/2025/12/2025-12-28_06-49_k2-1536x718.jpg?v=1766879640 1536w, https://max-everyday.com/wp-content/uploads/2025/12/2025-12-28_06-49_k2-615x288.jpg?v=1766879640 615w, https://max-everyday.com/wp-content/uploads/2025/12/2025-12-28_06-49_k2.jpg?v=1766879640 1811w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>把腦內草圖變現實： 你不需要繪畫基礎，只需要用文字描述你的邏輯。視覺化拆解成三個階段。</p>



<ul class="wp-block-list">
<li>Step 1：捕捉想法 <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 先別急著畫，先用文字寫下核心概念。</li>



<li>Step 2：拆解元素 <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 找出關係、流程或對比。</li>



<li>Step 3：視覺呈現 <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3a8.png" alt="🎨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 輸入指令，請 Gemini / chatGPT 生成簡單的圖示或示意圖。</li>
</ul>



<p>關鍵心法： 不要外包「思考」，要讓 AI 當你的「思考夥伴」。問AI：「針對這個觀點，有沒有更好的視覺表達方式？」</p>



<p>AI 的價值，建立在提問的品質上。我們下的提示詞較詳細，就可以取得更符合我們需求的圖片。</p>



<p>不知道怎麼下高品質的提示詞，也可以先去收集別人的作品，上傳給AI 之後，請 AI 分析圖片並生成可以生成出圖片的提示詞，有了提示詞再進行調整就比較有效率。例如提示詞：</p>



<pre class="wp-block-code"><code>請幫我拆解這張圖的圖片(影片)生成語法</code></pre>



<p>另一個方式是套用常見的提示詞用於風格與質感：</p>



<ul class="wp-block-list">
<li><strong>風格關鍵字：</strong> <code>Minimalist</code> (極簡)、<code>Hand-drawn</code> (手繪)、<code>Rough sketch</code> (粗糙草圖)。</li>



<li><strong>筆觸關鍵字：</strong> <code>Ink texture</code> (墨水紋理)、<code>Shaky lines</code> (顫抖的線條)、<code>Felt tip pen</code> (麥克筆感)。</li>



<li><strong>構圖關鍵字：</strong> <code>White background</code> (純白背景)、<code>Black and white</code> (黑白)、<code>No 3D render</code> (不要 3D 渲染)。</li>



<li><strong>氛圍關鍵字：</strong> <code>Conceptual</code> (概念性的)、<code>Simple</code> (簡單)。</li>
</ul>



<p>避免 AI 感或科技感太重, 可以加入指令：</p>



<ul class="wp-block-list">
<li><code>Shaky hand-drawn lines</code>: 避免 AI 生成太過完美的幾何線條。</li>



<li><code>Charcoal sketch effect</code>: 增加一點碳筆或原子筆的摩擦感。</li>



<li><code>Primitive drawing style</code>: 讓畫面看起來像是隨手在筆記本上畫的，而不是設計軟體拉出來的。</li>



<li><code>White paper texture</code>: 增加一點背景的真實感。</li>
</ul>



<p>在 AI 生圖（如 Midjourney, Stable Diffusion, DALL-E）中，「氛圍（Atmosphere/Mood）」是決定圖片質感的關鍵。好的氛圍詞能讓原本平淡的畫面瞬間變身為電影劇照或藝術畫作。</p>



<p>以下為你整理常用的氛圍關鍵字，依據<strong>光影、情感、環境與電影感</strong>進行分類：</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">1. 光影氛圍（Lighting &amp; Atmosphere）</h2>



<p>光線是營造氛圍最直接的手段，建議每次生圖至少加入一個。</p>



<ul class="wp-block-list">
<li><strong>Golden Hour</strong>: 黃金時刻（夕陽暖光，帶有懷舊或浪漫感）。</li>



<li><strong>Cinematic Lighting</strong>: 電影級光影（對比強烈、有敘事感）。</li>



<li><strong>Volumetric Lighting / God Rays</strong>: 體積光/耶穌光（光束穿過霧氣或窗戶，神聖或夢幻）。</li>



<li><strong>Soft Lighting</strong>: 柔光（溫暖、治癒、無陰影）。</li>



<li><strong>Hard Lighting</strong>: 硬光（影子清晰、戲劇衝突強）。</li>



<li><strong>Bioluminescent</strong>: 生物發光（如阿凡達場景，神祕奇幻）。</li>



<li><strong>Neon Glow</strong>: 霓虹光（賽博龐克風格，都市夜晚感）。</li>
</ul>



<h2 class="wp-block-heading">2. 情緒與色調（Emotional &amp; Color Palette）</h2>



<p>這類詞彙會直接改變 AI 選用的色偏與對比度。</p>



<ul class="wp-block-list">
<li><strong>Moody</strong>: 陰鬱/情緒化（暗調、帶有故事性與神祕感）。</li>



<li><strong>Ethereal</strong>: 超凡脫俗（輕盈、夢幻、仙氣十足）。</li>



<li><strong>Nostalgic / Vintage</strong>: 懷舊（復古色調，像老照片或老電影）。</li>



<li><strong>Melancholy</strong>: 憂鬱（冷色調、孤寂感）。</li>



<li><strong>Vibrant</strong>: 鮮艷生動（色彩飽和度高，充滿朝氣）。</li>



<li><strong>Muted Colors</strong>: 柔和/低飽和色調（高級感、冷靜、極簡）。</li>
</ul>



<h2 class="wp-block-heading">3. 環境與質感（Environmental Texture）</h2>



<p>用來增加畫面的細節層次感。</p>



<ul class="wp-block-list">
<li><strong>Misty / Foggy</strong>: 霧氣繚繞（增加深度，神祕或壓抑感）。</li>



<li><strong>Dust Motes</strong>: 漂浮的微塵（在陽光下非常顯精緻度）。</li>



<li><strong>Rain-soaked / Wet</strong>: 雨後潮濕（街道反光，適合街拍感）。</li>



<li><strong>Eerie</strong>: 怪誕不安（適合驚悚或克蘇魯風格）。</li>



<li><strong>Cyberpunk / Steampunk</strong>: 特定的風格氛圍。</li>
</ul>



<h2 class="wp-block-heading">4. 電影與攝影風格（Cinematic &amp; Camera）</h2>



<p>如果你想要圖片看起來像「拍」出來的，這些關鍵字必備。</p>



<ul class="wp-block-list">
<li><strong>Film Grain</strong>: 電影膠片質感。</li>



<li><strong>Depth of Field / Bokeh</strong>: 景深/背景虛化（突出主體，增加專業感）。</li>



<li><strong>Wide Shot</strong>: 廣角（壯闊感）。</li>



<li><strong>Close-up</strong>: 特寫（親密感或細節震撼）。</li>



<li><strong>Cyberpunk Aesthetic</strong>: 賽博龐克美學。</li>



<li><strong>Studio Ghibli style</strong>: 吉卜力式溫暖氛圍。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 實戰範例：</h3>



<ul class="wp-block-list">
<li><strong>普通描述</strong>：<code>A girl in a library</code> (一個在圖書館的女孩)</li>



<li><strong>加入氛圍</strong>：<code>A girl in a library, Golden Hour, Volumetric lighting, Dust motes, Cinematic, Muted colors</code><br>這會讓原本普通的人像，變成一張充滿午後陽光、塵埃飛舞、色調高級的電影海報。</li>
</ul>



<p>如果你還沒有具體想法，也可以跟我說你想要的感覺。例如：</p>



<ul class="wp-block-list">
<li>想要孤單、冷清的感覺。</li>



<li>想要溫暖、療癒的插畫風。</li>



<li>想要很酷、很帥的科技感。</li>
</ul>



<p>只要給我一個方向，我就能幫你寫出對應的提示詞。</p>



<p></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>YouTube: <a href="https://youtu.be/fAyuHGUviSM">https://youtu.be/fAyuHGUviSM</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="別再說你不會畫畫，透過 AI 的視覺化工具，把複雜概念變簡單" width="885" height="498" src="https://www.youtube.com/embed/fAyuHGUviSM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2025/12/gemini-ai-canva-figma/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>用字幕自動剪掉影片空白段落(Whisper + ffmpeg)</title>
		<link>https://max-everyday.com/2025/12/srt-video-cutter/</link>
					<comments>https://max-everyday.com/2025/12/srt-video-cutter/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Tue, 23 Dec 2025 21:08:04 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Tool]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=22610</guid>

					<description><![CDATA[在處理教學影片、訪談、Podcast 或逐字稿影片時，常見的需求是：只保留「有字幕的內容」，自動剪掉中間的停頓、空白或無聲段落。如果手動在剪輯軟體中一段段對齊字幕，不但耗 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="775" src="https://max-everyday.com/wp-content/uploads/2025/12/srt-video-cutter-1920x-1024x775.jpg?v=1766523728" alt="" class="wp-image-22615" srcset="https://max-everyday.com/wp-content/uploads/2025/12/srt-video-cutter-1920x-1024x775.jpg?v=1766523728 1024w, https://max-everyday.com/wp-content/uploads/2025/12/srt-video-cutter-1920x-500x378.jpg?v=1766523728 500w, https://max-everyday.com/wp-content/uploads/2025/12/srt-video-cutter-1920x-615x465.jpg?v=1766523728 615w, https://max-everyday.com/wp-content/uploads/2025/12/srt-video-cutter-1920x.jpg?v=1766523728 1184w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>在處理教學影片、訪談、Podcast 或逐字稿影片時，常見的需求是：<strong>只保留「有字幕的內容」，自動剪掉中間的停頓、空白或無聲段落</strong>。如果手動在剪輯軟體中一段段對齊字幕，不但耗時，也容易出錯。</p>



<p>這篇文章會帶你使用圖形化的設定介面，讓你不必記憶複雜的指令，即可透過滑鼠點擊完成剪掉影片空白段落。想了解複雜指令有附在下半部。</p>



<p>這套腳本，能自動刪除空白片段並保留語意內容。核心邏輯是先將影片轉成單聲道 MP3，再透過 OpenAI Whisper 生成 SRT 字幕。最後根據字幕的時間軸，利用 ffmpeg 進行影片裁切與合併。</p>



<p>建議安裝 AI 相關的 CLI, 使用指令: &#8220;幫我修正字幕檔的用字錯誤, 例如: 勇唱改為詠唱&#8221;</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="943" height="1024" data-id="23125" src="https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-10_ms-943x1024.jpg?v=1774282654" alt="" class="wp-image-23125" srcset="https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-10_ms-943x1024.jpg?v=1774282654 943w, https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-10_ms-461x500.jpg?v=1774282654 461w, https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-10_ms-615x668.jpg?v=1774282654 615w, https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-10_ms.jpg?v=1774282654 958w" sizes="auto, (max-width: 943px) 100vw, 943px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="943" height="1024" data-id="23127" src="https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-11_mt-943x1024.jpg?v=1774282654" alt="" class="wp-image-23127" srcset="https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-11_mt-943x1024.jpg?v=1774282654 943w, https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-11_mt-461x500.jpg?v=1774282654 461w, https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-11_mt-615x668.jpg?v=1774282654 615w, https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-11_mt.jpg?v=1774282654 958w" sizes="auto, (max-width: 943px) 100vw, 943px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="943" height="1024" data-id="23126" src="https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-12_mu-943x1024.jpg?v=1774282654" alt="" class="wp-image-23126" srcset="https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-12_mu-943x1024.jpg?v=1774282654 943w, https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-12_mu-461x500.jpg?v=1774282654 461w, https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-12_mu-615x668.jpg?v=1774282654 615w, https://max-everyday.com/wp-content/uploads/2025/12/2026-03-23_23-12_mu.jpg?v=1774282654 958w" sizes="auto, (max-width: 943px) 100vw, 943px" /></figure>
</figure>



<p>超讚的, 省下好多校稿的時間.</p>



<p>AI CLI（命令列介面）已經從單純的對話工具演進為能直接操作檔案、執行指令甚至修復 Bug 的智慧代理人（AI Agents）。以下是目前主流且功能強大的 CLI:</p>



<ul class="wp-block-list">
<li><strong>Claude Code</strong>：由 Anthropic 推出。它能理解複雜的專案架構，適合進行大規模重構（Refactoring）或修復測試失敗。它的強項在於強大的邏輯推理能力。</li>



<li><strong>Aider</strong>：開源社群非常受歡迎的工具。它能與 Git 深度整合，每次修改程式後會自動生成適當的 Commit Message。它支援多種模型（如 GPT-4o, Claude 3.5/3.7）。</li>



<li><strong>Gemini CLI</strong>：Google 推出的官方工具。特色是擁有極大的上下文視窗（Context Window），可以一次讀取整個大型專案的所有程式碼，並支援多模態輸入。</li>



<li><strong>Cursor CLI</strong>：雖然 Cursor 以 IDE 聞名，但其 CLI 版本在工具編排（Tool Orchestration）上非常流暢，適合追求快速迭代的開發者。</li>



<li><strong>GitHub Copilot CLI</strong>：GitHub 官方提供的工具（透過 <code>gh copilot</code> 使用）。它主要功能是「翻譯」指令，當你忘記 git 或 docker 的複雜參數時，它可以幫你寫好指令並解釋其意義。</li>



<li><strong>Ollama</strong>：如果你想在本地端（Offline）執行 AI，Ollama 是首選。它讓你在終端機就能輕鬆下載並執行各種開源模型（如 Llama 3, Mistral, Gemma 等）。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">語意切割 vs 靜音偵測</h3>



<ul class="wp-block-list">
<li><strong>靜音偵測（silencedetect）：</strong> 僅判斷聲音能量高低，容易誤留呼吸聲、笑聲或環境雜訊，無法判斷語句邊界。</li>



<li><strong>SRT 字幕辨識：</strong> 判斷「人類說話的意義」，能確保剪輯出的片段具備完整語意。</li>



<li><strong>最佳策略：</strong> 以 SRT 作為主判斷基準，輔以靜音偵測做品質檢查。</li>
</ul>



<h3 class="wp-block-heading">FFmpeg 音訊優化技巧</h3>



<ul class="wp-block-list">
<li><strong>音量調整：</strong> 使用 <code>loudnorm</code> 過濾器可自動進行音量標準化，讓小聲變清晰、大聲不破音。</li>



<li><strong>人聲增強：</strong> 透過 <code>highpass=f=80</code> 濾除低頻噪音（如冷氣聲），並用 <code>equalizer</code> 提升 3000Hz 頻段強化清晰度。</li>



<li><strong>去噪處理：</strong> <code>afftdn</code> 能智慧去除背景底噪，<code>agate</code> 則可在沒人講話時自動關閉音量。</li>



<li><strong>環境感：</strong> 加入微小的 <code>aecho</code>（如 40ms）能模擬錄音室空間感，讓聲音聽起來更厚實。</li>
</ul>



<h3 class="wp-block-heading">解決 Whisper 辨識異常</h3>



<ul class="wp-block-list">
<li><strong>幻覺與長片段問題：</strong> 若模型在空白處亂寫或時間軸拉太長，應縮短 <code>min_silence_duration_ms</code>（如 500ms）並關閉 <code>condition_on_previous_text</code>。</li>



<li><strong>強制切分：</strong> 設定 <code>max_speech_duration_s</code>（如 15 秒）限制單一片段長度，避免多句話被擠在同一個時間戳。</li>



<li><strong>效率提升：</strong> 使用 <code>faster-whisper</code> 並配合 VAD（語音活動檢測）進行平行處理，速度比原版快 4-5 倍。</li>



<li>增加簡體轉繁體字，避免whisper 誤判。</li>



<li>由於模型產生的 segment 不等於「一句話」，最穩定的做法是在程式碼中加入後處理邏輯：設定每行最大字數（如 22 字），若超長則平均分配時間點並換行。</li>
</ul>



<p>YouTube: <a href="https://youtu.be/FNh-PhIEBPY">https://youtu.be/FNh-PhIEBPY</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<div class="gutenbee-responsive-embed"><iframe loading="lazy" title="用字幕自動剪掉影片空白段落(Whisper + ffmpeg)" width="885" height="498" src="https://www.youtube.com/embed/FNh-PhIEBPY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
</div></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">使用情境</h2>



<p>這支腳本特別適合以下場景：</p>



<ul class="wp-block-list">
<li>教學影片只保留講話段落</li>



<li>訪談或會議影片去除空白等待時間</li>



<li>Podcast 錄影自動裁切發言片段</li>



<li>AI 轉錄後，直接用字幕反推影片剪輯</li>
</ul>



<p>你只需要：</p>



<ul class="wp-block-list">
<li>一個影片檔（mp4 / mkv / mov…）</li>



<li>運行 ffmpeg + whisper 的電腦環境. (Mac / Linux / Windows)</li>



<li>max 的腳本. (選配)</li>
</ul>



<p>max 的腳本下載：<br><a href="https://github.com/max32002/srt-video-cutter/">https://github.com/max32002/srt-video-cutter/</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">環境與套件需求</h2>



<p>在開始之前，請確認以下環境已準備好：</p>



<ul class="wp-block-list">
<li>Python 3.8+</li>



<li>系統已安裝 <code>ffmpeg</code> , <code>openai-whisper</code></li>



<li>Python 套件：</li>
</ul>



<pre class="wp-block-code"><code>pip install ffmpeg-python pysrt fastapi uvicorn python-multipart jinja2 openai-whisper setuptools-rust faster-whisper opencc-python-reimplemented
</code></pre>



<p>其中：</p>



<ul class="wp-block-list">
<li><strong>ffmpeg-python</strong>：FFmpeg 的 Python 封裝，用來描述影片處理流程</li>



<li><strong>pysrt</strong>：專門解析 <code>.srt</code> 字幕檔的工具</li>



<li><strong>whisper</strong>：聲音轉 <code>.srt</code> 字幕檔的工具</li>



<li><strong>opencc</strong>：簡體字轉繁體字</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">腳本整體流程說明</h2>



<p>video_cutter.py 程式的邏輯可以拆成 6 個步驟：</p>



<ol class="wp-block-list">
<li>讀取並檢查影片與字幕檔是否存在</li>



<li>解析 SRT，取得每一段字幕的開始與結束時間</li>



<li>對影片與音訊分別做 <code>trim</code></li>



<li>重設時間軸（PTS），避免剪接錯位</li>



<li>將所有片段依序 concat</li>



<li>輸出成一支新的影片檔</li>
</ol>



<p>來源檔案轉換為單聲道 MP3 (16kHz), 是透過 ffmpeg 指令</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp3 -ar 16000 -ac 1 -ab 16k output.mp3</code></pre>



<p>生成字幕, 是透過 whisper 指令</p>



<pre class="wp-block-code"><code>whisper audio.mp3 --language=zh --device=cpu --model=turbo</code></pre>



<p><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">說明：直接執行 run.bat 無法下載 whisper 的模型檔案, 請透過上面指令手動下載 turbo 模型.</mark></p>



<p>如果你遇到下列錯誤訊息, 就是需要手動執行一次 whisper 指令:</p>



<pre class="wp-block-preformatted">--- 開始處理: c:\max\woman.mp3 (Device: cpu, Model: turbo) ---<br>Warning: You are sending unauthenticated requests to the HF Hub. Please set a HF_TOKEN to enable higher rate limits and faster downloads.<br>C:\\Programs\Python\Python312\Lib\site-packages\huggingface_hub\file_download.py:138: UserWarning: `huggingface_hub` cache-system uses symlinks by default to efficiently store duplicated files but your machine does not support them<br>To support symlinks on Windows, you either need to activate Developer Mode or to run Python as an administrator. In order to activate developer mode, see this article: https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development<br>  warnings.warn(message)<br>Faster-Whisper 錯誤: [WinError 1314] 用戶端沒有這項特殊權限。</pre>



<p></p>



<p>安裝的教學, 參考: <a href="https://max-everyday.com/2025/12/whisper-python/">https://max-everyday.com/2025/12/whisper-python/</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">指令的使用方式</h2>



<pre class="wp-block-code"><code>python video_cutter.py input.mp4</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">video_cutter.py 實作的細節</h2>



<p>不知道也沒差，建議直接略過這個區塊</p>



<p>1&#x20e3; 合併過短字幕</p>



<ul class="wp-block-list">
<li>設定最小片段長度（例如 0.4 秒）</li>



<li>若某段太短，嘗試與前一段合併</li>



<li>合併條件：時間間隔不超過指定閾值（例如 0.3 秒）</li>
</ul>



<p>2&#x20e3; 前後 padding</p>



<ul class="wp-block-list">
<li>對每段字幕加上前後緩衝（例如 ±0.15 秒）</li>



<li>自動 clamp 在 0 與影片總長度之間</li>



<li>padding 在「合併後」才套用，避免重疊錯亂</li>
</ul>



<p>3&#x20e3; 靜音偵測（輔助條件）</p>



<ul class="wp-block-list">
<li>使用 ffmpeg 的 <code>silencedetect</code></li>



<li>先跑一次分析音訊，取得靜音區段</li>



<li>若字幕區間完全落在靜音內 → 捨棄</li>



<li>若只部分靜音 → 保留（字幕仍有意義）</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">使用「靜音偵測」就不需要輸入 srt 字幕檔了嗎?</h2>



<p>這是一個非常關鍵、而且問得很精準的問題。結論先給你，再把背後的設計邏輯一次說清楚。</p>



<p><strong>結論一句話：<br>只用「靜音偵測」可以剪影片，但「不能等價取代 SRT（Whisper）」；兩者的角色本質不同。</strong></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>先把兩者在「影片自動切割」中的定位講清楚。</p>



<p>Whisper 產生的 SRT，本質上是在回答一個問題：<br><strong>「這段時間，人類在說『有意義的話』嗎？」</strong></p>



<p>而靜音偵測（silencedetect），回答的是另一個問題：<br><strong>「這段時間，聲音能量是否低於某個門檻？」</strong></p>



<p>這兩件事不是同一件事，也不互為子集。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>一、只用靜音偵測，不用 SRT，會發生什麼事？</p>



<p>你可以完全不用 SRT，只靠靜音來切，例如：</p>



<ul class="wp-block-list">
<li>偵測所有非靜音區間</li>



<li>每段非靜音就是一個剪輯段</li>
</ul>



<p>這在「技術上」完全可行，而且程式還更簡單。</p>



<p>但實際效果會有幾個不可避免的問題：</p>



<ol class="wp-block-list">
<li>會保留大量「沒有語意價值」的聲音<br>例如：
<ul class="wp-block-list">
<li>呼吸聲</li>



<li>笑一下</li>



<li>背景音樂</li>



<li>咳嗽</li>



<li>嘆氣、嗯、啊</li>
</ul>
</li>



<li>無法判斷「語句邊界」<br>一句話中間短暫停頓 0.2 秒，<br>靜音偵測可能直接把它切成兩段。</li>



<li>對內容型影片不友善<br>像是：<ul><li>教學影片</li><li>訪談</li><li>Podcast</li><li>YouTube talking head</li></ul>你要的是「一句話一段」，<br>不是「有聲音就留」。</li>
</ol>



<p><strong>因此：<br>只靠靜音偵測，剪出來的是「聲音片段」，不是「語意片段」。</strong></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>二、那是否代表一定需要 SRT（Whisper）？</p>



<p>這要看你的「剪輯目標」。</p>



<p>可以這樣判斷：</p>



<p>如果你的目標是這種 → <strong>可以不需要 SRT</strong></p>



<ul class="wp-block-list">
<li>去掉完全沒聲音的空白</li>



<li>快速裁掉長時間靜默</li>



<li>監控錄音品質</li>



<li>Podcast 粗剪（人工後製）</li>
</ul>



<p>如果你的目標是這種 → <strong>SRT 幾乎是必要的</strong></p>



<ul class="wp-block-list">
<li>依照「一句話」切段</li>



<li>產生短影音（Reels / Shorts）</li>



<li>自動章節</li>



<li>後續做摘要、關鍵句擷取、翻譯</li>
</ul>



<p>你目前描述的用途是：</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>SRT 主要是透過 whisper 來產生，目的是利用 SRT 字幕自動切割影片</p>
</blockquote>



<p>這個用途，本質上就是 <strong>語意導向切割</strong>，<br>所以 <strong>SRT 不是多餘的，而是核心訊號來源</strong>。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>三、正確的工程思路：不是「二選一」，而是「主從關係」</p>



<p>在成熟的系統裡，設計通常是這樣：</p>



<p><strong>Whisper / SRT：主判斷（語意）<br>靜音偵測：輔助過濾（聲學）</strong></p>



<p>實務上最穩定的策略是：</p>



<ol class="wp-block-list">
<li>用 SRT 決定「候選剪輯區間」</li>



<li>用靜音偵測做「品質檢查」
<ul class="wp-block-list">
<li>字幕區間內如果 90% 都是靜音 → 丟棄</li>



<li>字幕前後有長靜音 → 裁掉</li>
</ul>
</li>



<li>最後再補 padding，讓語音自然進出</li>
</ol>



<p>也就是你目前優化方向中，最合理的一條路。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>四、什麼情況下「可以完全不要 SRT」？</p>



<p>只有在以下情境，我會建議你拿掉 SRT：</p>



<ol class="wp-block-list">
<li>你已經不在乎「說了什麼」</li>



<li>你只想保留「有聲音的地方」</li>



<li>或你後面還會人工看一遍再修</li>
</ol>



<p>例如：</p>



<ul class="wp-block-list">
<li>監控錄影</li>



<li>課堂錄音粗剪</li>



<li>音檔清理工具</li>
</ul>



<p>一旦你的目標是「自動產出可直接發布的內容」，<br><strong>SRT（Whisper）就不是 optional，而是語意層的 ground truth。</strong></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">ffmpeg 增加影片的音量</h2>



<p>要讓音量達到最大但不破音，最保險的做法是先進行音量標準化。這通常需要跑兩次指令，或者用一個比較聰明的過濾器。</p>



<h3 class="wp-block-heading">使用簡單的標準化</h3>



<p>這個指令會自動搜尋音軌中的最高點，並將其提升到 0dB，也就是不失真的最大極限。這對於聲音太小的檔案非常有用。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "loudnorm=I=-16:TP=-1.5:LRA=11" -c:v copy output.mp4</code></pre>



<h3 class="wp-block-heading">兩步驟自動偵測</h3>



<p>如果你想更精確地提升，可以先執行 volumedetect 找出最大增益。這個指令不會輸出新檔案，只是幫你計算數據。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af volumedetect -f null /dev/null</code></pre>



<p>在 Windows 中，我們把空輸出指向 NUL。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af volumedetect -f null NUL</code></pre>



<p>執行後在輸出的文字裡找 max_volume。如果顯示為 -6.0dB，代表你還有 6dB 的增加空間。接著再手動輸入增加的數值。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "volume=6dB" -c:v copy output.mp4</code></pre>



<h3 class="wp-block-heading">分析偵測結果</h3>



<p>你的 <code>max_volume</code> 是 -1.2 dB。這代表這段影片中最大聲的地方，距離數位音訊的極限（0 dB）只剩下 1.2 dB 的空間。如果你的目標是單純增加音量且不想讓聲音破掉，你最多只能增加 1.2 dB。</p>



<h3 class="wp-block-heading">執行調整指令</h3>



<p>如果你確定要調到極限（也就是讓最大聲的地方剛好達到 0 dB），請在 Windows CMD 執行以下指令：</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "volume=1.2dB" -c:v copy output.mp4</code></pre>



<h3 class="wp-block-heading">關於音量的建議</h3>



<p>雖然最大值接近極限，但你的 <code>mean_volume</code>（平均音量）只有 -25.0 dB。這表示這段影片大部分時間聲音其實很小，只有少數幾個地方突然很大聲。</p>



<p>如果你覺得聽起來還是太小聲，單純調高 <code>volume</code> 可能會導致大聲的地方破音。這種情況建議改用前面提到的 <code>loudnorm</code> 指令，它會壓縮大聲的部分並提升小聲的部分，讓整體的聽感變大。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "loudnorm" -c:v copy output_norm.mp4</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">為什麼直接使用 loudnorm 過濾器處理過的檔案, 再使用偵測可增加的音量空間, max_volumn 反而下降?</h2>



<p>這是一個很專業的觀察。直接使用 <code>loudnorm</code> 後 <code>max_volume</code> 反而下降，主要是因為這個過濾器的工作邏輯與單純調整增益（Gain）完全不同。</p>



<h3 class="wp-block-heading">動態範圍壓縮的影響</h3>



<p><code>loudnorm</code> 是一種智慧型的音量標準化工具。它不只是把聲音推大，還會同時檢查聲音的動態範圍。為了讓整體聽感達到目標的響度（預設通常是 -16 LUFS），它會壓縮聲音的高峰。當它偵測到原始音軌中某些瞬間的峰值太高時，為了符合整體的響度標準，它會主動把這些高峰壓低，導致你看到的 <code>max_volume</code> 數值從 -1.2 dB 往下降。</p>



<h3 class="wp-block-heading">防止數位失真的保護機制</h3>



<p><code>loudnorm</code> 內建了一個參數叫作 <code>TP</code>（True Peak），預設值通常是 -2.0 dB。這是一個安全閥，目的是確保處理後的聲音在任何播放設備上都不會產生數位破音。因為你原本的 <code>max_volume</code> 是 -1.2 dB，已經比這個安全標準還要大聲，所以 <code>loudnorm</code> 會強制把它壓回到 -2.0 dB 左右或更低，這就是為什麼偵測結果數值會變小的原因。</p>



<h3 class="wp-block-heading">響度與峰值的差異</h3>



<p>在音訊處理中，大聲不代表峰值高。<code>max_volume</code> 只代表影片中最響的那一個瞬間，而 <code>loudnorm</code> 關注的是整段影片聽起來的平均感覺。雖然峰值下降了，但因為它把原本微弱的聲音補償上來了，實際聽起來的感覺反而會比原本更清晰、更大聲。</p>



<h3 class="wp-block-heading">你的測試結果驗證</h3>



<p>這證明了 <code>loudnorm</code> 正在正確執行它的任務：它放棄了極少數的最高點空間，換取了整段音軌更一致、更飽滿的聽感。如果你希望處理後的 <code>max_volume</code> 更接近 0 dB，可以在指令中手動加上 <code>TP</code> 參數：</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "loudnorm=TP=-0.1" -c:v copy output.mp4</code></pre>



<p>這樣雖然峰值會上升，但通常不建議這麼做，因為留一點預留空間（Headroom）對音質比較好。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">產生 Echo 回音音效</h2>



<p>ffmpeg 使用 <code>aecho</code> 濾鏡來製作回音。你需要設定輸入增益、輸出增益、延遲時間以及衰減比例。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "aecho=0.8:0.8:1000:0.5" -c:v copy output.mp4</code></pre>



<p>這行指令的參數意義如下：</p>



<ul class="wp-block-list">
<li>0.8：原始聲音的音量。</li>



<li>0.8：回音的音量。</li>



<li>1000：延遲時間（毫秒），1000 代表 1 秒。</li>



<li>0.5：每次回音衰減的比例。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">調整 EQ 均衡器</h2>



<p>如果你想調整高低音，最直覺的是使用 <code>equalizer</code> 濾鏡。你可以針對特定的頻率進行增益或衰減。</p>



<p>例如，如果你想提升 1000Hz 附近的聲音（讓人聲更清晰），增加 6 分貝：</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "equalizer=f=1000:width_type=h:w=200:g=6" -c:v copy output.mp4</code></pre>



<ul class="wp-block-list">
<li>f=1000：中心頻率。</li>



<li>width_type=h：頻寬單位。</li>



<li>w=200：影響的頻率範圍寬度。</li>



<li>g=6：增益分貝數。</li>
</ul>



<h2 class="wp-block-heading">快速調整高低音 (Bass/Treble)</h2>



<p>如果你不想設定複雜的 EQ，可以直接用 <code>bass</code> 或 <code>treble</code> 濾鏡。這對高中生理解音訊調整最簡單。</p>



<p>提升重低音：</p>



<pre class="wp-block-code"><code> ffmpeg -i input.mp4 -af "bass=g=10" -c:v copy output.mp4</code></pre>



<p>提升高音： </p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "treble=g=8" -c:v copy output.mp4</code></pre>



<h2 class="wp-block-heading">多重濾鏡組合</h2>



<p>你可以把音量調整、EQ 和回音全部串在一起使用，中間用逗號隔開即可。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "volume=1.2,bass=g=5,aecho=0.8:0.5:500:0.3" -c:v copy output.mp4</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">完整的人聲優化指令</h2>



<p>這串指令包含了高通濾波、人聲強化和動態門檻去噪。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "highpass=f=80, lowpass=f=8000, afftdn=nr=10, equalizer=f=3000:width_type=h:w=200:g=3, loudnorm" -c:v copy output.mp4</code></pre>



<h2 class="wp-block-heading">濾鏡參數詳細解說</h2>



<h3 class="wp-block-heading">1. 高通與低通濾波 (highpass/lowpass)</h3>



<p><code>highpass=f=80</code> 會切斷 80Hz 以下的聲音。人聲通常不會低於這個頻率，但冷氣運轉或電流聲的低頻雜訊會被擋掉。<code>lowpass=f=8000</code> 則是過濾掉極高頻的刺耳雜音。</p>



<h3 class="wp-block-heading">2. 智慧去噪 (afftdn)</h3>



<p><code>afftdn</code> 是 ffmpeg 內建強大的降噪工具。<code>nr=10</code> 代表降噪強度。如果你的背景嘶嘶聲很明顯，可以適度調高這個數值（建議在 10 到 20 之間），但調太高會讓人聲聽起來像在水底下說話。</p>



<h3 class="wp-block-heading">3. 人聲頻段強化 (equalizer)</h3>



<p><code>equalizer=f=3000:g=3</code> 針對 3000Hz 左右進行微幅增益。這個頻段通常是人聲清晰度的關鍵，稍微拉高能讓講話聲更突出、更有磁性。</p>



<h3 class="wp-block-heading">4. 終端響度標準化 (loudnorm)</h3>



<p>最後放上 <code>loudnorm</code> 是為了確保優化後的聲音音量穩定，不會因為去噪過程讓音量忽大忽小。</p>



<h2 class="wp-block-heading">進階去噪：使用動態閘門 (agate)</h2>



<p>如果你的錄音環境有明顯的間歇性背景噪音（例如翻書聲或細微鍵盤聲），可以加入 <code>agate</code> 濾鏡。它會在沒人講話時自動把音量關到極小。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "agate=threshold=-30dB:ratio=2, highpass=f=80, afftdn, loudnorm" -c:v copy output.mp4</code></pre>



<p>加入一點點空間感（Room Ambience）可以讓人聲聽起來更自然，不會像是在完全真空的密室裡講話。我們可以利用 <code>aecho</code> 來模擬微弱的牆面反射，讓 Podcast 更有專業錄音室的質感。</p>



<h2 class="wp-block-heading">錄音室空間感指令</h2>



<p>這組設定會加入極短的回音，聽覺上不會感覺到有明顯的「回聲」，而是覺得聲音變厚實了。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "highpass=f=80, afftdn=nr=12, aecho=0.8:0.3:40:0.2, loudnorm" -c:v copy output.mp4</code></pre>



<h2 class="wp-block-heading">參數調整重點</h2>



<h3 class="wp-block-heading">1. 空間感設定 (aecho)</h3>



<p><code>aecho=0.8:0.3:40:0.2</code> 這裡的核心在於 <code>40</code> 毫秒。這是一個非常短的時間，人耳聽不出延遲，只會覺得聲音多了一層包覆感。如果數字調到 500 以上，就會變成像在山洞說話的效果。</p>



<h3 class="wp-block-heading">2. 去噪強度 (afftdn)</h3>



<p>我把 <code>nr</code> 微調到了 12。這在去除 Podcast 背景底噪（如電腦風扇聲）非常有效。如果雜音還是很大，你可以嘗試把這個數值加到 15。</p>



<h3 class="wp-block-heading">3. 低頻切除 (highpass)</h3>



<p>這一步絕對不能省。Podcast 聽眾很多是用耳機收聽，切掉 80Hz 以下的雜訊，能大幅減少聽覺疲勞，讓人聲聽起來很乾淨。</p>



<h2 class="wp-block-heading">檢查處理後的波形</h2>



<p>處理完後，建議你再次使用 <code>volumedetect</code> 檢查。</p>



<pre class="wp-block-code"><code>ffmpeg -i output.mp4 -af volumedetect -f null NUL</code></pre>



<p>你會發現 <code>mean_volume</code>（平均音量）應該會提升到 -16dB 附近，這正是目前國際 Podcast 平台的標準響度，聽眾在切換不同節目時，不需要一直手動調整手機音量。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">highpass=f=200 與 highpass=f=80 的差異</h2>



<h3 class="wp-block-heading">濾除雜訊的強度</h3>



<p>highpass=f=200 會切掉更多聲音。它能有效去掉冷氣運轉、交通工具轟鳴或遠處的低頻噪音。但缺點是它可能會切到男聲的基頻，讓聲音聽起來像透過舊式電話講話，變得很薄。對於 Whisper 來說，這通常不是問題，因為它辨識的是特徵而不是音質。</p>



<h3 class="wp-block-heading">保留人聲的自然感</h3>



<p>highpass=f=80 則溫和得多。它只會切掉人耳幾乎聽不到、但會讓麥克風產生震動的極低頻雜訊。這個設定能保留說話者聲音的厚度與磁性。如果你錄音的環境本來就很安靜，只是想做基本的清理，選 80 比較能維持原音。</p>



<h3 class="wp-block-heading">針對 Whisper 的實務建議</h3>



<p>如果你的錄音環境有明顯的環境低音，或是說話者離麥克風很近產生的噴麥聲（氣流撞擊聲），直接設定 200 會比較保險。Whisper 不需要好聽的低音，它需要的是乾淨的語音邊界。切掉 200Hz 以下的內容，可以讓模型更專注在 1kHz 到 4kHz 這些充滿語意資訊的頻段。</p>



<h3 class="wp-block-heading">兩者的適用場景</h3>



<p>如果你不確定該選哪一個，可以先聽聽看原始檔。如果背景有很重的嗡嗡聲，選 200。如果錄音很乾淨只是想稍微過濾，選 80 或 120 是比較折衷的做法。通常在嘈雜的咖啡廳或戶外錄音，我會建議直接從 200 起跳。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">lowpass=f=3000 與 lowpass=f=8000 的差異</h2>



<p>lowpass=f=3000 會把 3000Hz 以上的聲音全部切掉。這會讓聲音聽起來悶悶的，像是在隔壁房間說話。絕大多數的漢語或英語元音資訊都在這個範圍內。但要注意的是，像「s」、「f」、「sh」這類高頻的摩擦音，頻率通常在 4000Hz 以上。切得太乾（3000Hz）可能會讓這些齒音變得模糊。</p>



<h3 class="wp-block-heading">高頻雜訊的過濾</h3>



<p>lowpass=f=8000 則寬鬆許多。它能保留大部分的人聲細節，包含那些細微的發音特徵。它主要的功能是過濾掉電子設備的高頻嘶嘶聲、蟬鳴聲或極端尖銳的雜音。對於 Whisper 來說，8000Hz 通常是一個比較安全的平衡點，既能去噪又不會傷到語音特徵。</p>



<h3 class="wp-block-heading">對 Whisper 的影響</h3>



<p>Whisper 在訓練時看過各種品質的音檔。雖然 16kHz 的採樣率最高只能容納 8000Hz 的聲音，但如果你預處理時直接切到 3000Hz，可能會損失掉一些辨識子音的重要資訊。除非背景有非常刺耳的高頻電流聲，否則不建議切到 3000Hz 這麼低。</p>



<h3 class="wp-block-heading">建議的設定值</h3>



<p>如果你發現錄音中有很多噴麥或環境雜音，選 8000Hz 已經足夠應付多數情況。如果環境真的很糟糕，可以嘗試設定在 4000Hz 或 5000Hz 之間，這能保證語音的關鍵摩擦音不會被濾除。通常 3000Hz 是在極端惡劣、滿是高頻干擾時才考慮的最後手段。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">套用 loudnorm, 開場的第一句話變的很小聲.</h2>



<p>這通常是因為 <code>loudnorm</code> 預設是「單次掃描」（One-pass）模式。在這種模式下，ffmpeg 還沒分析完整段音訊，只能邊走邊猜。當開場的第一句話突然出現時，濾鏡為了保險起見會壓低音量，導致聽起來悶悶的。</p>



<h2 class="wp-block-heading">解決開場音量過小的問題</h2>



<p>要解決這個問題，最專業的做法是提供「預測數據」。你可以手動調整以下細部參數，或是改用兩次掃描模式。</p>



<h3 class="wp-block-heading">1. 調整目標響度與峰值</h3>



<p>你可以透過調整 <code>I</code>（目標響度）和 <code>TP</code>（真峰值）來讓整體聲音更響亮。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "loudnorm=I=-14:TP=-1.0:LRA=11" -c:v copy output.mp4</code></pre>



<ul class="wp-block-list">
<li>I=-14：目標響度。數值越小（如 -12）聲音越大。Podcast 建議在 -16 到 -14 之間。</li>



<li>TP=-1.0：允許的最高峰值。從預設的 -2.0 改成 -1.0 可以釋放更多音量空間。</li>
</ul>



<h3 class="wp-block-heading">2. 關閉線性限制 (measured)</h3>



<p>如果你發現第一句話被壓得太厲害，可以嘗試強制設定 <code>measured</code> 參數。但更簡單的方法是調整 <code>LRA</code>（響度範圍）。</p>



<p><code>LRA=15</code>：增加動態範圍。這會讓大聲與小聲的落差變大，有時候能減緩開場被強行壓低的感覺。</p>



<h2 class="wp-block-heading">徹底解決方法：兩次掃描 (Two-pass)</h2>



<p>這是大部份專業人士的做法。第一次先讓 ffmpeg 記住整段影片的音量特徵，第二次再根據這些數據進行精確調整。這樣濾鏡就不會在開場時「反應過度」。</p>



<p>在 Windows 上手動做兩次掃描比較麻煩，但有一個作弊的方法，就是調大內建的緩衝區。</p>



<h3 class="wp-block-heading">增加預測緩衝</h3>



<p>雖然 ffmpeg 的 <code>loudnorm</code> 主要靠演算法，但你可以嘗試在人聲處理鏈中，先放一個 <code>compand</code>（壓縮器）來預處理，或是直接改用 <code>speechnorm</code>。</p>



<p>如果你堅持用 <code>loudnorm</code> 且不想跑兩次指令，可以試試看這個組合，這對開場壓抑會有改善：</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "loudnorm=I=-16:TP=-1.5:LRA=11:measured_I=-25.0:measured_TP=-1.2:measured_LRA=7.0:measured_thresh=-35.0" -c:v copy output.mp4</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>註：上面的 <code>measured</code> 數值是我根據你之前提供的偵測數據填入的。手動餵入這些偵測到的數據，能讓 <code>loudnorm</code> 在開場時就知道該怎麼處理。</p>
</blockquote>



<h2 class="wp-block-heading">另一個選擇：speechnorm</h2>



<p>如果 <code>loudnorm</code> 讓 Podcast 開場聽起來還是很不自然，我強烈建議換成 <code>speechnorm</code>。它是專門為語音設計的，能非常平滑地調整每一句話的音量。</p>



<pre class="wp-block-code"><code>ffmpeg -i input.mp4 -af "speechnorm=e=4:p=0.9" -c:v copy output.mp4</code></pre>



<p>你想試試看用 <code>speechnorm</code> 處理的效果嗎？它通常比 <code>loudnorm</code> 更適合解決「第一句話變小聲」的問題。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Whisper 進行語音轉文字（Audio to Text），「將檔案切成小片段」是否比較有效率</h2>



<p>關於使用 OpenAI Whisper 進行語音轉文字（Audio to Text），<strong>「將檔案切成小片段」是否比較有效率</strong>，答案是：<strong>是的，通常比較有效率，但前提是「切分的方式要正確」。</strong></p>



<p>如果只是單純為了速度而粗暴地切割檔案（例如固定每 60 秒切一刀），可能會導致辨識準確度下降。</p>



<p>以下為您詳細分析為什麼要切分、以及如何切分才是最好的策略：</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">1. 為什麼切成小檔案比較有效率？（優點）</h3>



<ul class="wp-block-list">
<li><strong>平行處理（Parallel Processing / Batching）：</strong><br>這是最大的優勢。如果您將一個 1 小時的檔案切成 60 個 1 分鐘的檔案，您可以利用 GPU 的「批次處理（Batching）」功能，同時辨識多個片段。這比依序讀取一個長檔案要快得多。</li>



<li><strong>記憶體管理（VRAM Usage）：</strong><br>雖然 Whisper 的記憶體使用量主要取決於模型大小（如 large-v3），但處理極長的音訊檔案有時會導致記憶體溢出（OOM）或處理緩衝區過大的問題。切分檔案可以讓記憶體負載更穩定。</li>



<li><strong>避免累積錯誤（Hallucination Loop）：</strong><br>Whisper 在遇到長時間的靜音或背景噪音時，有時會產生「幻覺」（Hallucinations），例如不斷重複同一句話。切分檔案可以強制模型在每個新片段「重置」狀態，減少這種錯誤無限延續的風險。</li>



<li><strong>容錯率：</strong><br>如果處理長檔案到 99% 時程式崩潰，您可能要從頭再來；如果是小檔案，您只需要重新跑失敗的那一小段。</li>
</ul>



<h3 class="wp-block-heading">2. 切分檔案的潛在風險（缺點）</h3>



<ul class="wp-block-list">
<li><strong>上下文遺失（Context Loss）：</strong><br>Whisper 是利用上下文來判斷同音異字的。如果您<strong>剛好切在一個句子的中間</strong>，模型會失去前後文，導致誤判。</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>例子：</strong> 如果您在「人工智…」切斷，下一段是「…能」，模型可能分別辨識成錯誤的字，而不是完整的「人工智慧」。</p>
</blockquote>



<ul class="wp-block-list">
<li><strong>邊界效應：</strong><br>切分點附近的音訊可能會因為波形被截斷而產生雜音，影響辨識。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 如何正確地切分？（最佳實務）</h3>



<p>為了兼顧效率與準確率，<strong>絕對不要</strong>使用「固定時間切割」（例如每 30 秒切一次），建議採用以下策略：</p>



<h4 class="wp-block-heading">A. 使用 VAD（語音活動檢測）切割</h4>



<p>這是最標準的做法。利用 VAD (Voice Activity Detection) 演算法，找出音訊中的「靜音片段」，在說話者停頓換氣的地方進行切割。</p>



<ul class="wp-block-list">
<li><strong>優點：</strong> 確保句子是完整的，不會切斷單字。</li>



<li><strong>工具：</strong> <code>pyannote-audio</code> 或 Silero VAD。</li>
</ul>



<h4 class="wp-block-heading">B. 使用優化過的函式庫（推薦 <code>faster-whisper</code>）</h4>



<p>原版的 OpenAI Whisper 程式碼在處理長檔案時速度較慢。目前社群最推薦使用的是 <strong><code>faster-whisper</code></strong>。</p>



<ul class="wp-block-list">
<li><strong>原理：</strong> 它底層使用了 CTranslate2 引擎，比原版快 4-5 倍，並且內建了很好的 VAD 處理邏輯。它會自動在記憶體中幫您做好「切分 -&gt; 批次辨識 -&gt; 合併」的動作，您不需要手動去切實體檔案。</li>
</ul>



<h4 class="wp-block-heading">C. 若必須手動切檔 (使用 FFmpeg)</h4>



<p>如果您因為某些原因必須手動切檔，請利用 <code>ffmpeg</code> 的 <code>silencedetect</code> 功能來尋找靜音點切割，而不是單純用 <code>-segment_time</code>。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4. 總結比較表</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>處理方式</th><th>速度效率</th><th>準確度</th><th>記憶體消耗</th><th>建議程度</th></tr></thead><tbody><tr><td><strong>單一長檔案 (原版 Whisper)</strong></td><td>低 (依序處理)</td><td>高 (上下文完整)</td><td>高 (可能不穩)</td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td></tr><tr><td><strong>固定時間切割 (如每30秒)</strong></td><td>高 (可平行)</td><td><strong>低</strong> (容易切斷句子)</td><td>低</td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /> (不建議)</td></tr><tr><td><strong>VAD 靜音切割 (手動/程式)</strong></td><td><strong>極高</strong> (可平行)</td><td>高 (保留句子完整)</td><td>低</td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td></tr><tr><td><strong>使用 faster-whisper</strong></td><td><strong>極高</strong></td><td><strong>高</strong></td><td><strong>最佳化</strong></td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2b50.png" alt="⭐" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Whisper 模型陷入了「幻覺」或「長片段過度延伸」</h2>



<p>例如: 一句話占用了 2分鐘.</p>



<h3 class="wp-block-heading">問題原因與調整建議</h3>



<p>這種情況通常不是 VAD 沒運作，而是模型陷入了「幻覺」或「長片段過度延伸」。當語音結尾出現較長的空白，或者背景有極微弱的環境雜音（例如底噪、電扇聲），Whisper 有時會以為這句話還沒結束，硬生生把結束時間往後拉，直到遇到下一個明顯的聲音。</p>



<p>你可以嘗試調整 <code>transcribe</code> 函數中的參數來修正這個現象。</p>



<h3 class="wp-block-heading">建議修改的參數</h3>



<p>在你的程式碼中，找到 <code>model.transcribe</code> 的位置，建議加入以下參數進行微調：</p>



<p>Python</p>



<pre class="wp-block-code"><code>segments, info = model.transcribe(
    input_file, 
    language=language, 
    vad_filter=True,
    # 調整 VAD 參數
    vad_parameters=dict(min_silence_duration_ms=1000), 
    # 控制無聲片段的判斷
    no_speech_threshold=0.6,
    # 限制沒有聲音時的處理方式
    compression_ratio_threshold=2.4
)
</code></pre>



<h3 class="wp-block-heading">修改重點說明</h3>



<ul class="wp-block-list">
<li><strong>min_silence_duration_ms</strong>: 這是 VAD 判斷「靜音」的門檻。預設通常是 2000ms（2秒），如果你覺得兩分鐘太誇張，可以縮短這個數值（例如 1000 或 500），讓它更敏感地切斷句子。</li>



<li><strong>no_speech_threshold</strong>: 這是模型對「無聲」的信心門檻。提高這個數值（例如 0.6 或 0.7），可以讓模型在不確定有沒有人聲時，更果斷地放棄辨識，避免把底噪硬抓來轉文字。</li>



<li><strong>compression_ratio_threshold</strong>: 當模型開始亂寫、重複字詞或陷入長延時幻覺時，壓縮比通常會飆高。設定這個門檻可以讓模型在發現內容太混亂時，主動切斷該片段。</li>
</ul>



<h3 class="wp-block-heading">進階解決方案：強行切斷</h3>



<p>如果調整 VAD 參數後效果還是有限，通常是因為錄音環境的底噪被模型誤認為是人聲。你可以試著加入 <code>condition_on_previous_text=False</code>。</p>



<p>這個參數會讓模型在處理下一段時，不參考前一段的內容。雖然可能會降低語意連貫性，但能有效防止「上一句的幻覺」一直帶到下一句，導致時間軸無限延伸。</p>



<h3 class="wp-block-heading">整合參數後的程式碼</h3>



<p>我把建議的參數直接加入 <code>model.transcribe</code> 裡。這樣可以讓 VAD 更敏銳，並減少模型在空白處「硬湊」時間的問題。</p>



<p>Python</p>



<pre class="wp-block-code"><code>import os
from contextlib import ExitStack

def run_faster_whisper_task(input_file: str, language: str, model_size: str, device: str, output_formats: List&#91;str]):
    try:
        print(f"--- 開始處理: {input_file} (Device: {device}, Model: {model_size}) ---")
        
        compute_type = "float16" if device == "cuda" else "int8"
        model = WhisperModel(model_size, device=device, compute_type=compute_type)

        # 加入優化參數解決長延遲問題
        segments, info = model.transcribe(
            input_file, 
            language=language, 
            vad_filter=True,
            # 只要靜音超過 1 秒就切斷，不讓它連在一起
            vad_parameters=dict(min_silence_duration_ms=1000),
            # 提高對無聲的判定標準，避免抓到底噪
            no_speech_threshold=0.6,
            # 防止上一句的內容影響下一句，減少幻覺
            condition_on_previous_text=False
        )

        base_name = os.path.splitext(input_file)&#91;0]
        print(f"偵測到語言: {info.language} (信心度: {info.language_probability})")
        
        with ExitStack() as stack:
            f_srt = None
            f_txt = None

            if "srt" in output_formats or "all" in output_formats:
                srt_path = f"{base_name}.srt"
                f_srt = stack.enter_context(open(srt_path, "w", encoding="utf-8"))

            if "txt" in output_formats or "all" in output_formats:
                txt_path = f"{base_name}.txt"
                f_txt = stack.enter_context(open(txt_path, "w", encoding="utf-8"))
            
            for i, segment in enumerate(segments, start=1):
                start_time = format_timestamp(segment.start)
                end_time = format_timestamp(segment.end)
                text = segment.text.strip()
                
                if f_srt:
                    f_srt.write(f"{i}\n")
                    f_srt.write(f"{start_time} --&gt; {end_time}\n")
                    f_srt.write(f"{text}\n\n")
                    f_srt.flush() 

                if f_txt:
                    f_txt.write(f"{text}\n")
                    f_txt.flush()
                
                print(f"&#91;{start_time} -&gt; {end_time}] {text}")

        print(f"--- 處理完成 ---")

    except Exception as e:
        print(f"Faster-Whisper 執行錯誤: {e}")
</code></pre>



<h3 class="wp-block-heading">調整說明</h3>



<p>這段程式碼主要做了兩件事。第一是把 <code>min_silence_duration_ms</code> 縮短，讓 VAD 看到超過 1 秒的空白就強制收尾，不讓它繼續延伸。</p>



<p>第二是關掉了 <code>condition_on_previous_text</code>。這很重要，因為有時候模型會因為上一句還沒講完的錯覺，把後面的空白時間全部吃掉。關掉它後，每一段辨識都會比較獨立，時間軸也會精準很多。</p>



<p>最後也保留了你要的「不產生多餘檔案」的邏輯。如果跑完後發現時間軸還是偏長，可以再把 <code>no_speech_threshold</code> 往上調。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">解決多句話合併的方法</h2>



<h3 class="wp-block-heading">解決多句話合併的方法</h3>



<p>多句話被擠在同一個時間軸，通常是因為 Whisper 的 <code>max_initial_timestamp</code> 或內部的 <code>word_timestamps</code> 機制覺得這些句子之間停頓不夠明顯。要解決這個問題，除了調整 VAD 參數外，最有效的方法是加入「時間戳限制」與「強制切分」參數。</p>



<h3 class="wp-block-heading">建議調整的參數</h3>



<p>請在 <code>model.transcribe</code> 中加入 <code>max_new_tokens</code> 與 <code>chunk_length</code> 相關的限制：</p>



<p>Python</p>



<pre class="wp-block-code"><code>segments, info = model.transcribe(
    input_file, 
    language=language, 
    vad_filter=True,
    vad_parameters=dict(min_silence_duration_ms=500), # 縮短靜音判定，強制切分
    # 限制一個片段的最長秒數，避免過長合併
    clip_timestamps=&#91;0], 
    # 加入以下關鍵參數
    max_initial_timestamp=1.0, 
    word_timestamps=False, # 如果不需要逐字時間戳，關閉它有助於穩定句子邊界
    # 這是核心：限制模型一次處理的長度
    initial_prompt="以下是逐句對話。", # 給模型提示，讓它傾向於斷句
)
</code></pre>



<h3 class="wp-block-heading">修改重點說明</h3>



<ul class="wp-block-list">
<li><strong>縮短 min_silence_duration_ms</strong>: 將 1000ms 改為 500ms（0.5秒）。只要講話稍微停頓，VAD 就會把這段切開，不會讓它變成一大串。</li>



<li><strong>max_initial_timestamp</strong>: 限制模型在搜尋聲音起點時的範圍，這能強迫模型更頻繁地重新對齊時間軸。</li>



<li><strong>initial_prompt</strong>: 這是一個小技巧。在提示詞裡加入標點符號或說明「這是逐句轉錄」，模型在輸出時會更傾向於加上標點並斷句，而不是吐出一長串沒有停頓的文字。</li>



<li><strong>語音長度限制</strong>: 如果你的音檔底噪真的很大，導致 VAD 失靈，可以在程式碼層面檢查 <code>segment.end - segment.start</code>。如果差值超過 15 秒，就代表這一句太長了，這通常是模型卡住的徵兆。</li>
</ul>



<p>在 <code>faster-whisper</code> 中，雖然參數名稱和原始的 OpenAI Whisper 略有不同，但我們可以透過 <code>vad_parameters</code> 中的 <code>max_speech_duration_s</code> 來限制每個片段的最長秒數。</p>



<p>另外，我們可以用 <code>initial_prompt</code> 強制模型在語氣停頓處斷句。</p>



<h3 class="wp-block-heading">加入長度限制後的程式碼</h3>



<p>Python</p>



<pre class="wp-block-code"><code>segments, info = model.transcribe(
    input_file, 
    language=language, 
    vad_filter=True,
    # vad_parameters 是控制切分長度的關鍵
    vad_parameters=dict(
        min_silence_duration_ms=500,  # 只要停頓 0.5 秒就切斷
        max_speech_duration_s=15      # 強制每一段話最長不能超過 15 秒
    ),
    # 限制模型一次生成的字數，避免一段話塞進太多內容
    # beam_size 設小一點有助於減少模型過度延伸的幻覺
    beam_size=5,
    # 給模型暗示，讓它知道要分句
    initial_prompt="，。！？", 
    # 關閉前文關聯，防止模型為了連貫性把句子硬湊在一起
    condition_on_previous_text=False
)
</code></pre>



<h3 class="wp-block-heading">參數修改說明</h3>



<ul class="wp-block-list">
<li><strong>max_speech_duration_s</strong>: 這是最直接的解藥。我把它設為 15 秒，這代表 VAD 只要偵測到語音長度快到 15 秒，就會強行切斷並產生一個時間戳。這能解決你看到那種一整分鐘都沒斷句的問題。</li>



<li><strong>min_silence_duration_ms</strong>: 調降到 500ms（0.5秒）。這會讓程式對說話者的換氣、停頓更敏感，進而增加斷句頻率。</li>



<li><strong>initial_prompt</strong>: 我直接給它標點符號。這會引導模型在生成文字時，主動在該斷句的地方放上標點，這在處理「然後」、「接著」這種口頭禪時效果很好。</li>



<li><strong>beam_size</strong>: 雖然這主要影響準確度，但設在 5 左右通常是速度與穩定度的平衡點，能減少模型胡言亂語的機率。</li>
</ul>



<p>你可以先試試看這組設定，15 秒的強制限制應該能馬上解決多句合併的問題。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">為什麼已經知道是不同句話, 卻還是要合併句子</h2>



<p>這是一個常見的技術陷阱。之所以會出現「明明語氣斷了，時間軸卻連在一起」，主要有三個原因：</p>



<h3 class="wp-block-heading">為什麼會被合併</h3>



<ol start="1" class="wp-block-list">
<li><strong>VAD 沒抓到夠長的靜音</strong>：Whisper 預設要看到一段明顯的「無聲區」才會切段。如果說話者語速快，或環境底噪（如風扇、電腦運流聲）太重，VAD 會以為中間那幾毫秒的停頓只是換氣，不是句子結束。</li>



<li><strong>模型試圖補完語意</strong>：Whisper 的特色是它會「預測」下一句。當它聽到「然後」、「接著」這種連接詞，它會覺得這句話還沒講完，為了語句通順，它會把後面的內容強行拉進同一個時間戳裡。</li>



<li><strong>預設的最短片段限制</strong>：模型為了避免產生太多只有 1 秒的碎片段，有時會自動把相近的聲音合併，結果反而造成了你看到的 15 秒長句。</li>
</ol>



<h3 class="wp-block-heading">解決方案：強制切分與語境分離</h3>



<p>要修正這個問題，必須在 <code>model.transcribe</code> 裡加上更嚴格的參數。請將這段整合進你的程式中：</p>



<p>Python</p>



<pre class="wp-block-code"><code>segments, info = model.transcribe(
    input_file, 
    language=language, 
    vad_filter=True,
    vad_parameters=dict(
        min_silence_duration_ms=400,  # 更敏感，停頓 0.4 秒就切斷
        max_speech_duration_s=10,     # 強制每段最長 10 秒，解決長句問題
        speech_pad_ms=200             # 減少片段前后的緩衝音
    ),
    # 這是關鍵：關閉前文關聯
    condition_on_previous_text=False, 
    # 加入提示詞，強迫模型在看到連接詞時斷開
    initial_prompt="。，接著。然後。", 
    # 提高對無聲的判斷，不要讓底噪把兩句話連起來
    no_speech_threshold=0.6
)
</code></pre>



<h3 class="wp-block-heading">修改後的變化</h3>



<p>這組參數會讓 VAD 變得非常「沒耐心」。只要你稍微停頓 0.4 秒，它就會強行結束這一局。</p>



<p>加上 <code>condition_on_previous_text=False</code> 後，模型就不會因為看到「然後」就想去接前面的話。它會把每一段都當作全新的開始，這樣時間軸就會被切得很碎、很精準。</p>



<p>如果修改後發現句子斷得太細，可以再把 <code>min_silence_duration_ms</code> 稍微往上調。</p>



<p>需要我幫你把這組「嚴格斷句版」參數放進完整的函數程式碼中嗎？</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>還是  chatGPT 解決問題能力較強,</p>



<p>你這份設定其實已經<strong>接近 faster-whisper 能做到的極限切分</strong>了，多句字幕被合併，原因主要不是「bug」，而是 <strong>Whisper 本身的語言模型行為 + VAD 與 segment 定義方式</strong>。下面我直接用「為什麼會合併 → 怎麼徹底解」的角度來說，並給你<strong>可直接套用的修正方案</strong>。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>先說結論：<br><strong>只靠 transcribe 參數，無法 100% 防止多句合併在同一個 segment。</strong><br>真正穩定的解法是 <strong>「模型切段 + 後處理再切一次字幕」</strong>。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">為什麼你現在的設定還是會合併？</h2>



<p>即使你已經做了這些正確的事：</p>



<ul class="wp-block-list">
<li><code>condition_on_previous_text=False</code></li>



<li><code>vad_filter=True</code></li>



<li>縮短 <code>min_silence_duration_ms</code></li>



<li>限制 <code>max_speech_duration_s</code></li>



<li>設小 <code>beam_size</code></li>



<li>提高 <code>no_speech_threshold</code></li>
</ul>



<p>但 <strong>Whisper 的 segment 不是「一句話」概念，而是「語音連續區間」</strong>：</p>



<ul class="wp-block-list">
<li>只要中間沒有被 VAD 判定為「明確靜音」</li>



<li>或模型認為語意連續（尤其是中文）</li>



<li>就會把「多句話」吐在 <strong>同一個 <code>segment.text</code></strong></li>
</ul>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 所以你現在看到的是「一個 segment 裡面有好幾句話」</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">正確做法：保留 Whisper segment，但<strong>自己再切字幕</strong></h2>



<h3 class="wp-block-heading">核心策略</h3>



<ol class="wp-block-list">
<li><strong>讓 Whisper 只負責「時間區段」</strong></li>



<li><strong>字幕斷句交給你自己（用標點 / 長度 / 停頓）</strong></li>
</ol>



<p>這是專業字幕系統（YouTube、Netflix pipeline）實際用的做法。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">解法一（強烈推薦）：依標點再切 SRT（最穩）</h2>



<h3 class="wp-block-heading">新增一個「字幕斷句函式」</h3>



<pre class="wp-block-code"><code>import re

def split_text_to_sentences(text):
    # 中文 + 英文常見斷句符號
    pattern = r'(?&lt;=&#91;。！？!?；;])'
    parts = re.split(pattern, text)
    return &#91;p.strip() for p in parts if p.strip()]
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">修改你原本的 for loop（關鍵）</h3>



<pre class="wp-block-code"><code>srt_index = 1

for segment in segments:
    start = segment.start
    end = segment.end
    text = segment.text.strip()

    sentences = split_text_to_sentences(text)

    if len(sentences) == 1:
        # 原本行為
        if f_srt:
            f_srt.write(f"{srt_index}\n")
            f_srt.write(f"{format_timestamp(start)} --&gt; {format_timestamp(end)}\n")
            f_srt.write(f"{sentences&#91;0]}\n\n")
        srt_index += 1
        continue

    # 多句 → 平均切時間
    duration = end - start
    per_sentence = duration / len(sentences)

    for idx, sentence in enumerate(sentences):
        s = start + idx * per_sentence
        e = s + per_sentence

        if f_srt:
            f_srt.write(f"{srt_index}\n")
            f_srt.write(f"{format_timestamp(s)} --&gt; {format_timestamp(e)}\n")
            f_srt.write(f"{sentence}\n\n")

        srt_index += 1
</code></pre>



<h3 class="wp-block-heading">效果</h3>



<ul class="wp-block-list">
<li>一個 Whisper segment → 多個 SRT 條目</li>



<li>時間仍然合理</li>



<li><strong>字幕不再塞成一大句</strong></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">解法二（進階）：限制每行字數（更像專業字幕）</h2>



<p>你可以加上「字幕長度限制」，例如 20～25 字：</p>



<pre class="wp-block-code"><code>def split_by_length(text, max_len=22):
    result = &#91;]
    buf = ""
    for ch in text:
        buf += ch
        if len(buf) &gt;= max_len:
            result.append(buf)
            buf = ""
    if buf:
        result.append(buf)
    return result
</code></pre>



<p>可以先「標點切 → 再長度切」。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">你現在這些參數，哪些是「有效的」？</h2>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 保留（做得對）：</p>



<ul class="wp-block-list">
<li><code>condition_on_previous_text=False</code></li>



<li><code>vad_filter=True</code></li>



<li><code>min_silence_duration_ms=300</code></li>



<li><code>max_speech_duration_s</code></li>



<li><code>beam_size=5</code></li>
</ul>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 影響有限：</p>



<ul class="wp-block-list">
<li><code>initial_prompt</code></li>



<li><code>clip_timestamps</code></li>



<li><code>max_initial_timestamp</code></li>
</ul>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 無法根治的：</p>



<ul class="wp-block-list">
<li>單靠 VAD 期待「一句一段」</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">最佳實務建議（總結）</h2>



<p>一句話版本：</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Whisper 負責聽，字幕斷句要自己來。</strong></p>
</blockquote>



<p>你的 pipeline 建議是：</p>



<ol class="wp-block-list">
<li>faster-whisper：
<ul class="wp-block-list">
<li>穩定切出時間 segment</li>
</ul>
</li>



<li>Python 後處理：
<ul class="wp-block-list">
<li>依「標點 / 長度」再切字幕</li>
</ul>
</li>



<li>輸出 SRT</li>
</ol>



<p>這樣你會得到：</p>



<ul class="wp-block-list">
<li>不合併句子</li>



<li>時間合理</li>



<li>可控字幕品質</li>



<li>不依賴模型幻覺行為</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>下面是<strong>直接可用的「production 等級 SRT pipeline」</strong>，在你原本程式基礎上完成這些事：</p>



<ol class="wp-block-list">
<li><strong>Whisper 只負責時間段（segment）</strong></li>



<li><strong>字幕後處理再斷句（標點 → 長度）</strong></li>



<li><strong>每個 SRT 最多 2 行</strong></li>



<li><strong>每行最多 N 個字（可調）</strong></li>



<li><strong>時間合理平均分配</strong></li>



<li><strong>不再出現多句塞同一條字幕</strong></li>
</ol>



<p>你可以整段直接取代原本的 function。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">核心字幕切分工具（production 用）</h2>



<pre class="wp-block-code"><code>import os
import re
from contextlib import ExitStack
from typing import List
from faster_whisper import WhisperModel
</code></pre>



<h3 class="wp-block-heading">斷句：先標點，再長度</h3>



<pre class="wp-block-code"><code>def split_sentences(text: str):
    pattern = r'(?&lt;=&#91;。！？!?；;])'
    parts = re.split(pattern, text)
    return &#91;p.strip() for p in parts if p.strip()]
</code></pre>



<h3 class="wp-block-heading">控制每行長度</h3>



<pre class="wp-block-code"><code>def split_by_length(text: str, max_len: int):
    lines = &#91;]
    buf = ""
    for ch in text:
        buf += ch
        if len(buf) &gt;= max_len:
            lines.append(buf)
            buf = ""
    if buf:
        lines.append(buf)
    return lines
</code></pre>



<h3 class="wp-block-heading">合成「最多 2 行」字幕 block</h3>



<pre class="wp-block-code"><code>def build_subtitle_blocks(text: str, max_line_len=22, max_lines=2):
    sentences = split_sentences(text)
    blocks = &#91;]

    for sent in sentences:
        lines = split_by_length(sent, max_line_len)

        for i in range(0, len(lines), max_lines):
            block = lines&#91;i:i + max_lines]
            blocks.append("\n".join(block))

    return blocks
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">最終版：production SRT pipeline</h2>



<pre class="wp-block-code"><code>def run_faster_whisper_task(
    input_file: str,
    language: str,
    model_size: str,
    device: str,
    output_formats: List&#91;str],
    max_line_len: int = 22
):
    try:
        print(f"--- 開始處理: {input_file} ---")

        compute_type = "float16" if device == "cuda" else "int8"
        model = WhisperModel(model_size, device=device, compute_type=compute_type)

        segments, info = model.transcribe(
            input_file,
            language=language,
            vad_filter=True,
            condition_on_previous_text=False,
            vad_parameters=dict(
                min_silence_duration_ms=300,
                max_speech_duration_s=4,
                speech_pad_ms=200,
            ),
            beam_size=5,
            no_speech_threshold=0.6,
        )

        base_name = os.path.splitext(input_file)&#91;0]

        with ExitStack() as stack:
            f_srt = None
            f_txt = None

            if "srt" in output_formats or "all" in output_formats:
                f_srt = stack.enter_context(
                    open(f"{base_name}.srt", "w", encoding="utf-8")
                )

            if "txt" in output_formats or "all" in output_formats:
                f_txt = stack.enter_context(
                    open(f"{base_name}.txt", "w", encoding="utf-8")
                )

            srt_index = 1

            for segment in segments:
                start = segment.start
                end = segment.end
                text = segment.text.strip()

                if not text:
                    continue

                blocks = build_subtitle_blocks(
                    text,
                    max_line_len=max_line_len,
                    max_lines=2
                )

                duration = end - start
                per_block = duration / len(blocks)

                for i, block in enumerate(blocks):
                    s = start + i * per_block
                    e = s + per_block

                    if f_srt:
                        f_srt.write(f"{srt_index}\n")
                        f_srt.write(
                            f"{format_timestamp(s)} --&gt; {format_timestamp(e)}\n"
                        )
                        f_srt.write(f"{block}\n\n")

                    if f_txt:
                        f_txt.write(block.replace("\n", " ") + "\n")

                    print(f"&#91;{format_timestamp(s)} -&gt; {format_timestamp(e)}]")
                    print(block)

                    srt_index += 1

        print(f"--- 處理完成 ({info.language}, {info.language_probability:.2f}) ---")

    except Exception as e:
        print(f"Faster-Whisper 錯誤: {e}")
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">參數調整建議</h3>



<p>你的設定中 <code>max_speech_duration_s=1</code> 數值過小。這會強制 VAD 每秒鐘就切斷一次。當語音被切得太碎，模型反而容易因為上下文不足而產生幻覺，或是把零碎的聲音補償成重複的文字。建議將這個值放寬到 15 到 20 左右。</p>



<p>目前的字幕出現長達 30 秒的區間，通常是因為 VAD 沒有成功切斷聲音。模型認為這段時間內一直有人在說話。這可能與 <code>min_silence_duration_ms</code> 太短有關。</p>



<p>您可以嘗試以下參數組合：</p>



<pre class="wp-block-code"><code>segments, info = model.transcribe(
    input_file, 
    language=language, 
    vad_filter=True,
    condition_on_previous_text=False,
    vad_parameters=dict(
        min_silence_duration_ms=500,
        max_speech_duration_s=20,
        speech_pad_ms=400
    ),
    beam_size=5,
    initial_prompt="繁體中文字幕。",
    no_speech_threshold=0.6,
    log_prob_threshold=-1.0,
    compression_ratio_threshold=2.4
)
</code></pre>



<h3 class="wp-block-heading">關鍵調整說明</h3>



<p><code>min_silence_duration_ms</code> 增加到 500 毫秒。這樣模型比較能識別出正常的說話停頓。太短的設定會讓環境噪音干擾判定。</p>



<p><code>speech_pad_ms</code> 增加到 400 毫秒。這會在切分片段的前後多留一點空間。這能幫助模型完整辨識字首與字尾，減少因為聲音被截斷導致的重複亂碼。</p>



<p>加入 <code>initial_prompt</code>。指定為繁體中文可以導正模型的語氣。這能有效減少出現奇怪贅字或簡繁混雜的機率。</p>



<p>調整 <code>compression_ratio_threshold</code>。如果模型輸出的內容重複率太高，這個參數會觸發重新辨識。這對解決你提到的重複文字問題很有幫助。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">python opencc 的 s2t 與 s2tw 差異</h2>



<p>OpenCC 是一個很方便的簡繁轉換工具。s2t 與 s2tw 看起來很像，但處理邏輯有明顯區別。這對寫程式或處理文字檔的人來說，選錯轉換模式會讓結果變得很奇怪。</p>



<h2 class="wp-block-heading">核心轉換邏輯的差異</h2>



<p>s2t 的全稱是 Simplified Chinese to Traditional Chinese。它只做字對字的轉換。也就是把簡體字直接換成對應的正體字。這種模式不考慮各地區的用詞習慣。它最適合用在想保留原始語句，只需要更換字體形狀的場景。</p>



<p>s2tw 則是 Simplified Chinese to Traditional Chinese (Taiwan Standard)。它除了換字，還會加入台灣的字形標準。它處理的是字形上的微調，確保轉換後的文字符合台灣教育部門定義的標準字體。</p>



<h2 class="wp-block-heading">詞彙轉換的層次</h2>



<p>雖然 s2tw 處理了台灣字形，但它不一定會處理詞彙轉換。在 OpenCC 的配置中，如果你需要把簡體的計算機換成台灣常用的電腦，通常要使用的是 s2twp。那個 p 代表的是 Phrases，也就是詞彙修正。</p>



<p>單純的 s2t 轉換後，你的文章看起來會像是一個用簡體邏輯寫成的繁體文章。讀起來會有一種違和感。如果你的目標讀者是台灣人，s2tw 或 s2twp 會是比較好的選擇。</p>



<h2 class="wp-block-heading">實際應用建議</h2>



<p>如果你是要開發給台灣用戶使用的 App 或網站，建議選擇 s2twp。這樣不只字形正確，連軟體、內存這種詞彙都能自動轉換成軟體、記憶體。這能大幅提升用戶的閱讀體驗。</p>



<p>缺點也很明顯，完全無法使用大陸的用詞，會被強制轉成台灣用詞，但台灣明明可以用腳本，s2twp 會硬把腳本改成指令碼&#8230;, 實在很無言.</p>



<p>實際測試, s2hk 似乎比較好用.</p>



<ul class="wp-block-list">
<li><strong>原始文字：</strong><br>通过内存清理软件，可以提高计算机的速度。<br>台灣, 一台車, 芯片, 腳本, 脚本, 指令码, 指令碼, 软体, 軟體。土豆, 信息, <br>水平高清发现太后的头发后面有干的长发</li>



<li><strong>s2t 模式：</strong><br>通過內存清理軟件，可以提高計算機的速度。<br>臺灣, 一臺車, 芯片, 腳本, 腳本, 指令碼, 指令碼, 軟體, 軟體。土豆, 信息, <br>水平高清發現太后的頭髮後面有乾的長髮</li>



<li><strong>s2tw 模式：</strong><br>通過內存清理軟件，可以提高計算機的速度。<br>臺灣, 一臺車, 芯片, 腳本, 腳本, 指令碼, 指令碼, 軟體, 軟體。土豆, 信息, <br>水平高清發現太后的頭髮後面有乾的長髮</li>



<li><strong>s2twp 模式：</strong><br>透過記憶體清理軟體，可以提高計算機的速度。臺灣, 一臺車, 晶片, 指令碼, 指令碼, 指令碼, 指令碼, 軟體, 軟體。土豆, 資訊, 水平高畫質發現太后的頭髮後面有乾的長髮</li>



<li><strong>s2hk 模式：</strong><br>通過內存清理軟件，可以提高計算機的速度。<br>台灣, 一台車, 芯片, 腳本, 腳本, 指令碼, 指令碼, 軟體, 軟體。土豆, 信息, <br>水平高清發現太后的頭髮後面有乾的長髮</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2025/12/srt-video-cutter/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>gemini 回覆的內容, 部份單字會以前後加$ 符號, 這是什麼意思?</title>
		<link>https://max-everyday.com/2025/12/gemini-dollar-sign/</link>
					<comments>https://max-everyday.com/2025/12/gemini-dollar-sign/#respond</comments>
		
		<dc:creator><![CDATA[Max]]></dc:creator>
		<pubDate>Mon, 15 Dec 2025 04:20:40 +0000</pubDate>
				<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Google]]></category>
		<guid isPermaLink="false">https://max-everyday.com/?p=22556</guid>

					<description><![CDATA[這是一個格式上的問題。在我內部運作時，金錢符號是用來標示一些特殊的內容，例如數學公式或程式碼裡面的變數等等。它們告訴我，這些夾在符號中間的東西是比較正式或技術性的表達。  [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>這是一個<strong>格式</strong>上的問題。在我內部運作時，金錢符號是用來標示一些特殊的內容，例如<strong>數學公式</strong>或<strong>程式碼</strong>裡面的<strong>變數</strong>等等。它們告訴我，這些夾在符號中間的東西是比較正式或技術性的表達。</p>



<p>理論上，我應該只在處理<strong>複雜的數學</strong>或<strong>專業科學內容</strong>時才會使用這個格式。一般來說，我會盡量在日常的問答中把它們移除或轉換成一般的文字。</p>



<p>如果我在回答您的問題時出現了這個符號，那可能是我<strong>內部處理時的一個小疏忽</strong>。它並不是想表達什麼特別的意思，對您閱讀來說，您可以把它當成是<strong>一個普通的詞彙</strong>來看待就好。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>不喜歡複製文字的時候複製到$, 可以下指令給 gemini, 例如:</p>



<pre class="wp-block-code"><code>請以繁體中文回答，偏好回答精簡。不要使用小標題，只要使用段落標題，避免花俏排版，不使用 emoji。寫作特色為口語，但不要使用語尾詞，語句多以短句為主。不要在回答中使用斜體字。特殊的變數內容前後不要另外加$符號。</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="643" src="https://max-everyday.com/wp-content/uploads/2025/12/2025-12-15_12-17_j3-1024x643.jpg" alt="" class="wp-image-22557" srcset="https://max-everyday.com/wp-content/uploads/2025/12/2025-12-15_12-17_j3-1024x643.jpg?v=1765772374 1024w, https://max-everyday.com/wp-content/uploads/2025/12/2025-12-15_12-17_j3-500x314.jpg?v=1765772374 500w, https://max-everyday.com/wp-content/uploads/2025/12/2025-12-15_12-17_j3-615x386.jpg?v=1765772374 615w, https://max-everyday.com/wp-content/uploads/2025/12/2025-12-15_12-17_j3.jpg?v=1765772374 1099w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://max-everyday.com/2025/12/gemini-dollar-sign/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
