🦁

LLM時代のバックエンド再設計: Next.js + Go + PostgreSQLで作るRAG基盤

に公開

やっほー!( ᐢ ˙꒳˙ ᐢ )💗 生成 AI ブームで「とりあえず RAG やりたい!」って声が社内外から飛び交う今日この頃。だけど PoC 止まりのまま炎上 ⭐️ している案件も多くて、現場は 💢💢…。

そこで今回は Next.js + Go + PostgreSQL という黄金のホームスタックを使って、LLM 時代に耐える “筋肉質” な RAG 基盤をゼロから再設計するプロセスを語るよ。

目次

  1. RAG がバズってる理由を 30 秒でおさらい 🔽
  2. システム全体像とコンテキスト注入戦略 ❤️‍🔥
  3. Edge Runtime × Streaming GraphQL の設計指針
  4. Vector Search を Postgres でやるべきか問題
  5. Docker Compose → k8s 移行でハマるポイント 💢
  6. 観測性とコスト最適化 – Tracing から Infra-as-Code まで
  7. 今日からマネできる小さな 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 ⭕️

  1. pgvector 拡張を入れて CREATE INDEX ON docs USING ivfflat (embedding vector_cosine_ops);
  2. Next.js の app/ 配下で route.tsReadableStream サンプルを置く
  3. Go BFF に otelgrpc を噛ませて Jaeger へ export
  4. Makefile に make cost を追加して infracost を即見

おわりに

RAG は魔法じゃないし「LLM を DB につなげば OK」でもない。検索層・生成層・観測層それぞれの 抽象度を上げて責務分離 することで、スケールもデバッグもぐっとラクになるよ ❣️

この記事が「PoC 止まりで泣いてるサービス」を ❤️‍🩹 救うヒントになれば嬉しいな~。それではまた次の記事で!⸝⸝> ̫ <⸝⸝՞

GitHubで編集を提案

Discussion