LLMプロダクト育てていくためのデータフライホイール

# はじめに

本記事は、以下記事の翻訳・要約です。

https://www.sh-reya.com/blog/ai-engineering-flywheel/


### サマリ
- LLMプロダクトの評価基準とデータセットをどう育てていくか(Data Flywheel)についての実践的な知見
    - 実際のデータからラベル付などを行うエージェントをつくる
    - 内部プロセスにこそLLMエージェントを活用していく


## 予備知識
フライホイールについて馴染みのない方は、こちらを参照されたい。

https://www.capa.co.jp/archives/29136


# 要約

# A Framework for Creating a Flywheel

# 1. Evaluation: 成功指標の定義
- 成功基準を明確にし、適切な指標を実装する必要がある
  - 特定のユースケースに適した指標を特定する
    - 実際のデータを検証し、タスク固有の失敗モードを把握することが重要
    - 顧客サービスチャットボットの場合、「応答の簡潔さ」や「共感スコア」などが考えられる
  - 指標を実装する
    - コードベースの指標とLLMベースの指標を組み合わせて使用する
    - 簡単なコード関数で簡潔さなどのヒューリスティックを評価する
    - LLMを評価者として使用し、より主観的または複雑な基準を評価する
    - LLMを評価者として使用する場合、人間の判断と一致させることが重要
  - マルチステップパイプラインを検証する
    - LLMグラフの各ノードタイプに応じた検証を行う
      - 分類器ノード：意思決定の正確性を評価
      - 生成ノード：生成されたコンテンツの品質、一貫性、適切性を評価
      - コード生成ノード：静的コード解析、リンター、テストスイートを使用して生成されたコードを検証
  - 入力データも検証する
    - 適切な入力のみを処理するよう保証する
    - ユーザー認証、トピックの関連性、クエリの複雑さ、言語検出などの指標を使用

## a) 特定のユースケースに関連する指標の特定

- 成功の明確な基準を確立し、適切な指標実装を見出す
- 理論的な失敗モード検討だけでは不十分
- 実際のLLM出力データの検証が必要
- LLMの特異性やタスク固有の癖に対応する指標も存在
  - 例：「delve」や「crucial」などの単語が「GPT臭」を発する場合がある
- 実際の出力の慎重な検討から得られる洞察が重要

## b) 指標の実装

- コードベースの指標とLLMベースの指標（プロンプト経由）の両方を使用
  - 簡単なコード関数：簡潔さのための文字数カウントなど
  - 「LLMを判断者として」：主観的または複雑な基準に有用
- LLMを判断者として使用する場合、出力の調整が課題
  - 判断者のプロンプトに良い/悪い出力例を提供することで調整を改善
- バイナリ指標（真/偽）はUXの観点から整列と推論が容易
  - リッカート尺度や詳細な指標よりも単純に始めることが多い
  - 一貫した人間の判断が容易で、評価データの質を維持しやすい

## c) 多段階パイプライン（LLM呼び出しの「グラフ」）の検証

- 複雑なLLMアプリケーションではバリデータをソフトウェア観測性のプローブとして考える
- LLMグラフの各ノードタイプに対して異なる検証が必要
- LLMグラフノードの3つのタイプ：
  1. 分類器としてのLLM（状態遷移ノード）
     - 例：ユーザーの意図を分類し、適切なサブグラフにルーティング
     - 精度、再現率、F1スコアなどの指標を使用
     - ルールベースの検証を適用
  2. ライターとしてのLLM（生成ノード）
     - ユーザーとタスクに特化した指標が必要
     - 生成コンテンツの品質、一貫性、適切性を評価
     - ブランドのトーンと声のガイドラインへの準拠をチェック
  3. コンパイラ/コード生成器としてのLLM（コード生成ノード）
     - 例：ユーザーの意図とコンテキストに基づいてSQLクエリを生成
     - 静的コード分析、リンター、テストスイートを使用
     - 動的分析技術も適用（生成されたSQLの自動実行と検証など）
- バリデータ出力のラベル付けとステップごとの精度計算により、エラーの蓄積を追跡

## d) 入力と出力の両方の検証

