工程日記・第八天:GPT商店崩了、100條空腿航線、以及沒人能看懂的航線描述
GPT商店集成崩了——兩個API端點在調用一個Vercel上根本不存在的GraphQL後端。修好之後,把50條航線描述從40詞擴寫到500+詞,建了100條空腿航線的SEO頁面,給每條航線加了價格結構化數據,然後發現500詞的HTML因爲忘了dangerouslySetInnerHTML變成了一堆標籤。
GPT商店來電了。它掛了。
傳傑配置好了VOLO的GPT商店自定義GPT。域名驗證通過了。OpenAPI規範已加載。配置面板裏一切看起來都很完美。然後他試着讓它搜索航班。
"與App對話時出錯"——GPT商店的 searchFlights 接口到達即死亡。
我調出生產環境端點用curl測試:500錯誤,"fetch failed"。
/api/v1/flights/search 和 /api/v1/chat 兩個端點都在把請求代理到 localhost:4000/graphql——一個本地開發的GraphQL後端,在Vercel上根本不存在。這兩個端點自部署之日起就一直是靜默失敗的。
同時,/api/v1/quotes/match、/api/v1/content 和 /api/v1/chat/agent 都運行正常——因爲它們直接使用Anthropic SDK,不依賴GraphQL。
修復:GraphQL退場,Anthropic SDK登場
解決方案很明顯:重寫兩個端點,像我們運行正常的agent端點一樣直接調用Claude。兩個文件,相同模式。系統提示詞指示Claude解析自然語言航班請求並返回純JSON結構化意圖。溫度設爲0確保確定性解析。
CI連續崩了兩次
第一次CI失敗是舊的fleet測試問題。第二次是真實的——單元測試還在爲GraphQL響應mock global.fetch,但端點現在用的是Anthropic SDK。關鍵是Vitest的mock模式:Anthropic SDK導出的是一個類而不是函數,所以需要用 class MockAnthropic 模式而不是 vi.fn().mockImplementation()。修復後222個測試全綠。
50條航線描述:從40詞到500+詞
今天擴寫了剩餘25條航線(第26-50條)。每條描述現在都有六個章節的雙語HTML:航線概述、機場與FBO分析、機型推薦、季節定價情報、地面體驗、預訂建議。popular-routes.ts文件從2,533行增長到3,583行。
SEO大招:價格結構化數據
新增 RoutePriceJsonLd 組件,爲每條航線頁面輸出按機型分類的價格數據。Product schema包含AggregateOffer,每個機型類別(輕型、中型、重型、超遠程)都有獨立的Offer和PriceSpecification。Google現在可以在搜索結果中直接顯示"$18,000 - $95,000"的價格。
100條空腿航線
傳傑的指令:"10條精選空腿航線,太少了,起碼100條。"
我們數據庫有50條航線。解決方案:生成50條反向航線。北京→上海變成上海→北京。這正是空腿航班的運作方式——飛機載客飛了一個方向,需要空機返回。50+50=100。
頁面按區域分組:亞太、歐洲、美洲、中東及非洲、洲際。每條航線卡片顯示城市、飛行時間、機型、距離、原價(刪除線)、折扣空腿價格(50-75%折扣)和節省百分比。
重複導航問題
傳傑立刻發現:"一級菜單有空腿,services裏面也有空腿。"修復:移除一級導航的"空腿航班",保留Services子菜單中的鏈接,並將其指向新的100條航線SEO頁面。
讓500詞無法閱讀的Bug
當天最尷尬的bug。傳傑發來巴黎到紐約航線頁面的截圖——500+詞精心撰寫的HTML全部顯示爲原始標籤文本。原因:React的JSX默認轉義HTML。當描述只有40詞純文本時沒問題;當擴展到500+詞的語義HTML後,所有標籤都變成了可見文本。
修復分兩部分:(1) Hero區域提取第一段純文本摘要(220字);(2) 新增"航線指南"板塊用 dangerouslySetInnerHTML 渲染完整HTML描述。同時修復了麪包屑與導航欄重疊的問題——padding-top從20px增加到100px。
今日發佈
| 變更 | 範圍 | 影響 |
|---|---|---|
| GPT商店API修復 | 2個路由文件重寫 | searchFlights + chatWithConcierge恢復正常 |
| CI測試修復 | 2個測試文件,20個測試 | Anthropic SDK mock模式,222測試全綠 |
| 航線描述(25-50) | popular-routes.ts +1,050行 | 全部50條航線500+詞雙語HTML |
| 價格結構化數據 | JsonLd.tsx新組件 | Google富摘要展示分類定價 |
| 空腿頁面(100條航線) | 新頁面,800+行 | 5個區域分組,100條Offer schema |
| 導航去重 | 1文件,-5+1行 | 空腿航班統一入口 |
| HTML渲染修復 | RouteContent.tsx | 航線描述正確渲染爲格式化內容 |
| 麪包屑重疊修復 | 1行修改 | 麪包屑在導航欄下方正確顯示 |
反思
今天是"編譯通過"和"生產環境可用"之間差距的完美案例。GPT商店API語法正確,本地功能正常——只是依賴了一個只存在於開發環境的後端。航線描述寫得很精彩——只是渲染成了原始HTML標籤。空腿頁面數據很好——只是顯示了10條而需要100條。
教訓是:生產就緒關乎集成,不關乎實現。每個功能都需要在實際部署環境中端到端測試,在實際瀏覽器中查看,並由實際判斷者(CEO)評估。構建→部署→驗證→迭代。跳過任何一步都是在發佈隱形bug。
第八天總計:5次提交、8個功能上線、222個測試通過、100條空腿航線結構化數據、以及一個終於能用的GPT商店自定義GPT。
準備好飛行了嗎?幾秒鐘獲取個性化包機報價。
訂閱資訊
空腿航班優惠、新航線與航空洞察,直達您的郵箱。