Generation-then-comprehension
コーディングエージェントを使った開発では、人間が理解してから実装するよりも、まずコードが生成され、それを後から理解する場面が大幅に増える。
このため認知的降伏を起こしやすい条件が揃い、よくわからないが動いているからヨシ!でApproveしてしまうことになる。 これを避けるために、動くテストをパスするコードを生成して終わりではなく、生成されたコードについてコーディングエージェントに説明を求めることをやろう。これは人間の理解促進にもなるし、コーディングエージェントが自分の理解の浅さを気づくキッカケを与えることにもなる。
https://gyazo.com/540d441e1dd15df2f5ae253c7969c9fc
人間側の理解のため
コーディングエージェントは新しいプログラミング技術の習得速度を向上させるのか、コードの理解を妨げるのかについてのAnthropicの研究によれば、使い方によって学習効果に有意な差がみられる。 学習効果の比較的低かった行動
1. AI Delegation
全部AIへ書かせて、コードも見ない
2. Progressive AI Reliance
最初は自力で、途中から全部AI
3. Iterative AI Debugging
自分で書くが、エラーが出るたびAIへ聞く
学習効果の比較的高かった行動
1. Generation then Comprehension
まずコード生成し、そのあと「なぜ?」「他の方法は?」「もし○○なら?」「この設計の欠点は?」など質問を繰り返す。
2. Hybrid Code + Explanation
コード生成と同時に、説明も出力するようプロンプティングする
サンプル数が少ないので過度な一般化は危険ではあるものの、Generation then ComprehensionとHybrid Code + Explanationでは前者の方が理解度が高かった。一つの説明として、生成と説明を同時に提示すると、説明を流し読みし、自分で理解を確認しない受動的処理になりやすい可能性が考えられる。 AI側の理解のため
AIは説明している途中で、自分の実装の矛盾や不要な設計に気付き、その場で修正を提案することがある。Self-Debuggingの論文では、説明させるだけでAIの正答率が 81.3%から84.1%が見られる。コーディングエージェント版 ラバーダック・デバッグとも言える。 良い説明のさせ方・質問の仕方
単に「このコードを説明してください」と依頼するだけでは、コードを自然言語に言い換えた説明で終わることがある。理解を深めるには、設計判断の理由、代替案との差、変更した場合の挙動、成立条件、失敗条件まで説明させる必要がある。
したがって、説明を求める際には、コードの要約だけでなく、新しい推論を必要とする質問を重ねるとよい。
設計判断を説明させる
なぜこの実装を選んだのですか?
この設計が解決しようとしている問題は何ですか?
この処理をこのクラスや関数に置いた理由は何ですか?
このコードが前提としている条件は何ですか?
この実装で維持している不変条件は何ですか?
「何をしているか」だけでなく「なぜこの形になっているか」を説明させる。理由を説明するには、個々のコードと上位の原則や要件を結び付ける必要があるため、表面的な言い換えにとどまりにくい。
代替案と比較させる
なぜ別の実装方法ではなく、この方法を選んだのですか?
最も有力な代替案は何ですか?
代替案と比較して、何を得て何を失っていますか?
要件が違っていたら、どの実装を選びますか?
より単純な実装ではなぜ不十分なのですか?
比較対象を明示すると、一般的な長所を並べるだけでは済まず、採用した設計と代替案を分ける条件を説明する必要が生じる。ただし、この研究は主に人間が説明をどのように生成・評価するかを扱ったものであり、コード理解への効果を直接測定した研究ではない。
変更した場合を予測させる
この条件分岐を削除したら何が起きますか?
この処理の順序を逆にしたら結果は変わりますか?
この値をnullにしたらどうなりますか?
入力が空、最大値、境界値だったらどう振る舞いますか?
外部サービスが失敗したら、どこまで処理されますか?
同時に複数のリクエストが実行されたら何が起きますか?
この依存先の仕様が変わったら、どこが壊れますか?
これらは、現在のコードを説明するだけでなく、条件へ介入した場合の結果を予測させる質問である。厳密には、すべてが反実仮想ではなく、介入、出力予測、境界分析を含んでいる。
コードを現在の形のまま説明できることと、入力や状態を変えたときの挙動を予測できることは異なる。後者まで答えられる方が、実行モデルや依存関係を理解している可能性が高い。
失敗条件を探させる
このコードが正しく動かない条件を挙げてください。
最もバグになりやすい部分はどこですか?
正常系のテストだけでは発見できない問題は何ですか?
暗黙に信頼している入力や外部システムはありますか?
例外が握り潰される可能性はありますか?
部分的な成功によって不整合が残る可能性はありますか?
セキュリティ上の前提が破られると何が起きますか?
「正しく動く理由」だけを説明させると、AIは自分の実装を擁護する方向へ説明を組み立てやすい。失敗条件を明示的に尋ねることで、説明対象を正当化から反証へ切り替えられる。
レビューさせる
このコードを第三者としてレビューしてください。
採用を見送るとしたら、どの点が理由になりますか?
可読性、正しさ、性能、保守性、セキュリティの観点で問題を分けてください。
テストで確認できていない仮定は何ですか?
コメントと実装が矛盾している箇所はありますか?
不要な抽象化や重複した処理はありますか?
実装の複雑さに対して、要件は十分に複雑ですか?
生成者としてではなく、独立したレビュー担当者として評価させる。ただし、役割を変更するだけで評価の独立性が保証されるわけではない。同じ会話の中では、AIが直前の実装や説明へ引きずられる可能性があるため、重要なコードでは別の会話や別のモデルによるレビューも併用した方がよい。
人間側の理解を確認する
AIに説明させるだけでは、人間が理解したことにはならない。説明を読んだ後に、人間側が予測や再説明を行う必要がある。
私の理解では、このコードは○○という理由で△△している。間違っている部分を指摘してください。
私の理解を確認するための質問を出してください。
コードを見ずに答えられる小テストを作ってください。
この実装について、入力を変えた場合の出力予測問題を作ってください。
私の説明に含まれていない重要な前提を指摘してください。
Anthropicの研究で観察されたGeneration then Comprehensionは、AIが生成したコードに対して、利用者が後から概念的な質問や追質問を重ねる利用パターンである。この研究は反実仮想質問だけの効果を独立して検証したものではないが、コード生成後に能動的に理解を確認する行動と、高い理解度との関連を報告している。