- 公開日
AIが出力したコードは、対象環境、扱うデータ、実行権限、変更する対象を確認してから使います。説明に「出力例」があっても、それが実行記録なのか、コードを読んで予想した結果なのかを区別してください。小さな例が動いたという記録があっても、実データや本番環境への適合まで確認したことにはなりません。
最初に見るのは、「どこで、何を読み、何を変えるか」です。手元の架空データをメモリ上で変換する処理と、共有フォルダーを上書きする処理では、必要な準備が違います。同じ変換関数でも、利用場所を変えれば追加の確認が必要になります。
この記事は、AIが書いたコードを手元や検証環境で試しに使う段階の確認を扱います。本番環境に出してよいかの判定は「AI生成コードを本番利用する前のチェックリスト」で扱います。
環境と権限をコードの前提にする
環境にはOS、言語とその版、呼び出すシェル、依存ライブラリ、設定、作業フォルダーを含めます。「Pythonで実行」という説明だけでは、対象版や読み込むファイルの位置が決まりません。依存関係も、コードに直接現れるものだけでなく、起動時に読み込む設定や接続先を含めて確認します。
権限は、ログインできるかだけでなく、どのファイルやデータを読めるか、何を書き換えられるかです。変換に不要な管理者権限や本番の接続情報を渡さない構成を選びます。認証は利用者などの主体を確かめること、認可はその主体に対象操作を許すことです。非公開APIを扱う場合、OWASPのREST Security Cheat Sheetが示す各エンドポイントのアクセス制御も、単にログイン画面があるかとは別に確認します。
NISTのSSDF v1.1は、開発・試験の環境を保護し、試験の範囲と結果を記録する実践を示しています。すべての小さな関数に大規模な運用基盤を求める意味ではありません。失敗時の影響に合わせて、実データと切り離す範囲、外部接続を許す範囲、結果を誰が確認するかを決めます。
データ変換の小例にも前提を添える
以下は架空の名簿データから名前を取り出す、未実行の説明例です。対象環境はPython 3.14系を想定し、外部ライブラリ、ファイル入出力、ネットワーク接続を使わない構成に限定します。この記事で実際にPythonを起動して確認した結果ではありません。
入力は、各要素に文字列のnameがあるリストだけを受け取るという前提です。この最初の関数には、不正な入力を説明付きで拒否する処理を含めていません。
#未実行の説明例。入力が前提を満たす場合だけを示す。
def extract_names(rows):
return [row["name"] for row in rows]
sample = [{"name": "青木"}, {"name": "林"}]
#期待する戻り値: ["青木", "林"]
#実際の戻り値・実行日時・実行環境: 未実行のため記録なし
この例でコードから読み取れるのは、渡された順序でnameの値を集める意図です。nameがない要素、リストではない入力、巨大なデータへの対応は示していません。期待される二つの名前を説明に書けても、不正入力の扱いや実際の実行時間が分かるわけではありません。
外部から受け取ったデータへ適用するなら、型、必要な項目、長さや件数の条件を先に決めます。OWASPの入力検証ガイダンスは、形式と業務上の意味の両方を確認する考え方を示しています。たとえば名前が文字列でも、対象業務で空文字を認めるか、出力の対象者に含めてよいかは別の条件です。
ここで「見本の入力なら読む対象が限られている」と判断できることを、「実際の名簿にもそのまま使える」へ広げないようにします。名前を表示する画面や保存先が加われば、その出力先に合う処理と閲覧権限も必要です。入力の形式が正しいことは、個人情報を送信してよい根拠にはなりません。
未実行の説明と実際の試験を分ける
コードを受け取った段階では、「想定環境」「入力例」「期待結果」「未実行」をセットで残します。後から許可された環境で試験を行った場合にだけ、実際の環境、使用したコードの版、入力、出力、終了状態、確認者を追加します。この記事の例は、その後の試験を行っていません。
| 状態 | 記録できる内容 | その記録だけでは言えないこと |
|---|---|---|
| コードを読んだ | 処理の意図、入力条件、期待する戻り値 | その環境で起動できた、結果が一致した |
| 指定した入力で試験した | 対象環境、実際の出力、一致・不一致 | 別の入力や本番負荷でも成立する |
| 実環境に近い条件でも試験した | 調べた範囲の結果と残った問題 | 調べていない権限・障害・データの保証 |
実行したとしても、「エラーが出なかった」だけでは目的を確認できません。名前の件数、順序、欠落、意図しない追加がないかを入力と照合します。出力欄が空だった場合も、空の結果を正常に返したのか、結果を取得できなかったのかを分けます。
外部プログラムを呼ぶ場合は、Pythonのsubprocess文書にある終了コード、標準出力、標準エラーなどが記録材料になります。ただし、終了コード0だけで変換内容の正しさや安全性は保証されません。また、関数の戻り値とプロセスの終了コードは異なるものです。上の関数例に、取得していない終了コードを付け足さないでください。
入力と保存先が変わると判断も変わる
同じ名前抽出でも、次の条件差で、実行へ進むために必要な確認が変わります。表は本番利用の認証ではなく、作業を止める理由や準備すべきものを具体化するための整理です。
| 条件 | 判断の目安 | 次に行う確認 |
|---|---|---|
| 架空の二件だけをメモリ上で扱う | 影響が限定された試験候補 | 入力前提、関数内容、許可された試験環境 |
| 実際の名簿を新しいファイルへ出力する | 追加対策が必要 | データ利用許可、出力先の権限、欠落と漏えいの確認 |
| 共有名簿を同じ名前で上書きする | 準備不足なら実行を止める | 対象の確定、承認、退避、復元と競合への対応 |
| 接続先や入力の出所が分からない | 適用可否は未確認 | 出所、実行主体、依存設定を特定する |
最初の条件では、外部サービスの認証を新たに実装する必要はありません。それでも、コードを読まずに無制限の権限で実行してよいわけではありません。省けるのはその処理に存在しない外部接続への対策であり、実際に存在するファイルや権限の境界ではありません。
危険と判断する例は、対象を確認せず共有名簿を置き換える、エラーを無視して上書きを続ける、必要のない秘密を外部へ送る、といったものです。「AIが安全と言った」「サンプルは動いた」では、その判断を変更できません。何が変更されるか分からない場合は、危険だと断定する前に未確認として実行を保留し、対象を調べます。
失敗時の停止と復旧を先に考える
ファイルを書き換える処理では、実行前の状態をどう確保し、結果をどう比較するかを決めます。元データを残す、新しい出力先へ書く、確認後に切り替えるといった選択肢がありますが、対象の保存方式や同時更新に合うかを確認します。退避ファイルが存在することと、その内容から復元できることも別です。
途中で止まったときは、どこまで変更されたかを確かめてから復旧します。「失敗」と表示されても、一部の書き込みが済んでいる可能性を考慮します。状態が不明なまま同じ処理を再実行すると、二重追加や最新の変更の消失につながるため、まず出力と対象の状態を確認します。
名前抽出の小例なら、入力を変えない純粋な計算として試験範囲を絞れます。それをファイル変換へ広げる時点で、読み込み失敗、書き込み権限不足、途中終了、既存出力がある場合の扱いを追加します。ファイル保存を加えた差分に、これらの確認項目を対応付けます。
コードを読む段階、限られた入力で試す段階、実運用へ組み込む段階は、それぞれ別の判断です。環境と権限を特定し、未実行の部分を残したまま試験範囲を決め、実際に得た結果だけで次へ進む判断をします。説明を理解できたことを、運用開始の承認に置き換えないことが、技術出力を使う入口になります。
Coding Agentのコマンドや実行領域の制限は「Coding Agentのコマンド・変更ファイル・実行領域を制限する」、大量データを扱う生成コードのメモリ消費の見積もりは「大量データを扱うAI生成コードのメモリ消費を見積もり、確認する」で解説しています。
基本から確認する:この記事の前提になる考え方は、「AIエージェントの安全設計(権限・外部資料・承認・検証の基本)」にまとめています。

