llmops-platform-engineering について
社内 LLM プラットフォームの構築と運用を支援するエンジニアリングスキルです。評価ゲート、A/B テスト、Kubernetes でのモデル提供、ガバナンス、運用を扱います。
主な機能
- 01LLM プラットフォームの制御面とデータ面の設計
- 02評価ゲートを含む CI/CD の構築
- 03モデルバージョンの A/B テスト設定
- 04Kubernetes モデルサービングのデプロイ
- 05ガバナンス、可観測性、コスト分析の設定
活用シーン
- 01チーム向け社内 LLM プラットフォームの構築
- 02リリース前の品質・安全性評価
- 03モデルバージョン間の性能比較
- 04モデル昇格と本番デプロイの管理
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill llmops-platform-engineeringインストール後、Claude Code で/llmops-platform-engineeringを入力して読み込まれたか確認します。
詳細
LLMOps プラットフォームエンジニアリング
信頼性、コスト、コンプライアンスを損なうことなく迅速な実験を可能にする、社内 LLM プラットフォームを設計・運用します。
このスキルを使用する場面
- チームが LLM を活用した機能をデプロイ・管理できる社内プラットフォームを構築する
- モデル評価ゲートを含む CI/CD パイプラインを設計する
- モデルバージョン向けの A/B テストインフラストラクチャを構築する
- Kubernetes ベースのモデルサービングインフラストラクチャを作成する
- モデル昇格のガバナンスワークフローを確立する
前提条件
- GPU ノードプールを備えた Kubernetes クラスター(またはクラウド推論 API へのアクセス)
- コンテナレジストリ(Harbor、ECR、GCR、または ACR)
- CI/CD システム(GitHub Actions、GitLab CI、または Argo Workflows)
- オブザーバビリティスタック(Prometheus + Grafana + OpenTelemetry)
- モデルレジストリ(MLflow またはカスタムメタデータストア)
成果
- 実験から本番環境までの標準化された経路
- 品質と安全性のゲートによる安全なモデルロールアウト
- 推論、ベクトル DB、オブザーバビリティ向けの再利用可能なインフラモジュール
- プラットフォーム、アプリ、セキュリティ各チーム間で明確な責任体制
リファレンスアーキテクチャ
- コントロールプレーン:モデルレジストリ、プロンプト/バージョンカタログ、ポリシーチェック、評価パイプライン。
- データプレーン:推論ゲートウェイ、ベクトルデータベース、キャッシュ、フィーチャーストア。
- 運用プレーン:テレメトリ、アラート、SLO ダッシュボード、コスト分析。
- セキュリティプレーン:IAM 境界、シークレットのローテーション、コンテンツフィルター、監査ログ。
モデル昇格パイプライン
# .github/workflows/model-promotion.yaml
name: Model Promotion Pipeline
on:
workflow_dispatch:
inputs:
model_name:
description: "Model identifier"
required: true
model_version:
description: "Model version to promote"
required: true
target_env:
description: "Target environment"
required: true
type: choice
options: [staging, production]
jobs:
evaluate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run quality evaluation suite
run: |
python -m evals.run \
--model "${{ inputs.model_name }}:${{ inputs.model_version }}" \
--suite quality \
--output results/quality.json
- name: Run safety evaluation suite
run: |
python -m evals.run \
--model "${{ inputs.model_name }}:${{ inputs.model_version }}" \
--suite safety \
--output results/safety.json
- name: Run latency benchmark
run: |
python -m evals.benchmark \
--model "${{ inputs.model_name }}:${{ inputs.model_version }}" \
--concurrent-users 50 \
--duration 300 \
--output results/latency.json
- name: Gate check - quality
run: |
python -m evals.gate_check \
--results results/quality.json \
--threshold-file thresholds/quality.yaml
- name: Gate check - safety
run: |
python -m evals.gate_check \
--results results/safety.json \
--threshold-file thresholds/safety.yaml
- name: Gate check - latency
run: |
python -m evals.gate_check \
--results results/latency.json \
--threshold-file thresholds/latency.yaml
- name: Upload eval evidence
uses: actions/upload-artifact@v4
with:
name: eval-results-${{ inputs.model_version }}
path: results/
approve:
needs: evaluate
runs-on: ubuntu-latest
environment: ${{ inputs.target_env }}
steps:
- name: Record approval
run: |
echo "Approved by: ${{ github.actor }}"
echo "Model: ${{ inputs.model_name }}:${{ inputs.model_version }}"
echo "Target: ${{ inputs.target_env }}"
echo "Time: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
deploy:
needs: approve
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy canary
run: |
kubectl set image deployment/${{ inputs.model_name }}-canary \
model=${{ inputs.model_name }}:${{ inputs.model_version }} \
-n ai-${{ inputs.target_env }}
- name: Wait for canary validation (15 min)
run: |
python -m canary.validate \
--deployment ${{ inputs.model_name }}-canary \
--namespace ai-${{ inputs.target_env }} \
--duration 900 \
--quality-threshold 0.85 \
--error-rate-threshold 0.02
- name: Promote to full rollout
run: |
kubectl set image deployment/${{ inputs.model_name }} \
model=${{ inputs.model_name }}:${{ inputs.model_version }} \
-n ai-${{ inputs.target_env }}
kubectl rollout status deployment/${{ inputs.model_name }} \
-n ai-${{ inputs.target_env }} --timeout=300s
評価ゲートのしきい値
# thresholds/quality.yaml
gates:
groundedness:
metric: groundedness_score
min: 0.85
comparison: gte
task_success:
metric: task_success_rate
min: 0.90
comparison: gte
hallucination:
metric: hallucination_rate
max: 0.08
comparison: lte
regression:
metric: quality_delta_vs_baseline
min: -0.02
comparison: gte
description: "Must not regress more than 2% vs current production"
# thresholds/latency.yaml
gates:
p50_latency:
metric: latency_p50_ms
max: 800
comparison: lte
p95_latency:
metric: latency_p95_ms
max: 2000
comparison: lte
p99_latency:
metric: latency_p99_ms
max: 5000
comparison: lte
throughput:
metric: requests_per_second
min: 50
comparison: gte
A/B テストの設定
# ab-test-config.yaml
apiVersion: gateway.ai/v1
kind: ABTest
metadata:
name: model-comparison-q1
namespace: ai-production
spec:
duration: 7d
traffic_split:
control:
model: gpt-4o-2024-08-06
weight: 70
treatment:
model: gpt-4o-2025-01-15
weight: 30
metrics:
primary:
- task_success_rate
- user_satisfaction_score
secondary:
- latency_p95
- cost_per_request
- hallucination_rate
guardrails:
auto_rollback_if:
- metric: task_success_rate
threshold: 0.80
window: 1h
- metric: hallucination_rate
threshold: 0.15
window: 30m
assignment:
strategy: sticky_user
hash_key: user_id
Kubernetes モデルサービングのデプロイ
# model-serving-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: llm-inference
namespace: ai-production
labels:
app: llm-inference
model: gpt-4o
version: "2025-01"
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: llm-inference
template:
metadata:
labels:
app: llm-inference
model: gpt-4o
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/metrics"
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: llm-inference
containers:
- name: model
image: registry.internal/vllm-server:0.4.1
args:
- "--model=/models/current"
- "--tensor-parallel-size=1"
- "--max-model-len=8192"
- "--gpu-memory-utilization=0.90"
ports:
- containerPort: 8000
name: inference
- containerPort: 8080
name: metrics
resources:
requests:
cpu: "4"
memory: "16Gi"
nvidia.com/gpu: "1"
limits:
cpu: "8"
memory: "32Gi"
nvidia.com/gpu: "1"
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 120
periodSeconds: 30
volumeMounts:
- name: model-weights
mountPath: /models
readOnly: true
- name: config
mountPath: /etc/vllm
volumes:
- name: model-weights
persistentVolumeClaim:
claimName: model-weights-pvc
- name: config
configMap:
name: vllm-config
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
nodeSelector:
gpu-type: a100
---
apiVersion: v1
kind: Service
metadata:
name: llm-inference
namespace: ai-production
spec:
selector:
app: llm-inference
ports:
- name: inference
port: 8000
targetPort: 8000
- name: metrics
port: 8080
targetPort: 8080
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: llm-inference-hpa
namespace: ai-production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: llm-inference
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: llm_queue_depth
target:
type: AverageValue
averageValue: "5"
- type: Pods
pods:
metric:
name: gpu_utilization_percent
target:
type: AverageValue
averageValue: "75"
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 2
periodSeconds: 120
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 300
AI サービス向け CI/CD 設計
- 依存関係とモデルハッシュを固定した不変のコンテナをビルドします。
- 環境昇格を使用します:
dev -> stage -> prod。 - 次の場合はデプロイを失敗させます:
- 回帰評価の結果がベースラインを下回る
- 安全性テストの結果がリスクしきい値を超える
- p95 レイテンシが SLO の予算を超える
- 監査に備えてデプロイの証跡(コミット SHA、評価レポート、承認者)を保存します。
運用 SLO
| シグナル | 目標 | 測定期間 |
|---|---|---|
| 可用性 | 99.9% | 30 日間のローリング |
| p95 レイテンシ | < 1200ms | 5 分単位 |
| リクエストあたりのコスト | < $0.05 | 1 時間平均 |
| タスク成功率 | > 90% | 24 時間のローリング |
| グラウンデッドネス | > 85% | 24 時間のローリング |
プラットフォームのガードレール
- テナントごとのクォータとモデルの許可リストを適用します。
- 自動化経路では構造化出力の契約を必須にします。
- 重要なワークフローでは、デフォルトでリスクの低いモデル設定を使用します。
- 本番環境では、制約のないツール実行を無効にします。
ツールスタック(例)
| レイヤー | ツール |
|---|---|
| オーケストレーション | Argo Workflows、GitHub Actions、Airflow |
| モデルレジストリ | MLflow、カスタムメタデータ DB |
| ゲートウェイ | LiteLLM、Envoy ベースの API ゲートウェイ |
| オブザーバビリティ | OpenTelemetry + Prometheus + Grafana + Langfuse |
| ポリシー | デプロイ時と実行時のチェック向け OPA/Rego |
| 評価 | RAGAS、カスタム評価ハーネス、Promptfoo |
| サービング | vLLM、TGI、Triton Inference Server |
トラブルシューティング
| 問題 | 診断 | 解決策 |
|---|---|---|
| カナリアが品質ゲートに失敗する | 評価結果をベースラインと比較する | モデル設定を調整するか、バージョンをロールバックする |
| デプロイのロールアウトが停止する | Pod のイベントとリソースクォータを確認する | リソース制限またはノードの利用可能性を修正する |
| A/B テストで有意差が見られない | トラフィックの分割とサンプルサイズを確認する | テスト期間を延長するか、処置群の比率を増やす |
| モデルのコールドスタートが遅すぎる | モデルの重みのダウンロードサイズが大きい | キャッシュ済みの PVC または init コンテナを使用する |
| 評価パイプラインが不安定 | モデル出力が非決定的 | 評価時の temperature を 0 に設定し、サンプルサイズを増やす |
関連スキル
- ai-pipeline-orchestration - 取り込みおよび推論ワークフローをオーケストレーションします
- agent-evals - リリース用の評価ゲートを構築します
- llm-gateway - LLM トラフィックをルーティングして制御します
- model-registry-governance - モデルのライフサイクルと承認ワークフローを管理します
- ai-sre-incident-response - AI 固有のインシデントに対応します
コメント
Markdown 対応