星期六, 8月 15, 2026

2026 Google IO China 小記


2026 Google IO China 小記


今年有幸因為 GDE 的關係, 獲邀參加 Google IO China 研討會


首先要先謝謝 Google Eric ShangKuan  (  https://www.linkedin.com/in/ericsk/ ) , Yuying Tsai ( https://www.linkedin.com/in/yuying-tsai/  ) 以及所有項目組的夥伴組織活動與規劃.


這次的研討會主要是 4 天的行程, 亞洲的 GDG 與 GDE 都會共同參加與交流


第一天晚上是 Community Welcome Dinner


首先是很開心收到項目組安排的禮物



  • 研討會有 Dress code 個人覺得很好, 可以很快的識別與交流


晚上由接駁車接送到 其昌栈码头



在船上舉行歡迎晚宴與互動



採取 Buffet 的方式, 既可以交流互動也可以滿足 211 餐盤需求


上次去上海應該是 14 年前, 去內蒙當志願者, 但是那個時候沒有機會好好看黃浦江, 感謝 Google 可以讓我多解鎖一個成就


第二天與第三天 正式參加 Google IO China 


首先是 Keynote



這邊我覺得很棒的地方是所有的位置都有即時翻譯的耳機, 可以在外賓英文演說的時候使用中文聽講, 如我大家有興趣也可以從剛剛的會議首頁還觀察回放, 我覺得即時翻譯的部分很有品質


議程的部分 https://ioconnectchina.googlecnapps.cn/sessions/ 

  • 8/12 是 AI 與 Chrome

    • 這一天我主要聚焦在 Gemma 的相關議程, 也看得出 Google 在 Gemma 於不同設備, 例如 眼鏡或是端點裝置有了很多的案例與投入, 以及 Cloud Run / GKE 結合 Gemma 的相關案例與資訊, 這個部分吸引了我對於這方面的投入.

    • 另外我覺得有一個很棒的點是有社會公益案例分享, 這個方向放到正式商業議程內, 我在台灣的研討會還真的沒有太大的印象, 我有去參訪華南理工大學 (https://www.scut.edu.cn/new/ ) 的攤位, 詢問有關於他們設計的線上教育平台, 使用 Gemma 來進行教育輔助, 也有把相關程式碼放到 Github 上面, 覺得很棒

  • 8/13 是 Android 與 Cloud 

    • 這一天當然是聚焦在 Cloud 議程上

    • Ankur Kotwal 一開始以即時英文翻中文的語音介面, 給大家很深刻的印象, 介紹相關的技術以及使用 Agents CLI ( https://github.com/google/agents-cli ) 即時打造剛剛的翻譯語音介面 讓大家對 agents cli 這個工具的學習與使用更有興趣

    • 另外也提到 Google Skills ( https://www.skills.google/ )來串 workshop 與相關研習及介紹

    • 史洁 的 超级个体 到 AI 原生组织 的 Level 1 ~ Level 5 區分與 Policy 控管與演進也進一步把 AI 治理想法讓參與的會眾了解, 為何要採取企業的方案而不是各自單打獨鬥


工作坊的部分 ( https://ioconnectchina.googlecnapps.cn/workshops/ )

  • 一樣包涵 4 個面向 ( AI / Chrome / Android / Cloud ), 採取登記制與現場候補機制

  • 我有候補排上 从开发到生产,全面体验 Agent Platform 中的 Agent CLI

    • 使用 Google Skills 的 Lab 課程讓參與的學員體驗 agents cli 安裝與應用實作, 透過 Kahoot 與學員互動及增加相關知識亮點


開發者沙龍的部分 ( https://ioconnectchina.googlecnapps.cn/meetups/



接下來聊聊其他的


首先是攤位的部分



  • Gemini 奇趣影棚 可以讓參展人快速得到不同面向的照片,增加參與感以及感受 Gemini 的功能



也有不同面向的攤位, 如同剛剛說的社會公益 / 藝術攤位


以及不同面向的 Google 攤位


現場有很多地方都有小冰櫃, 也是小亮點


午餐飯盒真的也是管飽, 裡面竟然還有三杯雞 :)


第四天也是最後一天是 GDE Summit , 地點在 Google 上海辦公室




最後再次感謝 Google 的邀約與所有項目組的辛苦付出


也很開心可以有這個機會與大家交流





References



星期一, 6月 29, 2026

git-filter-repo 切分子專案小記

git-filter-repo 切分子專案小記



環境:

  • macOS 26.5.1
  • git 2.50.1


有的時候是這樣的, 專案會在測試目錄中發想, 然後慢慢測試, 慢慢就長成可以測試的小專案, 這個時候就會想把它獨立出來, 但是又想要保留當初開發的 git status.

今天要實作的是把 Git repo 裡面的子目錄切出去,變成一個獨立 repo,而且希望 Git history 可以一起帶過去。

我的原本 repo 在這裡:

/Users/max/Downloads/local_lab/lab_temp

要切出來的子目錄是這個:

02_實作中/20260627_chatbot_rag/


工具使用 `git-filter-repo`


Step 1: 先 clone 一份出來

重點是這裡要加 `--no-local`。如果只是從本機路徑直接 clone,`git-filter-repo` 可能會認為這不是乾淨的 fresh clone,然後拒絕改寫 history。

指令如下

cd /Users/max/Downloads/local_lab

git clone --no-local ./lab_temp chatbot_rag_split


  • 如果沒有加 `--no-local`,會遇到以下錯誤:

Aborting: Refusing to destructively overwrite repo history since
this does not look like a fresh clone.
  (expected freshly packed repo)
Note: when cloning local repositories, you need to pass --no-local to git clone to avoid this issue.


Step 2: 執行 git-filter-repo

接著只保留目標子目錄,並把它搬到新 repo 的根目錄:

cd chatbot_rag_split
git-filter-repo
\ --path '02_實作中/20260627_chatbot_rag/' \ --path-rename '02_實作中/20260627_chatbot_rag/':


這邊最容易看錯的是最後的冒號。`--path-rename` 的格式是 `OLD_PATH:NEW_PATH`,所以這行的意思是:

  • `OLD_PATH` 是 `02_實作中/20260627_chatbot_rag/`
  • `NEW_PATH` 是空字串
  • 結果就是把該子目錄底下的內容搬到 repo 根目錄

所以不是寫成 `:/`。Git repo 裡的 path 是相對路徑,不是檔案系統的 `/` 根目錄。要搬到 repo root,就是冒號後面留空。


成功輸出

最後成功時輸出長這樣:

NOTICE: Removing 'origin' remote; see 'Why is my origin removed?'
        in the manual if you want to push back there.
        (was /Users/max/Downloads/local_lab/./lab_temp)
Parsed 36 commits
New history written in 0.14 seconds; now repacking/cleaning...
Repacking your repo and cleaning out old unneeded objects
HEAD is now at 54dab99 build: 加入 Cloud Run 入口與資源保護
Enumerating objects: 296, done.
Counting objects: 100% (296/296), done.
Delta compression using up to 8 threads
Compressing objects: 100% (157/157), done.
Writing objects: 100% (296/296), done.
Total 296 (delta 136), reused 276 (delta 136), pack-reused 0 (from 0)
Completely finished after 0.25 seconds.

  • 這裡看到 `Removing 'origin' remote` 是正常的。`git-filter-repo` 會移除原本的 `origin`,避免不小心把改寫後的 history 推回原 repo。這個設計滿貼心的,is not really useful :)


檢查結果

跑完後可以先看一下目前內容、commit,以及 remote 狀態:

ls
git log --oneline --decorate -n 10
git status
git remote -v

  • 如果 `git remote -v` 沒有輸出,這次反而是正常狀態,因為 origin 已經被移除了。


Step 3: 接到新的 remote

確認內容沒問題後,再把它接到新的 GitLab 或 GitHub repo。

  • 建議新 repo 不要先初始化 README、`.gitignore` 或 license,避免第一推就要處理 unrelated history。

git remote add origin git@github.com:your-org/chatbot_rag.git

git push -u origin HEAD:main

  • 可用 `HEAD:main`,因為不用先管目前 local branch 叫 `main` 還是 `master`,直接把目前所在的 HEAD 推到遠端 `main`。


這次的完整版本

cd /Users/max/Downloads/local_lab

git clone --no-local ./lab_temp chatbot_rag_split

cd chatbot_rag_split

git-filter-repo \
  --path '02_實作中/20260627_chatbot_rag/' \
  --path-rename '02_實作中/20260627_chatbot_rag/':

git remote add origin git@github.com:your-org/chatbot_rag.git

git push -u origin HEAD:main

  • 這次的關鍵就是三個:本機 clone 要加 `--no-local`、實際指令用 `git-filter-repo`、`--path-rename` 最後的冒號要留下來。


又前進一步 ~ enjoy it

Reference

  • https://github.com/newren/git-filter-repo

星期日, 6月 14, 2026

Cline CLI 安裝與 Azure 部署小記

Cline CLI 安裝與 Azure 部署小記



環境:

  • macOS 14.5
  • Node.js v20.12.0
  • Cline CLI 1.0.0

有時候訂閱制的 AI 工具, 像是 Codex / Claude / Gemini 有時候額度不夠, 但是又不想要多訂閱, 保持彈性, 想法上就動到使用 Azure 上的模型來幫忙做事,嘗試幾個工具後, 決定來裝 Cline CLI,把 ChatGPT 5.4 部署上去測試。

Cline 官網 

  • https://github.com/cline/cline
  • 我有用過他的 vscode extension , 但是 extension 有些限制, 所以這次採取 CLI, 之後想要測試他的 Kanban


1. 在 Azure 部署 ChatGPT 5.4

這裡我們直接用 Azure CLI 來建立資源與部署模型,請確保已經使用 az login 登入。

先建立 Cognitive Services Account(假設 Resource Group cline-aoai-eastus2-rg 已經建好):

az cognitiveservices account create -n clineeastus2dbg1 -g cline-aoai-eastus2-rg --location eastus2 --kind OpenAI --sku S0

  • 這邊可以置換成 你的 Resource Group / Region 以及資源名稱


接著部署 gpt-5.4 模型,設定容量為 100K TPM,並且將 Deployment name 取為 gpt54-dev

az cognitiveservices account deployment create \
  -g cline-aoai-eastus2-rg \
  -n clineeastus2dbg1 \
  --deployment-name gpt54-dev \
  --model-name gpt-5.4 \
  --model-version 2026-03-05 \
  --model-format OpenAI \
  --sku-name GlobalStandard \
  --sku-capacity 100

  • 這邊比較重要的是 deployment-name , 因為 cline cli 識認你的 deployment name 不是模型名稱
  • sku-capacity 也很重要 這個如果設定太小就會遇到 Error: too many requests


拿好 Endpoint 跟 API Key:

# 取得 Endpoint (我們只需要前面的 Resource 網址,例如 https://clineeastus2dbg1.openai.azure.com/)
az cognitiveservices account show -n clineeastus2dbg1 -g cline-aoai-eastus2-rg --query properties.endpoint

# 取得 API Key
az cognitiveservices account keys list -n clineeastus2dbg1 -g cline-aoai-eastus2-rg --query key1


2. 安裝 Cline CLI

直接用 npm 全域安裝:

npm install -g cline-cli

裝完後測試一下版本:

cline --version


3. 設定 Cline CLI

Cline 實際讀取的設定檔在  ~/.cline/data/settings/providers.json

我們手動建立或編輯它,讓 Cline 透過 openai-compatible 介接 Azure:

{
  "version": 1,
  "lastUsedProvider": "openai-compatible",
  "providers": {
    "openai-compatible": {
      "settings": {
        "provider": "openai-compatible",
        "apiKey": "YOUR_AZURE_OPENAI_API_KEY",
        "model": "gpt54-dev",
        "baseUrl": "https://clineeastus2dbg1.openai.azure.com/openai/v1/"
      },
      "tokenSource": "manual"
    }
  }
}

  • 小提醒:baseUrl 後面固定接 /openai/v1/ 
  • model 要填你的 Azure Deployment Name,不是底層模型名稱喔。
  • api key 請填上自已的 key


設定完後確認一下目錄結構:

ls -al ~/.cline/data/settings/
total 8
drwxr-xr-x   3 user  staff    96 Jun 14 15:00 .
drwxr-xr-x+ 50 user  staff  1600 Jun 14 15:00 ..
-rw-r--r--   1 user  staff   200 Jun 14 15:05 providers.json

設定好後,進入互動模式看看:

cline -i

有吐出回應就大功告成啦。





又前進一步 ~ enjoy it

星期日, 6月 07, 2026

LINE 聊天紀錄備份自動化小記

LINE 聊天紀錄備份自動化小記



環境:

  • macOS
  • Google Apps Script (GAS)
  • Google Drive

跟朋友聊到一個需求

  • LINE 的對話備份有點難管理,想把一對一私訊丟到自己的 Google Drive 上,備份與管理。麻煩 AI 用 Google Apps Script 寫了一個小工具,自動把匯出的對話記錄整理好。

部署與設定

整個專案不需要伺服器,直接跑在 GAS 上,官網 https://script.google.com。部署步驟滿簡單的:

專案的相關程式碼與介紹我放在 Github


大概的步驟長這樣

# 1. 建立新專案,把 gas/ 裡的 Code.gs 等檔案貼上去
# 2. 手動執行初始化函數
installTrigger()
# 3. 部署成 Web App,存取權限選「只有我自己」


詳細部署步驟就請看 https://github.com/sakanamax/linechat-backup/blob/main/gas/README.md


專案核心的目錄結構大概長這樣:

gas/
├── Code.gs           # 後端邏輯(解析、整理、Drive 操作)
├── Index.html        # Web App 管理介面
├── appsscript.json   # GAS 設定權限與範圍
└── README.md         # 完整說明


日常使用流程

設定完以後,用起來就很無腦了。在 LINE 裡面點開對話的「傳送聊天記錄」,分享到 Google Drive 裡的「LINE待處理」資料夾。




接著背後的觸發器每小時會自動掃描,把上傳的 .txt 檔案抓出來解析,防重複處理後,再按月份或聯絡人分類歸檔到「LINE備份」資料夾裡。

整理完的結果看起來很舒壓:

📁 我的雲端硬碟
   📁 LINE備份
      📁 王花花
         📁 2026-06
            📄 對話記錄.txt


資料架構有設定兩種歸檔的邏輯

可以在管理介面上設定, 管理介面設定長這樣





雖然只能備份文字(圖片影片還是要手動存),而且目前解析器只吃 Android 格式,但至少對話紀錄穩穩地躺在完全私密的雲端裡,不用擔心不見,也不用依賴第三方工具。

感覺又向前一步 

~ enjoy it!


星期六, 6月 06, 2026

Claude Code 多帳號切換小記

Claude Code 多帳號切換小記




環境:

  • macOS 26.5
  • Claude Code: 2.1.153

使用 AI 工具時因為同時有個人帳號跟公司帳號,兩邊都要跑 Claude Code, 每次都要 /logout/login 其實很煩。 找了一下解法發現 Claude Code 有個環境變數 CLAUDE_CONFIG_DIR, 讓每個帳號可以有完全獨立的設定目錄,各自存憑證、記憶體、對話記錄, 完全不需要頻繁切換登入。

核心概念

預設情況下 Claude Code 的設定放在 ~/.claude/。 只要在啟動時給定不同的 CLAUDE_CONFIG_DIR,就能完全切開兩個帳號, 甚至同時開兩個終端機視窗,一個跑個人帳號、一個跑公司帳號,互不干擾。

每個獨立目錄裡面會隔離的東西:

  • credentials.json:帳號憑證
  • settings.json:Claude Code 設定
  • Session history:對話記錄
  • Memory:Project memory


macOS / Linux 設定方式

~/.zshrc(macOS)或 ~/.bashrc(Linux)加入:

# 現有帳號:沿用預設 ~/.claude/,什麼都不用動
alias claude-main='claude'

# 第二個帳號:指向新目錄
alias claude-team='CLAUDE_CONFIG_DIR="$HOME/.claude-team" claude'

名稱可以自己取,例如 claude-personal / claude-work,whatever。套用設定:

source ~/.zshrc


初始化第二個帳號(只做一次)

方法 A:瀏覽器 OAuth 登入(macOS 一般狀況)

CLAUDE_CONFIG_DIR="$HOME/.claude-team" claude
# 進入後執行 /login,依照指示完成驗證

方法 B:setup-token(WSL2 推薦,有效期整整一年,很適合公司帳號)

CLAUDE_CONFIG_DIR="$HOME/.claude-team" claude setup-token

WSL2 的瀏覽器登入跳轉有時候會炸掉,直接用 setup-token 比較省事。


日常使用

claude          # 原本用法,完全不變
claude-main     # 同上,明確標示是主帳號
claude-team     # 第二個帳號


兩個終端機視窗可以同時開,一邊跑個人帳號、一邊跑公司帳號,帳號完全獨立互不干擾。


Windows cmd.exe 的話

Windows 沒有 alias,要改用 bat 檔。先建個 bin 資料夾:

mkdir %USERPROFILE%\bin

建立 %USERPROFILE%\bin\claude-team.bat

@echo off
set CLAUDE_CONFIG_DIR=%USERPROFILE%\.claude-team
claude %*

建立 %USERPROFILE%\bin\claude-main.bat

@echo off
set CLAUDE_CONFIG_DIR=
claude %*

把 bin 加進 PATH(永久生效):

setx PATH "%USERPROFILE%\bin;%PATH%"

關掉重開 cmd 後生效。確認一下:

where claude-team
:: 應顯示 C:\Users\你的名字\bin\claude-team.bat


幾個注意事項

  • CLAUDE_CONFIG_DIR 在 macOS / Linux / Windows 都有效,macOS 雖然用 Keychain 存憑證,但不影響目錄切換
  • WSL2 瀏覽器登入若跳轉失敗,改用 claude setup-token
  • Token 過期後重新執行對應帳號的 setup-token 即可,不影響另一個帳號
  • 如果環境有設定 ANTHROPIC_API_KEY,它的優先權高於 OAuth,要先 unset ANTHROPIC_API_KEY 才行

設定完之後兩個帳號可以同時開著跑,再也不用反覆 logout / login


感覺又向前一步 ~ enjoy it

星期日, 5月 31, 2026

Codex 與 Claude Code statusline 設定小記

Codex 與 Claude Code statusline 設定小記



環境:

  • macOS 26.5
  • Codex CLI 0.135.0
  • Claude Code 2.1.149

最近在整理 AI coding tool 的使用環境,發現底部那條 statusline 其實很值得設定一下。平常一直切 repo、切模型、跑長任務,如果沒有一眼看到 context 或 quota 狀態,很容易做到一半才發現快滿了,或是突然被中斷 Orz ....

這篇記一下目前我自己的 Codex 與 Claude Code statusline 設定。兩者概念有點不一樣, Codex 目前是用內建欄位組合;Claude Code 則是把 JSON 丟給 shell script,再把 script 印出的內容顯示出來。


Claude Code 官方文件 

  • https://code.claude.com/docs/en/statusline

Codex 官方文件
  • https://developers.openai.com/codex/cli/slash-commands



Codex 的 status_line

Codex 的設定檔在這裡:

~/.codex/config.toml

我目前放在 [tui] 裡,讓底部狀態列顯示模型、context、額度和目前目錄:

[tui]
status_line = [
  "model-with-reasoning",
  "context-remaining",
  "five-hour-limit",
  "weekly-limit",
  "current-dir",
]


這組欄位對我來說剛好。

  • model-with-reasoning 可以確認現在是不是用預期的模型和 reasoning effort
  • context-remaining 看長任務還剩多少空間
  • five-hour-limitweekly-limit 看額度壓力
  • current-dir 則是避免自己在錯的專案裡下指令


我的 Codex 前面也有模型設定,整體看起來像這樣:

model = "gpt-5.5"
model_reasoning_effort = "medium"
personality = "pragmatic"

[tui]
status_line = [
  "model-with-reasoning",
  "context-remaining",
  "five-hour-limit",
  "weekly-limit",
  "current-dir",
]

改完後可以用下面指令確認版本,順便重開 Codex 看底部是否出現新欄位:

codex --version


Claude Code 的 statusLine

Claude Code 這邊比較自由。設定檔在:

~/.claude/settings.json
~/.claude/statusline-command.sh


也可以直接在 Claude Code 裡用 /statusline 讓它幫忙產生,或是直接呼叫 ai 幫你設定 :)

{
  "theme": "auto",
  "verbose": true,
  "statusLine": {
    "type": "command",
    "command": "bash /Users/max/.claude/statusline-command.sh"
  }
}

重點是 statusLine.command。Claude Code 會執行這個 command,並把目前 session 的 JSON 從 stdin 傳進去。script 只要讀 stdin,最後印出一行文字就好。

我的 script 目前顯示 

  • model
  • context 使用率
  • 上一輪 token 數
  • 有資料時顯示 5-hour limit:


內容如下

#!/bin/sh
input=$(cat)

model=$(echo "$input" | jq -r '.model.display_name // "Unknown"')

used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
if [ -n "$used_pct" ]; then
  ctx=$(printf "%.0f%%" "$used_pct")
else
  ctx="ctx:--"
fi

in_tok=$(echo "$input" | jq -r '.context_window.current_usage.input_tokens // empty')
out_tok=$(echo "$input" | jq -r '.context_window.current_usage.output_tokens // empty')
if [ -n "$in_tok" ] && [ -n "$out_tok" ]; then
  total=$(( in_tok + out_tok ))
  if [ "$total" -ge 1000 ]; then
    tok_display=$(awk "BEGIN { printf \"%.1fk\", $total/1000 }")
  else
    tok_display="${total}"
  fi
  cost_part="tokens:${tok_display}"
else
  cost_part="tokens:--"
fi

後面再把 5-hour limit 接上去:

five_h_pct=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
five_h_reset=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')
if [ -n "$five_h_pct" ]; then
  five_h_pct_display=$(printf "%.0f%%" "$five_h_pct")
  if [ -n "$five_h_reset" ]; then
    five_h_reset_display=$(date -r "$five_h_reset" "+%H:%M" 2>/dev/null || date -d "@$five_h_reset" "+%H:%M" 2>/dev/null || echo "?")
  else
    five_h_reset_display="?"
  fi
  five_h_part="5h:${five_h_pct_display}(↺${five_h_reset_display})"
else
  five_h_part=""
fi

if [ -n "$five_h_part" ]; then
  printf "%s | ctx:%s | %s | %s" "$model" "$ctx" "$cost_part" "$five_h_part"
else
  printf "%s | ctx:%s | %s" "$model" "$ctx" "$cost_part"
fi

script 建好後記得給執行權限:

chmod +x ~/.claude/statusline-command.sh


最後看一下相關檔案位置,之後要備份或搬到新機器比較不會忘記:

~/.codex/
├── config.toml
└── version.json

~/.claude/
├── settings.json
├── settings.local.json
└── statusline-command.sh


小結一下:

  • Codex 的 statusline 比較像「選內建資訊欄位」
  • Claude Code 的 statusline 比較像「自己寫一個小 renderer」。
兩個都不難,但設定完之後,在長時間 coding session 裡真的比較安心。


又前進一步 ~ enjoy it


Reference

  • https://code.claude.com/docs/en/statusline
  • https://developers.openai.com/codex/cli/slash-commands

星期六, 5月 30, 2026

OpenSpec 安裝與工作流程小記

OpenSpec 安裝與工作流程小記



環境:
  • macOS 26.5
  • Node.js v26.0.0
  • OpenSpec 1.3.1

最近在研究 AI 與 SDD (Spec Driven Development),注意到 OpenSpec 這個工具,先把想做什麼寫清楚,再讓 AI 動手。今天來記錄安裝與第一次跑完整流程的過程。

GitHub https://github.com/Fission-AI/OpenSpec


安裝

# 全域安裝
npm install -g @fission-ai/openspec@latest

# 確認版本
openspec --version
# 1.3.1

在專案初始化

進到專案目錄執行 init,它會問你用哪個 AI 工具(選 Claude Code):

openspec init

安裝完確認一下結構,commands 跟 skills 都裝到 .claude/ 下,不影響版控(因為 .claude/ 在 .gitignore 裡):

.claude/
├── commands/opsx/
│   ├── apply.md
│   ├── archive.md
│   ├── explore.md
│   └── propose.md
└── skills/
    ├── openspec-apply-change
    ├── openspec-archive-change
    ├── openspec-explore
    └── openspec-propose

openspec/
├── changes/
│   └── archive/
└── specs/

openspec/ 下的三個目錄都是空的,git 不追蹤空目錄,所以 git status 完全乾淨。


工作流程:propose → apply → archive

OpenSpec 的核心是三個 slash command:

  • /opsx:propose 規劃
  • /opsx:apply 實作
  • /opsx:archive 歸檔

以這次新增器材摘要功能為例:


Step 1:/opsx:propose

輸入想做什麼,AI 自動在 openspec/changes/<name>/ 建立四份文件:

openspec/changes/admin-machines/
├── proposal.md    # 做什麼、為什麼做
├── design.md      # 技術決策、風險評估
├── specs/
│   └── machine-summary/
│       └── spec.md  # 需求規格與 scenario
└── tasks.md       # 逐一打勾的實作清單

可以在這裡修改內容,確認設計沒問題再繼續。


Step 2:/opsx:apply

AI 讀入四份文件,按 tasks.md 的清單逐一實作,每完成一項就打勾。這次四個 task 全跑完,最後一項是依照 qa-spec.md 補寫 QA 腳本並執行通過。

  • 這邊會列出相關的工項給使用者確認,如果有跟需求不符合的部分可以請 AI 加上工項
  • 預設執行工項不會進行 QA,建議可以將 QA 加入工項,或是引入自己的參照

Step 3:/opsx:archive

實作完畢後歸檔,把 change 資料夾移到 archive/,同時把 specs/ 下的規格同步至主規格庫 openspec/specs/:

openspec/
├── changes/
│   └── archive/
│       └── 2026-05-30-admin-machines/  # 歸檔的 change
└── specs/
    └── machine-summary/
        └── spec.md  # 長期維護的規格

沒有進行中的功能時,changes/ 下只剩 archive/。清爽。


操作了一下沒有太多違和感,如果平常就有使用規範的話,我覺得使用 OpenSpec 最大的好處應該是會保留清楚的 spec 與功能歷史紀錄。



又前進一步 ~ enjoy it

Reference

星期一, 4月 06, 2026

Gemini CLI 多帳戶設定小記

Gemini CLI 多帳戶設定小記



OS: macOS 26.3.1

Gemini CLI: 0.36.0


今天來實作 gemini cli 多帳號設定

  • 因自己有 AI Pro 訂閱, 公司有自己的 GCP 帳號

  • google 在 2026/3/25 限制非訂閱帳戶使用 Gemini Pro 模型, 我使用的環境又會牽扯 不同的 GCP 專案, 故今天花時間整理如何進行多帳號設定與分離


要如何達成呢?

核心觀念:雙重環境隔離

要達成完美的帳戶切換,建議同時操作以下兩組環境變數:

GEMINI_CLI_HOME (Gemini 專屬)

決定了所有 Gemini CLI 本身 的資料存放位置。

  • 預設路徑$HOME (CLI 會自動在其下建立或尋找 .gemini/ 目錄)

  • 目錄結構:包含:

    • .gemini/settings.json: 存放全域偏好設定。

    • .gemini/.env: 存放該 Profile 專用的 API KeyGCP 專案 ID

    • .gemini/tmp/: 存放所有的 對話紀錄 (Sessions)

CLOUDSDK_CONFIG (GCP 認證專屬)

決定了 Google Cloud SDK (gcloud) 的配置目錄與憑證存放位置。

  • 預設路徑~/.config/gcloud/

  • 目錄結構:包含:

    • application_default_credentials.json: 獨立的 ADC 檔案。

    • configurations/: 獨立的專案設定。



那就讓我們開始吧 


編輯 環境設定檔, ( 環境是 macOS 使用 zsh, 所以修改 ~/.zshrc )

加入以下設定


% vi   ~/.zshrc


# --- Gemini CLI 多帳戶隔離配置 ---

# CLOUDSDK_CONFIG (GCP 認證專屬)

# 決定了 **Google Cloud SDK** (`gcloud`) 的配置目錄。

# **預設路徑**:`~/.config/gcloud/` (macOS/Linux)

# GEMINI_CLI_HOME (Gemini 專屬)

# 決定了所有 **Gemini CLI 本身** 的資料存放位置。

# **預設路徑**:`$HOME` (CLI 會自動在其下建立或尋找 `.gemini/` 目錄)


# 1. 個人開發帳戶 (Dev: 預設環境)

alias env-personal='export CLOUDSDK_CONFIG="$HOME/.config/gcloud"; export GEMINI_CLI_HOME="$HOME"; mkdir -p "$CLOUDSDK_CONFIG" "$GEMINI_CLI_HOME/.gemini"; touch "$GEMINI_CLI_HOME/.gemini/.env"; echo "已載入 Gemini/gcloud 個人環境"; echo "提醒:請確保 $GEMINI_CLI_HOME/.gemini/.env 已正確設定個人 API Key 與 Project ID"'


# 2. 臨時測試環境 (Stage: 實驗性質)

alias env-test='export CLOUDSDK_CONFIG="$HOME/.gcloud-test"; export GEMINI_CLI_HOME="$HOME/.gemini-test"; mkdir -p "$CLOUDSDK_CONFIG" "$GEMINI_CLI_HOME/.gemini"; touch "$GEMINI_CLI_HOME/.gemini/.env"; echo "已載入 Gemini/gcloud 測試環境"; echo "提醒:請確保 $GEMINI_CLI_HOME/.gemini/.env 已正確設定測試用 API Key 與 Project ID"'


# 3. 公司工作帳戶 (Prod: 正式環境)

alias env-work='export CLOUDSDK_CONFIG="$HOME/.gcloud-work"; export GEMINI_CLI_HOME="$HOME/.gemini-work"; mkdir -p "$CLOUDSDK_CONFIG" "$GEMINI_CLI_HOME/.gemini"; touch "$GEMINI_CLI_HOME/.gemini/.env"; echo "已載入 Gemini/gcloud 公司環境"; echo "提醒:請確保 $GEMINI_CLI_HOME/.gemini/.env 已正確設定公司 API Key 與 Project ID"'


  • alias 皆為一行, 設定 CLOUDSDK_CONFIG 變數, GEMINI_CLI_HOME 變數, 建立相關目錄, 建立環境 .env 檔案與提醒



開啟一個新的終端機

開始前檢查環境相關設定


% echo  $CLOUDSDK_CONFIG


% echo  $GEMINI_CLI_HOME


% set  |  grep  CLI       

CLICOLOR=1


% env |  grep  CLOUD


% ls  -al  $HOME | grep gemini

drwxr-xr-x  19 max   staff    608  4月  6 14:07 .gemini


% ls  -al  $HOME/.gemini  |  grep  env


% ls  -al  $HOME  |  grep  gcloud


  • 預設 $CLOUDSDK_CONFIG 與 GEMINI_CLI_HOME 沒有設定

  • 如果有看到有 GOOGLE_CLOUD_PROJECT 或是 GOOGLE_CLOUD_LOCATION 這樣的全域變數設定記得要移動到 環境的 .evn 檔案內


執行 env-personal


% env-personal


已載入 Gemini/gcloud 個人環境

提醒:請確保 /Users/max/.gemini/.env 已正確設定個人 API Key 與 Project ID


再次觀察資訊


% echo  $CLOUDSDK_CONFIG          

/Users/max/.config/gcloud


% echo  $GEMINI_CLI_HOME          

/Users/max

% set  |  grep CLI

CLICOLOR=1

GEMINI_CLI_HOME=/Users/max


% env |  grep  CLOUD

CLOUDSDK_CONFIG=/Users/max/.config/gcloud


% ls  -al  $HOME |  grep  gemini     

drwxr-xr-x  20 max   staff    640  4月  6 14:36 .gemini


% ls  -al  $HOME/.gemini  |  grep  env

-rw-r--r--   1 max  staff     0  4月  6 14:36 .env


% ls  -al  $HOME |  grep  gcloud


  • 這邊可以觀察到相關的變數已經設定, 另外也建立了 ~/.gemini/.env 檔案


接下來編輯 ~/.gemini/.env 檔案將相關變數填入


% vi   ~/.gemini/.env


# 認證與身分 (必填)

# ==== Google login 相關 ====

GOOGLE_CLOUD_PROJECT="your-project-id"

# ====  Vertex AI 相關 ====

# gemini cli 因為要使用 vertex ai 模式還要多設定 GOOGLE_CLOUD_LOCATION, gemini 3 可能要設定為global

GOOGLE_CLOUD_LOCATION="global"


# 影像生成 (選填)

# ==== nano banana 相關 ====

# The following Nano Banana models are supported:

#

# gemini-3.1-flash-image-preview (Nano Banana 2 - default)

# gemini-3-pro-image-preview (Nano Banana Pro)

# gemini-2.5-flash-image (Nano Banana v1)

NANOBANANA_MODEL="gemini-3.1-flash-image-preview"

NANOBANANA_API_KEY="YOUR_API_KEY"


# ==== Gemini API Key 相關 ====

#

GEMINI_API_KEY="YOUR_API_KEY"


# 擴充功能設定 (選填)

# ==== Bigquery-data-analytics 相關 ====

# 使用 bigquery-data-analytics Gemini CLI Extension 所需之變數

BIGQUERY_PROJECT="your-billing-project"


  • 這邊請依照自己的需求填入相關變數


接下來開一個新的終端機, 啟動 gemini

詢問雲端專案ID, 看看是否載入正確



到這邊, 個人的開發環境己經設定完成, 接下來要來設定個人測試環境

  • 個人測試環境有可能是另外一個 gmail 帳號, 以不同的訂閱或是驗證方式來執行


執行 env-test 來初始化環境


% env-test


已載入 Gemini/gcloud 測試環境

提醒:請確保 /Users/max/.gemini-test/.gemini/.env 已正確設定測試用 API Key 與 Project ID


觀察資訊


% echo  $CLOUDSDK_CONFIG      

/Users/max/.gcloud-test


% echo  $GEMINI_CLI_HOME      

/Users/max/.gemini-test


% set  |  grep  CLI                 

CLICOLOR=1

GEMINI_CLI_HOME=/Users/max/.gemini-test


% env  |  grep CLOUD           

CLOUDSDK_CONFIG=/Users/max/.gcloud-test


% ls  -al  $HOME |  grep  gemini     

drwxr-xr-x  20 max   staff    640  4月  6 15:00 .gemini

drwxr-xr-x   3 max   staff     96  4月  6 15:21 .gemini-test


% ls -al $HOME | grep gcloud     

drwxr-xr-x   2 max   staff     64  4月  6 15:21 .gcloud-test


  • 這邊可以觀察到變數有新增, 以及建立應有的目錄


接下來進行 gcp 認證 初始化 (測試帳號)


% gcloud  auth  login


開啟瀏覽器進行登入與授權

觀察資訊


% ls  ~/.gcloud-test 


access_tokens.db   config_sentinel    credentials.db     gce                logs

active_config      configurations     default_configs.db legacy_credentials


接下來設定 ADC


% gcloud  auth  application-default login


開啟瀏覽器進行登入與授權


設定 ADC 配額專案 (Quota Project)


% gcloud  auth  application-default  set-quota-project  YOUR_PROJECT_ID


Credentials saved to file: [/Users/max/.gcloud-test/application_default_credentials.json]



接下來設定預設專案

% gcloud  config  set  project  YOUR_PROJECT_ID


Updated property [core/project].


觀察資訊


% gcloud  config  list


在還沒有編輯 .env 環境變數前, 先觀察相關資訊



觀察使用的 gmail 帳號

% gcloud  auth  list


觀察 GEMINI 目錄

% echo  $GEMINI_CLI_HOME

/Users/max/.gemini-test


啟動 gemini


因為是初次啟動, 會詢問驗證方式



選擇登入方式


這個時候可以跟 gemini 進行對話



這個是新的測試環境, 可以觀察到之前的 MCP 都沒有載入, 也因為是使用 Google login 驗證, 使用的模型也受到限制



  • 上方為測試環境, 下方為個人開發環境



這樣終於完成多環境隔離, 又前進一步


~ enjoy it


References

  • 跟 gemini 一起討論