Agent Traceは誰のためのものか?
CursorはAgent Traceをリリースした。これは、リポジトリ内のどのコードがLLMによって書かれたかを追跡するためのオープン仕様である。モデル、ツール、会話、正確な行範囲を記録し、すべてがプロジェクト内のJSONLファイルに追加される。
提案内容:「エージェントがより多くのコードを書くにつれて、AIと人間のどちらから来たかを理解することが重要になる。」
私は仕様とリファレンス実装を読むのに時間を費やした。エンジニアリングは堅実だ。クリーンなスキーマ、思慮深い拡張性、良好なパートナーリスト(Amp、Amplitude、Cloudflare、Cognition、Google、Vercel)。しかし、私は一つの疑問に何度も戻った:このデータで何をするのか?
何を捕捉するか
LLMがファイルを編集するたびに、フックが起動してトレースを記録する:どのモデル、どのツール、どの行、どの会話。リファレンス実装は、CursorとClaude Codeの両方からのイベントを処理する:
// リファレンスフックから — イベントはstdinを通じて流れ込む
appendTrace(createTrace("ai", input.file_path!, {
model: input.model,
rangePositions,
transcript: input.transcript_path,
metadata: { conversation_id: input.conversation_id, generation_id: input.generation_id },
}));
仕様は4つの貢献者タイプ(human、ai、mixed、unknown)を定義し、コンテンツハッシュによる行レベルの帰属をサポートして、移動するコードを追跡する。ベンダー中立で、VCSに依存せず、名前空間付きメタデータを介して拡張可能である。
データフォーマットとしては、よく設計されている。問題は、それが何を可能にするかである。
帰属の課題
仕様は著者権を分類としてモデル化している。しかし、LLM支援コーディングは会話である。あなたは欲しいものを説明する。LLMが何かを生成する。あなたはその半分を編集し、関数を却下し、修正を求め、2回目の試行を受け入れ、その後手動でエッジケースを修正する。後で、別のLLMがブロック全体をリファクタリングする。
そのコードを誰が書いたのか?人間とLLMの著者権の境界は曖昧であり、ますます曖昧になっている。ほとんどの実際のコードはmixedになり、ほぼすべてがmixedであれば、分類はあまり意味をなさない。
行レベルの帰属には賞味期限の問題もある。トレースは「Claudeがコミットabc123で10-50行を書いた」と言う。2つのコミット後、誰かがそのブロックを再フォーマットするか、そこから関数を抽出する。仕様の答えはgit blameを通じてチェーンすることであり、コンテンツハッシュは移動するコードの追跡に役立つ。しかし、リベースやスカッシュマージのあるワークフローでは、チェーンが壊れる。これらは難しい問題であり、初期のRFCが表面化すべき種類のものだ。
欠けているアクション
仕様は明示的に明白な用途を否認している:コード所有権のためではない、品質評価のためではない、トレーニングデータの出所のためではない。「透明性」と言っている。しかし、透明性は手段であり、目的ではない。
コードがレビューとテストを通過すれば、LLMが書いたからといって何が変わるのか?バグがあれば、とにかく修正する。仕様は帰属を具体的なアクションに結びつけることは決してない。データは入るが、答えを得るための定義された方法がない。それがギャップだ — フォーマットではなく、ユースケースである。
興味深くなるところ
これは、仕様がまだ言っていないとしても、Agent Traceが実際に指し示していると私が考えるものだ。
すべてのLLM生成関数の背後には、推論トークン、間違った方向、リトライ、コンテキストスイッチ、ツール呼び出しがある。エージェントは単にコードを生成するだけでなく、そこに到達するためのプロセスを経る。ファイルを読み、インターフェースを誤解し、バックトラックし、別のアプローチを試し、テストを実行し、失敗を修正し、解決策に到達する。そのプロセスは最終的な差分では見えない。
フックはすでに帰属以上のものを捕捉している。入力サーフェスを見てみよう:
interface HookInput {
hook_event_name: string;
model?: string;
transcript_path?: string | null;
conversation_id?: string;
generation_id?: string;
session_id?: string;
file_path?: string;
edits?: FileEdit[];
command?: string;
duration?: number;
is_background_agent?: boolean;
composer_mode?: string;
tool_name?: string;
tool_input?: { file_path?: string; new_string?: string; old_string?: string; command?: string };
tool_use_id?: string;
}
モデル、セッション、会話、ツール、コマンド、期間、バックグラウンドエージェントかどうか、コンポーザーモード、その入力を持つすべてのツール呼び出し。これは単なる帰属データではない。これはプロセスデータである。そして、プロセスデータこそが真の価値が存在する場所である:
- 評価。 どのモデルがどのパターンで苦労するか?1回の試行で済んだ関数は、12回のリトライを要した関数とは異なる — 出力が同一であっても。「誰が書いたか」ではなく「生成するのがどれほど困難だったか」。
- エージェントネイティブなコードベース。 エージェントがモジュールで一貫して苦労している場合(多くの間違った方向、高いリトライ率、繰り返されるコンテキスト混乱) — それは、コードがエージェントの動作方法に対して構造化されていないというシグナルである。明確性、より良いインターフェース、より明示的な契約のためにリファクタリングできる。トレースデータは、コードベースがLLMコラボレーションに敵対的である場所のマップになる。
- プロセス最適化。 どのツール構成がより良い初回試行コードを生成するか?どのプロンプティングパターンがバックトラックを減らすか?行の帰属からこれらに答えることはできない。目的地ではなく、旅が必要である。
正しい問い
Agent Traceは初期段階である。帰属モデリング、範囲の耐久性、クエリセマンティクスに関する実際の課題を持つRFCである。しかし、直感は正しい — LLMがより多くのコードを書くにつれて、それがどのように起こるかについての構造化データが必要である。
この仕様の最も有用なバージョンは、「LLMが何を書いたか?」ではなく「LLMがどのようにそこに到達したか?」かもしれない。行レベルの台帳は出発点である。プロセストレース — 推論、反復、解決策に到達するコスト — こそが、これがチームがLLMでより良いコードを書くために実際に使用するものになる場所である。
それが私が構築したい仕様である。