本文 AI 產出,尚未審核

LangChain ─ 安裝與環境設定

主題:環境變數與 API Key 設定


簡介

在使用 LangChain 這套結合大型語言模型(LLM)與外部工具的框架時,最先需要解決的就是 環境變數API Key 的管理。

  • 正確的環境設定不僅能讓程式碼在本機、測試環境與正式環境之間無縫切換,也能避免把機密資訊(如 OpenAI、Azure、Anthropic 等服務的金鑰)意外寫入程式庫,降低資安風險。
  • LangChain 的許多範例與官方文件都假設你已經在 process.env 中配置好相應的金鑰;若缺少或寫錯,程式在執行時會直接拋出 AuthenticationError,讓開發者在除錯階段浪費大量時間。

本篇文章將從 環境變數的基本概念不同平台的設定方式安全存放 API Key 以及 實務範例 四個面向,完整說明如何在 Node.js(JavaScript/TypeScript)環境中為 LangChain 打好基礎。


核心概念

1. 為什麼要使用環境變數?

  • 分離設定與程式碼:同一套程式碼可以在開發、測試、正式三個環境共用,只要切換環境變數即可。
  • 避免金鑰外泄:把金鑰寫在程式碼裡(例如 const OPENAI_API_KEY = "sk-xxxx")會被 git 追蹤,甚至被公開倉庫抓取。
  • 支援 CI/CD:大部分的 CI 平台(GitHub Actions、GitLab CI、Azure Pipelines)都提供「Secret」功能,直接注入環境變數即可。

2. .env 檔案與 dotenv 套件

在 Node.js 專案中,最常見的做法是把環境變數寫在根目錄的 .env 檔案,然後在程式啟動時由 dotenv 套件載入:

# .env 範例
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxx
LANGCHAIN_TRACING_V2=true
// index.js
// 先載入 dotenv,讓 process.env 取得 .env 內的變數
require('dotenv').config();

const { OpenAI } = require('langchain/llms/openai');

// 從環境變數取得金鑰
const openai = new OpenAI({
  openAIApiKey: process.env.OPENAI_API_KEY,
});

⚠️ 注意.env 檔案絕對不能加入版本控制,務必在 .gitignore 中排除:

# .gitignore
.env

3. 多環境(development / staging / production)

如果專案需要同時支援多個環境,建議使用以下慣例:

環境 .env 檔名 說明
開發 .env.development 本機開發使用的設定
測試 .env.test CI 測試或本機測試用
正式 .env.production 部署到雲端或容器時的設定

在啟動指令中指定載入的檔案:

// package.json scripts 範例
{
  "scripts": {
    "start:dev": "node -r dotenv/config index.js dotenv_config_path=.env.development",
    "test": "node -r dotenv/config jest dotenv_config_path=.env.test",
    "start:prod": "node -r dotenv/config index.js dotenv_config_path=.env.production"
  }
}

4. 使用平台原生的環境變數(Docker、K8s、Vercel、Render)

雖然 .env 方便本機開發,但在容器化或雲端平台時,建議直接在 DockerfileKubernetes ConfigMap/Secret、或平台提供的 環境變數設定頁 中注入:

# Dockerfile 範例
FROM node:20-alpine

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .

# 使用 build‑arg 傳入金鑰(不建議在 image 中硬編碼金鑰)
ARG OPENAI_API_KEY
ENV OPENAI_API_KEY=${OPENAI_API_KEY}

CMD ["node", "index.js"]

在部署時:

docker build --build-arg OPENAI_API_KEY=sk-xxxx -t my-langchain-app .
docker run -e ANTHROPIC_API_KEY=sk-ant-xxxx -p 3000:3000 my-langchain-app

5. LangChain 常見的環境變數

變數名稱 功能 範例值
OPENAI_API_KEY OpenAI 金鑰 sk-xxxxxxxxxxxx
ANTHROPIC_API_KEY Anthropic 金鑰 sk-ant-xxxxxxxx
COHERE_API_KEY Cohere 金鑰 xxxxxxxxxxxxxxxx
LANGCHAIN_TRACING_V2 開啟 LangChain 追蹤(true/false) true
LANGCHAIN_ENDPOINT 自訂追蹤服務端點 https://api.smith.langchain.com
LANGCHAIN_API_KEY LangChain 追蹤服務金鑰 lc_XXXXXXXXXXXXXXXX

程式碼範例

