回到頂部
應用程式後端經過驗證、逾時與記錄層呼叫 AI API 的資料流程

AI API 串接教學:第一次呼叫到可上線的 Node.js 架構

用 Node.js 串接 AI API,真正困難的是金鑰、逾時、重試、格式驗證與成本監控。本文以 OpenAI Responses API 示範一條可執行路徑,再說明如何抽換 Claude 或 Gemini。

你的程式已經能收到第一段模型回覆,現在可以直接上線嗎?還不行。正式產品最常遇到的是金鑰外洩、請求卡住、格式偶爾變形、重試造成重複動作,以及費用沒有人監控。

這篇用 Node.js 與 OpenAI Responses API 示範一條最短可行路徑。若你最後改用 Claude 或 Gemini,後端的驗證、逾時、日誌與評測設計仍然適用。

先確認:你真的需要 API 嗎?

如果只是自己偶爾整理文件,網頁版工具通常比較省事。當需求符合以下任一情況,才值得串 API:

  • 使用者會在你的網站或 App 裡直接使用 AI。
  • 同一流程需要批次處理大量資料。
  • 模型要查詢你控制的資料或呼叫內部工具。
  • 輸出必須是程式可解析的固定格式。
  • 需要記錄延遲、成本、錯誤與版本。

API 帳號與 ChatGPT 等訂閱通常是不同的計費與權限系統。開發前先確認供應商的 API billing、地區與資料處理條款。

最小架構:瀏覽器不要直接呼叫模型

正確流向是「前端 -> 你的後端 -> AI Provider」。API Key 只存在後端環境變數;前端只送必要輸入給你自己的 endpoint。

如果把 Key 寫進 JavaScript bundle,即使畫面沒有顯示,任何人仍可在瀏覽器開發工具或下載的程式碼中找到它。發現外洩時要立刻撤銷 Key、建立新 Key,並檢查用量。

第一步:建立專案與環境變數

mkdir ai-api-demo
cd ai-api-demo
npm init -y
npm install openai express zod

設定環境變數,不要把值寫進原始碼:

OPENAI_API_KEY=你的金鑰
OPENAI_MODEL=gpt-5.6-terra

把 .env 加入 .gitignore。正式環境使用部署平台的 Secret 或雲端 Secret Manager,並讓開發、測試與正式環境使用不同金鑰。

第二步:完成第一次 Responses API 呼叫

先用一個獨立腳本確認金鑰、SDK 與模型權限都正常:

import OpenAI from "openai";

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const response = await client.responses.create({
  model: process.env.OPENAI_MODEL || "gpt-5.6-terra",
  input: "用三句繁體中文解釋 RAG,並給一個客服知識庫例子。",
});

console.log(response.output_text);
console.log(response.usage);

OpenAI 目前建議新模型與工具工作流使用 Responses API。模型名稱會隨時間變動,所以用環境變數管理;升級前以測試集比較,不要把 model ID 散落在多個檔案。

第三步:在後端驗證輸入

下面是一個精簡的 Express endpoint。它先限制輸入長度,再設定 20 秒逾時;前端不會取得 Provider 的原始錯誤或 API Key。

import express from "express";
import OpenAI from "openai";
import { z } from "zod";

const app = express();
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const inputSchema = z.object({
  question: z.string().trim().min(1).max(2_000),
});

app.use(express.json({ limit: "16kb" }));

app.post("/api/answer", async (req, res) => {
  const parsed = inputSchema.safeParse(req.body);
  if (!parsed.success) {
    return res.status(400).json({ error: "輸入格式不正確" });
  }

  try {
    const response = await client.responses.create(
      {
        model: process.env.OPENAI_MODEL || "gpt-5.6-terra",
        input: [
          { role: "developer", content: "使用繁體中文。資料不足時直接說不知道。" },
          { role: "user", content: parsed.data.question },
        ],
      },
      { timeout: 20_000 },
    );

    return res.json({ answer: response.output_text });
  } catch (error) {
    console.error("ai_request_failed", {
      requestId: error?.request_id,
      status: error?.status,
      message: error?.message,
    });
    return res.status(502).json({ error: "AI 服務暫時無法使用" });
  }
});

app.listen(3000);

這還不是完整正式系統。你仍需加上登入、速率限制、CORS 規則、內容大小限制、監控與隱私處理,但已比從瀏覽器直接送 Key 安全許多。

