Skip to content

Solo Mode

12フェーズのインテリジェントワークフローを通じて、1人のアノテーターがLLMと協調してデータセット全体にラベルを付けます。

Solo Mode

v2.3.0の新機能

従来のアノテーションプロジェクトでは、複数のアノテーター、アノテーター間一致度の計算、裁定ラウンド、そして大きな調整オーバーヘッドが必要です。多くの研究チームにとって、主なボトルネックはアノテーションインターフェースではなく、チームの雇用、トレーニング、管理のロジスティクスです。

Solo Modeは、マルチアノテーターパラダイムを、1人の人間エキスパートがLLMと協調する形に置き換えます。人間は小さく戦略的に選択されたサブセットに高品質のラベルを提供します。LLMはそのラベルから学習し、残りにラベルを提案し、人間はLLMが不確かまたは誤りの可能性が高いケースのみをレビューします。12フェーズのワークフローがこのプロセスを自動的にオーケストレーションします。

社内ベンチマークでは、Solo Modeは全人間ラベルのわずか10〜15%で、フルのマルチアノテーターパイプラインと95%以上の一致を達成しました。

12フェーズワークフロー

Solo Modeは12のフェーズを進行します。システムは設定可能な閾値に基づいて自動的に進行しますが、管理ダッシュボードから手動で遷移をトリガーすることもできます。

フェーズ1:シードアノテーション

人間のアノテーターが初期シードセットにラベルを付けます。Potatoは埋め込みベースのクラスタリングを使用して、データ分布のカバレッジを最大化するように多様で代表的なインスタンスを選択します。

デフォルトのシードサイズ: 50インスタンス(seed_countで設定可能)

フェーズ2:初回LLMキャリブレーション

LLMはシードアノテーションをfew-shot例として受け取り、キャリブレーションバッチにラベルを付けます。Potatoはホールドアウトされたシードラベルに対するLLMの予測を比較し、ベースライン精度を確立します。

フェーズ3:混同分析

Potatoは人間とLLMの間の体系的な不一致パターンを特定します。混同行列を構築し、最も一般的なエラータイプを表面化します(例:「LLMがneutralをpositiveとラベル付けする確率40%」)。

フェーズ4:ガイドライン改善

混同分析に基づいて、PotatoはLLM用の改善されたアノテーションガイドラインを生成します。人間はこれらのガイドラインを適用前にレビューおよび編集します。これはインタラクティブなステップで、アノテーターは例を追加し、エッジケースを明確にし、ラベル定義を調整できます。

フェーズ5:ラベリング関数生成

ALCHEmistフレームワークに着想を得て、Potatoは既存のアノテーションからプログラマティックなラベリング関数を生成します。これらはシンプルなパターンベースのルール(例:「テキストに'excellent'が含まれ否定がなければ、positiveとラベル付け」)で、高い精度で簡単なインスタンスにラベルを付け、人間とLLMの労力をより難しいケースに集中させます。

フェーズ6:アクティブラベリング

人間が能動学習によって選択された追加のインスタンスにラベルを付けます。Potatoは、LLMが最も不確かなインスタンス、ラベリング関数が不一致のインスタンス、または埋め込み空間で既存のトレーニング例から遠いインスタンスを優先します。

フェーズ7:自動改善ループ

LLMは更新されたガイドラインとfew-shot例でデータセット全体を再ラベリングします。Potatoはすべての人間ラベルに対して比較し、精度が閾値を下回る場合は混同分析とガイドライン改善の別のサイクルをトリガーします。

フェーズ8:不一致探索

人間はLLMとラベリング関数が不一致のすべてのインスタンスをレビューします。これらは通常、最も情報量が多く困難な例です。これらのケースに対する人間のラベルは最高の限界価値を提供します。

フェーズ9:エッジケース合成

Potatoは、特定された混同パターンに基づいてLLMを使用して合成エッジケースを生成します。人間はこれらの合成例にラベルを付け、その後LLMのトレーニングコンテキストに追加されて、最も難しいケースでのパフォーマンスを向上させます。

フェーズ10:カスケード信頼度エスカレーション

LLMは残りのすべてのラベルなしインスタンスに信頼度スコアを割り当てます。インスタンスは難易度の降順(信頼度の昇順)で人間にエスカレーションされます。品質メトリクスが安定するまで人間がラベルを付けます。

