LLM時代のバックエンド再設計: Next.js + Go + PostgreSQLで作るRAG基盤
やっほー!( ᐢ ˙꒳˙ ᐢ )💗 生成 AI ブームで「とりあえず RAG やりたい!」って声が社内外から飛び交う今日この頃。だけど PoC 止まりのまま炎上 ⭐️ している案件も多くて、現場は 💢💢…。
そこで今回は Next.js + Go + PostgreSQL という黄金のホームスタックを使って、LLM 時代に耐える “筋肉質” な RAG 基盤をゼロから再設計するプロセスを語るよ。
目次
- RAG がバズってる理由を 30 秒でおさらい 🔽
- システム全体像とコンテキスト注入戦略 ❤️🔥
- Edge Runtime × Streaming GraphQL の設計指針
- Vector Search を Postgres でやるべきか問題
- Docker Compose → k8s 移行でハマるポイント 💢
- 観測性とコスト最適化 – Tracing から Infra-as-Code まで
- 今日からマネできる小さな TODO ⭕️
1. RAG がバズってる理由を 30 秒でおさらい 🔽
RAG (Retrieval-Augmented Generation) は「LLM の幻覚を抑えつつ独自ドメイン知識を叩き込みたい」というワガママを実現するアーキテクチャ。ポイントは “ドキュメントキャッシュ層” と “プロンプト生成層” を分離 できることで、従来の MVC モノリスに強引に押し込むと確実に壊れる。抽象的には “検索と生成の責務分割” がテーマだよ。
2. システム全体像とコンテキスト注入戦略 ❤️🔥
Next.js をエッジ配置し、API Routes から Go 製 BFF へ GraphQL over HTTP/2 でストリーミング。フロントは React Server Components で「検索 → 生成 → ストリーム表示」をノンブロッキングに実現。文書分割は recursive-character-text-splitter を使い、メタデータは JSONB で Postgres の同一テーブルに寄せておくと JOIN 地獄を回避できる。(ฅ•ω•ฅ)
3. Edge Runtime × Streaming GraphQL の設計指針
普通の REST だと chunked-response を自前実装しがちだけど、GraphQL なら @defer/@stream 指令で解決。Go 側は gqlgen
+ http2
で Push Promise。ここで重要なのは「LLM が返す token」をそのまま node ストリームに流すのではなく、cursor ベースの incremental payload に変換すること。クライアントは React 18 の use
で待機できるから UX が劇的に上がる。
4. Vector Search を Postgres でやるべきか問題
外部 Vector DB (Pinecone 等) は楽だけど、コストとリージョンレイテンシが爆増 ⚠️。Postgres 16 + pgvector
なら same-process JOIN が利くので ACID 要件が高い SaaS では有利。
ただし HNSW index は RAM モリモリ消費するから、max_connections
を絞りつつ connection_pool ↔ RPS ↔ vector size の 3 変数をモニタリングする設計が必須。
5. Docker Compose → k8s 移行でハマるポイント 💢
初期は Compose が最速だけど、RAG のバッチインデクサは突発的に CPU を食う。k8s で HorizontalPodAutoscaler + CronJob に分離しないとワーカーが全体を巻き込むよ。
それと Secrets。環境変数に OpenAI key をベタ書きすると即死なので、SealedSecrets
or External Secrets
Controller で GitOps するのが最適解。
6. 観測性とコスト最適化 – Tracing から Infra-as-Code まで
- Tracing: OpenTelemetry + Jaeger で token-level latency を計測し、prompt 改善よりネットワーク改善が効くケースを数値で証明。
-
IaC: Terraform で Cloud Run / Cloud SQL / Cloud Storage を管理し、
tfsec
,infracost
を CI に組み込むと FinOps も自動化できる。 - LLM Cost Guard: Go の middleware に tokencounter を挟んで使用量を headers にエコーバック。ブラウザの DevTools だけで月額を見積もれるのが体験神。
7. 今日からマネできる小さな TODO ⭕️
-
pgvector
拡張を入れてCREATE INDEX ON docs USING ivfflat (embedding vector_cosine_ops);
- Next.js の
app/
配下でroute.ts
にReadableStream
サンプルを置く - Go BFF に
otelgrpc
を噛ませて Jaeger へ export - Makefile に
make cost
を追加して infracost を即見
おわりに
RAG は魔法じゃないし「LLM を DB につなげば OK」でもない。検索層・生成層・観測層それぞれの 抽象度を上げて責務分離 することで、スケールもデバッグもぐっとラクになるよ ❣️
この記事が「PoC 止まりで泣いてるサービス」を ❤️🩹 救うヒントになれば嬉しいな~。それではまた次の記事で!⸝⸝> ̫ <⸝⸝՞
Discussion