第四步:需要 JSON 時,用 schema 驗證

若下游程式需要分類、金額或日期,不要叫模型「盡量回 JSON」後直接 JSON.parse()。應使用 Provider 支援的 structured outputs 或 JSON schema,收到結果後再用 Zod、JSON Schema 等工具驗證。

驗證失敗時,可以有限度地重試一次或回到人工處理,但不要悄悄猜測缺少欄位。詳細做法可參考 Structured Output 指南。

第五步:哪些錯誤可以重試?

先依 HTTP 狀態與錯誤類型分類:

  • 400:請求內容有誤,修正程式,不要原樣重試。
  • 401:金鑰無效或未載入,檢查 Secret。
  • 403:帳號或專案沒有權限,確認模型與地區。
  • 429:速率或配額限制,可依回應資訊退避重試。
  • 500、503:供應商暫時錯誤,可有限次數重試。
  • timeout:先取消請求並記錄;若任務可重複,再決定是否重試。

退避可採 1 秒、2 秒、4 秒並加少量隨機延遲,上限通常 2 到 3 次。涉及寄信、付款或寫入資料的工具呼叫,還要設計 idempotency key,否則重試可能把同一動作執行兩次。

第六步:記錄什麼,才找得到問題?

至少保存請求 ID、模型、版本、延遲、輸入與輸出 Token、錯誤類型、功能名稱與成功狀態。不要把完整個資、密碼、API Key 或機密文件原文直接寫進日誌。

你要能回答三個問題:哪個功能最花錢、哪種請求最常失敗、模型升級後成功率有沒有真的變好。只有總 Token 數,通常無法定位產品問題。

成本怎麼估?

不要用一個手算範例當長期預算。把實際回應的 usage 欄位送進成本紀錄,依當下官方價格計算,並設定每日與每月告警。

更有意義的指標是「每次成功任務成本」:

每次成功任務成本 = 模型、工具與重試總費用 / 成功完成的任務數

小模型若需要多次重試或大量人工修正,未必比較便宜。先用真實案例測品質,再調整模型、prompt、快取與最大輸出。

要不要做多 Provider fallback?

第一版先不要。不同 Provider 的訊息格式、工具呼叫、結構化輸出與安全行為並不完全相同;直接切換可能回傳格式正確但語意錯誤的結果。

當單一供應商中斷已造成明確商業損失,再抽象出小型介面,並為每個 Provider 跑同一套回歸測試。Fallback 也應依功能分級:一般摘要可以降級,付款、法律或醫療流程則寧可暫停並轉人工。

Google 官方目前建議使用 google-genai 或 @google/genai,舊的 google-generativeai、@google/generative-ai 已不再積極維護。因此 Provider SDK 應集中在 adapter,避免版本更換時修改整個專案。

上線前檢查清單

  • Key 只在後端 Secret,且開發與正式環境分開。
  • 輸入有型別、長度、檔案大小與權限驗證。
  • 每個請求有 timeout,重試次數有上限。
  • 寫入動作有 idempotency 與人工確認。
  • 結構化輸出通過 schema 驗證。
  • 日誌不包含完整敏感資料。
  • 成本、延遲、錯誤率與成功率都有告警。
  • 模型或 prompt 更新前會重跑代表性測試集。

常見問題

OpenAI、Claude、Gemini API 應該先學哪一個?

先選最符合現有團隊與產品需求的一家,把驗證、錯誤處理、格式與監控做完整。三家的 SDK 名稱與模型會更新,不要為了表面相容一開始就同時維護三套。之後用同一批真實任務評估替代方案。

可以把 API Key 放在 Vercel 或 Cloudflare 的前端環境變數嗎?

只有明確標記為伺服器端、且不會打包進瀏覽器的 Secret 才可以。凡是會出現在 client bundle、公開環境變數或網路請求中的值,都視為已公開。

串接 AI API 一定要用 LangChain 嗎?

不用。單次生成、分類或固定工具呼叫先用官方 SDK,較容易理解錯誤與成本。當工作流真的需要多步編排、狀態或多 Provider,再評估框架是否減少複雜度。

官方資料

完成基本呼叫後,下一步是把答案做成程式可驗證的資料。請接著閱讀 Structured Output 指南。

№ · further reading

延伸閱讀