LangChain を Serverless へ配備:AWS Lambda/Fly.io/Railway の実装手順
LangChain を使った AI アプリケーションを開発したあと、次のステップはデプロイですよね。サーバーレス環境への配備は、スケーラビリティとコスト効率の両面で優れた選択肢となります。
本記事では、LangChain アプリケーションを AWS Lambda、Fly.io、Railway という 3 つの人気プラットフォームへ配備する具体的な手順をご紹介します。それぞれのプラットフォームには異なる特徴があり、用途に応じて最適な選択ができるでしょう。
背景
LangChain とサーバーレスの組み合わせ
LangChain は、大規模言語モデル(LLM)を活用したアプリケーション開発を容易にするフレームワークです。ChatGPT や Claude などの LLM を使った複雑なワークフローを、シンプルなコードで実装できます。
サーバーレスアーキテクチャは、インフラ管理の負担を大幅に削減し、使用した分だけ課金される従量課金モデルを提供します。LangChain アプリケーションは、リクエストごとに処理を行うため、サーバーレス環境との相性が抜群なんです。
以下の図は、LangChain アプリケーションがサーバーレス環境でどのように動作するかを示しています。
mermaidflowchart LR
client["クライアント"] -->|リクエスト| serverless["サーバーレス<br/>環境"]
serverless -->|プロンプト送信| langchain["LangChain<br/>処理"]
langchain -->|API コール| llm["LLM<br/>(OpenAI/Claude)"]
llm -->|レスポンス| langchain
langchain -->|結果| serverless
serverless -->|レスポンス| client
各プラットフォームの特徴比較
3 つのプラットフォームはそれぞれ異なる強みを持っています。
| # | プラットフォーム | 特徴 | 料金モデル | 起動時間 |
|---|---|---|---|---|
| 1 | AWS Lambda | AWS エコスystem との統合 | 実行時間+リクエスト数 | コールドスタート有 |
| 2 | Fly.io | グローバル展開が容易 | 常時稼働型 | 高速起動 |
| 3 | Railway | シンプルなデプロイ体験 | 使用リソース課金 | 中程度 |
AWS Lambda は既存の AWS サービスと連携したい場合に最適で、Fly.io は低レイテンシが求められるグローバルアプリケーションに向いています。Railway は開発者体験を重視し、素早くプロトタイプを公開したい場合におすすめですね。
課題
サーバーレス環境特有の制約
LangChain をサーバーレス環境に配備する際、いくつかの技術的課題に直面します。
実行時間制限が最も大きな課題でしょう。AWS Lambda では最大 15 分、他のプラットフォームでも一定の制限があります。LangChain の処理、特に複数の LLM 呼び出しを含むチェーンは、時間がかかることがあるんです。
コールドスタート問題も無視できません。サーバーレス関数は、しばらく使われていないと停止し、次回起動時に初期化時間がかかります。LangChain のライブラリは比較的大きいため、この初期化に数秒かかることもあります。
依存関係のサイズ制限も考慮が必要です。AWS Lambda では、デプロイパッケージのサイズに制限があるため、必要最小限の依存関係のみをインストールする工夫が求められますね。
以下の図は、サーバーレス環境で LangChain を実行する際の課題を整理したものです。
mermaidflowchart TD
deploy["LangChain<br/>デプロイ"] --> challenge1["実行時間制限"]
deploy --> challenge2["コールドスタート"]
deploy --> challenge3["パッケージサイズ"]
challenge1 --> sol1["タイムアウト<br/>エラー対策"]
challenge2 --> sol2["ウォームアップ<br/>戦略"]
challenge3 --> sol3["依存関係<br/>最適化"]
sol1 --> impl["実装での<br/>解決策"]
sol2 --> impl
sol3 --> impl
環境変数と秘匿情報の管理
API キーなどの秘匿情報を安全に管理することも重要な課題です。OpenAI や Anthropic の API キーは、コードに直接記述せず、環境変数として管理する必要があります。各プラットフォームで環境変数の設定方法が異なるため、それぞれの手順を理解しておかなければなりません。
解決策
基本的な実装アプローチ
LangChain アプリケーションをサーバーレス環境に配備するには、以下の 3 つの基本戦略を採用します。
軽量化されたパッケージングでは、必要な依存関係のみをインストールし、デプロイサイズを最小限に抑えます。langchain-core や langchain-openai など、特定機能に絞ったパッケージを使用するのが効果的ですね。
適切なタイムアウト設定により、LLM の応答時間を考慮した余裕のある制限時間を設定します。一般的には 30 秒から 60 秒程度が適切でしょう。
環境変数による設定管理で、API キーやモデル名などをコードから分離し、デプロイ環境ごとに柔軟に変更できるようにします。
プラットフォーム選択のガイドライン
用途に応じて最適なプラットフォームを選択することが重要です。
| # | ユースケース | 推奨プラットフォーム | 理由 |
|---|---|---|---|
| 1 | AWS サービスと連携 | AWS Lambda | DynamoDB、S3 等との統合が容易 |
| 2 | グローバル展開 | Fly.io | 複数リージョンへの自動展開 |
| 3 | 素早いプロトタイプ | Railway | デプロイが最も簡単 |
| 4 | 低コスト・低トラフィック | AWS Lambda | 無料枠が充実 |
| 5 | 常時稼働が必要 | Fly.io / Railway | コールドスタートなし |
以下の図は、プラットフォーム選択のフローチャートです。
mermaidflowchart TD
start["プラットフォーム<br/>選択"] --> q1{"AWS サービス<br/>連携が必要?"}
q1 -->|はい| lambda["AWS Lambda"]
q1 -->|いいえ| q2{"グローバル<br/>展開?"}
q2 -->|はい| flyio["Fly.io"]
q2 -->|いいえ| q3{"開発速度<br/>優先?"}
q3 -->|はい| railway["Railway"]
q3 -->|いいえ| q4{"トラフィック<br/>パターン?"}
q4 -->|不定期| lambda
q4 -->|常時| flyio_or_railway["Fly.io または<br/>Railway"]
具体例
共通:LangChain アプリケーションの準備
まず、すべてのプラットフォームで使用する基本的な LangChain アプリケーションを作成しましょう。
プロジェクトの初期化
新しいプロジェクトディレクトリを作成し、必要なパッケージをインストールします。
bashmkdir langchain-serverless
cd langchain-serverless
yarn init -y
依存関係のインストール
LangChain と OpenAI のパッケージをインストールします。軽量化のため、必要最小限のパッケージのみを選択しますね。
bashyarn add langchain-core langchain-openai
yarn add -D typescript @types/node
TypeScript の設定
tsconfig.json を作成し、TypeScript の設定を行います。
json{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
基本的な LangChain ハンドラーの実装
src/handler.ts を作成し、LangChain を使った簡単なチャットボットを実装します。このコードは、ユーザーからの質問に対して OpenAI の GPT モデルで応答を生成するものです。
typescript// 環境変数から OpenAI API キーを読み込み
import { ChatOpenAI } from "langchain-openai";
import { HumanMessage, SystemMessage } from "langchain-core/messages";
// LangChain のチャットモデルを初期化
const initializeChatModel = () => {
return new ChatOpenAI({
modelName: process.env.OPENAI_MODEL || "gpt-3.5-turbo",
temperature: 0.7,
openAIApiKey: process.env.OPENAI_API_KEY,
});
};
上記のコードでは、環境変数から API キーとモデル名を取得しています。これにより、デプロイ環境ごとに異なる設定を柔軟に適用できるんです。
メッセージ処理ロジック
次に、実際のメッセージ処理ロジックを実装します。
typescript// ユーザーの質問を処理する関数
export const processQuestion = async (question: string): Promise<string> => {
try {
const model = initializeChatModel();
// システムメッセージとユーザーメッセージを準備
const messages = [
new SystemMessage("あなたは親切で知識豊富なアシスタントです。"),
new HumanMessage(question),
];
// LLM を呼び出して応答を取得
const response = await model.invoke(messages);
return response.content.toString();
} catch (error) {
console.error("Error processing question:", error);
throw new Error("質問の処理中にエラーが発生しました");
}
};
このコードでは、try-catch ブロックでエラーハンドリングを行い、問題が発生した際にも適切なエラーメッセージを返すようにしています。
AWS Lambda への配備
AWS Lambda は、AWS のサーバーレスコンピューティングサービスです。イベント駆動型のアーキテクチャに最適で、他の AWS サービスとシームレスに連携できます。
Lambda ハンドラーの実装
AWS Lambda 用のハンドラーを src/lambda.ts として作成します。Lambda は特定の形式のハンドラー関数を要求するため、それに合わせた実装が必要です。
typescript// AWS Lambda のイベントと型定義をインポート
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";
import { processQuestion } from "./handler";
// Lambda ハンドラー関数
export const handler = async (
event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
// CORS ヘッダーの設定
const headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Content-Type",
};
CORS ヘッダーを設定することで、ブラウザからの API 呼び出しを許可しています。本番環境では、Access-Control-Allow-Origin を特定のドメインに制限することをおすすめしますね。
リクエストボディの解析とレスポンス生成
typescript try {
// リクエストボディから質問を取得
const body = JSON.parse(event.body || "{}");
const question = body.question;
// 質問が空の場合はエラーを返す
if (!question) {
return {
statusCode: 400,
headers,
body: JSON.stringify({ error: "質問が指定されていません" }),
};
}
// LangChain で質問を処理
const answer = await processQuestion(question);
バリデーションを追加することで、不正なリクエストを早期に検出し、適切なエラーレスポンスを返せます。
エラーハンドリングとレスポンス
typescript // 成功レスポンスを返す
return {
statusCode: 200,
headers,
body: JSON.stringify({ answer }),
};
} catch (error) {
console.error("Lambda handler error:", error);
return {
statusCode: 500,
headers,
body: JSON.stringify({
error: "内部サーバーエラーが発生しました",
message: error instanceof Error ? error.message : "不明なエラー"
}),
};
}
};
Lambda 用の依存関係追加
Lambda デプロイに必要な型定義をインストールします。
bashyarn add -D @types/aws-lambda
ビルドスクリプトの設定
package.json にビルドスクリプトを追加しましょう。
json{
"scripts": {
"build": "tsc",
"build:lambda": "tsc && cd dist && zip -r ../lambda.zip .",
"clean": "rm -rf dist lambda.zip"
}
}
build:lambda スクリプトは、TypeScript をコンパイルした後、dist ディレクトリを ZIP ファイルにパッケージ化します。
AWS Lambda 関数の作成
AWS CLI を使用して Lambda 関数を作成します。事前に AWS CLI のインストールと設定が必要ですね。
bash# Lambda 関数を作成
aws lambda create-function \
--function-name langchain-chatbot \
--runtime nodejs20.x \
--handler lambda.handler \
--role arn:aws:iam::YOUR_ACCOUNT_ID:role/lambda-execution-role \
--zip-file fileb://lambda.zip \
--timeout 60 \
--memory-size 512
--timeout オプションで 60 秒を指定し、LLM の応答時間を考慮した余裕のある制限を設定しています。--memory-size も 512MB に設定し、十分なリソースを確保しましょう。
環境変数の設定
OpenAI API キーを環境変数として設定します。
bashaws lambda update-function-configuration \
--function-name langchain-chatbot \
--environment Variables={OPENAI_API_KEY=your-api-key-here,OPENAI_MODEL=gpt-3.5-turbo}
API キーは絶対にコードにハードコーディングせず、環境変数として管理することが重要です。
API Gateway の設定
Lambda 関数を HTTP エンドポイントとして公開するため、API Gateway を設定します。
bash# REST API を作成
aws apigateway create-rest-api \
--name langchain-api \
--description "LangChain Chatbot API"
# リソースとメソッドを作成(API ID は上記コマンドの出力から取得)
aws apigateway create-resource \
--rest-api-id YOUR_API_ID \
--parent-id ROOT_RESOURCE_ID \
--path-part chat
Lambda のデプロイと更新
コードを更新した場合、以下のコマンドで再デプロイできます。
bash# ビルドとパッケージング
yarn build:lambda
# Lambda 関数の更新
aws lambda update-function-code \
--function-name langchain-chatbot \
--zip-file fileb://lambda.zip
Lambda のエラー対処
AWS Lambda で発生しやすいエラーと対処法をご紹介します。
エラーコード: Task timed out after 3.00 seconds
このエラーは、Lambda のデフォルトタイムアウト(3 秒)を超えた場合に発生します。
bash# タイムアウトを 60 秒に延長
aws lambda update-function-configuration \
--function-name langchain-chatbot \
--timeout 60
エラーコード: Cannot find module 'langchain-openai'
依存関係が正しくパッケージングされていない場合のエラーです。
発生条件:
- node_modules が ZIP に含まれていない
- Lambda レイヤーの設定ミス
解決方法:
- ビルド前に依存関係をインストール:
yarn install --production - ZIP に node_modules を含める:
cd dist && zip -r ../lambda.zip . ../node_modules - または Lambda レイヤーとして依存関係を分離する
Fly.io への配備
Fly.io は、アプリケーションをグローバルに展開できるプラットフォームです。Docker コンテナをベースとし、世界中のエッジロケーションで実行できるのが特徴ですね。
Fly.io CLI のインストール
まず、Fly.io の CLI ツールをインストールします。
bash# macOS の場合
curl -L https://fly.io/install.sh | sh
# インストール後、ログイン
flyctl auth login
Express サーバーの実装
Fly.io では常時稼働するサーバーとしてデプロイするため、Express を使った HTTP サーバーを実装します。
bash# Express と関連パッケージをインストール
yarn add express
yarn add -D @types/express
サーバーコードの作成
src/server.ts を作成し、Express サーバーを実装しましょう。
typescriptimport express, { Request, Response } from "express";
import { processQuestion } from "./handler";
// Express アプリケーションの初期化
const app = express();
const port = process.env.PORT || 3000;
// JSON ボディパーサーを有効化
app.use(express.json());
Express の基本設定を行い、JSON リクエストを処理できるようにしています。
ヘルスチェックエンドポイント
Fly.io はヘルスチェックでアプリケーションの状態を監視します。そのためのエンドポイントを追加しましょう。
typescript// ヘルスチェック用エンドポイント
app.get("/health", (req: Request, res: Response) => {
res.status(200).json({ status: "healthy" });
});
// ルートエンドポイント
app.get("/", (req: Request, res: Response) => {
res.json({ message: "LangChain Chatbot API" });
});
チャットエンドポイントの実装
実際の LangChain 処理を行うエンドポイントを作成します。
typescript// チャットエンドポイント
app.post("/chat", async (req: Request, res: Response) => {
try {
const { question } = req.body;
// バリデーション
if (!question || typeof question !== "string") {
return res.status(400).json({
error: "質問が指定されていません"
});
}
// LangChain で処理
const answer = await processQuestion(question);
res.json({ answer });
} catch (error) {
console.error("Chat endpoint error:", error);
res.status(500).json({
error: "質問の処理中にエラーが発生しました",
message: error instanceof Error ? error.message : "不明なエラー"
});
}
});
サーバーの起動
typescript// サーバーを起動
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
package.json の更新
サーバー起動用のスクリプトを追加します。
json{
"scripts": {
"build": "tsc",
"start": "node dist/server.js",
"dev": "ts-node src/server.ts"
}
}
Dockerfile の作成
Fly.io では Docker コンテナを使用してデプロイします。プロジェクトルートに Dockerfile を作成しましょう。
dockerfile# Node.js の公式イメージを使用
FROM node:20-slim
# 作業ディレクトリを設定
WORKDIR /app
# package.json と yarn.lock をコピー
COPY package.json yarn.lock ./
ベースイメージには軽量な slim バージョンを使用し、イメージサイズを最小限に抑えています。
依存関係のインストールとビルド
dockerfile# 依存関係をインストール(本番用のみ)
RUN yarn install --production=false
# ソースコードをコピー
COPY . .
# TypeScript をビルド
RUN yarn build
# 開発用の依存関係を削除
RUN yarn install --production
マルチステージではなく、開発依存関係を後から削除する方法でイメージを最適化しています。
コンテナの起動設定
dockerfile# ポートを公開
EXPOSE 3000
# アプリケーションを起動
CMD ["yarn", "start"]
.dockerignore の作成
不要なファイルをイメージに含めないよう、.dockerignore を作成します。
bashnode_modules
dist
.git
.env
*.md
.gitignore
Fly.io アプリケーションの初期化
Fly.io プロジェクトを初期化します。対話形式で設定を行いますね。
bashflyctl launch
このコマンドを実行すると、アプリケーション名やリージョンを選択するプロンプトが表示されます。
fly.toml の設定
fly.toml ファイルが自動生成されますが、以下のように調整することをおすすめします。
tomlapp = "langchain-chatbot"
primary_region = "nrt"
[build]
[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = false
auto_start_machines = true
min_machines_running = 1
[[vm]]
cpu_kind = "shared"
cpus = 1
memory_mb = 512
auto_stop_machines = false により、コールドスタートを防ぎ、常に 1 台以上のマシンを稼働させます。
環境変数の設定
Fly.io に環境変数を設定します。
bashflyctl secrets set OPENAI_API_KEY=your-api-key-here
flyctl secrets set OPENAI_MODEL=gpt-3.5-turbo
secrets コマンドを使用することで、環境変数が暗号化されて保存されます。
デプロイの実行
準備ができたら、デプロイを実行しましょう。
bashflyctl deploy
デプロイが完了すると、URL が表示されます。この URL にアクセスして動作を確認できますね。
デプロイの確認とログ確認
bash# アプリケーションの状態を確認
flyctl status
# ログを確認
flyctl logs
Fly.io のエラー対処
エラーコード: Error: connect ECONNREFUSED
アプリケーションが正しいポートでリッスンしていない場合のエラーです。
発生条件:
process.env.PORTを使用していない- fly.toml の
internal_portと実際のポートが一致しない
解決方法:
- サーバーコードで
process.env.PORTを使用する - fly.toml の
internal_portを確認(デフォルトは 3000)
typescriptconst port = process.env.PORT || 3000;
app.listen(port);
エラーコード: Health check failed
ヘルスチェックエンドポイントが応答していない場合のエラーです。
解決方法:
/healthエンドポイントを実装- fly.toml にヘルスチェック設定を追加
toml[http_service.checks]
[http_service.checks.health]
grace_period = "10s"
interval = "30s"
method = "GET"
path = "/health"
timeout = "5s"
Railway への配備
Railway は、Git リポジトリと連携した自動デプロイが特徴のプラットフォームです。GitHub リポジトリにプッシュするだけでデプロイが完了するため、開発体験が非常にスムーズなんです。
Railway プロジェクトの準備
まず、Railway のアカウントを作成し、プロジェクトを準備します。Railway は Web UI から簡単に操作できますね。
- Railway にアクセスしてサインアップ
- GitHub アカウントで認証
- 新しいプロジェクトを作成
Express サーバーの実装(Fly.io と共通)
Railway でも Express サーバーを使用します。Fly.io のセクションで作成した src/server.ts をそのまま使用できます。
package.json の start スクリプト確認
Railway は yarn start コマンドでアプリケーションを起動するため、package.json を確認しましょう。
json{
"scripts": {
"build": "tsc",
"start": "node dist/server.js",
"railway:build": "yarn install && yarn build"
}
}
railway:build スクリプトを追加することで、ビルド手順を明示的に指定できます。
Railway 設定ファイルの作成
railway.json を作成し、ビルドとデプロイの設定を記述します。
json{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "NIXPACKS",
"buildCommand": "yarn railway:build"
},
"deploy": {
"startCommand": "yarn start",
"restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 10
}
}
この設定により、ビルドとデプロイのプロセスが自動化されます。
.gitignore の確認
Git リポジトリにコミットする前に、.gitignore を確認しましょう。
bashnode_modules
dist
.env
*.log
.DS_Store
環境変数ファイルや node_modules を除外することで、リポジトリサイズを小さく保てます。
Git リポジトリの初期化とプッシュ
コードを Git リポジトリにプッシュします。
bash# Git の初期化
git init
git add .
git commit -m "Initial commit: LangChain serverless app"
# GitHub にリポジトリを作成し、リモートを追加
git remote add origin https://github.com/YOUR_USERNAME/langchain-serverless.git
git branch -M main
git push -u origin main
Railway プロジェクトの作成
Railway の Web UI から、GitHub リポジトリをデプロイします。
手順:
- Railway ダッシュボードで「New Project」をクリック
- 「Deploy from GitHub repo」を選択
- デプロイしたいリポジトリを選択
- Railway が自動的にビルドとデプロイを開始
Railway は package.json を検出し、自動的に Node.js 環境を構築してくれるんです。
環境変数の設定
Railway の Web UI から環境変数を設定します。
手順:
- プロジェクトの「Variables」タブを開く
- 「New Variable」をクリック
- 以下の環境変数を追加
| # | 変数名 | 値 |
|---|---|---|
| 1 | OPENAI_API_KEY | your-api-key-here |
| 2 | OPENAI_MODEL | gpt-3.5-turbo |
| 3 | PORT | 3000 |
環境変数を追加すると、Railway が自動的にアプリケーションを再デプロイします。
カスタムドメインの設定(オプション)
Railway は自動的に URL を生成しますが、カスタムドメインも設定できます。
手順:
- 「Settings」タブを開く
- 「Domains」セクションで「Add Domain」をクリック
- ドメイン名を入力(例:
chatbot.yourdomain.com) - DNS レコードを設定(Railway が指示を表示)
デプロイログの確認
Railway の「Deployments」タブから、リアルタイムでビルドログを確認できます。
bash# ログの例
Building...
Installing dependencies...
Running build command: yarn railway:build
Build completed successfully
Starting application: yarn start
Server is running on port 3000
自動デプロイの設定
Railway では、GitHub の main ブランチにプッシュすると自動的にデプロイされます。この機能は設定不要で、デフォルトで有効になっているんです。
コードを更新して GitHub にプッシュするだけで、新しいバージョンがデプロイされます。
bash# コードを更新
git add .
git commit -m "Update chatbot logic"
git push origin main
# Railway が自動的に新しいデプロイを開始
Railway のエラー対処
エラーコード: Error: Cannot find module './dist/server.js'
TypeScript のビルドが失敗している、またはビルド成果物が正しくデプロイされていない場合のエラーです。
発生条件:
- ビルドコマンドが実行されていない
- tsconfig.json の outDir 設定が間違っている
解決方法:
- railway.json に正しいビルドコマンドを指定
- package.json の build スクリプトを確認
- Railway のビルドログでエラーを確認
json{
"build": {
"buildCommand": "yarn install && yarn build"
}
}
エラーコード: Application failed to respond
アプリケーションが起動していない、または正しいポートでリッスンしていない場合のエラーです。
解決方法:
process.env.PORTを使用しているか確認- Railway の環境変数に PORT を設定(通常は自動設定)
- ログで起動エラーを確認
各プラットフォームの比較と選択基準
3 つのプラットフォームへの実装を見てきましたが、それぞれの実装方法と特性をまとめてみましょう。
| # | 項目 | AWS Lambda | Fly.io | Railway |
|---|---|---|---|---|
| 1 | デプロイ方法 | ZIP アップロード | Docker コンテナ | Git プッシュ |
| 2 | 実行モデル | イベント駆動 | 常時稼働 | 常時稼働 |
| 3 | コールドスタート | あり(数秒) | ほぼなし | ほぼなし |
| 4 | スケーリング | 自動・無制限 | 手動設定 | 自動 |
| 5 | セットアップ難易度 | 高 | 中 | 低 |
| 6 | AWS 連携 | 優れている | 不可 | 不可 |
| 7 | 料金モデル | 従量課金 | 月額+従量 | 月額+従量 |
以下は、各プラットフォームのデプロイフローを比較した図です。
mermaidflowchart TD
subgraph Lambda["AWS Lambda フロー"]
L1["コードを<br/>ビルド"] --> L2["ZIP に<br/>パッケージング"]
L2 --> L3["AWS CLI で<br/>アップロード"]
L3 --> L4["API Gateway<br/>設定"]
end
subgraph Flyio["Fly.io フロー"]
F1["Dockerfile<br/>作成"] --> F2["flyctl<br/>コマンド実行"]
F2 --> F3["自動的に<br/>デプロイ"]
end
subgraph Rail["Railway フロー"]
R1["Git に<br/>プッシュ"] --> R2["自動的に<br/>ビルド"]
R2 --> R3["自動的に<br/>デプロイ"]
end
パフォーマンス最適化のポイント
どのプラットフォームでも、以下の最適化手法が有効です。
依存関係の最小化
LangChain は多くのサブパッケージを持っています。必要な機能だけをインストールすることで、デプロイサイズとコールドスタート時間を削減できますね。
bash# 全部入りではなく、必要なパッケージのみ
yarn add langchain-core langchain-openai
# 不要なパッケージは追加しない
# yarn add langchain ← これは避ける
ストリーミングレスポンスの実装
長い応答を待つ代わりに、ストリーミングで段階的にレスポンスを返すことができます。
typescriptimport { ChatOpenAI } from "langchain-openai";
export const streamResponse = async (
question: string,
onToken: (token: string) => void
) => {
const model = new ChatOpenAI({
streaming: true,
callbacks: [
{
handleLLMNewToken(token: string) {
onToken(token);
},
},
],
});
await model.invoke([new HumanMessage(question)]);
};
このストリーミング機能により、ユーザーは応答が生成されている様子をリアルタイムで確認でき、体感速度が向上します。
キャッシング戦略
頻繁に使用されるプロンプトや応答をキャッシュすることで、LLM への API 呼び出しを削減できます。
typescript// シンプルなインメモリキャッシュ
const cache = new Map<string, string>();
export const processQuestionWithCache = async (
question: string
): Promise<string> => {
// キャッシュをチェック
if (cache.has(question)) {
console.log("Cache hit");
return cache.get(question)!;
}
// LLM を呼び出し
const answer = await processQuestion(question);
// キャッシュに保存(最大 100 件)
if (cache.size >= 100) {
const firstKey = cache.keys().next().value;
cache.delete(firstKey);
}
cache.set(question, answer);
return answer;
};
まとめ
LangChain アプリケーションをサーバーレス環境に配備する方法について、AWS Lambda、Fly.io、Railway の 3 つのプラットフォームで具体的な実装手順をご紹介しました。
AWS Lambda は、AWS エコシステムとの統合が必要な場合や、トラフィックが不定期なアプリケーションに最適です。完全な従量課金モデルにより、使用していない時間はコストがかかりません。ただし、コールドスタートやデプロイの複雑さは考慮が必要ですね。
Fly.io は、グローバルに展開したいアプリケーションや、低レイテンシが求められる場合に優れた選択肢となります。Docker ベースのデプロイは柔軟性が高く、複数のリージョンへの展開も容易です。常時稼働モデルのため、コールドスタートの心配がありません。
Railway は、素早くプロトタイプを公開したい場合や、開発体験を重視する場合に最適でしょう。Git プッシュだけでデプロイが完了する仕組みは、開発フローを大幅に効率化します。初心者にも扱いやすく、学習コストが低いのが魅力ですね。
どのプラットフォームを選択するかは、プロジェクトの要件、チームのスキルセット、予算などによって変わってきます。本記事で紹介した実装パターンを参考に、最適なプラットフォームを選択してください。
LangChain の軽量化、適切なタイムアウト設定、環境変数の管理など、共通する最適化手法も忘れずに適用しましょう。これらの工夫により、安定した高性能な AI アプリケーションを提供できるはずです。
関連リンク
各プラットフォームの公式ドキュメントや参考資料です。
articleLangChain を Serverless へ配備:AWS Lambda/Fly.io/Railway の実装手順
articleHaystack と LangChain/LlamaIndex 徹底比較:設計思想・拡張性・学習コスト
articleLangChain を使わない判断基準:素の API/関数呼び出しで十分なケースと見極めポイント
articleLangChain プロンプトのバージョニング運用:リリース・ロールバック・A/B テスト
articleLangChain JSON 出力が壊れる問題を解く:ストリーミング整形・スキーマ強制・再試行設計
articleLlamaIndex と LangChain を徹底比較:開発速度・可観測性・精度ベンチ
articleNode.js 25.x, 24.x, 22.x, 20.x の脆弱性対応:2025 年 12 月版で修正された 3 件の High Severity 問題の詳細
articleEmotion × Vite の最短構築:開発高速化とソースマップ最適設定
articleLangChain を Serverless へ配備:AWS Lambda/Fly.io/Railway の実装手順
articleYarn PnP 互換性チートシート:loader 設定・patch・packageExtensions の書き方
articleElectron IPC 設計チートシート:チャネル命名・型安全・エラーハンドリング定型
articleDocker セキュアイメージ設計:非 root・最小ベース・Capabilities 削減の実装指針
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来