AIの提案が正しそうでも動作しない理由を、uvicornのソースコード解析から解明した話
LayerXのエンジニアが、AIの提案コードがuvicornで動作しなかった原因をソースコード解析で解明し、AI支援開発における実装検証の重要性を実体験として語る記事
キーポイント
AI提案コードの実装失敗と原因究明
AIが提案したコードをそのまま実装したところuvicornで動作せず、フレームワークのソースコードを読むことで根本原因を特定した経験を共有している
ソースコード解析による問題解決プロセス
uvicornのソースコードを詳細に読み解き、AIの提案が理論的には正しいが実装環境では動作しない理由を明らかにした具体的な調査方法を説明している
AI支援開発における実装検証の重要性
Coding Agentの利用が増える中で、AIの提案を盲信せず、実際の実行環境やフレームワークの仕様を理解した上での実装検証が不可欠であることを強調している
開発者成長における実践的学習の価値
ソースコードを直接読むことで得られる深い理解が、表面的なAI提案の実装以上の技術的成長をもたらすという個人的な気づきを述べている
影響分析・編集コメントを表示
影響分析
この記事は、AI支援開発が一般化する中で、開発者が陥りがちな「AI提案の盲信」という課題を具体的な事例で示し、技術的深堀りの重要性を再認識させる教育的価値がある。特に若手開発者に対して、表面的な実装だけでなく基盤技術の理解を促す内容となっている。
編集コメント
AI支援開発の実践現場で起こりうる具体的な課題とその解決プロセスを、技術的深堀りを交えて丁寧に解説した良質な技術記事。特に若手エンジニアの教育コンテンツとして価値が高い。
こんにちは。LayerX AI Workforce事業部でSWE(ソフトウェアエンジニア)としてインターンをしているYuです。本記事では、AIの提案をそのまま実装してうまくいかなかった経験や、フレームワークのソースコードを読んで解決に至ったプロセス、そしてその過程で感じたことについてお話しします。
はじめに
みなさんは、普段開発をするときに、Coding Agentを使っていますか?Claude Codeがリリースされてから、Coding Agentの利用が加速したように感じており、最近では自分自身でコードを書くこともかなり減ってきています。私はソフトウェア開発を始めて2年ほどなのですが、自分の成長スピードを遥か…
原文を表示
こんにちは。LayerX Ai Workforce事業部でSWEとしてインターンをしているYuです。
本記事では、AIの提案をそのまま実装してうまくいかなかった経験や、フレームワークのソースコードを読んで解決に至ったプロセス、そしてその過程で感じたことについてお話しします。
はじめに
みなさんは、普段開発をするときに、Coding Agentを使っていますか?
Claude Codeがリリースされてから、Coding Agentの流れが加速したように感じており、最近では自分自身でコードを書くこともかなり減ってきています。自分はソフトウェア開発を始めて2年ほどなのですが、自分の成長スピードを遥かに超える速度で進化するCoding Agentを見ていると、自分が学ぶ意味とは?と思ってしまうことが時々あります。
そんな中、自分なりに学ぶことの楽しさや重要性を感じたタスクがあるので、そのお話について書きたいと思います。
発生していた問題
Ai Workforce事業部では、バックエンドとしてPythonのFastAPIを使用しています。
ある時から、ローカルでの開発中にホットリロードやサーバーシャットダウンが確率的にうまくいかないという現象が生じました。同じ操作でも成功したり失敗したりするため、再現性がなく原因の特定が難しい状態でした。
本番環境での影響は特になかったのですが、開発時にホットリロードがうまくいかないというのは地味に不便で、開発生産性に影響が出ていたため、改善しようということになり自分が取り組むことになりました。
タスクに着手した直後は、SSE(Server-Sent Events)周りが原因になっていそうだなと、なんとなく予想していました。ただ、「SSEが怪しい」以上の仮説を立てられる状態ではなく、ましてやホットリロードやシャットダウンの仕組み自体を正確には理解していませんでした。
そこで、普段から使っていたコーディングエージェントに聞いてみたところ、on_event("shutdown") でSSE接続を止めるという提案をしてもらいました。
on_event("shutdown") について簡単に説明すると、FastAPIが提供する「アプリ終了時に呼ばれるフック」です。
つまり、提案された方針は、シャットダウン時にこのフックの中でフラグを立て、SSEのループを終了させるという方針です。
それっぽい方針だったので実装してみたのですが、、、うまくいきませんでした。
なぜうまくいかなかったのか。この時点の自分にはわかりませんでした。AIの提案が「もっともらしかった」からこそ、何が間違っているのかの見当がつかなかったのです。
FastAPIのシャットダウンの仕組みを理解する
AIの提案で解決できなかったことで、そもそも自分がシャットダウンの仕組みを理解していないことが問題なのではないかと思いました。
そこでまずは、ソースコードを読んで、仕組みを理解することにしました。
FastAPIは内部的には uvicorn というASGIサーバーの上で動いています。
今回の問題はシャットダウン処理に関わるものだったため、uvicorn のソースコードを読むことにしました。
コードを追っていくと、シャットダウンはおおよそ次の順番で行われていることがわかりました。
SIGTERM / SIGINTの受信
新規リクエストの受付停止
アクティブな接続が閉じるのを待つ(ここにSSEのような長寿命接続も含まれる)
lifespanのshutdown(on_event("shutdown") など)
実際の処理も、ざっくりいうとこの順番で実行されています。
async def shutdown(...):
server.close()
await self._wait_tasks_to_complete()
await self.lifespan.shutdown()
※より詳細な実装はこちらをご覧ください
ポイントは、lifespanのshutdownが呼ばれるのは一番最後という点です。
また、ホットリロード時の挙動についても確認しました。
uvicornのリロード機能では、サーバーはサブプロセスとして起動されており、ファイル変更が検知されるとそのプロセスに対して SIGTERM が送られます。
つまり、ホットリロードの実体は「プロセスの再起動」です。
原因の特定と、なぜAIの提案ではうまくいかなかったのか
シャットダウンの仕組みを理解した上で改めて問題を整理すると、原因は明確でした。
SIGTERM / SIGINTの受信
新規リクエストの受付停止
アクティブな接続が閉じるのを待つ ← SSE接続が無限ループで生き続けているため、ここで止まる
lifespanのshutdown ← ここに到達しない
AIが提案した on_event("shutdown") は、ステップ4で実行される処理です。しかし、問題はステップ3で発生していました。SSE接続が閉じないからステップ4に進めない。ステップ4でSSEを止めようとしても、そもそもそこに辿り着けないのです。
また確率的にシャットダウンがうまくいかない原因もここで判明しました。SSE接続が必要な画面を開いていない場合には、SSE接続を閉じる必要がないため、問題なくステップ4に進むことができる。
つまり、問題なくシャットダウンできるかどうかは、SSE接続の有無次第なため、確率的な挙動に見えていました。
この「順番」がわかった瞬間、解決策も見えました。
ステップ4の on_event("shutdown") で対応するのではなく、もっと手前、シグナルを受け取った時点でSSE接続に終了を通知する必要があります。
具体的には、SIGTERM / SIGINT を受けたタイミングで、SSEのループが自発的に終了できるようにフラグを立てる方針にしました。ここまで解像度が上がっていると、AIに対して具体的な指示を出すことができ、一発で修正をすることができました。
実装としては、uvicornが内部で登録しているシグナルハンドラをそのまま置き換えるのではなく、その前段で少しだけ処理を挟む形にしています。
シグナルを受けたらまずSSE側に終了通知を送り、その後で元のハンドラに処理を委譲する、という流れです。
これによって、アクティブなSSE接続が終了待ちで詰まる前にループを抜けるようになり、その後の通常のシャットダウン処理や lifespan によるクリーンアップも、これまで通り正しく実行されるようになりました。
修正自体は数十行程度で、仕組みさえ理解してしまえばシンプルなものでした。
まとめ
Coding Agentはすごいスピードで進化していて、開発スタイルを大きく変えつつあります。かく言う自分自身も日々助けられており、すでにCoding Agentなしでの開発は想像ができません。
ただ今回、AIの提案をそのまま実装してうまくいかず、ソースコードを読んで解決したという経験を通じて、「原理を理解すること」の大切さを改めて実感することができました。シャットダウンの順番という、たった一つの知識があるかないかで、AIの提案が正しいかどうかの判断や、正しい解決策を導くためのAIへの指示の出し方も、全てが変わってきます。
コードを自分で書く機会は減っていくかもしれませんが、技術を理解しようとする姿勢はこれからも持ち続けたいと思います。そして幸いなことに、理解するためのハードルもAIによって下がっています。今回のuvicornのソースコードも、基本的にはAIと並走しながら理解を進めました。
また、シンプルに自分の知らないことを理解するというのは非常に楽しいことだという、初心を思い出すこともできました。
AIなどのツールをうまく活用して、自分自身の成長に繋げていきたいです。
おわりに
LayerXでは「Bet AI」を掲げ、全社でAIの活用と新しい開発スタイルの模索を推進しています。圧倒的なスピードで進化するAIを楽しみながら、自らの技術力もアップデートし続けたいエンジニアインターンを絶賛募集中です!
▼ 技術を楽しみながら確かな成長を目指すエンジニアインターンに興味のある方はこちら
open.talentio.com
▼ 「Bet AI」を掲げるエンジニア組織の裏側をもっと知りたい方はこちら
speakerdeck.com
技術への知的好奇心を絶やさず、AIと共に新しい開発の形を模索したい方、まずはカジュアルにお話しできるのを楽しみにしています!
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み