分類: 筆記x備忘

  • 不只是 Prompt!Agent Skills 正悄悄統一 AI 助理,成為跨平台的超能力標準

    不只是 Prompt!Agent Skills 正悄悄統一 AI 助理,成為跨平台的超能力標準

    來源:NotebookLM
    摘要影片:https://youtu.be/JzskVI-wsT4

    當我們談論客製化 AI 助理時,大多數人的第一反應可能是「調整 Prompt」。然而,這種方法往往感覺像是隔靴搔癢,難以建立可重複、結構化的複雜工作流程。現在,一個名為「Agent Skills」(代理人技能)的強大標準正在改變這一切。它不僅提供了一種更結構化的方式來擴展 AI 的能力,更令人驚訝的是,它正迅速成為一個跨越不同公司和產品的通用語言。

    1. 驚喜的跨平台開放標準:AI 界的「通用語言」

    最令人意外的發現是:Agent Skills 並非某家公司的專有技術,而是一個開放標準,正被多家相互競爭的 AI 開發工具所採納。有趣的是,「Skills」這個名稱最初由 Anthropic 的 Claude 推廣,但其核心理念——一個可移植、結構化的能力封裝——正被各家以不同名稱採納,例如 Google Gemini 的「Extensions」或 OpenAI Codex 的 AGENTS.md 文件,但都遵循著相同的開放標準原則。這在當前 AI 領域各自為政的環境中,顯得尤為難得且影響深遠。

    支持此標準的 AI 代理和工具橫跨了業界的主要參與者,包括:

    • GitHub Copilot (根據官方文件,支援其編碼代理、CLI 及 VS Code Insiders)
    • Anthropic 的 Claude (包含 Claude Code、Claude.ai 和 API)
    • Google 的 Gemini CLI (目前為實驗性功能)
    • Cursor
    • OpenAI Codex (作為早期支援該模式的工具之一)

    這個開放標準的官方文檔位於 agentskills.io。更重要的是,一個蓬勃發展的跨平台社群生態系正在形成。例如,Hugging Face 的 skills 程式碼倉庫就明確指出其技能可與主流編碼代理工具互通,而 GitHub 自己的 github/awesome-copilot 專案也收錄了大量社群創建的技能。這種跨公司的標準化意味著開發者可以「一次編寫,到處使用」,為特定任務封裝的專業知識和工作流程將具備前所未有的可移植性。

    2. 為你的 Context Window 減壓:高效的「漸進式揭露」

    Agent Skills 的核心運作機制是一種稱為「漸進式揭露」(progressive disclosure) 的高效模式,它極大地節省了寶貴的 Context Window 空間。

    其運作方式如下:當 AI 代理啟動時,它只會載入每個可用技能的輕量級元數據,也就是 name (名稱) 和 description (描述)。完整的技能指令集 (SKILL.md 的內容) 和相關資源並不會立即被載入。只有當用戶的請求與某個技能的描述相符,該技能被「啟動」時,其詳細內容才會被注入到當前的對話上下文中。

    這與將所有客製化指令都塞進一個龐大的系統提示 (system prompt) 中的低效做法形成鮮明對比。根據 awesome-claude-skills 倉庫的資料,一個技能在被啟動前可能只佔用 30-50 個 token,這充分展示了其在管理上下文時的卓越效率。

    3. 最關鍵的一行程式碼:description 欄位是你的魔法棒

    SKILL.md 檔案中,最重要的部分出乎意料地不是指令本身,而是 YAML frontmatter 中的 description 欄位。這一行文字是決定你的技能能否在正確時機被觸發的關鍵。

    AI 代理會自主分析用戶的請求,並將其與所有可用技能的 description 進行比對。如果匹配成功,代理就會決定使用該技能。這個過程在文檔中被稱為「隱式調用」(implicit invocation) 或「自動發現」(automatic discovery)。

    這意味著,一個寫得精準、具體、包含用戶常用關鍵字的描述,遠比指令內容本身更能確保技能的成功啟動。例如,一個模糊的描述如「幫助處理文件」,遠不如「從 PDF 文件中提取文字和表格,填充表單,合併文檔」來得有效。對於任何想要打造自己技能的開發者來說,這是一個至關重要的洞見。

    4. 各司其職:何時用 Skills,何時用自訂指令?

    Agent Skills 和其他客製化方法,如「自訂指令」(例如 CLAUDE.mdGEMINI.md),並非相互取代,而是各司其職。理解它們的區別是有效運用 AI 助理的關鍵。

    根據源文件的定義,它們的用途涇渭分明:

    • 自訂指令 (Custom Instructions): 用於設定持續性、全域性的規則和指導方針。這些指令在幾乎所有對話中都應該生效,例如整個專案的編碼標準、程式碼風格指南或固定的輸出格式。
    • Agent Skills: 用於提供特定任務、按需取用的專業知識和可重複的工作流程。這些技能只在處理特定任務時被觸發,例如一套標準化的除錯流程、一份 PR 審查清單,或一個資料庫遷移的工作流程。

    一個簡單的比喻是:自訂指令就像是公司的「員工手冊」,為所有員工提供通用的行為準則;而 Agent Skills 則像是為特定專案聘請的「外部專家顧問」,只在需要其專業領域知識時才會介入。

    5. 層層疊加的專業知識:強大的範圍與優先級系統

    Agent Skills 的設計中包含一個強大的分層結構,允許技能在不同的「範圍」(scope) 內生效,並定義了明確的優先級規則。

    技能可以被儲存在不同的位置,從而決定其適用範圍:

    • 專案/工作區 (Project/Workspace) 技能: 儲存在專案目錄下 (例如 GitHub Copilot 的 .github/skills、Gemini 的 .gemini/skills 或 Claude 的 .claude/skills),通常會納入版本控制,與團隊共享。
    • 使用者/個人 (User/Personal) 技能: 儲存在使用者的家目錄下 (例如 ~/.copilot/skills~/.claude/skills),適用於該使用者所有的專案。
    • 系統/擴充功能 (System/Extension) 技能: 由 AI 工具本身或其擴充功能捆綁提供,適用範圍最廣。

    當不同範圍中存在同名技能時,優先級規則確保了行為的可預測性:更具體的範圍會覆蓋更通用的範圍。例如,專案技能會覆蓋使用者技能,而使用者技能會覆蓋系統技能。

    這個分層系統極具威力,它讓團隊可以建立標準化的工作流程 (專案技能),同時又賦予個別開發者根據個人偏好進行客製化或擴展的靈活性 (使用者技能)。

    結論

    Agent Skills 代表了 AI 協作模式的一次重要演進,從簡單的提示工程邁向了一個更結構化、可重用且具備互通性的新範式。它不僅為開發者提供了前所未有的能力來「教導」AI 如何以標準化方式完成複雜任務,其跨平台的開放標準特性更有可能在未來催生出一個繁榮的技能生態系統。

    隨著這個開放標準的發展,您會想打造什麼樣的專業技能來為您的工作流程賦能?

    附上心智圖

    同場加映

    SKILL.md 的 YAML 前言(Frontmatter)中,雖然各工具都遵循基礎標準,但 Claude Code 提供最豐富的進階控制欄位。

    Claude Code YAML 欄位定義

    根據官方文件,Claude Code 的欄位配置如下:

    欄位名稱是否必填說明與使用方式範例
    name技能唯一標識符,僅限小寫字母、數字與連字號,上限 64 字元。name: pr-reviewer
    description描述功能與觸發時機,上限 1024 字元。代理據此決定何時激活技能。description: 審查 PR 並檢查代碼規範。
    allowed-tools限制代理在技能激活時可用的工具。若省略則不限制。allowed-tools: Read, Grep, Glob
    model指定執行該技能時使用的特定 AI 模型。model: claude-sonnet-4-20250514
    context設置為 fork 時,技能會在獨立的子代理上下文中執行,不影響主對話。context: fork
    agentcontext: fork 時,可指定子代理類型(如 Explore, Plan)。agent: Plan
    hooks定義技能生命週期中的自動化腳本(如 PreToolUse, PostToolUse)。見下文說明
    user-invocable是否在斜線命令選單中顯示。預設為 trueuser-invocable: false
    disable-model-invocation設置為 true 可阻止代理自動發現並觸發此技能。disable-model-invocation: true

    其他 AI 工具的欄位差異與額外欄位

    其他工具通常僅支援基礎欄位,但有少數獨特定義:

    • GitHub Copilot:
      • license (選填):用於描述該技能適用的授權條款。
    • OpenAI Codex:
      • metadata (選填):可在其下定義 short-description,作為面向使用者的簡短說明。
    • Cursor & Antigravity:
      • name (選填):這兩個工具中 name 並非必填。若省略,系統會自動使用父資料夾名稱作為技能名稱。
    • Gemini CLI:
      • 主要遵循基礎標準(namedescription),並無 Claude 特有的 hooksfork 欄位。

    共通的核心機制

    儘管欄位略有不同,所有工具皆採用**漸進式披露(Progressive Disclosure)**機制:啟動時僅讀取 namedescription 以節省 Token,只有當任務匹配時才會加載完整的指令與資源。

    在撰寫 SKILL.md 的 YAML 前言時,VS Code (GitHub Copilot)Claude Code 都遵循基礎標準,但 Claude Code 提供了更多進階的控制欄位。

    VS Code (GitHub Copilot) 的 YAML 欄位

    VS Code 的配置相對簡約,主要聚焦於識別與觸發:

    • name (必填):唯一標識符,限小寫、數字與連字號,上限 64 字元。
    • description (必填):定義技能功能與觸發時機(Copilot 據此決定何時加載),上限 1024 字元。
    • license (選填):描述該技能適用的授權條款。

    Claude Code 的進階 YAML 欄位

    Claude Code 除了支援上述基礎欄位外,還增加了許多功能性控制:

    • allowed-tools:限制代理在技能激活時可使用的工具(例如只允許 ReadGrep),增加安全性。
    • context: fork:將技能放在獨立的「子代理」中執行,避免污染主對話歷史。
    • agent:配合 fork 使用,指定子代理類型(如 ExplorePlan)。
    • hooks:定義自動化腳本的觸發事件(如 PreToolUseStop)。
    • user-invocable:控制該技能是否顯示在 / 斜線命令選單中(預設為 true)。
    • disable-model-invocation:若設為 true,可阻止 Claude 自動發現並觸發此技能。

    核心差異總結

    特性VS Code (Copilot)Claude Code
    主要定位任務導向的指令擴充高度自動化的工作流控制
    工具限制不支援限制工具可透過 allowed-tools 精確限制
    環境隔離始終在當前對話中加載可透過 fork 建立獨立執行環境
    生命週期無特定事件處理可透過 hooks 執行前後置腳本
  • 臺灣的全民安全指引不只教你打包:5個你可能從沒想過的防災真相

    臺灣的全民安全指引不只教你打包:5個你可能從沒想過的防災真相

    這是一篇最近台灣政府發的小冊子《當危機來臨時:臺灣全民安全指引》 下載連結 心得,我把他丟到 NotebookLM 上,順道生成了一篇 blog ,就紀錄起來。

    以下正文:


    我檢查了我的緊急避難包三次,但讀完臺灣最新的《全民安全指引》後,我才發現自己錯過了最重要的一環。

    當我們談到「防災準備」,許多人腦中浮現的第一個畫面,就是一個裝滿物資的背包。但這真的夠了嗎?這份官方指引揭示了一個遠比打包更深入、更現代的安全思維。它提出了一些真正發人深省的問題:如果手機和網路中斷,你和家人有約定好的集合地點嗎?如果提款機因停電而失靈,你有足夠的現金應急嗎?

    這篇文章將從這份重要的官方手冊中,為你提煉出5個最令人驚訝、也最關鍵的防災真相,幫助你重新思考「準備」的真正意義。

    1. 你的準備不是一個背包,而是一個系統 (Your Prep Isn’t a Bag, It’s a System)

    在這裡,這份指引做出了一個與傳統思維 brilliantly different 的區別。許多人誤以為防災就是準備一個「緊急避難包」,但指引強調,你的準備應該是「一個為了『在家固守』,一個為了『緊急撤離』的雙軌系統」。

    這套系統的核心在於「彈性」。單一的避難包只適用於撤離,但現代危機中,更有可能發生的情境是必須在家避難(例如大規模封鎖或基礎設施中斷)。因此,系統的第一部分是「日常的居家儲備」,指引建議至少要有一週的份量,涵蓋每人每日3公升的飲用水、食物、衛生用品和常備藥物。

    為了讓儲備變得簡單,手冊推薦了一個聰明的「生活竅門」:採用「循環儲備」法。平時就購買儲備物資,在日常生活中優先使用它們,然後再定期補充。這個「先儲備、後使用、再補充」的循環,移除了防災準備的經濟與管理負擔,讓它成為人人都能輕鬆實踐的習慣。這個「居家儲備」加上「避難包」的雙重系統,遠比單純一個背包來得更具韌性,能應對更多元的危機情境。

    2. 現代危機中,最大的斷點是「電」和「網路」 (In a Modern Crisis, the Biggest Failures are ‘Power’ and ‘Internet’)

    這部分揭示了這份指引對現代社會運作方式的深刻理解。我們高度依賴的數位化社會,同時也極度脆弱。指引特別點出,大規模停電或網路中斷將引發一連串災難性的「骨牌效應」(cascading failures)。

    這不僅僅是無法上網而已。手冊列舉了幾個你可能沒想過的第二、三層後果:

    • 提款機(ATM)可能無法運作,讓你無法提領現金。
    • 電子鎖、電動鐵捲門和電梯將會失效,可能讓你被困在室內或無法進入家中。
    • 冰箱失去電力,儲存的食物會迅速腐敗。
    • 使用加壓馬達供水的高樓層住戶,可能會在停電後不久就面臨停水。

    面對這些高科技社會的脆弱點,指引提出的解決方案卻出奇地「低科技」且極具韌性:隨身備有少量現金、擁有一台可攜式的電池收音機,以及確保行動電源隨時充飽電。這提醒了我們,真正的準備不是追求更炫的科技裝備,而是要建立簡單、可靠、不會輕易失效的備援方案。

    3. 真正的戰場也在你的手機裡 (The Real Battlefield is Also in Your Phone)

    這份指引將資訊安全與辨識假訊息,提升到了國家安全的高度。手冊明確指出,在危機時期,敵人會利用網路散播假訊息,其目的在於「動搖民心與破壞社會穩定」。

    為了應對資訊戰,指引提出了「3不1要」原則:不製造不輕信不轉傳來源不明的訊息,並且要查證。這不僅僅是媒體素養教育,指引將其視為一項核心的國民防衛技能——你的心智,也是戰場的一部分。在網路與通訊中斷時,手冊也指明了可靠的官方資訊管道,例如警廣與漢聲廣播電臺的特定頻率。

    其中,手冊用最嚴肅的語氣強調了一條至關重要的原則:

    倘若臺灣遭受軍事侵略,任何有關國家戰敗或政府宣布投降的訊息,都是假訊息!

    這句話清楚地告訴我們,在最壞的情況下,保持資訊判斷力與心理上的堅定,和準備物資同等重要。

    4. 急救不只是等救護車 (First Aid Isn’t Just Waiting for the Ambulance)

    平時我們習慣遇到緊急狀況就撥打119,等待專業救護。但《全民安全指引》點出一個殘酷的現實:在重大危機中,消防和醫療系統將會不堪重負,無法像平時一樣即時回應每個人的需求。

    這意味著,等待救援可能不再是選項。這是一種根本性的思維轉變——責任的「去中心化」。我們每個人都必須學會簡單的自救與互救能力,才能在救援抵達前的黃金時間內,保護自己與家人的生命。

    手冊中涵蓋了基礎但極為重要的急救技巧,例如燒燙傷處理的「沖、脫、泡、蓋、送」五步驟、嚴重出血時的直接加壓法或止血帶使用,以及心肺復甦術(CPR)。這代表著從一個被動等待救援的受害者,轉變為能為自己、家人乃至社區提供第一時間援助的主動救援者。

    5. 心理韌性和社區連結是你的終極裝備 (Mental Resilience and Community Ties are Your Ultimate Gear)

    這份指引的思維是一以貫之的。如同它將急救的責任從專業人員下放到每一位公民,它也將社會安全網的重心,從大型機構延伸到了你我身邊的鄰居。這同樣是「去中心化」韌性的體現。

    真正的安全準備,不僅僅是物質層面。《全民安全指引》花了相當的篇幅討論心理健康與社區支持系統,這兩者才是面對長期壓力與未知威脅的終極裝備。

    手冊建議,當我們感到焦慮時,可以透過以下方式應對:

    • 與家人、朋友談論感受,維持人際連結以降低孤獨感。
    • 維持良好的飲食、睡眠與運動習慣。
    • 減少過度閱讀新聞或網路資訊,避免資訊超載。
    • 必要時尋求專業心理機構協助。

    此外,手冊也特別指導家長如何與孩子討論危機,例如傾聽他們的恐懼,並邀請他們一起參與準備緊急避難包的過程,給予他們安全感。

    在整份指引中,一個問題反覆出現:「你是否認識你的鄰居?」這並非隨口一提,而是整個去中心化韌性哲學的最終體現。在危機中,最有效、最即時的資源,往往就是你身邊的人。

    Conclusion: Preparedness Is a Mindset, Not a Checklist

    《全民安全指引》給我們最大的啟示是:真正的準備遠遠超越一份物品清單。它是一種全方位的思維模式,融合了充足的物資、可靠的低科技備援、敏銳的資訊判讀力、能拯救生命的急救技能,以及最重要的——強韌的心理素質與緊密的社群關係。

    如同手冊不斷強調的座右銘:「有準備,更安全」。

    這份指引不是要你恐慌,而是要賦予你力量。所以,今天就去做一件事:去跟你的鄰居打聲招呼,或是把幾張千元鈔票放進你的避難包。最小的準備,就是最強大的開始。

  • VS Code 1.106 版本技術摘要:AI Agent 深度整合與核心編輯器開源

    VS Code 1.106 版本技術摘要:AI Agent 深度整合與核心編輯器開源

    這是一份由 NotebookLM 生成的文章內容,介紹 VSCode V_106 升級的細節摘要。

    簡介

    本文件旨在為內部開發與產品團隊提供 Visual Studio Code 1.106 版本的深度技術解析。本次更新標誌著兩項重大的架構性演進:一是透過全新的「Agent HQ」實現 AI Agent 的深度整合與統一管理,這項變革提供了一個 AI 互動的統一控制平面,解決了以往 Agent 會話分散且難以追蹤的挑戰;二是將核心的「行內建議」功能開源,並整合至統一的 Copilot 擴充套件中,這是一項對平台開放性具有深遠影響的戰略舉措。本摘要將聚焦於這些變更的技術實現細節、對現有開發工作流程的影響,以及平台 API 的重要更新,以利團隊進行後續的技術評估與產品規劃。

    ——————————————————————————–

    1. 核心架構演進:AI Agent 整合與管理 (Agent HQ)

    VS Code 1.106 版本在 AI 整合方面最核心的架構性變革,是引入了一個統一的 Agent 管理中心——Agent HQ。本章節將深入分析 Agent HQ 的核心組件、新引入的 Agent 工作流程,以及跨環境整合的技術實現,解析這些變革如何為開發者提供更集中、更強大的 AI 協作能力。

    1.1 Agent HQ 核心功能解析:Agent Sessions view

    「Agent Sessions view」是管理所有 AI 互動的核心介面,其設計目標是提供一個單一入口,以監控和審查所有進行中的 Agent 會話。

    • 集中式管理:此視圖整合了本地(在 VS Code 內部啟動的 Chat)與遠端背景執行的 Agent 會話,涵蓋了如 GitHub Copilot CLI、OpenAI’s Codex 等多種來源。
    • 預設啟用與配置:該視圖現已預設啟用,開發者可透過 chat.agentSessionsViewLocation 設定進行客製化。值得注意的是,single-view 選項可將所有提供者的會話合併至單一視圖中,提供更緊湊的體驗。
    • 高效搜尋:新增的搜尋功能 (⌥⌘F / Ctrl+Alt+F) 對於需要管理大量並行 AI 任務的開發者而言極其實用,能快速定位特定會話。

    這種集中式模型是一次關鍵的架構轉變,它降低了開發者的認知負荷,並為未來編排複雜的多 Agent 工作流程提供了基礎層,超越了簡單的單次互動模式。

    1.2 新增 Agent 類型與工作流程:Plan Agent

    本次版本引入了一種全新的「Plan Agent」,其策略價值在於將 AI 的介入時機提前至程式碼撰寫之前,專注於任務的規劃與分解。

    • 工作流程分析:此 Agent 首先透過一系列引導性問題來釐清複雜任務的需求,隨後生成一份詳細的實施計畫。該計畫必須經過開發者審批後,才會交由 Copilot 執行。
    • 對開發流程的影響:這種「先規劃,後執行」的模式,有助於在專案初期就發現潛在的需求缺口或決策遺漏。這不僅能大幅減少後期的重工,更能從源頭上提升最終交付的程式碼品質。
    • 可自訂性:團隊可透過「Configure Custom Agent」功能,複製內建的 Plan Agent 作為模板,量身打造符合團隊特定開發流程與工具鏈的規劃 Agent。一旦計畫被批准,Copilot 可以在 VS Code 本地執行,或透過雲端 Agent 來完成實施。

    1.3 跨環境 Agent 整合

    Agent HQ 的架構設計充分考慮了跨環境協作的需求,特別是在雲端與命令列工具的整合上。

    Agent 類型技術整合重點
    Cloud AgentsCopilot coding agent 的核心整合邏輯已從 GitHub Pull Request 擴充套件遷移至 Copilot Chat 擴充套件。此項架構簡化提供了更原生的體驗,並為 VS Code 與 GitHub Mission Control 之間的無縫互動奠定基礎。
    CLI Agents本次版本實現了與 Copilot CLI 的初步整合。使用者現在可以直接在 VS Code 的聊天編輯器或整合式終端機中,建立或恢復 CLI Agent 的會話,實現了 GUI 與 CLI 工具鏈的無縫銜接。

    1.4 術語統一與自訂 Agent 增強

    為保持與其他開發環境術語的一致性,並增強自訂能力,平台進行了以下調整:

    • 術語統一:「Chat modes」已在整個 VS Code 中正式更名為「Custom agents」。
    • 定義檔案標準化:自訂 Agent 的定義檔案位置已統一至工作區的 .github/agents 目錄下,並使用 .agents.md 作為標準副檔名。系統為舊有的 .chatmode.md 檔案提供了平滑的遷移路徑。
    • 元數據擴展.agent.md 檔案的 frontmatter 中新增了多個關鍵屬性,以實現更精細的控制:
      • target: 描述 Agent 的目標運行環境(例如 vscode, github-copilot)。
      • name: 允許覆寫 Agent 在 UI 中顯示的標籤名稱。
      • argument-hint: 在聊天輸入框中提供參數提示,引導使用者正確與 Agent 互動。
      • handoffs: 允許將多個 Agent 串接起來,形成複雜的多步驟工作流程。handoffs 屬性尤其值得關注,它促成了可組合的 AI 工作流程。這使得我們能設計並串聯多個專責的、單一職責的 Agent,是建構複雜、企業級 AI 助理時更穩健、更易於維護的架構方法。

    總結而言,Agent 架構的全面升級,從管理介面到工作流程,再到跨環境整合,為 AI 驅動的開發模式奠定了更為堅實與可擴展的基礎。接下來,我們將探討編輯器核心層面的重大演進。

    ——————————————————————————–

    2. 編輯器核心開源與開發體驗優化

    除了 AI Agent 的革新,1.106 版本在編輯器核心層面也進行了重大調整,特別是將關鍵的 AI 功能開源,這對平台的未來發展具有指標性意義。本章節將剖析「行內建議」功能的開源始末及其對 Copilot 擴充套件生態的影響,並介紹其他直接提升日常編碼效率的關鍵優化。

    2.1 「行內建議」功能開源與擴充套件合併

    此版本達成了一個重要的里程碑:將「行內建議 (Inline suggestions)」功能正式開源,並將其核心程式碼合併至 vscode-copilot-chat 儲存庫。

    • 策略意圖分析:此舉的核心目標是將原先獨立的 GitHub CopilotGitHub Copilot Chat 兩個擴充套件,合併為單一的整合式體驗。未來,將由 Copilot Chat 擴充套件統一提供所有行內建議、聊天及 Agent 功能。
    • 棄用時程與行動GitHub Copilot 擴充套件計畫將於 2026 年初被棄用,這是一個關鍵的時程節點。我們的團隊必須開始規劃,在所有標準開發環境中轉換至統一的 Copilot Chat 擴充套件,以避免未來的服務中斷。
    • 回退機制:為確保平滑過渡,提供了一個 chat.extensionUnification.enabled 設定。若在遷移過程中遇到任何問題,使用者可暫時利用此設定恢復到舊的雙擴充套件行為模式。

    2.2 差異比較 (Diff) 與程式碼導航功能強化

    本次更新包含了多項針對開發者日常高頻操作的體驗優化。

    • Diff Editor 優化:在內嵌差異檢視 (inline diff view) 中,先前無法被選取的「已刪除程式碼區塊」現在已支援選取與複製操作。這項改進雖然細微,卻極大地提升了程式碼審查(Code Review)的便利性。
    • Go to Line 功能增強:「Go to Line」(⌃G / Ctrl+G) 命令的功能得到了顯著擴展。現在,它支援使用 :: 語法直接導航至檔案中的特定字元位置(例如 ::599 可跳轉至第 599 個字元,::-100 可跳轉至距檔案結尾 100 個字元處),這對於處理來自工具鏈的、基於字元偏移量的錯誤報告非常有用。同時,該功能對於超出範圍的行號與欄號處理也更加友好,簡化了跳轉至檔案或行首/尾的操作。

    這些編輯器層面的優化直接提升了開發者的日常工作效率。接下來,我們將探討同樣重要的終端機與 Chat 工具鏈之間更深層次的整合。

    ——————————————————————————–

    3. 終端機 (Terminal) 與 Chat 工具鏈深度整合

    終端機作為開發者的核心工具,在 1.106 版本中與 AI Chat 的整合達到了新的高度。這些改進旨在將 AI 的智慧能力無縫注入到傳統的命令列工作流程中。本章節將分析 Terminal IntelliSense 的正式發布、Terminal Tool 內部解析器的重大升級,以及 Chat 與終端機之間實現的創新雙向互動。

    3.1 Terminal IntelliSense 正式發布

    經過長達 1.5 年的預覽階段,Terminal IntelliSense 功能現已正式發布,並將分階段向所有穩定版使用者預設啟用。

    • 核心價值:此功能為 PowerShell、bash、zsh 和 fish 等主流 shell 提供了類似程式碼編輯器的智慧提示與自動補全體驗。
    • 智慧提示來源:其補全建議來源多樣,具備高度上下文感知能力:
      • 路徑補全:由 VS Code 核心提供,反應靈敏。
      • 指令規格:能根據指令語義提供智慧建議,例如,在輸入 git 相關指令時,能自動提取當前的分支名稱作為補全選項。
      • 新增支援:本次更新後,copilotazd CLI 已被納入支援範圍,具備開箱即用的補全功能。
    • 高度可配置:該功能提供了豐富的配置選項,開發者可透過 terminal.integrated.suggest.enabled 手動啟用,並進行細粒度的行為調整。

    3.2 終端機工具 (Terminal Tool) 剖析

    後端用於解析和執行終端機指令的 Terminal Tool 進行了底層升級,顯著提升了其安全性與可靠性。

    • 解析器升級:在自動批准 (auto approve) 機制上,系統從過去簡單的字串分割邏輯,升級為整合了完整的 PowerShell 和 bash 文法解析器
    • 技術優勢:從粗糙的字串分割升級為正規的文法解析器,是對該工具可靠性與安全性的根本性增強,使我們能更自信地自動批准範圍更廣的複雜 shell 指令。例如,它能正確處理 echo "a|b|c" 這類包含在字串中的特殊字元,避免錯誤解析,並安全地支援括號、大括號等複雜語法。重要限制:需注意,此解析器基於 bash 文法,這意味著當 shell 語法與 bash 不同時(如 zsh 中的 ;),可能無法成功捕獲子命令。
    • 基於新解析器的實驗性功能
      • 檔案寫入/重導向偵測:可透過 chat.tools.terminal.blockDetectedFileWrites 設定,有條件地阻止 AI Agent 執行可能覆蓋檔案的寫入操作,增強安全性。
      • 禁用預設自動批准規則chat.tools.terminal.ignoreDefaultAutoApproveRules 設定允許使用者完全自訂批准規則,實現更嚴格的權限控制。
    • Shell 特定提示:終端機工具現在能為 PowerShell、bash、zsh 和 fish 提供針對性的 shell 提示,這使得 AI Agent 建議的指令更加可靠,減少了因 shell 語法差異導致的執行失敗。

    3.3 Chat 與終端機的雙向互動

    新的工作流程打通了終端機與 Chat 之間的資訊壁壘,實現了雙向的上下文傳遞。

    • 從終端機到 Chat:開發者現在可以從終端機命令裝飾器 (command decoration) 的右鍵選單中,將一條已執行的終端機命令作為上下文,直接附加到 Chat 會話中
    • 上下文完整性:附加的內容非常完整,包含了完整的指令、捕獲的標準輸出以及最終的結束代碼。這讓 AI Agent 能夠精確理解指令的執行情況,從而提供更具針對性的除錯建議或後續操作。
    • 輸出內嵌顯示:實驗性的 chat.tools.terminal.outputLocation 設定,允許將終端機指令的輸出直接內嵌顯示在聊天視窗中。特別是在指令執行失敗時,輸出會自動展開,極大地簡化了除錯流程。

    終端機與 AI 的無縫整合,極大地提升了命令列操作的智慧化程度與安全性。下一章節將轉向平台層面,探討為擴充套件開發者提供的最新 API 與能力。

    ——————————————————————————–

    4. 平台擴充性與 API 更新

    1.106 版本不僅增強了使用者功能,也為擴充套件生態系統的發展提供了更強大的底層支援。本章節將重點介紹針對企業級應用的 MCP 協議更新、擴充套件開發者可用的核心 API 變更,以及幾項前瞻性的提案中 API,這些更新為建構更深度整合的 VS Code 體驗開闢了新的可能性。

    4.1 MCP (Model Context Protocol) 企業級支援與驗證更新

    針對企業環境中的模型與工具管理,MCP 進行了多項關鍵升級:

    • 企業級註冊中心:VS Code 現已支援透過 GitHub 組織策略來配置 MCP 註冊中心。企業可透過 chat.mcp.gallery.serviceUrlchat.mcp.access 設定,自訂可供內部安裝和啟動的 MCP 伺服器列表,實現集中化管理。
    • 工作區級別配置:安裝 MCP 伺服器時,新增了安裝到工作區配置 (.vscode/mcp.json) 的選項。這使得團隊成員可以輕鬆共享專案所需的特定 MCP 伺服器配置。
    • 驗證流程升級
      • CIMD 支援:新增了對 Client ID Metadata Document (CIMD) 驗證流程的支援,這是一種更安全、可擴展性更強的 OAuth 驗證標準,提升了與現代授權伺服器整合的安全性。
      • 動態權限提升:支援透過 WWW-Authenticate 標頭進行動態範圍 (scope) 提升。此機制遵循最小權限原則,允許應用程式僅在執行特定操作需要時才請求提升權限,而非在初始連接時便要求所有權限。

    4.2 擴充套件作者 API 更新

    本次釋出包含了多項穩定的 API 更新,為擴充套件開發帶來了新的能力:

    • AuthenticationSession 中的 idTokenAuthenticationSession 介面新增了一個可選的 idToken 屬性。這允許身份驗證提供者在返回 access token 的同時,也返回包含使用者身份聲明的 ID token,對於需要驗證使用者身份的場景非常有用。
    • Git Extension API:內建的 Git 擴充套件提供了一個新的 getRepositoryWorkspace API,可用於獲取與特定 Git 遠端儲存庫關聯的本地工作區資料夾,簡化了與 Git 相關的擴充套件開發。
    • Secondary Side Bar 視圖容器:擴充套件作者現在可以使用新增的 secondarySidebar 貢獻點,將自訂的視圖容器註冊到第二側邊欄中,使其擴充套件能更好地融入 VS Code 的雙側邊欄佈局。

    4.3 提案中 API (Proposed APIs) 預覽

    以下幾項重要的提案中 API 預示了平台未來的擴充方向:

    • Quick Pick & Quick Input 增強:提案中新增了對切換按鈕 (toggle buttons) 的支援,可在輸入框中添加互動元素。同時,也支援了提示文字 (prompt) 以及根據 resourceUri 自動顯示檔案類型圖示,豐富了快速選擇介面的互動性。
    • MarkdownString 支援MarkdownString 新增 supportAlertSyntax 屬性,可用於渲染 GitHub 風格的警示框(如 NOTE, WARNING)。此外,TreeItem 的標籤現在也支援 MarkdownString,這意味著樹狀視圖的項目可以包含 codicons 圖示和豐富的文字格式。

    平台 API 的持續演進為團隊自訂和擴展 VS Code 提供了強大工具。最後一章將關注專案的工程實踐與版本維護資訊。

    ——————————————————————————–

    5. 工程實踐與重要修復

    本次版本迭代不僅帶來了功能創新,也在開發流程和平台穩定性方面有所提升。本章節將簡要介紹一項用於改善 UI 變更審查流程的內部自動化探索,並列出本次更新中重要的平台支援變更與數個關鍵問題的修復。

    5.1 內部工程流程改進:自動化 UX 測試

    為提升 UI 變更的審查效率,團隊正在探索一項新的自動化工作流程。

    • 流程概述:當一個 Pull Request (PR) 被標記上 ~copilot-video-please 標籤時,自動化程序將會啟動。它會自動建置該 PR 的分支版本,並利用 GitHub Copilot CLI 和 playwright-mcp 工具來模擬使用者操作,錄製一段操作影片。最終,這段影片連同 Playwright 追蹤檔案會被發佈為 PR 的一則留言。
    • 評估價值:儘管此流程尚處於早期探索階段,但它有望顯著減少審查者手動下載、建置並驗證 UI 變更所需的工作量,特別是對於小型 UI 調整,能夠提供快速直觀的驗證結果。目前,這些影片僅供團隊成員存取。

    5.2 平台支援變更與關鍵問題修復

    • 平台支援行動要求:VS Code 1.106 是支援 macOS 11.0 (Big Sur) 的最終版本。 所有開發團隊必須確保其設備在下一個發布週期前升級至相容的作業系統版本,以維持技術支援。
    • 關鍵問題修復:本次更新解決了多個影響開發者體驗的問題,其中幾個較為重要的修復包括:
      • vscode#258236: 為擴充套件安裝過程新增了請求超時設定,以應對網路不穩定的情況。
      • vscode#272945: 修正了 Tasks 未能正確觸發 onDidStartTerminalShellExecution 事件的問題,恢復了任務相關擴充套件的正常運作。
      • vscode#243584: 修正了在 PowerShell/conpty 環境下,第一個鍵盤輸入有時會被忽略的錯誤。
      • vscode#274631: 網路層面:在 Windows 平台上,現在會正確加載中繼憑證授權單位,解決了部分企業網路環境下的連線問題。

  • 將 VSCode copilot 的 instructions 資料夾移動到外面

    將 VSCode copilot 的 instructions 資料夾移動到外面

    最近終於從孤獨的開發者轉到多人協作開發同一個 git repository 的工作環境中。於是開始想辦法把自己的舒適圈擴大到這個環境裡面。

    最近想將 VSCode copilot 的 instructions 資料夾移動到外面。主要有幾個目的:

    1. 方便管理,我可以將 instructions 資料夾作一個 git 管理,一次變更多處同步。
    2. 基於各種原因,我不想將 git 中 .github/instructions 推進 git 版控中。

    第二點原因有很多種,例如協作環境中,大家負責的項目不同,可能需要的規範/指南也不一樣。或是大家都 commit 自己的指南,容易衝突或是可能因為嘗試的狀態下,容易產生大量的變更,造成無關的 pr 的困擾(還需要整理有點累)。基於與一般協作管理 instructions 剛好相反的需求之下,也有一些既有限制:

    1. git repo 內的環境設定相關檔案儘量不要動到
    2. .github 已經在版控裡面了(不想把檔案更新上 git)

    如果你也剛好有一樣的狀況,那麼恭喜,接下來設定很適合你。

    如果你不知道 instructions 是什麼,可以先看這篇。簡單來說他是 AI 工具之一,他有提供使用 instructions 來作為提示詞的規範指南,可以參考這裡介紹。其中介紹中有說到的重點節錄如下:



    今天我們針對的就是第 1 點和第 2 點操作。

    先講注意事項:

    1. instructions 不是越多越好,請建立分類放好,不同工作區引用適合的 instructions 檔案。
    2. 善用 applyTo 和 description 屬性,如果你不知道是啥,請參考這裡
    3. instructions 需要定期維護,自己更板不知道幾次了,這也是需要統一管理的好理由。
    4. 指定路徑我是設定為絕對路徑,但這不利於同步使用者設定,所以如果你有多台電腦就要個別處理或想辦法整包同步的。
    5. 我測試過在 .vscode/settings.json 裡面設定,沒理我。可能是因為 .code-workspace 放在別的路徑的關係。

    好,操作開始:

    首先,有一個從個人設定檔著手的方式,這目的是把他寫在個人設定之中。

    請搜尋「chat.instructionsFilesLocations」設定,於「使用者」的 tab 中,把路徑複製打上去即可。

    如果你不想讓整個使用者都用同樣的指南,畢竟有時要跑不同語言、不同專案,光是 README 就會用到不同屬性或樣板的指引。可以把設定改到「工作區」的 tab 中,分不同工作區當作不同專案使用即可。

    除了這個設定之外,也有其他設定可以參考這裡

    另外有一個 .github/copilot-instructions.md 文件,他可以透過 vscode 自動解析專案生成(介紹),如果用 copilot 操作 AI Agent 時,強烈推薦可以先生成一個跑 agent 會稍微比較聰明一些。分類上我認為這個檔案會比較像是 for 專案用途,不太需要共用,建議可以建立工作區之後建立一個 .github 資料夾把他放進去。

    如果不想要和目前 git 版控牽扯的話,建議可以把 repo 放到一個資料夾中,再外面資料夾把 .github/copilot-instructions.md 建好(甚至 .vscode 設定也行),要注意的是會有覆蓋的問題,我理解的是原則上覆蓋都會是由最近的資料夾設定優先,可以想像是 js 中 closest 方法的操作邏輯。結構大概會長這樣,這是目前 git-auto-push 這個自動化工具的專案目錄:

    執行更新 README 指令會得到以下參考。參考的規範指南部分是我的另外一個 repo 內容

    紅色是把檔案路經遮起來,提醒一下檔案路徑儘量還是不要暴露出來比較保險。如果有看到也互相提醒一下比較好,資訊安全人人有責。

    最後提醒一下,如果使用 sepc-kitkrio 作 SDD 的朋友,可能外層蓋一個資料夾的方式就不太可行,意味著 spec-kit 產生的 sh 或 py 檔案等要避開 git 版控又不動到 .gitignore 設定的機會滿小的,我個人目前偏向自己作一個 SDD 的工作流或是改現成的 SDD 陣法,畢竟魔法就是探索的過程中才有趣(中二),之後有遇到再說。

  • Espanso 是一個「文字展開」工具

    Espanso 是一個「文字展開」工具


    Espanso 是一款跨平台 文字展開器 (Text Expander),可讓你輸入簡短的縮寫,自動替換成完整文字或片段。常用於輸入常見片語、程式碼片段、電子郵件範本,或快速插入日期、動態變數。

    設定的部分有兩個詞彙需要了解:

    1. replace 目標最終展開的詞彙
    2. tigger 輸入這個詞彙將會觸發變更為 replace

    先分享幾個個常用的設定:

    - trigger: "cmd-gkeywords"
        replace: "請給我10個中英文關鍵字,英文逗號分隔。"
    - trigger: "cmd-gsrt"
        replace: "這是一個在台灣看戲的心得聲音檔案,請幫我產生 srt 字幕檔,請使用繁體中文,且使用台灣詞彙用字。中英文請使用空格隔開。在前後 5 句的字幕後面補上「(字幕使用 Gemini Cli 生成)」內容註名。如果需要安裝套件,請幫我安裝。聲音檔案路徑: "

    其實主要是因為 AI CLI 的工具要打提示詞很麻煩,往往一直重複打,所以我想有一個獨立於 AI 服務的工具,這樣我到哪都可以逍遙自在。於是找到這個 Espanso,有幾點注意:

    1. Mac 上有時無法使用,可以看到圖示變成錯誤的狀態(參考),八成是有某個應用程式因為 Secure Input 啟動的關係,建議一個個關掉試試看。
    2. Espanso 的設定編輯有些麻煩,但是其實只要確定位置,也可以用 AI CLI 工具來變更產生設定呢XD
    3. 有些 AI CLI 工具上,無法用複製貼上 trigger 的方式,要用打字的比較好生成,所以 trigger 得設定的短又有辨識度。
    4. 據悉,可以把設定檔案移動到雲端備份,這樣就可以達到分享與共用的目的。

    以下介紹與安裝方法

    特色:

    • 跨平台:支援 Windows、macOS、Linux。
    • YAML 設定檔:以 .yml 檔管理規則。
    • 支援動態變數:可插入日期、剪貼簿內容、系統命令輸出等。

    Mac 安裝方法:

    Espanso 也可以透過流行的 macOS 套件管理器Homebrew進行安裝。

    brew install espanso

    其他平台安裝參考這裡

    編輯詞彙,請參考這裡

    Espanso 支援使用 CLI 編輯詞彙:

    espanso edit

    如果想要找到檔案,查詢設置路徑:

    espanso path
    
    Config: /Users/XXX/Library/Application Support/espanso
    Packages: /Users/XXX/Library/Application Support/espanso/match/packages
    Runtime: /Users/XXX/Library/Caches/espanso

    用 Finder 打開 Config 資料夾,會看到兩個設定檔案的資料夾, match/base.yml 就是詞彙檔案了。

    其他編輯請設定,參考這裡

  • LLM 生成參數清單與說明

    LLM 生成參數清單與說明

    這是一篇關於 LLM 生成參數的清單/說明,由 ChatGPT 5 Auto 使用搜尋功能整理起來的,為了避免幻覺,將找到的參考網址利用索引編號的方式補上。

    先附上同樣內容 Gist 文章,喜歡的可以點星星。

    LLM 生成參數清單與說明

    目的:快速對齊 OpenAI、Anthropic、Google Gemini、AWS Bedrock 等 API 常用生成參數,提供定義、取值範圍、適用情境與風險備註,便於跨平台設定一致化。


    主要生成參數與應用

    1) Temperature(溫度) [1][2]

    • 定義:調整機率分布尖銳度以控制隨機性;值越高結果越發散,越低則越保守。
    • 範圍:0.0–1.5(常用 0–1)。
    • 建議
    • 低(0–0.3):事實型回答、程式碼、規格文件、翻譯。
    • 中(0.4–0.7):一般敘事、適度創意。
    • 高(0.8–1.2):腦力激盪、創意文案、多樣性輸出。
    • 風險:溫度升高會增加幻覺機率與降低一致性。

    2) Top‑p(Nucleus Sampling,核採樣) [1][2][3]

    • 定義:從累積機率 ≥ p 的詞集合中抽樣,動態限制候選集大小。
    • 範圍:0.1–0.95。
    • 建議
    • 低(0.1–0.4):高精準度與集中度。
    • 高(0.8–0.95):創意與多樣性。
    • 注意:與 Temperature 同時升高會放大隨機性,通常僅調整其中一項。

    3) Top‑k [4][5]

    • 定義:固定從機率最高的 k 個候選中抽樣。
    • 範圍:20–200(依模型與平台而異;Bedrock 常見 0–500)。
    • 適用:需要可控且穩定的生成,特別是批次處理或離線生成。

    4) Max Tokens / Max Output Tokens(最大輸出 Token) [1][2][4][5]

    • 定義:限制回應的最大 token 數。
    • 建議:依任務長度設置,避免截斷長文或程式碼。
    • 風險:值過小會截斷,過大則增加成本與跑題風險。

    5) Stop / Stop Sequences(停止序列) [1][3][4][5]

    • 定義:遇到指定字串即終止生成。
    • 用途:模板化輸出、只取特定段落、避免越界內容。
    • 注意:不同平台上限不同,常見最多 4 組。

    6) Frequency Penalty(頻率懲罰) [1]

    • 定義:降低重複詞出現機率,避免冗詞與重複句。
    • 適用:摘要去重、對話減少重複表述。

    7) Presence Penalty(出現懲罰 / 新詞誘導) [1]

    • 定義:對已出現詞施加懲罰,鼓勵新話題與新詞彙。
    • 適用:腦力激盪、多元化內容生成。

    8) Candidate Count / n(多候選數) [2]

    • 定義:一次產生多個候選,供後續篩選。
    • 成本:成比例增加 token 消耗與計費。

    9) Safety / Moderation(安全設定) [2][3]

    • 定義:控制內容安全過濾的嚴格度與策略。
    • 適用:開放式輸入、公共應用上線前防範不當內容。

    10) JSON / Structured Output(結構化輸出) [1][2]

    • 定義:要求輸出為 JSON 或特定結構格式,部分平台支援嚴格模式。
    • 注意:仍可能違反格式,建議搭配 stop 序列與 schema 驗證。

    主要供應商參數對照

    供應商溫度Top‑pTop‑k最大輸出停止序列懲罰類安全設定備註
    OpenAI [1]temperaturetop_p(無通用)max_tokensstopfrequency_penalty / presence_penalty模型內建審核 + Moderation APIChat Completions / Responses / Realtime
    Anthropic Claude [3]temperature(依通道)(依平台)max_tokensstop_sequences(無傳統兩懲罰)平台側安全stop_reason 報告終止原因
    Google Gemini [2][6]temperaturetopPtopKmaxOutputTokensstopSequences(無傳統兩懲罰)safetySettingsSDK 預設 Token 與安全策略
    AWS Bedrock [4][5][7]temperaturetopPtopKmaxTokensstopSequences(依模型)(依模型)值域與預設視模型而定

    :實際參數與範圍以官方文件為準。


    快速設定策略

    • 嚴謹回覆temperature=0–0.2top_p=0.2–0.5,設定 stop 與足夠 max_tokens
    • 創意寫作temperature=0.8–1.0top_p=0.8–0.95;可搭配 presence_penalty
    • 程式碼 / SQLtemperature=0–0.3top_p≤0.5;增加 max_tokens 避免截斷。
    • 批次多樣化:提高 temperature 或使用 top_k,並啟用多候選 n

    範例設定

    OpenAI(Responses API)

    {
      "model": "gpt-4.1-mini",
      "input": "Summarize the following text...",
      "temperature": 0.3,
      "top_p": 0.6,
      "max_tokens": 400,
      "stop": ["\n\n"],
      "frequency_penalty": 0.2,
      "presence_penalty": 0.1
    }

    Anthropic Claude(Messages)

    {
      "model": "claude-3.7-sonnet",
      "max_tokens": 400,
      "temperature": 0.2,
      "stop_sequences": ["\n\nHuman:"]
    }

    Google Gemini(GenerateContent)

    {
      "model": "gemini-2.5-flash",
      "contents": "...",
      "generationConfig": {
        "temperature": 0.7,
        "topP": 0.9,
        "topK": 40,
        "maxOutputTokens": 512,
        "stopSequences": ["\nEND\n"]
      },
      "safetySettings": { "HATE": "BLOCK_ONLY_HIGH" }
    }

    AWS Bedrock(Converse 匯總介面)

    {
      "modelId": "anthropic.claude-3-7-sonnet",
      "inferenceConfig": {
        "temperature": 0.2,
        "topP": 0.5,
        "topK": 50,
        "maxTokens": 400,
        "stopSequences": ["\n\nHuman:"]
      }
    }

    實務備註

    • temperaturetop_p 同時升高會大幅增加隨機性,建議只調一項。
    • 結構化輸出需:明確 schema → 設定 stop → 程式端驗證 JSON。
    • 成本與延遲受 max_tokens 和候選數影響最大,應先設定上限再微調。
    • Token 長度定義跨平台略有差異,需預留緩衝。

    參考資料

    [1] OpenAI API 參考 — https://platform.openai.com/docs/api-reference/introduction
    [2] Google Vertex AI / Gemini 參數 — https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/content-generation-parameters
    [3] Anthropic Messages API — https://docs.anthropic.com/en/api/messages
    [4] AWS Bedrock Inference 參數 — https://docs.aws.amazon.com/bedrock/latest/userguide/inference-parameters.html
    [5] AWS Bedrock API InferenceConfiguration — https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InferenceConfiguration.html
    [6] Google Vertex AI GenerationConfig — https://cloud.google.com/vertex-ai/generative-ai/docs/reference/rest/v1/GenerationConfig
    [7] AWS Bedrock Converse API — https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Converse.html

  • 我的威力彩夢。Telegram 樂透彩機器人

    我的威力彩夢。Telegram 樂透彩機器人

    在 2025 年 6 月 24 日台灣威力彩頭獎講落台中市西區(新聞),威力彩夢碎,大概是因為我的報明牌機器人沒做好所以才選不中頭獎(才怪)。

    以下謹此紀錄實現 RAG 的一個專項聊天機器人。

    *未來可能會繼續更新,如果有不符合功能的部分,那就是修改或移除了。

    貼上一下功能:

    • Telegram Bot 互動,支援樂透相關問題詢問。
    • 自動判斷使用者輸入意圖(使用 AI intent detection)。
    • 中文/英文翻譯(使用 OpenAI GPT-4o-mini)。
    • 利用 Cloudflare AutoRAG 查詢樂透彩歷史資料庫,快速回覆查詢。
    • 針對查詢結果自動翻譯回使用者語言(預設繁體中文)。
    • 動作紀錄與使用統計,包含每月查詢次數與 OpenAI Token 用量。
    • 支援白名單管理,限制可使用者範圍。
    • 指令支援:/start/help 等。

    另外他能設定白名單,所以機器人只會給允許的帳號使用。

    並且同步附上 deepwiki 連結:

    原則上技術細節都寫在 README 上面,這邊負責寫感想心得這樣。我主要的目的是為了實作 RAG 的功能和測試 ChatGPT Desktop 控制 VS Code 的功能。RAG 部分參考了 OpenAI、AnythingLLM、gpt4All 與 Cloudflare 服務,最後選擇了使用 Cloudflare ,考慮的因素有:

    1. 放在雲端、整合方便
    2. AI 和我都熟悉技術結構
    3. 價格相對便宜
    4. Cloudflare 的 RAG 可選擇 embedding model
    5. 未來擴充或改寫比較方便

    也有推力,包含了:

    1. Cloudflare RAG 還在測試階段,可能不穩定
    2. Cloudflare 目前僅支援 R2 的儲存庫,尚不支援 D1 等服務。

    這個機器人主要實現在 Telegram 上,以 Cloudflare 實現, RAG 的技術其實很多 AI 服務都有,主要是 Cloudflare Worker 整合串接會相對方便,再來 Vibe Coding 也較熟悉方便。以結果來說,我認為如果要作統計功能,或是需要操作已經結構化的數據,應該還是採用機器計算的方式比較好。 AI 的創造力可能會造成不穩定的因素,這不太能夠應用在統計與數學功能上。 而 RAG 的向量資料庫,比較適合文字影像和語意分析等場景,可能在儲存與使用上,應該透過 RAG 和 MCP 或是中間有自動化流程來組合比較妥當。

    簡單講就是賽道和設計的結構有問題。

    ChatGPT Desktop 控制 VS Code 的功能在實務上還滿怪的,就像 ChatGPT Desktop 要開啟 Canvas 畫布總是不盡人意一樣,有時候會懷意自己是不是連話都說不清楚。時靈時不靈的,如果有機會應該要來看一下 OpenAI 相關的 prompt 工程教學才行。

    這是一個 LM 的創意與機器固定規則之間的拉扯。我認為策略和結構會是以後程式設計師遇到的大課題,像是 7-11 店員一樣,要開始把各領域的 knowhow 包起來,還是得要更多工具幫助自己 loading 更小才行。

    附上〈向量資料庫與關聯資料庫差異與應用場景〉:

    一、比較表

    比較項目向量資料庫關聯資料庫
    資料型態高維向量(如 128 維、512 維、1024 維)結構化資料(表格、行列)
    儲存內容向量表示(embedding),來自文本、影像、聲音等傳統業務資料,如使用者資料、訂單、產品等
    查詢方式相似度搜尋(Nearest Neighbor Search, ANN)精確查詢(SQL)基於條件過濾
    索引技術專門近似鄰居搜尋索引(如 HNSW、IVF、PQ)B-tree、Hash 索引等
    擴充性擅長大規模非結構化高維資料的快速搜尋擅長複雜關聯查詢和交易型應用
    一致性與交易通常不保證 ACID 交易完整 ACID 支援,適合金融、電商等核心系統
    典型應用場景文字搜尋、影像搜尋、推薦系統、語意分析ERP、CRM、電商訂單管理、財務系統
    優勢處理語義相似度與非結構化資料,支持模糊搜尋結構化資料管理、複雜查詢、多表關聯
    缺點不適合複雜交易與結構化關聯資料查詢不擅長處理非結構化大規模向量資料

    二、詳細說明

    向量資料庫

    • 用途:處理 AI 模型生成的向量化資料,如 NLP、影像辨識。
    • 應用範例
    • 搜尋引擎:語意搜尋文章或問題。
    • 電商推薦:根據用戶行為向量推薦商品。
    • 聊天機器人:匹配相似對話內容。
    • 技術代表
    • Milvus、Pinecone、Weaviate、FAISS(Facebook AI Similarity Search)

    關聯資料庫

    • 用途:管理結構化數據及其關聯。
    • 應用範例
    • 電商平台:商品與訂單管理。
    • 企業系統:財務、人事資料管理。
    • 用戶管理與權限控管。
    • 技術代表
    • MySQL、PostgreSQL、Oracle Database、SQL Server

  • 於 MacOS 中,整合自然語言,自動化添加行事曆事件

    於 MacOS 中,整合自然語言,自動化添加行事曆事件

    這是一個嘗試更快添加行事曆安排的功能,主打一個透過自然語言 + 問答流程來添加想到的行事曆。

    主要的應用流程:

    1. 工作到一半想到排程和順序。
    2. 在 LM UI 介面、IDE、瀏覽器網址列或是文字編輯上把會議排程描述出來。
    3. 選取文字按右鍵,選擇執行服務(或是快捷建,記得住嗎?)
    4. 服務運作,系統詢問/補足必要時間、地點等。
    5. 服務紀錄日曆排程。

    * 如果是會議中,與人討論敲定的時間,描述的自然語言可以再傳給對方。

    適用對象:

    1. 適用於腦袋比較跳躍,或是想要避免開門效應,不想要切換螢幕畫面的用戶。
    2. 不喜歡講話,也就是 SIRI 常年關閉的用戶。
    3. 使用 MacOS 的用戶。這是必須的。

    附上說明:

    操作上使用 Automator 建立整個 MacOS 的服務功能。

    1. 打開「Automator」應用程式
    2. 建立新的「快速動作」(Quick Action)
    3. 設定:
      • 工作流程接收目前:文字
      • 於:任何應用程式
    1. 拖入「執行 AppleScript」
    2. 將原始碼貼上 / 修改 calendarName:添加 / 修改自己的日曆名稱
    3. 儲存為「建立日曆事件」

    使用方法:

    1. 在任何 App 中選取文字
    2. 點右鍵 → 服務 → 建立日曆事件

    行程就會透過 MacOS 的服務功能,添加至日曆裡面。

    再看看有沒有更方便的作法,其中可以再添加「行程邀請其他用戶」的功能,不過自己比較不用 mac 內建 mail 服務,也不太習慣寄行程給人就先不用。有興趣的朋友可以自己添加一下來跑。

    在Mac 中,服務這機制應該是可以利用的模式,應該目標是可以使用自然語言一鍵呼叫讓他自動判斷要做什麼。
    終極的想像還是預測啊,那個仰望的聖杯。
    不過這如果無法做到離線運作的話有些太可怕了,看有沒有辦法做到最小主動意圖就能精準動作的操作流程。

    最後備份一下原始碼:

    use AppleScript version "2.4"
    use framework "Foundation"
    use scripting additions
    
    property calendarName : "自動化生成" -- 請添加 / 修改為你自己的日曆名稱
    
    on run {input, parameters}
    	set theQuery to input as text
    	set theString to current application's NSString's stringWithString:theQuery
    	
    	-- 偵測時間
    	set dateDetector to current application's NSDataDetector's dataDetectorWithTypes:(current application's NSTextCheckingTypeDate) |error|:(missing value)
    	set theRange to current application's NSMakeRange(0, theString's |length|())
    	set dateMatch to dateDetector's firstMatchInString:theString options:0 range:theRange
    	
    	if dateMatch ≠ missing value then
    		set startDate to dateMatch's |date|() as date
    		if startDate < (current date) then set startDate to startDate + 1 * days
    		set endDate to startDate + (1 * hours)
    		
    		set dateRange to dateMatch's range()
    		set matchString to theString's substringWithRange:dateRange
    		set cleanedTitleNSString to theString's stringByReplacingCharactersInRange:dateRange withString:""
    		set eventTitle to cleanedTitleNSString as string
    	else
    		set validInput to false
    		repeat until validInput is true
    			display dialog "⚠️ 未能自動偵測時間,請手動輸入(格式:2025/06/10 15:30):" default answer ""
    			set userInput to text returned of result
    			try
    				set startDate to date userInput
    				set validInput to true
    			on error
    				display dialog "❌ 格式錯誤,請重新輸入(範例:2025/06/10 15:30)" buttons {"OK"} default button 1
    			end try
    		end repeat
    		set endDate to startDate + (1 * hours)
    		set eventTitle to theQuery
    	end if
    	
    	-- 偵測地點
    	set addressDetector to current application's NSDataDetector's dataDetectorWithTypes:(current application's NSTextCheckingTypeAddress) |error|:(missing value)
    	set addressMatch to addressDetector's firstMatchInString:theString options:0 range:theRange
    	
    	if addressMatch ≠ missing value then
    		set addressDict to addressMatch's addressComponents()
    		set locationString to (addressDict's objectForKey:"Name") as string
    		if locationString is missing value or locationString is "" then
    			set locationString to (theString's substringWithRange:(addressMatch's range())) as string
    		end if
    	else
    		display dialog "未偵測到地點,請手動輸入地點(可留空):" default answer ""
    		set locationString to text returned of result
    	end if
    	
    	-- 請使用者輸入附註
    	display dialog "請輸入附註內容(可留空):" default answer ""
    	set notesContent to text returned of result
    	
    	-- 建立事件
    	tell application "Calendar"
    		activate
    		set theCalendar to first calendar whose name is calendarName
    		set newEvent to make new event at end of events of theCalendar with properties {summary:eventTitle, start date:startDate, end date:endDate, location:locationString, description:notesContent}
    		
    		-- 加入提醒
    		tell newEvent
    			make new display alarm at end with properties {trigger interval:-60} -- 1 小時前
    			make new display alarm at end with properties {trigger interval:-30} -- 30 分鐘前
    			
    			-- 若活動超過一天後,加入 1 天前提醒
    			set nowDate to current date
    			if (startDate - nowDate) > (1 * days) then
    				make new display alarm at end with properties {trigger interval:-1440}
    			end if
    		end tell
    	end tell
    end run
  • 使用 Tailwind CLI 快速建立靜態 CSS 檔的基本步驟

    使用 Tailwind CLI 快速建立靜態 CSS 檔的基本步驟

    當 AI 建立可使用的文字越來越可靠的時候,部落格筆記就剩下避免重複問被 AI 當作失智患者的功能。

    這是為使用 Tailwind CLI 快速建立靜態 CSS 檔的基本步驟。

    參考這裡。

    先講注意事項事項,血淚史:

    1. npm 設定與初始化需助要是否在 root 權限,切換會很麻煩。
    2. 如果採用 SSR 在套版開始之前,記得先把 tailwindcss 的靜態 CSS 創建出來,要不也會很麻煩。
    3. tailwindcss 提供其他靜態檔案產生方法,我覺得 tailwindcss-cli 是最好用的,如果使用前端框架可以參考官方連結
    4. 還有另外一中作法,也可以參考:https://tailwindcss.com/blog/standalone-cli

    —-
    1. 初始化專案 & 安裝套件

    npm init -y
    npm install tailwindcss @tailwindcss/cli

    這會在專案中安裝 Tailwind CSS 與其 CLI 工具 

    2.  建立輸入 CSS 檔

    在專案內建立檔案 src/input.css,並加入:

    @import "tailwindcss";

    這行指令會載入 Tailwind 的所有基礎、組件與工具類樣式 

    3.  執行 CLI 產出靜態檔

    執行下列指令,Tailwind 會掃描你所有的原始檔中的 class,並輸出到指定的 CSS 檔:

    npx @tailwindcss/cli -i ./src/input.css -o ./dist/output.css --watch

    -i:指定輸入檔
    -o:指定輸出檔 (建議放到 dist/ 或 public/ 等靜態資源資料夾)
    –watch:開啟檔案變動監看,自動重建

    4. 在 HTML 中引入已編譯的 CSS

    如果沒有 input.css 或是不想整合在一起:

    npx @tailwindcss/cli -i ./src/input.css -o ./dist/output.css --watch

    最後,在你的 HTML 中加入:

    <link href="./dist/output.css" rel="stylesheet">

    即可在標記中使用所有 Tailwind 的 utility classes 

    備註:
    • 若不需要即時監看,可將 –watch 拿掉,做一次性建置。
    • 若希望調整預設設定(如自訂斷點、色票等),可執行 npx tailwindcss init 產生 tailwind.config.cjs 後再修改。
    • CLI 也提供獨立執行檔版本,無需 Node.js 環境,詳見官方文件「standalone executable」。

  • Visual Studio Code 的 PHP CS Fixer 設定

    Visual Studio Code 的 PHP CS Fixer 設定

    最近有幸換一台好一點電腦,開始投入 VSCode 的懷抱,轉換總是陣痛一波波襲來,於是趕緊記錄下來。希望能對以後使用 VSCode 的 PHPer 排版有幫助。

    PHP CS Fixer 是一個自動格式化 PHP 程式碼,利用這個外掛達到達到 PHP 統一風格的效果。


    版本:

    PHP CS Fixer 3.73.1 Persian Successor by Fabien Potencier, Dariusz Ruminski and contributors.

    PHP runtime: 8.2.28


    PHP CS Fixer 安裝與設定

    1. 安裝 PHP CS Fixer

    你有兩種主要安裝方式:透過 Composer 全域安裝或下載 phar 檔案。以下以 Composer 全域安裝為例:

    1. 確保 Composer 已安裝

    如果尚未安裝 Composer,請至 Composer 官方網站 下載並安裝。

    2. 全域安裝 PHP CS Fixer

    開啟終端機(Terminal),執行下列指令:

    composer global require friendsofphp/php-cs-fixer

    安裝完成後,透過以下指令確認執行檔路徑:

    composer global config bin-dir --absolute

    例如,你可能會得到 /Users/yourname/.composer/vendor/bin。記下這個路徑,因為稍後在 VSCode 或命令列使用時需要指定。

    注意兩點:

    1. 注意 Composer / PHP 的路徑和權限。可能會遇到執行權限不足的問題。
    2. 注意 User 的路徑名稱,這邊統一用 yourname 代替。

    2. 建立 PHP CS Fixer 設定檔

    我們提供以下最新版的 config.php 設定檔範例,此檔案包含多項格式化規則(例如 PSR、Symfony 規範),並採用新版語法。請將此檔案存放在你希望統一管理格式化規則的位置,例如 ~/.config/php-cs-fixer/config.php。

    小提醒,註解我是用 AI 生成的。裡面設定得依照需求和團隊規範來調整。

    <?php
    
    $header = <<<'EOF'
    This file is part of PHP CS Fixer.
    
    (c) Fabien Potencier <[email protected]>
        Dariusz Rumiński <[email protected]>
    
    This source file is subject to the MIT license that is bundled
    with this source code in the file LICENSE.
    EOF;
    
    $finder = PhpCsFixer\Finder::create()
        ->exclude('tests/Fixtures') // 排除特定目錄
        ->in(__DIR__) // 設定要檢查的目錄
    ;
    
    $config = (new PhpCsFixer\Config())
        ->setRiskyAllowed(true) // 允許使用可能具有風險的規則
        ->setRules([
            // '@PHP56Migration' => true, // PHP 5.6 的語法遷移規則集(已註解掉)
            '@PHPUnit60Migration:risky'   => true, // 適用於 PHPUnit 6.0 的遷移規則(風險規則)
            '@PSR1'                       => true, // 遵循 PSR-1 基本編碼標準
            '@PSR2'                       => true, // 遵循 PSR-2 編碼風格指南
            '@Symfony'                    => true, // 遵循 Symfony 的編碼標準
            '@Symfony:risky'              => true, // Symfony 的風險規則集
            'align_multiline_comment'     => true, // 將多行註解對齊
            'array_indentation'           => true, // 陣列的縮排規則
            'array_syntax'                => ['syntax' => 'short'], // 使用短陣列語法
            'blank_line_before_statement' => true, // 在特定語句前插入空行
            'binary_operator_spaces'      => [ // 二元運算符的空格規則
                'operators' => [
                    '=>' => 'align', // 將 `=>` 對齊
                    '='  => 'single_space', // `=` 使用單一空格
                ],
            ],
            'combine_consecutive_issets'   => true, // 合併連續的 `isset` 語句
            'combine_consecutive_unsets'   => true, // 合併連續的 `unset` 語句
            'comment_to_phpdoc'            => true, // 將普通註解轉換為 PHPDoc
            'compact_nullable_typehint'    => true, // 使用緊湊的 nullable 類型提示語法
            'concat_space'                 => ['spacing' => 'one'], // 字串連接符號使用單一空格
            'escape_implicit_backslashes'  => true, // 轉義隱式的反斜線
            'explicit_indirect_variable'   => true, // 明確的間接變數語法
            'explicit_string_variable'     => true, // 明確的字串變數語法
            'final_internal_class'         => true, // 將內部類標記為 final
            'fully_qualified_strict_types' => true, // 使用完全限定的類型名稱
            'function_to_constant'         => ['functions' => ['get_class', 'get_called_class', 'php_sapi_name', 'phpversion', 'pi']], // 將特定函數轉換為常數
            // 'header_comment' => ['header' => $header], // 添加檔案頭部註解(已註解掉)
            'heredoc_to_nowdoc'                             => true, // 將 heredoc 轉換為 nowdoc
            'increment_style'                               => false, // 遞增/遞減運算符的風格
            'list_syntax'                                   => ['syntax' => 'short'], // 使用短語法的 list
            'logical_operators'                             => true, // 使用邏輯運算符 `and`, `or`, `xor` 替代符號
            'method_argument_space'                         => ['on_multiline' => 'ensure_fully_multiline'], // 方法參數的空格規則
            'method_chaining_indentation'                   => true, // 方法鏈式調用的縮排
            'multiline_comment_opening_closing'             => true, // 多行註解的開頭和結尾格式化
            'no_alternative_syntax'                         => true, // 禁用替代語法(如 `endif`)
            'no_binary_string'                              => true, // 禁用二進位字串語法
            'no_extra_blank_lines'                          => ['tokens' => ['break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block']], // 移除多餘的空行
            'no_null_property_initialization'               => true, // 移除屬性初始化為 null
            'echo_tag_syntax'                               => ['format' => 'long'], // 使用長格式的 echo 標籤
            'no_superfluous_elseif'                         => true, // 移除多餘的 elseif
            'no_unneeded_curly_braces'                      => true, // 移除不必要的大括號
            'no_unneeded_final_method'                      => true, // 移除不必要的 final 方法
            'no_unreachable_default_argument_value'         => true, // 移除無法到達的默認參數值
            'no_unset_on_property'                          => true, // 禁止對屬性使用 unset
            'no_useless_else'                               => true, // 移除無用的 else
            'no_useless_return'                             => true, // 移除無用的 return
            'ordered_class_elements'                        => true, // 排序類的元素
            'ordered_imports'                               => true, // 排序 import 語句
            'php_unit_internal_class'                       => true, // PHPUnit 的內部類應標記為 final
            'phpdoc_order_by_value'                         => ['annotations' => ['covers']], // 按值排序 PHPDoc 的註解
            'php_unit_set_up_tear_down_visibility'          => true, // 設置 PHPUnit 的 setUp/tearDown 方法的可見性
            'php_unit_strict'                               => true, // 使用 PHPUnit 的嚴格模式
            'php_unit_test_annotation'                      => true, // 強制使用 PHPUnit 的 @test 註解
            'php_unit_test_case_static_method_calls'        => ['call_type' => 'this'], // 使用 `$this` 調用靜態方法
            'php_unit_test_class_requires_covers'           => true, // 強制測試類需要 @covers 註解
            'phpdoc_add_missing_param_annotation'           => true, // 添加缺失的 @param 註解
            'phpdoc_order'                                  => true, // 排序 PHPDoc 的標籤
            'phpdoc_trim_consecutive_blank_line_separation' => true, // 修剪 PHPDoc 中的連續空行
            'phpdoc_types_order'                            => true, // PHPDoc 類型排序
            'return_assignment'                             => false, // 避免直接返回賦值
            'semicolon_after_instruction'                   => true, // 在指令後添加分號
            'single_line_comment_style'                     => true, // 單行註解的風格
            'strict_comparison'                             => false, // 使用嚴格比較
            'strict_param'                                  => false, // 使用嚴格參數
            'string_line_ending'                            => true, // 字串行結尾一致
            'ternary_operator_spaces'                       => true, // 三元運算符的空格規則
            'trim_array_spaces'                             => true, // 修剪陣列中的多餘空格
            'unary_operator_spaces'                         => true, // 一元運算符的空格規則
            'yoda_style'                                    => true, // 使用 Yoda 條件風格
            'whitespace_after_comma_in_array'               => true, // 陣列中逗號後的空格
        ])
        ->setFinder($finder)
    ;
    
    // special handling of fabbot.io service if it's using too old PHP CS Fixer version
    if (false !== getenv('FABBOT_IO')) {
        try {
            PhpCsFixer\FixerFactory::create()
                ->registerBuiltInFixers()
                ->registerCustomFixers($config->getCustomFixers())
                ->useRuleSet(new PhpCsFixer\RuleSet($config->getRules()));
        } catch (PhpCsFixer\ConfigurationException\InvalidConfigurationException $e) {
            $config->setRules([]);
        } catch (UnexpectedValueException $e) {
            $config->setRules([]);
        } catch (InvalidArgumentException $e) {
            $config->setRules([]);
        }
    }
    
    return $config;

    3. 配置與使用

    (1) 測試設定檔是否正常運作

    在終端機中執行以下指令,檢查格式化是否能正常運作:

    php-cs-fixer fix --config=/Users/yourname/.config/php-cs-fixer/config.php --dry-run --diff

    若顯示格式化差異且無錯誤訊息,代表設定檔運作正常。

    (2) 在 VSCode 中整合使用

    若你在 VSCode 中進行開發,請依下列步驟進行設定:

    1. 安裝 VSCode PHP CS Fixer 擴充套件

    可從 VSCode 擴充功能市場搜尋並安裝例如 junstyle.php-cs-fixer 之類的擴充套件。

    2. 設定 VSCode 使用全域 PHP CS Fixer

    在 VSCode 的 settings.json 中加入下列設定,指定執行檔路徑與全域設定檔位置:

    {
        "php-cs-fixer.executablePath": "/Users/yourname/.composer/vendor/bin/php-cs-fixer",
        "php-cs-fixer.config": "/Users/yourname/.config/php-cs-fixer/config.php",
        "editor.formatOnSave": true,
        "[php]": {
            "editor.defaultFormatter": "junstyle.php-cs-fixer"
        }
    }

    ※ 請依據實際路徑修改 “php-cs-fixer.executablePath” 的內容。

    3. 測試 VSCode 格式化功能

    開啟一個 PHP 檔案,嘗試保存(Save),檢查程式碼是否依照設定自動格式化。

    4. 設定檔內容說明

    這份設定檔主要包含以下部分:

    Header 字串:定義了版權和授權說明,雖然目前透過 header_comment 規則被註解掉,但可根據需求啟用。

    Finder 設定:透過 PhpCsFixer\Finder 指定排除某些目錄(例如 tests/Fixtures),並指定掃描路徑(使用 __DIR__)。

    Config 物件:利用 (new PhpCsFixer\Config()) 建立設定物件,並透過 setRules 指定各項格式化規則,例如 PSR、Symfony、單行註解、縮排、運算子對齊等。

    特別注意:

    • 將原本已被移除的規則集(如 @PHP56Migration)註解掉。

    • 對於已重命名的規則,例如 no_short_echo_tag 改為 echo_tag_syntax,並依新規範提供相應配置。

    • binary_operator_spaces 的設定改為使用 operators 陣列,設定 => 為 align,而 = 為 single_space。

    特殊處理:針對 fabbot.io 等可能使用較舊版 PHP CS Fixer 的服務,透過 try/catch 機制進行相容性處理。


    總結

    按照以上步驟完成安裝、設定檔建立及 VSCode 整合後,你就能使用這份統一的 PHP CS Fixer 設定來自動格式化 PHP 程式碼,確保程式碼風格的一致性與可讀性。若有需要進一步調整規則,可以參考 PHP CS Fixer 官方文件 進行自訂。