以下提供 5 個實用範例,示範如何在不同情境下載入與使用環境變數。每段程式碼皆加上說明性註解,方便讀者快速上手。

範例 1:最簡單的 OpenAI LLM 呼叫

// 01-openai-basic.js
require('dotenv').config(); // 載入 .env

const { OpenAI } = require('langchain/llms/openai');

const llm = new OpenAI({
  // 從環境變數取得 API Key,若未設定會拋出錯誤
  openAIApiKey: process.env.OPENAI_API_KEY,
  temperature: 0.7,
});

async function run() {
  const response = await llm.invoke("請用繁體中文說明什麼是 LangChain");
  console.log(response);
}

run().catch(console.error);

重點process.env.OPENAI_API_KEY 必須在執行前正確載入,否則 OpenAI 會在建構子內檢查失敗。

範例 2:使用 dotenv-flow 管理多環境

// 02-multi-env.js
// dotenv-flow 會自動根據 NODE_ENV 載入對應的 .env.* 檔案
require('dotenv-flow').config();

const { OpenAI } = require('langchain/llms/openai');

const llm = new OpenAI({
  openAIApiKey: process.env.OPENAI_API_KEY,
  modelName: "gpt-4o-mini",
});

console.log(`目前環境:${process.env.NODE_ENV}`); // development / test / production

技巧:在 CI 測試時只要把 NODE_ENV=testdotenv-flow 會自動讀取 .env.test,不必再寫額外指令。

範例 3:在 Docker 中使用 build‑arg 注入金鑰

# Dockerfile (簡化版)
FROM node:20-alpine

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .

ARG OPENAI_API_KEY
ENV OPENAI_API_KEY=${OPENAI_API_KEY}

CMD ["node", "03-docker-example.js"]
// 03-docker-example.js
require('dotenv').config(); // Docker 內的 ENV 已經設定好

const { OpenAI } = require('langchain/llms/openai');

const llm = new OpenAI({
  openAIApiKey: process.env.OPENAI_API_KEY,
});

llm.invoke("列出 3 個 LangChain 的核心概念")
  .then(console.log)
  .catch(console.error);

安全提醒ARG 只在建構階段可見,ENV 才會在容器執行時可用。避免在 Dockerfile 中直接寫死金鑰。

範例 4:使用 LangChain 追蹤功能(Tracing)

// 04-tracing.js
require('dotenv').config();

const { OpenAI } = require('langchain/llms/openai');
const { LangChainTracer } = require('langchain/tracing');

const tracer = new LangChainTracer({
  // 若已在 .env 中設定 LANGCHAIN_API_KEY,這裡可不必手動填
  apiKey: process.env.LANGCHAIN_API_KEY,
  endpoint: process.env.LANGCHAIN_ENDPOINT, // 可自訂
});

const llm = new OpenAI({
  openAIApiKey: process.env.OPENAI_API_KEY,
  temperature: 0,
  // 啟用追蹤
  callbacks: [tracer],
});

async function run() {
  const res = await llm.invoke("說明什麼是 Retrieval Augmented Generation (RAG)");
  console.log(res);
  // 追蹤資料會自動送到 LangChain Cloud
}

run().catch(console.error);

說明:只要把 LANGCHAIN_TRACING_V2=true 加入 .env,LangChain 會自動啟用 V2 追蹤;若想自行設定 tracer,請參考上例。

範例 5:結合多個 LLM(OpenAI + Anthropic)與環境變數

// 05-multi-llm.js
require('dotenv').config();

const { OpenAI } = require('langchain/llms/openai');
const { Anthropic } = require('langchain/llms/anthropic');
const { ChatPromptTemplate, ChatMessage } = require('langchain/prompts');

// 建立兩個不同的 LLM 實例
const openai = new OpenAI({ openAIApiKey: process.env.OPENAI_API_KEY });
const anthropic = new Anthropic({ anthropicApiKey: process.env.ANTHROPIC_API_KEY });

async function compareModels(question) {
  const [oaRes, anRes] = await Promise.all([
    openai.invoke(question),
    anthropic.invoke(question),
  ]);

  console.log("=== OpenAI 回答 ===");
  console.log(oaRes);
  console.log("\n=== Anthropic 回答 ===");
  console.log(anRes);
}

compareModels("什麼是 Prompt Engineering?")
  .catch(console.error);

實務價值:在同一個應用中同時測試不同供應商的模型,能快速比較效能與成本,對於 RAGAgent 的設計非常有幫助。


