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 方便本機開發,但在容器化或雲端平台時,建議直接在 Dockerfile、Kubernetes 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=test,dotenv-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);
實務價值:在同一個應用中同時測試不同供應商的模型,能快速比較效能與成本,對於 RAG 或 Agent 的設計非常有幫助。
常見陷阱與最佳實踐
| 陷阱 | 可能的結果 | 解決方案 / Best Practice |
|---|---|---|
| 金鑰硬編碼在程式碼 | 金鑰被推到 public repo,造成資安與帳單風險 | 永遠使用 process.env,並把 .env 加入 .gitignore |
忘記載入 .env |
process.env.xxx 為 undefined,導致 AuthenticationError |
在入口檔(index.js、app.ts)最上方執行 require('dotenv').config() |
| 在 Dockerfile 中直接寫金鑰 | 金鑰會出現在 image 歷史,任何人拉取 image 都能看到 | 使用 ARG + ENV,或在容器執行時用 -e 注入 |
| 環境變數名稱拼寫錯誤 | 程式無法取得金鑰,卻不會立即拋出錯誤(除非 LLM 初始化時檢查) | 建議使用 TypeScript 的 process.env 型別或 dotenv-safe 來驗證必填變數 |
| 不同環境使用相同金鑰 | 測試時不小心消耗正式金鑰額度 | 每個環境皆使用獨立金鑰,並在 CI 中使用 secret 管理 |
| 未加密的 .env 檔案在共享磁碟 | 其他開發者或 CI 工作者可直接讀取金鑰 | 若必須共享,可使用 git‑crypt 或 sops 進行加密,或改用雲端 secret 管理服務(AWS Secrets Manager、GCP Secret Manager) |
最佳實踐清單
- 使用
dotenv-safe:在.env.example中列出必填變數,程式啟動時自動檢查缺漏。 - 建立 CI secret:在 GitHub Actions 中使用
secrets.OPENAI_API_KEY,並在 workflow 裡注入env:。 - 最小權限原則:若平台支援,為每個環境產生單獨的 API 金鑰,並限制可用模型或配額。
- 日誌遮蔽:不要直接
console.log(process.env),若需要除錯,僅印出變數名稱而非值。 - 版本控制
.env.example:讓新加入的開發者知道需要哪些環境變數,並提供範例格式。
實際應用場景
1. Chatbot 服務
在一個多租戶的客服聊天機器人中,每個租戶 可能對應不同的 LLM 金鑰(OpenAI、Anthropic)。透過環境變數(或更彈性的 secret 管理)在每次請求時動態載入正確金鑰,既能保持程式碼乾淨,也能在同一容器內支援多種模型。
2. RAG(Retrieval‑Augmented Generation)系統
RAG 需要同時呼叫向量資料庫(如 Pinecone)與 LLM。將 向量資料庫的 API Key、LLM 的金鑰、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 ECS、Google Cloud Run、Azure Container Apps 部署,同一套程式碼只需要在各平台的環境變數設定頁面填入對應金鑰,即可無縫切換,減少維護成本。
總結
- 環境變數是 LangChain 與 LLM 金鑰管理的核心,透過
.env、dotenv、dotenv-flow或平台原生的 secret 功能,可安全、彈性地配置 API Key。 - 切勿硬編碼金鑰,必須使用
process.env,並確保.env不被提交至 Git。 - 多環境、容器化、CI/CD 均有對應的最佳實踐:使用
.env.development/.test/.production、DockerARG/ENV、GitHub Actionssecrets。 - LangChain 內建的追蹤(Tracing)功能 也依賴環境變數,正確設定
LANGCHAIN_API_KEY與LANGCHAIN_TRACING_V2後,即可即時觀測 LLM 呼叫與 Prompt 流程。 - 實務上,從簡單的單一 LLM 呼叫,到多模型比較、RAG 與 Chatbot 多租戶設計,都離不開環境變數的統一管理。只要遵守上面列出的 陷阱與最佳實踐,就能在開發、測試與部署階段保持安全、可維護與可擴充的程式碼基礎。
祝你在 LangChain 的開發旅程中,環境設定無痛、模型呼叫順暢! 🚀