AIエージェントの操作記録に何を残すか:あとで追える作業ログの項目設計
AIを使いこなすClaudeで執筆し、GPTで自動校閲・修正しています。

結論から言うと、最小構成は「1回の操作につき1行、12項目前後」です。軸になるのは次の5つです。 • 誰が何を依頼したか(依頼) • エージェントがなぜその操作を選んだか(判断) • どのツールをどんな引数で呼んだか(ツール呼び出し) • 何が起きたか(結果) • 誰が許可したか(承認者) この5つを同じ依頼ID(request_id)でつなげば、「あの変更はどの依頼から始まり、誰が通したのか」を後から逆にたどれます。入出力の全文は別に保管し、ログ行には要約と参照先だけを置くのが、多すぎず少なすぎない落としどころです。 以下は編集上の設計案です。サンプル行は説明用の例で、実際に動かして得た記録ではありません。
先に公式ツールが何を出してくれるかを知る
自前で項目を決める前に、使っているエージェント製品が標準で何を記録するかを確認します。ここがずれると二重に作ることになります。
Claude Codeのフックのリファレンス(2026年10月28日に閲覧)では、ツール呼び出しの前後で動くフックに、session_id、prompt_id、tool_name、tool_input、tool_use_id、cwd、permission_modeなどがJSONで渡されると説明されています。成功後のフックにはtool_responseも含まれます。prompt_idはOpenTelemetryのイベントと突き合わせる用途だと書かれています。
監視(OpenTelemetry)のドキュメントには、claude_code.user_prompt、claude_code.tool_decision、claude_code.tool_resultなどのイベントがあります。tool_decisionには承認か拒否か(decision)と、その出どころ(source:設定、フック、ユーザーの許可など)が入ります。プロンプト本文やツールの引数・出力は、既定では伏せられます。出すにはOTEL_LOG_USER_PROMPTSやOTEL_LOG_TOOL_DETAILSなどの設定を明示的に有効にする作りです。
つまり、製品側のログで取れるのは「呼び出し・許可の経路・成否」が中心です。一方で「依頼の目的」「なぜその操作を選んだか」「承認した人の役割」は、運用側で足す必要があります。ほかの製品を使う場合も、同じ観点で一覧を見比べてください。
最小のログ項目表
次の表が提案する項目です。右端に、Claude Codeの上記ドキュメントで確認できる近い項目を添えました。「なし」は、その資料から該当項目を確認できなかったという意味で、製品に機能がないという断定ではありません。
- ts、内容:発生時刻(ISO 8601、タイムゾーン付き)、区分:時間、製品側の近い項目:event.timestamp
- request_id、内容:1つの依頼を束ねるID、区分:依頼、製品側の近い項目:prompt_id / prompt.id
- session_id、内容:作業セッションのID、区分:依頼、製品側の近い項目:session_id
- event、内容:request / decision / tool_call / result / approval のいずれか、区分:種別、製品側の近い項目:イベント名で区別
- request_summary、内容:依頼内容の1文要約と依頼者、区分:依頼、製品側の近い項目:プロンプト本文(既定は非表示)
- reason、内容:操作を選んだ理由(エージェント自己申告の1〜2文)、区分:判断、製品側の近い項目:なし
- tool、内容:ツール名、区分:ツール呼び出し、製品側の近い項目:tool_name
- target、内容:触る対象(ファイルパス、ID、URL)、区分:ツール呼び出し、製品側の近い項目:tool_inputの一部
- effect、内容:read / write / delete / external_send の別、区分:ツール呼び出し、製品側の近い項目:なし
- status、内容:success / error / denied、区分:結果、製品側の近い項目:success、decision
- result_summary、内容:結果の要約と件数、区分:結果、製品側の近い項目:tool_response
- approver、内容:承認した人または承認ルール、区分:承認者、製品側の近い項目:source(経路のみ)
- ref、内容:全文の保管先への参照、区分:参照、製品側の近い項目:transcript_path
押さえたいのは、reasonとeffectとapproverの3つです。この3つは製品の標準ログだけでは薄くなりがちで、後から「なぜ」「どれほど危険な操作だったか」「誰の責任で通ったか」を判断するときの決め手になります。
reasonはモデル自身が書いた説明であり、内部動作を正確に写した証拠とは限りません。あくまで「当時の意図の目安」として扱い、事実の確認はtool・target・statusで行います。
サンプル行(説明用の例)
経費精算の領収書フォルダのファイル名を整える、という架空の依頼です。1行が1イベントで、JSON Lines形式にしています。
{"ts":"2026-10-28T10:00:02+09:00","request_id":"r-001","session_id":"s-12","event":"request","request_summary":"領収書フォルダのファイル名を日付_店名に統一(依頼者:経理A)"}
{"ts":"2026-10-28T10:00:09+09:00","request_id":"r-001","session_id":"s-12","event":"tool_call","tool":"list_files","target":"/receipts/2026-09","effect":"read","reason":"変更前に対象ファイルと現在の名前を把握するため","status":"success","result_summary":"42件を取得"}
{"ts":"2026-10-28T10:01:30+09:00","request_id":"r-001","session_id":"s-12","event":"decision","reason":"42件中3件は店名が読み取れず、推測で改名すると誤りの恐れがあるため対象外にする","effect":"read"}
{"ts":"2026-10-28T10:02:11+09:00","request_id":"r-001","session_id":"s-12","event":"approval","tool":"rename_files","target":"/receipts/2026-09(39件)","effect":"write","approver":"経理A(画面で個別承認)","status":"approved"}
{"ts":"2026-10-28T10:02:15+09:00","request_id":"r-001","session_id":"s-12","event":"result","tool":"rename_files","effect":"write","status":"success","result_summary":"39件改名、3件スキップ、旧名対応表を保存","ref":"logs/r-001/rename_map.csv"}この5行だけで、依頼の中身、3件を除外した判断、書き込み前の承認者、結果、元に戻すための手がかりまで追えます。逆に、各行にファイル一覧の全文を入れていないので、行は短いままです。
残す・参照にする・残さないの判断表
「多すぎる」を防ぐには、項目ごとに扱いを決めておきます。
- 依頼の要約、ツール名、対象、成否、扱い:ログ行に直接残す、理由:検索と集計に使うため
- ツールの出力全文、差分、変更前後の対応表、扱い:別保管してrefで参照、理由:行を肥大化させず、権限も分けられる
- 内部の長い思考過程、扱い:原則残さない、理由:量が多く、事実確認にも向かない。理由は短い自己申告に絞る
- パスワード、APIキー、セッショントークン、接続文字列、扱い:絶対に残さない、理由:漏えい時の被害が大きい
- 個人情報(氏名、口座、健康情報など)、扱い:伏せるかIDに置き換える、理由:必要最小限に抑える
最後の2行は、OWASPのLogging Cheat Sheetが、セッション識別値、認証パスワード、暗号鍵などの秘密情報や、個人識別情報・健康情報・接続文字列をログに含めないよう挙げている点に沿っています。同資料は、時刻・場所・主体・内容(when/where/who/what)を記録すること、ログの改ざんや削除を検知できる仕組みを持つこと、閲覧権限を絞ることも述べています。
Claude Codeが既定でプロンプトや引数を伏せるのも同じ発想です。逆に、全文を出す設定を有効にするなら、保管先のアクセス権と保存期間を先に決めてください。個人情報を含むログの扱いは、組織の規程と適用される法令(日本なら個人情報保護法など)に左右されます。具体的な保存期間は自社の担当部門と確認してください。
エージェントに書かせる依頼文
ログをエージェント自身に書かせる場合の指示文の例です。製品側のフックで機械的に取れる項目(時刻、ツール名、成否)は、この指示ではなくフックに任せるほうが確実です。
作業ごとに、次のルールで作業ログ(JSON Lines)に1行追記してください。
- 書き込み・削除・外部送信の前に、必ず event=decision の行を書く。
reason には「なぜこの操作が必要か」を1〜2文で書く。
- 人の承認が必要な操作は、承認が出るまで実行しない。
承認後に event=approval の行を書き、approver に承認者を記録する。
- パスワード、キー、トークン、個人名・口座番号は書かない。
必要なら「[伏せ字]」またはIDで表す。
- 出力全文は書かず、result_summary に件数と成否だけを書き、
詳細は ref にファイルパスで示す。
- 分からないことは推測で埋めず、reason に「不明」と書く。人が確認するポイントは3つです。approval行がないwriteやdeleteがないか。reasonが空や定型文ばかりになっていないか。ログに秘密情報が混ざっていないか。これを週1回、数十行だけ抜き取って見るだけでも、設計の穴に気づけます。
運用で崩れやすい点
- request_idが途中で切れる:複数のエージェントやサブエージェントが動くと、IDが引き継がれないことがあります。Claude Codeのフックにはagent_idやagent_typeも渡されるとされているので、同様の項目を足すと切り分けやすくなります。
- 承認が「設定で自動許可」になっている:approverに人名が入らないのは正常です。その場合は「ルール名」を入れ、誰がそのルールを作ったかを別途記録します。
- ログを書く権限をエージェントが持つ:エージェントが自分のログを書き換えられると、追跡の意味が薄れます。追記専用にするか、保管先を分けてください。
まずは上の13項目からreasonが不要な読み取り操作の行を省く形で始め、実際に振り返って「足りなかった項目」だけを足すのが現実的です。

