你可能剛聽到 GPT‑5‑Codex 這個詞,搜尋結果多半是「它是什麼?怎麼安裝?可以做什麼?跟 Copilot/Cursor/Claude Code 有何不同?」這篇是給工程師、校務單位、社團與教學現場的一步一步指南:理解觀念 → 安裝設定 → 5 分鐘實測 → 校園可落地的「活動報名+QR 點名」專案 → 安全與合規 → 進階最佳化。
為何 GPT‑5‑Codex 正夯(定位與情境)
以往「會寫程式的 AI」多半像超強的自動補全;而 GPT‑5‑Codex 的重點在於它被設計成可委派任務的程式代理(AI 程式代理),能看懂整個專案、分解工作、執行指令、跑測試再修到通過,甚至提出 PR 審查建議。這樣的能力特別適合:
- 個人開發者:快速建立小工具、重構舊專案、補測試。
- 團隊與學校單位:把例行工作(匯表、寄發通知、簡易資料庫 CRUD)自動化。
- 教學場景:在課堂演示「從規格到可運行系統」的完整流程。
一句話總結:Codex = 能動手做事的夥伴,不只寫出程式片段,而是能在安全邊界內「自己跑完一件事」。
核心觀念:Agentic Coding 與模型特性
1) Agentic Coding(代理式編碼)
你提供目標與限制,Codex 會規劃步驟、撰寫與執行程式、觀察結果、再自動調整。這與傳統「只回一段程式碼」不同,它偏向流程導向與結果導向。
2) 動態思考時間(Test‑Time Compute)
簡單任務=短思考、少資源;困難任務=拉長推理與測試時間。這讓體驗更像跟人類夥伴配對:小事快做完,大事耐心處理。
3) 專案級理解與 PR 審查
它能跨檔走讀、理解相依、提出實用的 Code Review 建議(例如性能、安全性、測試缺口),並搭配雲端長任務完成大型重構。
4) 預設安全邊界
本機/雲端皆以沙盒執行、預設關閉網路、限制寫入當前工作目錄;若需上網,使用 allowlist 有條件開放。
安裝設定:Codex CLI/IDE/雲端
系統需求
- 作業系統:macOS 或 Linux;Windows 建議使用 WSL。
- Node.js 18+、Git;(選用)VS Code 或 JetBrains 系列。
- 可登入 CLI 的 OpenAI/ChatGPT 帳號。
安裝 Codex CLI
# 安裝(擇一) npm i -g @openai/codex # 或 Homebrew(如你的環境有提供) # brew install codex # 啟動與登入(首次會引導登入) codex # 在 CLI 內切換模型(建議明確指定) /model gpt-5-codex
IDE 擴充與雲端任務(選用)
VS Code 外掛可提供行內補全、配對編程、指令面板;雲端任務適合大型重構或長時間測試,讓代理在你離開鍵盤時持續工作,完成後回報結果與差異。
5 分鐘實測:CSV → JSON 任務
先用最小可行任務理解 Codex 的節奏與安全邊界。
mkdir quick-csv && cd quick-csv && git init echo "id,name\n1,Ada\n2,Bob" > sample.csv # 進入 CLI(若尚未) codex /model gpt-5-codex # 在 CLI 互動視窗貼上任務: 請幫我用 Node.js 建立一支 CLI 工具: 1. 讀取 sample.csv 2. 轉為 JSON 並輸出到 dist/out.json 3. 以 Jest 撰寫一個基本單元測試 4. 執行測試,若失敗請修到通過並解釋修改原因
通常 Codex 會:初始化專案 → 寫入程式與測試 → 安裝依賴 → 執行測試 → 回報結果。你可以追加需求,例如「加入欄位驗證與錯誤訊息」、「CLI 參數支援自訂輸入檔」。
dist/out.json 成功產生、Jest 全數通過,並能在 CLI 裡看到 Codex 的變更說明。校園實作:活動報名+QR 點名(完整步驟)
這是最常見、也最能展示 Agentic Coding 價值的案例。功能包含:線上報名(學號/姓名/Email)、個人 QR 入場碼、現場點名、CSV 匯出、30 天自動刪除。
0) 建專案骨架
mkdir campus-event-qr && cd campus-event-qr && git init npx create-next-app\@latest . --typescript --eslint npm i @prisma/client prisma qrcode nanoid npx prisma init --datasource-provider sqlite
1) Prisma Schema
/* prisma/schema.prisma */
datasource db { provider = "sqlite"; url = "file:./dev.db" }
generator client { provider = "prisma-client-js" }
model Registration {
id String @id @default(cuid())
studentId String
name String
email String
uniqueCode String @unique
createdAt DateTime @default(now())
checkedInAt DateTime?
}
npx prisma migrate dev --name init
2) 共用 Prisma Client
// lib/prisma.ts
import { PrismaClient } from '@prisma/client';
const globalForPrisma = global as unknown as { prisma: PrismaClient };
export const prisma = globalForPrisma.prisma || new PrismaClient();
if (process.env.NODE\_ENV !== 'production') globalForPrisma.prisma = prisma;
3) 報名 API
// app/api/register/route.ts
import { NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
import { customAlphabet } from 'nanoid';
const nano = customAlphabet('123456789ABCDEFGHJKLMNPQRSTUVWXYZ', 10);
export async function POST(req: Request) {
const body = await req.json();
const { studentId, name, email } = body || {};
if (!studentId || !name || !email) {
return NextResponse.json({ ok\:false, message:'缺少必要欄位' }, { status:400 });
}
const uniqueCode = nano();
const rec = await prisma.registration.create({
data: { studentId, name, email, uniqueCode }
});
return NextResponse.json({ ok\:true, uniqueCode, id: rec.id });
}
4) 產生個人 QR
// app/api/qr/[code]/route.ts
import { NextResponse } from 'next/server';
import QRCode from 'qrcode';
export async function GET(\_: Request, { params }: { params: { code: string }}) {
const url = `${process.env.NEXT_PUBLIC_BASE_URL}/checkin?code=${params.code}`;
const dataUrl = await QRCode.toDataURL(url, { margin: 1, width: 320 });
const base64 = dataUrl.split(',')\[1];
const buf = Buffer.from(base64, 'base64');
return new NextResponse(buf, {
headers: { 'Content-Type':'image/png', 'Cache-Control':'public, max-age=86400' }
});
}
5) 點名 API
// app/api/checkin/route.ts
import { NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
export async function POST(req: Request) {
const { code, pass } = await req.json();
if (pass !== process.env.CHECKIN\_PASS) {
return NextResponse.json({ ok\:false, message:'未授權' }, { status:401 });
}
const found = await prisma.registration.update({
where: { uniqueCode: code },
data: { checkedInAt: new Date() }
}).catch(()=>null);
if (!found) return NextResponse.json({ ok\:false, message:'無效或不存在' }, { status:404 });
return NextResponse.json({ ok\:true, checkedInAt: found.checkedInAt });
}
6) 匯出 CSV
// app/api/export/route.ts
import { NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
export async function GET() {
const rows = await prisma.registration.findMany({ orderBy:{ createdAt:'asc' }});
const head = 'studentId,name,email,uniqueCode,createdAt,checkedInAt';
const body = rows.map(r => \[
r.studentId, r.name, r.email, r.uniqueCode,
r.createdAt.toISOString(),
r.checkedInAt ? r.checkedInAt.toISOString() : ''
].join(',')).join('\n');
const csv = head + '\n' + body;
return new NextResponse(csv, { headers:{
'Content-Type':'text/csv; charset=utf-8',
'Content-Disposition':'attachment; filename="registrations.csv"'
}});
}
7) 前台頁面(報名/Check‑in)
// app/page.tsx
'use client';
import { useState } from 'react';
export default function Home(){
const \[form,setForm]=useState({studentId:'',name:'',email:''});
const \[code,setCode]=useState\(null);
const submit=async(e\:any)=>{e.preventDefault();
const r = await fetch('/api/register',{method:'POST',headers:{'Content-Type':'application/json'},body\:JSON.stringify(form)});
const j = await r.json(); if(j.ok) setCode(j.uniqueCode); else alert(j.message||'failed');
};
return (
\
活動報名
學號\setForm({...form,studentId\:e.target.value})}/> 姓名\setForm({...form,name\:e.target.value})}/> Email\setForm({...form,email\:e.target.value})}/>送出報名 {code && (你的入場 QR
\現場可直接掃描,或開啟 /checkin?code={code} 頁面。
現場點名
code:{code || '(URL 未帶 code 參數)'}
\setPass(e.target.value)} type="password"/>點名{msg}
8) 自動刪除(30 天)
// scripts/cleanup.ts
import { prisma } from '@/lib/prisma';
async function main(){
const cutoff = new Date(Date.now() - 30*24*60*60*1000);
const res = await prisma.registration.deleteMany({ where:{ createdAt:{ lt: cutoff } }});
console.log('deleted:', res.count);
}
main().finally(()=>process.exit(0));
// package.json
"scripts": { "cleanup": "ts-node --transpile-only scripts/cleanup.ts" }
# 伺服器以 cron 每日執行一次
9) 讓 Codex 代辦更多事
- 寫 e2e 測試(Playwright/Cypress)。
- 根據校內品牌色做主題化樣式。
- 新增「多場次」與「匯出指定場次」功能。
- 產出操作手冊 PDF 與簡報摘要(Codex 可草擬內容、你再潤飾)。
安全風險與治理:沙盒、網路權限、資料保存
可把下列原則當作團隊標準作業:
- 預設沙盒:維持無網路、限制寫入工作目錄;必要時以 allowlist 開啟特定網域(如學校郵件 API)。
- 憑證管理:金鑰與密碼只放環境變數;避免寫入程式碼庫。
- 資料最小化:只蒐集必須欄位;提供查詢/刪除權;建立固定清理排程。
- PR 與稽核:所有變更走 PR;CI 執行測試、Lint、安全掃描;保留變更紀錄。
比較:GPT‑5 vs Codex、與 Copilot/Cursor/Claude Code
GPT‑5(通用)vs GPT‑5‑Codex(工程實作)
- 定位:前者偏對話與通用推理;後者專攻工程任務與長流程自動化。
- 能力:Codex 在跨檔走讀、大型重構、PR 審查較有優勢;並能動態調整思考時間。
與 Copilot / Cursor / Claude Code 的常見比較點
- 補全 vs 代理:補全型工具對「單檔輸入、即時建議」很強;而跨檔任務、落地執行與修測,代理式流程更合適。
- 安全治理:是否有預設沙盒、網路權限控管、審批與稽核機制,是導入組織時的關鍵。
- 生態整合:各家對 Git 平台、CI/CD、Issue/PR 工作流的整合程度不同,導入前請實測。
常見錯誤排除(Troubleshooting)
安裝/登入問題
- NPM 失敗:檢查 Node 版本、代理/防火牆、改用離峰時段;Windows 請用 WSL。
- CLI 登入卡住:改用無痕視窗、關閉廣告/追蹤外掛;公司/校園網路請先開放必要網域。
執行任務問題
- 依賴安裝失敗:請 Codex 產生
package-lock.json並重試;或改用pnpm/yarn。 - 測試不通過:要求 Codex 「逐一解釋失敗原因並提供修正 PR」。
- 檔案太多:把需求整理為
SPEC.md,請它分批完成與提交。
FAQ:價格、中文、下載、相容性
Q1. 價格/方案怎麼看?
依帳戶方案與使用情境(CLI、雲端、企業)而定。建議先用個人方案完成 PoC,再按團隊需求升級。
Q2. 有中文介面或教學嗎?
有,本篇即為完整中文教學;在 SPEC 中也可要求「產生含繁中註解的程式碼」。
Q3. 下載與安裝遇到錯誤?
多半是 Node 過舊、權限不足、或代理阻擋。先 node -v 檢查,再看是否需設定 Proxy/替代登錄。
Q4. 支援哪些 IDE?
VS Code、JetBrains(視外掛支援)皆可;或純 CLI+雲端模式也行。
Q5. 一定要資料庫嗎?
小活動用 SQLite 即可;長期與多人並發建議 PostgreSQL(留意個資合規與備份策略)。
下一步:最佳實務與延伸應用
- 把代理納入 PR 流程:要求 Codex 產生變更說明、風險清單與回滾策略。
- 建立「安全模板」:專案初始就包含 ESLint、Prettier、測試、掃描與資料刪除腳本。
- 教學延伸:把 QR 點名改為「器材借用、教室預約、課程回饋儀表板」。
- 評估指標:以「通過測試、PR 審查意見命中率、修復時間」衡量導入成效。
行動清單(立刻動手):
- 安裝 Codex CLI 並切
/model gpt-5-codex。 - 完成「CSV → JSON」實測任務,熟悉代理節奏。
- 依本文步驟建立「活動報名+QR 點名」並部署;撰寫 README 的資料保存政策。
附錄 B|參考連結