フェーズ11:プロンプト最適化

DSPyに着想を得て、Potatoは蓄積された人間ラベルを検証セットとして使用し、自動プロンプト最適化を実行します。複数のプロンプトバリエーション(指示の表現、例の順序、chain-of-thought vs. 直接)を試し、最もパフォーマンスの良いプロンプトを選択します。

フェーズ12:最終検証

人間はLLMラベル付きインスタンスからのランダムサンプルの最終レビューを実行します。精度が閾値を満たせば、データセットは完了です。そうでなければ、システムはフェーズ6に戻ります。


設定

クイックスタート

最小限のSolo Mode設定:

yaml
task_name: "Sentiment Classification"
task_dir: "."
 
data_files:
  - "data/reviews.jsonl"
 
item_properties:
  id_key: id
  text_key: text
 
solo_mode:
  enabled: true
 
  # LLM provider
  llm:
    endpoint_type: openai
    model: "gpt-4o"
    api_key: ${OPENAI_API_KEY}
 
  # Basic thresholds
  seed_count: 50
  accuracy_threshold: 0.92
  confidence_threshold: 0.85
 
annotation_schemes:
  - annotation_type: radio
    name: sentiment
    labels:
      - Positive
      - Neutral
      - Negative
 
output_annotation_dir: "output/"
output_annotation_format: "jsonl"

完全な設定リファレンス

yaml
solo_mode:
  enabled: true
 
  # LLM configuration
  llm:
    endpoint_type: openai        # openai, anthropic, ollama, vllm
    model: "gpt-4o"
    api_key: ${OPENAI_API_KEY}
    temperature: 0.1             # low temperature for consistency
    max_tokens: 256
 
  # Phase control
  phases:
    seed:
      count: 50                  # number of seed instances
      selection: diversity        # diversity, random, or stratified
      embedding_model: "all-MiniLM-L6-v2"
 
    calibration:
      batch_size: 100
      holdout_fraction: 0.2      # fraction of seed used for validation
 
    confusion_analysis:
      min_samples: 30
      significance_threshold: 0.05
 
    guideline_refinement:
      auto_suggest: true         # LLM suggests guideline edits
      require_approval: true     # human must approve changes
 
    labeling_functions:
      enabled: true
      max_functions: 20
      min_precision: 0.90        # only keep high-precision rules
      min_coverage: 0.01         # must cover at least 1% of data
 
    active_labeling:
      batch_size: 25
      strategy: uncertainty       # uncertainty, diversity, or hybrid
      max_batches: 10
 
    refinement_loop:
      max_iterations: 3
      improvement_threshold: 0.02
 
    disagreement_exploration:
      max_instances: 200
      sort_by: confidence_gap
 
    edge_case_synthesis:
      enabled: true
      count: 50
      diversity_weight: 0.3
 
    confidence_escalation:
      escalation_budget: 200     # max instances to escalate
      batch_size: 25
      stop_when_stable: true     # stop if last batch accuracy is 100%
 
    prompt_optimization:
      enabled: true
      candidates: 10             # number of prompt variants to try
      metric: f1_macro
      search_strategy: bayesian  # bayesian, grid, or random
 
    final_validation:
      sample_size: 100
      min_accuracy: 0.92
      fallback_phase: 6          # go back to Phase 6 if validation fails
 
  # Instance prioritization across phases
  prioritization:
    pools:
      - name: uncertain
        weight: 0.30
        description: "LLM confidence below threshold"
      - name: disagreement
        weight: 0.25
        description: "LLM and labeling functions disagree"
      - name: boundary
        weight: 0.20
        description: "Near decision boundary in embedding space"
      - name: novel
        weight: 0.10
        description: "Far from all existing labeled examples"
      - name: error_pattern
        weight: 0.10
        description: "Matches known confusion patterns"
      - name: random
        weight: 0.05
        description: "Random sample for calibration"

主な機能

混同分析

各ラベリングラウンド後、Potatoは人間とLLMのラベル間の混同行列を構築します。管理ダッシュボードには以下が表示されます:

  • LLMの観点からのクラスごとの適合率、再現率、F1
  • 最も一般的な混同ペア(例:「neutralをpositiveと誤分類:23件」)
  • 各混同ペアのインスタンス例
  • 改善ラウンド間の改善を示すトレンドチャート

