1. 為什麼需要思考環境
在一般的 Web 開發中,遲早會出現三件組合:本機開發、測試伺服器,以及 production 環境。在 ChatGPT Apps 的世界裡也一樣,但多了一個轉折:用戶端(ChatGPT)永遠在雲端,即使你在「本機」開發。
如果一切只在你的筆電上透過隨機的通道位址運作,會出現一些不愉快的情況。第一,URL 不斷變動,你也記不清 Dev Mode 目前綁到哪個 endpoint。第二,效能與網路不像真實上線環境。第三,本機環境經常使用不同的金鑰、不同的服務,等於活在平行時空。
另一方面,長期「直接在正式環境上」也不好。任何修改都可能突然影響到真實使用者的流程,特別是當你已經有 Stripe、OAuth 或 ACP 付款等整合時。從法規與政策角度也有問題:拿真實使用者當實驗對象—並不是進入 Store 的最佳做法。
因此,本講座的目標是讓你腦中形成一個簡單但嚴謹的架構:有 local dev、有 staging、有 production,還有 Dev Mode 作為把 ChatGPT 指向正確環境的方式。而不是一個「我的筆電 + 通道,偶爾突然變成正式環境」的大雜燴。
2. ChatGPT Apps 的特性:用戶端永遠在雲端
在典型的 SPA 應用中,你常常會同時在本機啟動用戶端與伺服器:瀏覽器在 localhost,後端在 localhost,彼此在同一台機器內愉快溝通。
在 ChatGPT Apps 中,事情不是這樣。用戶端(ChatGPT + 你的小工具)始終位於 OpenAI 的基礎設施內。即使你的應用程式在你的筆電上運行,請求會這樣走:
sequenceDiagram
participant User as 使用者
participant ChatGPT as ChatGPT (雲端)
participant Tunnel as HTTPS 通道
participant App as 你的 Next.js + MCP
User->>ChatGPT: 訊息 / 點擊小工具
ChatGPT->>Tunnel: 對 App URL 的 HTTPS 請求
Tunnel->>App: 代理轉發到 localhost
App-->>Tunnel: 回應(UI/JSON)
Tunnel-->>ChatGPT: 回應
ChatGPT-->>User: 更新後的聊天 + 小工具
即使你「只是本機測試」,其實你已經身處分散式系統:有雲端用戶端、有網路、有通道,還有你的本機伺服器。
這一點很重要,因為:
- 本機環境並非全部「都在我這台」。它其實是「雲端 → 通道 → 本機伺服器」。
- 當你之後加入 staging 與 production,差別只在於 ChatGPT 把請求送到哪裡:通道、staging 網域,或正式網域。
3. Local dev:你現在的架構長什麼樣
我們來看看這個通用架構在你那裡現在長怎樣。
經過模組 2–6 之後,你大概會是這個樣子:
- 由指令 npm run dev 啟動的 Next.js 開發伺服器(通常是 http://localhost:3000)。
- 本機 MCP 伺服器(常為獨立行程,例如 http://localhost:2091)。
- HTTPS 通道(ngrok、Cloudflare Tunnel 等),把你的 Next.js/HTTP endpoint 對外公開為像 https://abc123.ngrok.app 這樣的位址。
在 ChatGPT 的 Dev Mode 中,你把這個公開 URL 指給它,ChatGPT 便會開始呼叫你的應用。這整套就是 local dev 環境。
local dev 的關鍵特性:
- 本機環境提供非常快的回饋循環(feedback loop)。你在 VS Code 改了程式,Next.js 做 hot reload,小工具幾秒內就更新。
- 在這裡可以任意嘗試與破壞、使用 mock 資料、測試用金鑰、各種奇怪的設定。
- 這裡沒有真實使用者,除了你之外幾乎沒人知道這個 URL。
通常會像這樣:
graph LR
subgraph Dev Laptop
Next[Next.js dev server]
MCP[MCP server]
end
ChatGPT((ChatGPT Cloud))
Tunnel[[HTTPS 通道]]
ChatGPT --> Tunnel --> Next
Next --> MCP
為了之後不在 local/staging/production 之間搞混,最好讓應用程式本身「知道」它目前在哪個環境。就程式碼而言,顯式固定自己處於 dev 環境是很有幫助的。最簡單的一步——加入一個小小的環境設定模組。
例如,建立檔案 app/config/env.ts:
// app/config/env.ts
export type AppEnv = 'local' | 'staging' | 'production';
export const APP_ENV: AppEnv =
(process.env.NEXT_PUBLIC_APP_ENV as AppEnv) ?? 'local';
export const isProd = APP_ENV === 'production';
在這裡我們:
- 定義一個具型別的環境列舉。
- 讀取變數 NEXT_PUBLIC_APP_ENV(之後你會在 dev/staging/prod 設為不同值)。
- 預設視為 'local',讓本機開發「開箱即用」。
這段本身不涉及部署,但已經提供一個基準點:你的程式碼能理解自己正在哪個環境執行。
接下來,你可以在小工具上顯示目前環境,避免混淆。
// app/components/EnvBadge.tsx
import { APP_ENV } from '../config/env';
export function EnvBadge() {
return <span>ENV: {APP_ENV}</span>;
}
這樣一個小小的徽章,能大幅避免「我現在是在 staging 還是 prod?」的誤判,尤其當小工具在外觀上幾乎一致時。
4. Staging:正式環境的總彩排
Staging 環境就是「正式環境的彩排」。它已不是你筆電上的 dev 伺服器,而是遠端伺服器或 Vercel 部署,跑的是已編譯好的程式碼。
對 ChatGPT 而言,staging 幾乎就像 production:它是一個方便、穩定的 HTTPS endpoint,使用像 https://staging.giftgenius.app 這樣的網域,其中:
- 程式碼已編譯完成(npm run build 成功);
- 使用與正式環境相似的環境變數(相同名稱與格式),但搭配測試金鑰;
- 可用的外部服務相同(Stripe sandbox、測試用 OAuth 帳號);
- 網路拓撲與正式環境相近(例如相同的資料庫類型與區域)。
在 ChatGPT Apps 的脈絡下,為什麼需要 staging:
第一,staging 很適合跑 end‑to‑end 情境。例如:使用者在 ChatGPT → ChatGPT 啟動你的應用 → 小工具詢問使用者 → 呼叫 MCP tool 連到外部 API → 回傳建議 → 小工具顯示結果。這種情境在本機透過隨機通道的行為可能是一種樣子;而在 staging 環境會更接近真實:延遲、網路與資源都更貼近現實。
第二,staging 讓你測試那些在本機很難放心跑的整合,例如付款:Stripe、ACP/Instant Checkout 等。在 staging 中你設定測試金鑰、測試 webhook,完整跑一遍「大人的劇本」,但不會動到真實金流。
第三,staging 是團隊驗證的場所。若你有多位工程師、設計、QA、PM,他們需要一個共同的 URL,不依賴某台筆電是否開機、通道有沒有掛。
你可以把 staging 想成這樣:
graph LR
ChatGPT((ChatGPT Cloud))
AppStaging["GiftGenius Staging https://staging.giftgenius.app"]
ChatGPT --> AppStaging
在 https://staging.giftgenius.app 這個位址背後,可能同時跑著 Next.js、MCP 伺服器、staging 資料庫等。
本講座不深入 Vercel 部署細節,這會在後續主題介紹。此刻只要把 staging 視為一個獨立環境,它在設定與 ChatGPT 的到達方式上,儘可能貼近 production。
5. Production:正式伺服器與真實使用者
Production 環境是有真實使用者 與真實金流 的地方。這裡不再是「我先在 main 快修一下看會怎樣」——任何變更都要審慎、先測試,並盡量要能回滾。
Production 網域必須穩定。它不是隨機的 ngrok URL,而是像 https://giftgenius.app 這樣的正式網域。這也是你在 App 的 Store 設定中填寫的位址:當使用者在 ChatGPT Store 發現並啟動你的應用時,ChatGPT 會呼叫的就是這個 endpoint。
對 production 環境通常有更高要求:
- 穩定性。 低錯誤率、可預期的回應時間、在負載下也能正確運作。後續模組會談到 SLO/SLI,但直覺上就是「應用應該『幾乎一直』可用,且『幾乎總是』回應快速」。
- 安全性。 只放必要的祕密、最低必要權限、妥善處理 PII 與金流。
- 限制實驗。 上班時間不該再有「又重啟了 dev 伺服器」;實驗透過 feature flag、A/B 或獨立的 dev/staging 環境,而不是直接動正式伺服器。
就 ChatGPT 而言,production 已經不是 Dev Mode 的故事,而是 已發佈的 App:它透過 Store 或組織設定提供給使用者,會經過審查,且必須足夠可靠,才能通過審核。
6. Dev Mode 與正式使用 App:各自綁到什麼
最常見的誤解來了:ChatGPT 的 Dev Mode 並不是「一個獨立環境」。它更像是一個路由切換器:在你測試應用時,ChatGPT 目前看向哪個 URL。
在 Dev Mode 你可以:
- 透過通道連到本機應用;
- 連到 staging 環境;
- 甚至暫時把 Dev Mode 指到 production(通常不建議這麼做)。
形式上,Dev Mode 會告訴 ChatGPT:「這是我的 App 的 manifest,這是我的 MCP/Apps SDK endpoint 的 URL。當我啟動這個應用時請用它。」而且你可以更改這個 URL。
發佈到 Store 之後,App 會有正式的 production endpoint。實際使用者將會透過它來連線,而且不能隨意變更:需要新版本、審核等。
在實務上,你的教學專案可以採用如下的合理架構:
graph TD
subgraph Dev Mode
DevApp["GiftGenius Dev App
(Dev Mode)"]
end
subgraph Store
ProdApp["GiftGenius
(Store App)"]
end
UserDev[你/團隊] --> DevApp
UserProd[真實使用者] --> ProdApp
DevApp -->|URL 通道| LocalEnv[Local dev
https://abc123.ngrok.app]
DevApp -->|staging URL| StagingEnv[Staging
https://staging.giftgenius.app]
ProdApp -->|prod URL| ProdEnv[Production
https://giftgenius.app]
你把 Dev Mode 應用 GiftGenius Dev 設定為通常指向 local dev(經由通道),需要時再指向 staging。Store 應用 GiftGenius 僅綁定 production URL。
有時也會另外做一個給 QA 的 App,例如 GiftGenius Staging,只會指向 staging URL。若你有大型測試團隊很方便;在本課程中,一個 dev‑App 就足夠。
要養成這樣的思維:Dev Mode 是你與團隊的私人沙盒,可以更改 URL、調整中繼資料、重啟通道。Store 的正式 App 只看向 production,並遵守更嚴格的規則。
7. 把 Git 分支、網域與 ChatGPT App 串起來
環境不只是伺服器,還包括程式碼分支與 ChatGPT 中 App 的設定。你早晚會希望,光看 URL 或 App 名稱就能知道目前跑的是哪一版程式碼。
一個簡單實用的做法如下。
在開發個別功能時,使用分支 feature/*,例如 feature/new-recommendation-algo。程式碼在本機啟動並配合通道。Dev Mode ChatGPT 通常指向同一個 dev endpoint,由你們輪流啟動各自的本機版本。為每個 feature 分支都建一個獨立的 App 過猶不及。
在發佈前整合功能時,可以設一個 develop 或 staging 分支。這個分支上的內容會自動部署到 staging 環境,例如 Vercel 預覽 URL https://giftgenius-staging.vercel.app。你可以為它建獨立的 Dev Mode‑App,或偶爾把共用的 Dev‑App 暫時指到這個 URL。
分支 main(或 master)只放通過測試的程式碼。它會部署到 production URL,並綁定到 Store 應用 GiftGenius。
看起來可能像這樣:
| 環境 | Git 分支 | URL | ChatGPT App |
|---|---|---|---|
| Local dev | |
|
GiftGenius Dev(Dev Mode) |
| Staging | |
|
GiftGenius Dev 或 GiftGenius Staging |
| Prod | |
|
GiftGenius(Store) |
還記得 APP_ENV(在 app/config/env.ts)嗎?'local'/'staging'/'production' 這些值就對應到表格中的「環境」欄:在 local dev 你用 APP_ENV=local 啟動,staging 部署用 APP_ENV=staging,production 則是 APP_ENV=production。
這張小表不是官僚作風,而是避免用「這個網域上到底跑的是哪個版本?」來除錯的方式。
在程式碼中也能再加強這層連結。例如,在小工具的偵錯模式顯示不僅是 ENV,還加上 commit/branch:
// app/config/buildInfo.ts
export const BUILD_COMMIT = process.env.NEXT_PUBLIC_BUILD_COMMIT ?? 'dev';
export const BUILD_ENV = process.env.NEXT_PUBLIC_APP_ENV ?? 'local';
// app/components/BuildInfo.tsx
import { BUILD_COMMIT, BUILD_ENV } from '../config/buildInfo';
export function BuildInfo() {
return <small>Build: {BUILD_ENV}@{BUILD_COMMIT}</small>;
}
如果你在部署時把 NEXT_PUBLIC_BUILD_COMMIT 設為 commit 的 SHA,小工具就會精確顯示目前運行的是哪個版本。在 staging/prod 這有時能省下數小時的除錯時間。
8. 小練習:把你的環境畫成一張圖
在深入 Vercel 與日誌之前,先「直接畫在餐巾紙上」會很有幫助。這可以是 README.md 中的 mermaid 圖、白板上的草圖,甚至筆記本中的圖片。
對我們的教學專案 GiftGenius,圖可以長這樣:
graph TD
subgraph ChatGPT
DevMode["Dev Mode
(你與團隊)"]
Store["Store
(真實使用者)"]
end
subgraph Servers
Local[Local dev
通道 → localhost]
Staging[Staging
staging.giftgenius.app]
Prod[Production
giftgenius.app]
end
DevMode --> Local
DevMode --> Staging
Store --> Prod
下課立刻可做的實作練習:
- 列出你已經有的所有環境:本機 + 通道、也許是早期的 Vercel 部署,等等。
- 在旁邊標註,哪些 Git 分支會部署到那裡。
- 再旁邊標註哪些 ChatGPT Apps(或連接器)是指向哪裡。
- 用箭頭標出 ChatGPT 連到各伺服器的路徑。
如果你不是單打獨鬥,請在版本庫建立一個 architecture/environments.md 檔案。這能立刻降低「我們的 staging 掛了,但沒人知道 URL 是什麼」的風險。
為了把這套做法和你的應用串在一起,你現在就可以在 Dev Mode 建立一個 App GiftGenius Dev 並約定:預設指向本機環境的通道;當你想測試整個釋出版時,暫時把它改為指向 staging URL。接下來的講座你會學到如何把 staging/prod 部署到 Vercel,並與環境變數串接。
把這些濃縮成一句話:把環境與 Dev Mode 視為你的 App 的坐標系。本機—用於快速開發;staging—用於總彩排;production—面向真實使用者;而 Dev Mode 是你在它們之間的切換器,而不是另一個神奇的獨立環境。
9. 在環境與 Dev Mode 上的常見錯誤
錯誤 1:只用 localhost + 通道,卻把它當成正式環境。
這種做法看似方便:「我幹嘛要 staging 和 prod?通道不是能用?ChatGPT 也連得上。」但通道的 URL 不穩定、網路特性不同,整套系統還依賴一台筆電。當你需要 OAuth callback、Stripe webhooks 或 MCP Gateway 時,缺少像樣的 staging/prod 會帶來痛苦。
錯誤 2:把 Dev Mode 誤認為獨立環境。
很多人以為:「我有 Dev Mode,所以我有 dev 環境。」其實 Dev Mode 只是告訴 ChatGPT 要去哪裡:通道、staging,甚至 prod。Dev Mode 是「用戶端的設定」,不是「伺服器的環境」。伺服器端的環境(local/staging/prod)要由你自己建立:部署程式碼、設定網域與環境變數。
錯誤 3:把 Dev Mode 指向 production,然後「稍微測一下」。
技術上可行:你可以在 Dev Mode 寫上 production URL,像在本機一樣玩你的 App。麻煩在於,你突然開始在真實使用者、真實資料、甚至真實金流上做測試。任何工具或小工具的錯誤,都可能讓正式使用者出問題,而你甚至一時還搞不清原因。最好讓 Dev Mode 連到 dev/staging,正式環境用 Store 的 App。
錯誤 4:缺少清楚的「分支 ↔ 環境 ↔ URL ↔ App」地圖。
如果團隊中沒有任何人能立刻回答:哪些分支部署到 staging、它的 URL 是什麼、哪個 ChatGPT App 指向它,那幾乎保證會混亂。接著就會出現「在我機器上可以、在 staging 不行、在 prod 又是另一回事」的故事。一張簡單的表或 markdown 檔,能反覆為你省下時間。
錯誤 5:低估 local dev 與 staging 的差異。
在本機你啟動的是 dev 伺服器,使用一套金鑰、一組服務與一種網路;在 staging,程式碼已經編譯、在不同環境運行,有不同限制、逾時與路由。如果你只在本機測、把 staging 當裝飾,關鍵錯誤就會在 prod 才爆出來。請習慣這條鏈:先本機開發,再到 staging 驗證,最後才發佈到 production。
錯誤 6:遇到問題只想問 ChatGPT,而忽視環境架構。
有時候遇到問題,開發者會直接「問 ChatGPT 發生什麼事」,而不是先看圖:哪個 App 綁了哪個 URL、在哪個環境出錯、哪裡有日誌。我們今天建立的環境架構,就是下一講系統性除錯的基礎:看日誌、用 MCP 檢視器,最後才考慮模型本身。
GO TO FULL VERSION