常見陷阱與最佳實踐

陷阱 可能的結果 解決方案 / Best Practice
金鑰硬編碼在程式碼 金鑰被推到 public repo,造成資安與帳單風險 永遠使用 process.env,並把 .env 加入 .gitignore
忘記載入 .env process.env.xxxundefined,導致 AuthenticationError 在入口檔(index.jsapp.ts)最上方執行 require('dotenv').config()
在 Dockerfile 中直接寫金鑰 金鑰會出現在 image 歷史,任何人拉取 image 都能看到 使用 ARG + ENV,或在容器執行時用 -e 注入
環境變數名稱拼寫錯誤 程式無法取得金鑰,卻不會立即拋出錯誤(除非 LLM 初始化時檢查) 建議使用 TypeScriptprocess.env 型別或 dotenv-safe 來驗證必填變數
不同環境使用相同金鑰 測試時不小心消耗正式金鑰額度 每個環境皆使用獨立金鑰,並在 CI 中使用 secret 管理
未加密的 .env 檔案在共享磁碟 其他開發者或 CI 工作者可直接讀取金鑰 若必須共享,可使用 git‑cryptsops 進行加密,或改用雲端 secret 管理服務(AWS Secrets Manager、GCP Secret Manager)

最佳實踐清單

  1. 使用 dotenv-safe:在 .env.example 中列出必填變數,程式啟動時自動檢查缺漏。
  2. 建立 CI secret:在 GitHub Actions 中使用 secrets.OPENAI_API_KEY,並在 workflow 裡注入 env:
  3. 最小權限原則:若平台支援,為每個環境產生單獨的 API 金鑰,並限制可用模型或配額。
  4. 日誌遮蔽:不要直接 console.log(process.env),若需要除錯,僅印出變數名稱而非值。
  5. 版本控制 .env.example:讓新加入的開發者知道需要哪些環境變數,並提供範例格式。

實際應用場景

1. Chatbot 服務

在一個多租戶的客服聊天機器人中,每個租戶 可能對應不同的 LLM 金鑰(OpenAI、Anthropic)。透過環境變數(或更彈性的 secret 管理)在每次請求時動態載入正確金鑰,既能保持程式碼乾淨,也能在同一容器內支援多種模型。

2. RAG(Retrieval‑Augmented Generation)系統

RAG 需要同時呼叫向量資料庫(如 Pinecone)與 LLM。將 向量資料庫的 API KeyLLM 的金鑰LangChain 追蹤金鑰 分別放在環境變數中,讓部署腳本只需要切換 .env.production 即可完成完整的生產環境切換。

3. CI/CD 測試

在 GitHub Actions 中跑單元測試時,使用 dotenv-flow 載入 .env.test,並把測試金鑰設為 GitHub secret。測試完畢後自動刪除或過期金鑰,避免測試期間的濫用。

# .github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    env:
      OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY_TEST }}
      LANGCHAIN_TRACING_V2: false
    steps:
      - uses: actions/checkout@v3
      - name: Install dependencies
        run: npm ci
      - name: Run tests
        run: npm test

4. 多雲部署

若同時在 AWS ECSGoogle Cloud RunAzure Container Apps 部署,同一套程式碼只需要在各平台的環境變數設定頁面填入對應金鑰,即可無縫切換,減少維護成本。


總結

  • 環境變數是 LangChain 與 LLM 金鑰管理的核心,透過 .envdotenvdotenv-flow 或平台原生的 secret 功能,可安全、彈性地配置 API Key。
  • 切勿硬編碼金鑰,必須使用 process.env,並確保 .env 不被提交至 Git。
  • 多環境、容器化、CI/CD 均有對應的最佳實踐:使用 .env.development/.test/.production、Docker ARG/ENV、GitHub Actions secrets
  • LangChain 內建的追蹤(Tracing)功能 也依賴環境變數,正確設定 LANGCHAIN_API_KEYLANGCHAIN_TRACING_V2 後,即可即時觀測 LLM 呼叫與 Prompt 流程。
  • 實務上,從簡單的單一 LLM 呼叫,到多模型比較、RAG 與 Chatbot 多租戶設計,都離不開環境變數的統一管理。只要遵守上面列出的 陷阱與最佳實踐,就能在開發、測試與部署階段保持安全、可維護與可擴充的程式碼基礎。

祝你在 LangChain 的開發旅程中,環境設定無痛、模型呼叫順暢! 🚀