- 入力検証により適切なクエリのみがLLMによって処理されることを保証
- 従来のMLでのデータ検証技術をLLMパイプラインに適応させる必要がある
- Postelの法則に基づく設計原則：LLMへの送信は厳格に、有効な応答の受け入れは寛容に
- 入力検証指標の例：
  - ユーザー認証
  - トピックの関連性
  - クエリの複雑さ
  - 言語検出
  - 機密情報の検出
  - 敵対的入力の検出
  - 異常検出
- LLMベースのバリデータを入力検証にも使用可能


# 2. Monitoring: メトリクスの改善最適化
- 指標の実装を本番データに適応させる
  - 選択した指標が目標と一致しているか自動的に再評価する
    - LLMエージェントを使用して指標セットの進化を半自動化する
    - 新しい指標の提案、指標定義の変更、重要でない指標の削除を行う
  - 指標の実装を評価基準と一致させ続ける
    - 定期的にデータをサンプリングし、ラベル付けする
    - ラベル付きの例をタイムスタンプ付きでデータベースに保存する
    - コードベースの指標実装を定期的に手動レビューする
    - LLMベースの評価には動的な例示検索を実装する
      - 入力の類似性に基づいて関連する例を検索する
      - アクティブラーニングを活用し、人間のラベルとLLMの予測が異なる例を優先的に選択する

## a) 選択した指標が目標に合致しているかの自動的再評価

- 指標セットは静的ではなく、進化する必要がある
  - アプリケーションのデプロイ後に新たな失敗モードを学習
  - LLM APIは常に変化し、理想的なシステム動作も時間とともに進化
- 指標セット進化の半自動化のためのLLM「エージェント」の導入
  - ラベル付き本番データのサンプルを定期的に分析
  - 新しい指標の提案（例：顧客が特定のフレーズを一貫して嫌う場合）
  - 指標定義の変更提案（例：簡潔さが単純な文字数よりも主観的と認識）
  - 重要なパフォーマンス指標と相関しない指標の削除を推奨
- LLMエージェントは本番データのサンプルと現在の指標セットのみを必要とする
- AI エンジニアによる新しい指標セットの検証が実装前に重要

## b) 指標実装を評価基準と一致させ続ける

- 本番データのドリフト(変化)に伴い、継続的な再評価が必要
- LLMベースの指標評価者にとって特に重要

### 詳細なワークフロー
  1. 各指標について、本番データから定期的にレスポンスをサンプリングしラベル付け
  2. ラベル付き例をデータベースに保存
     - タイムスタンプ付きで最新性を追跡
     - 埋め込みベースのインデックスも保存する場合あり
  3. コードベースの指標実装は定期的な手動レビューをスケジュール
  4. LLMベースの評価はバリデータのプロンプトを動的に保つ
     - 関連する例をデータベースから取得
     - 入力の類似性に基づく動的な少数ショット例の取得
     - アクティブラーニング的アプローチ：人間のラベルとLLM予測が異なる例を優先
     - ラベルの最新性で類似性スコアに重み付け

```mermaid
graph TD
    A[開始] --> B[本番データからレスポンスをサンプリング]
    B --> C[レスポンスにラベル付け]
    C --> D[ラベル付き例をDBに保存]
    D --> E{指標タイプ?}
    E -->|コードベース| F[定期的な手動レビューをスケジュール]
    E -->|LLMベース| G[バリデータのプロンプトを動的に保つ]
    G --> H[関連する例をDBから取得]
    H --> I[入力類似性に基づく動的少数ショット例取得]
    I --> J[人間ラベルとLLM予測が異なる例を優先]
    J --> K[ラベルの最新性で類似性スコアに重み付け]
    F --> L[終了]
    K --> L
    D --> N[埋め込みベースのインデックスを保存]
    
```

- 各指標に対する定期的な人間によるデータラベル付けの確保が課題
  - 重要だが負担になる可能性がある
- LangChainによるアプローチ：
  - デフォルトでLLMがデータにラベル付け
  - 人間が必要に応じてラベルを編集可能
  - ラベル付け負担を軽減するが、人間の判断との長期的な一致は不明確
  - 完璧でなくとも、少数ショットデモンストレーションのための最新で関連性の高い例の流れを確保



