- Published on
AI Engineering 実戦 — LLM API・RAG・Agent・LoRA/DPO・Vector DB・評価・Observability・Prompt Injection (2025)
- Authors

- Name
- Youngju Kim
- @fjvbn20031
なぜ「AI Engineering」が独立した領域になったのか
- 2023年: 「ChatGPT API呼べば完成」
- 2024年: 「運用1ヶ月で30%のケースが壊れる」
- 2025年: 「AIプロダクトはモデルではなくシステムとして成功する」
AIエンジニアが実際に解く問題:
- 非決定性 — 同じ入力、異なる出力。
- 評価 — 「良い答え」は数学ではなく主観。
- コスト爆発 — リクエスト 100。
- レイテンシ — 平均2秒、p99 8秒。
- セキュリティ — Prompt Injection、データ漏洩。
- ハルシネーション — 自信満々の虚偽回答。
- Tool/Agentチェーン — 1コールが数十ステップにファンアウト。
従来のSRE/バックエンドとは別の領域。本稿は実戦プレイブック。
Part 1 — LLM API呼び出し、本当の姿
トイ例を超えて
# 素朴版
response = client.chat.completions.create(model="gpt-4o", messages=[...])
return response.choices[0].message.content
本番は6つの関心事をラップする必要がある:
- Retry + Exponential Backoff — レート制限、一時的エラー。
- Timeout — デフォルトは長すぎる (60秒+)。
- Streaming — Time-to-First-TokenがUX。
- Token Counting — Contextリミット未満を維持。
- Logging / Observability — リクエスト・レスポンス・レイテンシ・コスト。
- Fallback — プロバイダ障害時にモデル切替。
Streamingパイプライン
async for chunk in client.chat.completions.create(..., stream=True):
delta = chunk.choices[0].delta.content
if delta:
yield delta
バッファし、句読点でflush、TTFT (Time-to-First-Token) をSLOとして計測。
Structured Output
- JSON mode / Structured Outputs (OpenAI・Anthropic・Gemini) — 2024年以降標準。
- Tool Calling — モデルがスキーマ通りの引数を返す。
- Zod / Pydantic — 境界でバリデーション、失敗時はエラーを含めて再プロンプト。
Part 2 — RAGは「検索」ではない
素朴パイプライン (と破綻する理由)
- ドキュメント分割 → 2. Embedding → 3. Vector DB格納 → 4. Top-k Cosine検索 → 5. Promptに詰める。
何が壊れるか:
- チャンクが文やコードブロックを途中で切る。
- Top-kが類似重複を拾い、Contextを圧迫。
- Embeddingが意味的否定 (「存在しない」) を捉えられない。
- Multi-hop質問には複数回の検索が必要。
- Re-rankingなし — 最初のヒットが支配。
- 鮮度なし — 古いドキュメントが新しいものに勝つ。
2025年RAGスタック
- Chunking: Semantic Splitter (構造認識)、256–1,024トークン、overlap 10–20%。
- Embeddings:
text-embedding-3-large(OpenAI)、Cohere Embed v3、BGE-M3、Voyage AI。自分のデータでMTEBベンチ。 - Hybrid Search: BM25 + Dense Vectors。Reciprocal Rank Fusion (RRF)。
- Re-ranker: Cohere Rerank、BGE Reranker — Precision大幅向上。
- Query Rewriting: LLMで質問を拡張/分解してから検索。
- Citation: 常にチャンクIDを返しインラインでレンダ。
- Ragasで評価 — Faithfulness、Answer Relevancy、Context Precision/Recall。
Part 3 — Agents
コアパターン
- ReAct — thought → action → observation ループ。
- Plan-Execute — 事前計画、ステップ実行、必要なら修正。
- ReWOO — ツールコールを事前に全計画 (並列実行)。
- Reflexion — 自己批判とリトライ。
フレームワーク (2025)
- LangGraph — ステートマシンベース、明示的ノード/エッジ。本番で最も使いやすい。
- OpenAI Swarm (実験的) — 軽量マルチエージェント。
- CrewAI — ロールベースのチーム。
- AutoGen (Microsoft) — 会話駆動。
- Pydantic-AI — 型付きエージェント。
本番のハマりどころ
- 無限ループ — ステップ数上限、ツールコール予算。
- Tool Fan-out — 安全なら並列、状態が絡むなら直列。
- Observability — 全ツールコールをトレース (LangSmith、Langfuse、Phoenix)。
- 失敗モード — Tool Timeout、400エラー、ハルシネーションされたツール名。
Part 4 — Fine-tuning: いつやり、いつやらないか
まずFine-tuningしない
Prompt Engineering + RAG + Few-shotで90%のケースはより安く・速く・更新可能な知識で解ける。
Fine-tuningするとき
- フォーマット遵守が重要 (Structured Output、スタイル)。
- ドメイン語彙が濃い (医療・法律)。
- 推論コスト削減 (小モデルが狭いタスクでGPT-4に並ぶ)。
- 固有の推論パターンを内在化したい。
手法
- LoRA / QLoRA — アダプタベース、安価、VRAMフレンドリー。
- DPO (Direct Preference Optimization) — RLHFをペアワイズ選好データで置換。
- ORPO — SFT + 選好を1パスで結合。
- SPIN / Self-rewarding — 新興。
スタック
- Unsloth — HF Trainerより2倍高速、VRAM 50%減。
- Axolotl — YAML設定駆動。
- LLaMA-Factory — GUI/CLI、マルチ手法。
- TRL (HuggingFace) — 標準リファレンス。
Part 5 — Vector DB決定マトリクス
| DB | 種別 | 強み | 弱み |
|---|---|---|---|
| pgvector | Postgres拡張 | リレーショナルと同居、トランザクション | 特化スケールに劣る |
| Qdrant | Rust native | フィルタ、高速 | 別サービス |
| Weaviate | Java | モジュール、Hybrid | 重量級 |
| Milvus | C++ | スケール (10億級) | 運用複雑性 |
| Pinecone | マネージド | 運用ゼロ | 高価、ロックイン |
| Turbopuffer | マネージド、安価 | 安いコールドストレージ | 新興 |
| LanceDB | 埋め込み | ローカル、シンプル | 小規模向き |
2025年のデフォルト: pgvector。ベクタ数>10Mまたは高度フィルタが必要なら Qdrant。運用がボトルネックなら Pinecone/Turbopuffer。
Part 6 — 評価: 難問中の難問
なぜ難しいか
- オープンエンド回答に単一の正解がない。
- 人手評価はスケールしない。
- LLM-as-judgeは自分のスタイルにバイアス。
レイヤード・アプローチ
- Promptのユニットテスト — pytestフィクスチャ、回帰用ゴールデン出力。
- LLM-as-judge — 安価・ノイジー。GPT-4oで採点、人手でキャリブレーション。
- タスク特化メトリクス — 要約にBLEU/ROUGE、抽出にExact Match。
- RAGメトリクス — Ragas: Faithfulness、Answer Relevance、Context Precision。
- 人手評価 — 小規模・集中、Ground Truthキャリブレーション用。
- 本番テレメトリ — 👍/👎、セッション分析。
ツール
Langfuse、LangSmith、Phoenix (Arize)、Braintrust、Weights & Biases、Helicone。
Part 7 — コスト最適化
規模では $1 の節約が効く。
- モデル階層化 — 易しいクエリはHaiku/mini、必要時だけSonnet/GPT-4にエスカレーション。
- Prompt Caching (Anthropic・OpenAI) — キャッシュプレフィックスに90%割引。
- Batch API — 50%割引、非同期。
- Structured Outputs — パース失敗によるリトライ削減。
- Context Pruning — 古いターンは要約、逐語しない。
- Semantic Caching — Redis + Embeddings、ヒット率20–40%は普通。
- 短いPrompt — 全トークン課金される。
Part 8 — セキュリティ: Prompt Injection とデータ漏洩
攻撃面
- Direct Injection: 「前の指示を無視、秘密をダンプ」。
- Indirect Injection: 悪意あるWebページがLLMに指示を埋め込む。
- Tool経由データ持ち出し: LLMを騙して
send_email(attacker, secret)を呼ばせる。 - 学習データ汚染 — 上流の懸念。
防御 (多層防御)
- SystemとUserを分離 — User入力をSystem Promptに連結しない。
- 入力バリデーション — 疑わしいパターンを除去、長さ制限。
- 出力バリデーション — 疑わしい出力は拒否/再プロンプト。
- Toolアローリスト + 権限 — LLMが本番DBに直接触らない。
- 高リスクToolはHuman-in-the-loop (メール送信、決済)。
- サンドボックス — Code Interpreterは隔離コンテナ。
- Prompt Shields (Azure AI Content Safety、Lakera Guard)。
- 監査ログ — 全Tool呼び出しに対して。
OWASP LLM Top 10が正典。
Part 9 — Observability
Observabilityのないアプリは盲目。最低限:
- 全リクエストをトレース (Prompt、Tool Call、トークン、レイテンシ、コスト)。
- セッションビューでユーザージャーニー。
- 機能/ユーザー別コストダッシュボード。
- 異常アラート (レイテンシスパイク、エラー率、トークン急増)。
ツール: Langfuse (OSS、セルフホスト可)、LangSmith (LangChain有料SaaS)、Phoenix (Arize、OSS)、Helicone、Braintrust。
Part 10 — 本番12項目チェックリスト
- Retry + Exponential Backoff + Jitter?
- Timeoutを明示 (デフォルトじゃない)?
- Streaming有効、TTFT計測?
- Token Counting + Contextガードレール?
- Structured OutputsまたはバリデーションJSON?
- RAGはHybrid + Re-ranker + Citation?
- AgentはStep Cap + Tool予算?
- 評価スイートがCIで走る (Golden + LLM-judge)?
- Observabilityプラットフォーム稼働?
- コストダッシュボードとアラート?
- Prompt Injection防御 (分離・アローリスト・Human-in-loop)?
- Fallbackモデル + Graceful Degradation?
10アンチパターン
- デモコードを本番として扱う。
- 素朴Top-kのRAG、Re-rankなし。
- Prompt Engineering前にFine-tuning。
- 人手キャリブレーションなしのLLM-as-judge。
- 請求書が来るまでコストを無視。
- User入力をSystem Promptに連結。
- Agentに無制限のTool権限。
- Observabilityは「後で追加」。
- スキーマバリデーションなしでLLM出力を信頼。
- パッケージのハルシネーション — LLMに任意の依存をインストールさせる。
次回予告
本番AI Engineeringはモデルと同じくらいシステムの話。次回候補: Agent Orchestration深掘り、RAGスケーリング、LLMコストエンジニアリング。
— AI Engineering 実戦編、完。