コマンドラインから混同分析にアクセス:

bash
python -m potato.solo confusion --config config.yaml

出力:

text
Confusion Analysis (Round 2)
============================
Overall Accuracy: 0.87 (target: 0.92)

Top Confusion Pairs:
  neutral -> positive:  23 instances (15.3%)
  negative -> neutral:  11 instances (7.3%)
  positive -> neutral:   5 instances (3.3%)

Per-Class Performance:
  Positive:  P=0.91  R=0.94  F1=0.92
  Neutral:   P=0.78  R=0.71  F1=0.74
  Negative:  P=0.93  R=0.88  F1=0.90

自動改善ループ

改善ループはLLMラベリング、混同分析、ガイドライン更新を繰り返します。各イテレーション:

  1. LLMが現在のガイドラインでデータセット全体にラベルを付ける
  2. Potatoがすべての利用可能な人間ラベルと比較する
  3. 精度が閾値を下回る場合、混同分析が実行される
  4. LLMがエラーパターンに基づいてガイドライン編集を提案する
  5. 人間が編集をレビューし承認する
  6. サイクルが繰り返される(max_iterationsまで)
yaml
solo_mode:
  llm:
    endpoint_type: anthropic
    model: "claude-sonnet-4-20250514"
    api_key: ${ANTHROPIC_API_KEY}
 
  phases:
    refinement_loop:
      max_iterations: 3
      improvement_threshold: 0.02    # stop if improvement is less than 2%

ラベリング関数(ALCHEmistに着想を得た)

Potatoは人間のアノテーションで観察されたパターンから軽量なラベリング関数を生成します。これらはLLM呼び出しではなく、高速で決定論的なルールです。

生成されたラベリング関数の例:

python
# Auto-generated labeling function 1
# Precision: 0.96, Coverage: 0.08
def lf_strong_positive_words(text):
    positive = {"excellent", "amazing", "fantastic", "outstanding", "perfect"}
    if any(w in text.lower() for w in positive):
        if not any(neg in text.lower() for neg in {"not", "never", "no"}):
            return "Positive"
    return None  # abstain
 
# Auto-generated labeling function 2
# Precision: 0.93, Coverage: 0.05
def lf_explicit_negative(text):
    negative = {"terrible", "awful", "horrible", "worst", "disgusting"}
    if any(w in text.lower() for w in negative):
        return "Negative"
    return None

ラベリング関数の動作を設定:

yaml
solo_mode:
  phases:
    labeling_functions:
      enabled: true
      max_functions: 20
      min_precision: 0.90
      min_coverage: 0.01
      types:
        - keyword_match
        - regex_pattern
        - length_threshold
        - embedding_cluster

不一致エクスプローラー

不一致エクスプローラーは、異なるシグナルが矛盾するインスタンスを提示します。各インスタンスについて、アノテーターには以下が表示されます:

  • LLMの予測ラベルと信頼度
  • ラベリング関数の投票(ある場合)
  • 埋め込み空間での最近傍ラベル付き済みインスタンス
  • 生のテキスト/コンテンツ

これは最も価値の高いアノテーション活動です:各ラベルが本物の曖昧さを解決します。

yaml
solo_mode:
  phases:
    disagreement_exploration:
      max_instances: 200
      sort_by: confidence_gap     # or "lf_disagreement" or "random"
      show_llm_reasoning: true    # display LLM's chain-of-thought
      show_nearest_neighbors: 3   # show 3 nearest labeled examples

カスケード信頼度エスカレーション

データセットの大部分がLLMによってラベル付けされた後、Potatoはすべてのラベル付き済みインスタンスを信頼度でランク付けし、最も信頼度の低いものを人間にエスカレーションします。品質が安定するまでバッチで続行します。

yaml
solo_mode:
  phases:
    confidence_escalation:
      escalation_budget: 200
      batch_size: 25
      stop_when_stable: true
      stability_window: 3        # stop if last 3 batches are all correct

マルチシグナルインスタンス優先順位付け

人間のラベリングを含むすべてのフェーズにおいて、Potatoは重み付けプールシステムを使用して最も情報量の多いインスタンスを選択します。6つのプールが統一された優先キューに供給されます:

yaml
solo_mode:
  prioritization:
    pools:
      - name: uncertain
        weight: 0.30
      - name: disagreement
        weight: 0.25
      - name: boundary
        weight: 0.20
      - name: novel
        weight: 0.10
      - name: error_pattern
        weight: 0.10
      - name: random
        weight: 0.05
  • uncertain:LLMの信頼度がconfidence_threshold未満のインスタンス
  • disagreement:LLMとラベリング関数が異なるラベルを生成するインスタンス
  • boundary:埋め込み空間の決定境界付近のインスタンス
  • novel:既存のラベル付き済み例から遠いインスタンス
  • error_pattern:前回のラウンドからの既知の混同パターンに一致するインスタンス
  • random:キャリブレーションを維持し、盲点を検出するための小さなランダムサンプル

エッジケース合成

Potatoは既知の弱点をターゲットにした合成例を生成するためにLLMを使用します:

yaml
solo_mode:
  phases:
    edge_case_synthesis:
      enabled: true
      count: 50
      diversity_weight: 0.3
      confusion_pairs:            # focus on these error types
        - ["neutral", "positive"]
        - ["negative", "neutral"]

LLMは指定されたラベルペア間で曖昧な例を生成します。人間がラベルを付け、これらのラベルは後続のLLMラベリングラウンドのfew-shotコンテキストに追加されます。

プロンプト最適化(DSPyに着想を得た)

フェーズ11で、Potatoは自動プロンプト最適化を実行し、LLMにとって最良の指示形式を見つけます:

yaml
solo_mode:
  phases:
    prompt_optimization:
      enabled: true
      candidates: 10
      metric: f1_macro
      search_strategy: bayesian
      variations:
        - instruction_style      # formal vs. conversational
        - example_ordering       # random, by-class, by-difficulty
        - reasoning_mode         # direct, chain-of-thought, self-consistency
        - example_count          # 3, 5, 10, 15 few-shot examples

進捗のモニタリング

管理ダッシュボードはSolo Modeの進捗をリアルタイムで表示します:

  • 現在のフェーズと各フェーズ内の進捗
  • 完了した人間ラベル数 vs. 総予算
  • LLMの精度の推移(ラウンドごと)
  • ラベリング関数のカバレッジと精度
  • 信頼度分布ヒストグラム
  • 完了までの推定時間

コマンドラインからアクセス:

bash
python -m potato.solo status --config config.yaml
text
Solo Mode Status
================
Current Phase: 6 (Active Labeling) - Batch 3/10
Human Labels: 142 / ~300 estimated total
LLM Accuracy: 0.89 (target: 0.92)
LF Coverage: 0.23 (labeling functions cover 23% of data)
Dataset Size: 10,000 instances
  - Human labeled: 142
  - LF labeled: 2,300
  - LLM labeled: 7,558
  - Unlabeled: 0

Solo Mode vs. 従来のマルチアノテーターの使い分け

Solo Modeを使用すべき場合:

  • 高品質のラベルを提供できるドメインエキスパートがいる
  • 予算やロジスティクスの制約で複数のアノテーターを雇えない
  • タスクに明確で定義されたカテゴリがある
  • 大規模なデータセット(1,000件以上)にラベルを付ける必要がある
  • アノテーター間一致度の測定よりも速度が重要

従来のマルチアノテーターを使用すべき場合:

  • 出版のためにアノテーター間一致度の統計が必要
  • タスクが非常に主観的(例:攻撃性、ユーモア)
  • アノテーターの不一致パターンを研究する必要がある
  • 規制要件が複数の独立したアノテーターを義務付けている
  • ラベル空間が複雑または発展途上(アノテーションガイドラインがまだ開発中)

ハイブリッドアプローチ: 初期の一括ラベリングにSolo Modeを使用し、ランダムな10〜20%のサンプルに2人目のアノテーターを割り当てて一致度統計を計算します。これによりSolo Modeの効率性とマルチアノテーター検証の品質保証が得られます。

yaml
solo_mode:
  enabled: true
  # ... solo mode config ...
 
  # Hybrid: assign verification sample to second annotator
  verification:
    enabled: true
    sample_fraction: 0.15
    annotator: "reviewer_1"

参考資料

実装の詳細については、ソースドキュメントを参照してください。