# 3. Continual Improvement: ループさせる(Closing the Loop)
- 評価と監視に基づいてアプリケーションを体系的に改善する
  - プロンプトやパイプラインを手動で反復改善する
    - メトリクスのスコア分布を分析し、パフォーマンスの低いインスタンスのパターンを特定する
    - 入力やクエリデータの分布を分析し、ユーザー行動の変化を観察する
    - A/Bテストを実施し、異なるプロンプト構造やパイプライン構成を比較する
  - メトリクスに応じてパイプラインを自動的に改善する
    - 低スコアの出力を定期的にレビューし、修正する
    - 修正内容とその理由を文書化し、チームメンバーと共有する
    - アクティブラーニングを活用した継続的改善アプローチを実装する
      - 生産トレースとそのメトリクススコア、人間による修正をデータベースに保存する
      - 低スコアのトレースを優先的に手動レビューと修正の対象とする
      - 現在のクエリに最も類似した「修正済み」トレースを検索し、プロンプトに含める


# LLMアプリケーション：新たな課題のセット

- 自己改善するLLMアプリケーション構築の基盤を提供
- システムの可能性を押し広げると、新たな課題が浮上
- LLMOpsライフサイクルにおける研究的観点からの問題を提示

## LLM不確実性定量化のバリデータ調整への応用

- LLM APIの不確実性定量化が主要な課題
  - カスタムタスクの場合に特に問題
- アクティブラーニングがLLM APIで困難
  - 有意な確率推定が欠如
- 命令調整モデルの次トークン確率は非校正で、大規模出力分析に不適
- LLMに信頼度スコアの出力を求める研究もあるが、効果は限定的
- LLMのファインチューニングが直接的解決策だが、LLM APIの簡便さを無視
- 堅牢な不確実性推定の重要性
  - 指標実装の調整能力向上
  - 有益な少数ショット例のサンプリング
  - 人間によるラベル付けのためのデータ優先順位付け
- この分野の進展がフレームワークの評価と継続的改善を強化する可能性

## LLMエージェントグラフのためのデータフライホイール

- LLMアプリケーションの複雑化に伴い、LLMエージェントの相互接続ネットワークやグラフが出現
  - 多段階推論プロセスを表現
  - LLMをループ内に配置するアプリケーションも存在
- このようなシステムのデータフライホイール実装には独自の課題がある
  - 1つのノードのエラーが後続ノードで増幅する可能性
  - 早期検出と修正の必要性
  - 中間出力と最終出力の両方の品質評価が必要
  - 人間による手動評価が困難
  - グラフの動的性質
    - 入力や中間結果に基づき構造が変化
    - 評価と改善プロセスが複雑化

### 研究の方向性

1. グラフ対応の評価指標の実装
   - 階層的検証の可能性
   - 個別LLM呼び出し、ウォーク、サブグラフ、全体グラフの検証
   - ノードタイプに応じた検証プローブの差異化

2. グラフの重要地点に動的に検証プローブを挿入するシステム設計
   - 高リスクノードや遷移を特定するアルゴリズム開発
   - 過去のパフォーマンスデータや不確実性測定、因果分析技術の活用
   - エラーの早期検出と修正を目指す

3. 動的少数ショット学習のグラフ構造への拡張
   - 現在のグラフ構成とタスクに基づく関連サブグラフトレース取得技術の開発
   - グラフ対応埋め込みやサブグラフマッチングアルゴリズムの探索
   - 過去データから類似パターンを発見

## データベース駆動のLLMパイプライン検証

- バリデータをデータベースシステムに直接統合する可能性を探求
- 現状では開発者にとって全トレースのロギングと検証の実装が困難
  - 少数ショット取得の実装
  - すべてのバリデータ（特にLLM駆動）の成功完了の保証
  - 結果のDBへの書き込み
  - リアルタイムや背景での実行が計算資源や時間を要する
- データベースによる自動化の理想

### 主要な検討事項

1. バリデータをデータベーストリガーまたはストアドプロシージャとして実装
   - 新規データの挿入や更新時に自動実行
   - コードベースとLLMベースのバリデータの両方に対応
   - 効率的で、データベースパフォーマンスへの影響を最小限に抑える設計

2. 柔軟な指標計算のためのデータベースビューの使用
   - すべての指標を計算せず、ビューとして実装することでリソース節約の可能性
   - オンデマンド計算とマテリアライズドビューのトレードオフ検討

3. ログの意味的インデックスの増分メンテナンス
   - 少数ショット例の効率的取得のため、LLMパイプライントレースの最新の意味的類似性インデックスを維持
   - 完全な再構築を避ける簡単な増分更新戦略の模索