Skip to content

SFT/DPO のための軌跡編集

アノテーターはエージェントのトレースのステップを書き換えて、誤った推論ステップの修正、ツール呼び出しの訂正、最終回答の強化を行い、Potato は各オリジナル/修正済みのペアを教師ありファインチューニングのターゲットと DPO 選好ペアとしてエクスポートします。

trajectory_edit スキーマを使うと、アノテーターはエージェントのトレースのステップを書き換え、各修正を訓練データとしてエクスポートできます。 誤った推論ステップの修正、タイプミスしたツール呼び出しの訂正、最終回答の強化を行うと、Potato は修正後の軌跡を元の軌跡の隣に保存します。続いて trajectory_correction エクスポーターが各 (original, corrected) ペアを教師ありファインチューニング(SFT)のターゲットと直接選好最適化(DPO)選好ペアに変換します。

これにより Potato は評価ツールであるだけでなく、訓練データの生成ツールにもなります。これはステップレベルのスコアリングに対する編集版です。つまり、アノテーターは軌跡を評価する代わりに修復し、その修復が学習シグナルになるのです。

ライブ差分付きの軌跡修正エディター読み取り専用のオリジナルと、単語レベルの差分を備えた編集可能な修正ボックスで表示されたエージェントのステップ

クイックスタート

リポジトリのルートから付属のサンプルを実行します。

bash
python potato/flask_server.py start examples/agent-traces/trajectory-correction/config.yaml -p 8000

仕組み

各エージェントのステップは、オリジナルテキスト(読み取り専用)と、オリジナルがあらかじめ入力された編集可能な修正ボックスを表示するカードとしてレンダリングされます。アノテーターが入力すると、

  • ライブの単語レベル差分が挿入(緑)と削除(赤い取り消し線)をハイライト表示し、
  • 変更された単語数と文字数がカウントされ、
  • 変更されたフィールドに「編集済み」フラグが表示されます。

「リセット」ボタンはフィールドごとにオリジナルを復元します。edit_final_answer: true を指定すると、最終回答に専用のエディターが付きます。何も必須ではありません。編集されていないトレースは単に訓練ペアを生成しないだけです。

設定

yaml
annotation_schemes:
  - annotation_type: trajectory_edit
    name: corrected_trajectory
    description: "Fix any wrong steps, then correct the final answer"
    steps_key: steps          # instance field holding the step list
    step_text_key: action     # the default per-step editable field
    editable_fields:          # which fields get an editor
      - action
      # - thought             # add to also edit reasoning
    show_diff: true
    show_edit_distance: true
    allow_reset: true
    require_reason_on_edit: false   # add a per-field "reason" input
    edit_final_answer: true
    final_answer_key: final_answer
オプションデフォルト説明
steps_keystepsステップリストを保持するインスタンスフィールド。
step_text_keyactionステップごとのデフォルトの編集可能フィールド。
editable_fields[step_text_key]どのステップフィールドにエディターを付けるか、例:[action, thought]
show_difftrueライブの単語レベル差分を表示します。
show_edit_distancetrue変更された単語数と文字数を表示します。
allow_resettrueフィールドごとの「オリジナルにリセット」ボタン。
require_reason_on_editfalseフィールドごとの「編集理由」入力欄。
edit_final_answerfalse最終回答用のエディターを追加します。
final_answer_keyfinal_answer最終回答を保持するインスタンスフィールド。

データ形式

スキーマはインスタンスの steps_key の下からステップを読み取ります。各ステップは、そのフィールド(actionthought など)を編集できるオブジェクトです。文字列だけのステップは step_text_key フィールドとして編集されます。

json
{
  "id": "traj_001",
  "task_description": "Find the weather in San Francisco.",
  "steps": [
    {"thought": "Look it up.", "action": "web_search(queyr='SF weather')"},
    {"thought": "Open it.",    "action": "open_url(results[0])"}
  ],
  "final_answer": "It is sunny."
}

エクスポート

trajectory_correction エクスポーターを実行します。3 つのファイルを書き出します。

  • trajectory_corrections.json — すべてのレコード:original_trace、再構築された corrected_trace、編集距離と理由を含むフィールドごとの edits
  • trajectory_sft.jsonl — 編集されたトレースごとに 1 行:{"prompt": <task>, "completion": <corrected_trace>}
  • trajectory_dpo.jsonl — 編集されたトレースごとに 1 行:{"prompt": <task>, "chosen": <corrected_trace>, "rejected": <original_trace>}

編集されていないトレースはカウントされますが SFT/DPO からは除外されます。変更されていない軌跡で訓練しても何も得られないためです。スキップされた数はエクスポート統計に表示されます。複数のアノテーターがいる場合、トレースを編集した各アノテーターが 1 つの SFT/DPO レコードを生成します。

注意事項と制限

  • 差分は単語レベルです。スペースのないコードのようなツール呼び出しでは、1 文字だけの修正でも 1 つのトークンが丸ごと変更されたように表示されることがあります。文字距離カウンターが正確なシグナルです。
  • 同じトレース上でステップごとの正確性やエラー分類体系も得たい場合は、ステップレベルのスコアリングと組み合わせてください。

関連

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