世界を動かす技術を、日本語で。

私のAIの好きな活用法はログを書くことです

概要

  • PyCharm のFull Line Code Completion機能の特長と利便性
  • ローカル推論による 高速・安全なコード補完
  • JetBrainsによる 小型・特化型モデル の設計と圧縮手法
  • 実際の 開発・デバッグ効率化 の具体例
  • 小型モデルの将来性と 大規模汎用LLMとの住み分け

PyCharmのFull Line Code Completion体験

  • PyCharm に2023年末から標準搭載された Full Line Code Completion 機能の高い完成度
  • GoLand など他のJetBrains IDEでも利用可能な利便性
  • 開発者自身がコードの主導権を維持できる設計
  • JetBrains の長年の顧客満足度の理由となる機能追加
  • 順次処理・計算・非同期APIコール・PyTorchでのベクトル操作など多様な開発現場での活用実績

ログ出力・デバッグの効率化

  • print文デバッグ と良質なログ記述の重要性

  • f-stringによるログ記述の繰り返し作業の煩雑さ

  • 変数名やデータ構造の参照・記述ミスによる認知的負荷

  • Full Line Code Completion による自動補完でログ記述の手間を大幅削減

  • モデルが文脈を理解し、適切なログ内容を推論

    • 例: Redis URLチェックやDataFrame形状のログ自動生成

モデルのローカル推論と技術的工夫

  • モデルが 完全ローカル で動作し、 圧縮と高速化 が必須要件

  • IDE同梱可能な1GB程度のサイズに収めるため、 大規模LLMの99%を除外

  • Python専用に最適化された 小型・高速モデル

  • モデル初期はGPT-2系、後に Llama2 アーキテクチャへ移行

    • PyTorch で100Mパラメータ規模のデコーダオンリーモデルを訓練
    • 訓練データはThe Stackサブセット、45GB規模、 コメント除去import除去 によるデータクリーニング
    • Python特有のインデントを考慮した BPEトークナイザー の工夫
    • 8枚のNVIDIA A100 GPUで数日間訓練、クロスエントロピー損失で最適化

プラグイン実装・推論最適化

  • プラグイン本体は Kotlin、推論サーバは C++ でローカル実行
  • モデルを FP32→INT8量子化 し400MB→100MBへ圧縮
  • ONNX Runtime によるCPU推論、CUDA依存排除
  • サーバ側は後に llama.cpp でLlamaモデル提供に切り替え
  • ビームサーチ によるトークン生成(最大20ビーム、改行で終了)
  • キャッシュ戦略 :コンテキストの50%を事前ロードし、既存コード編集や新規追加にも対応
  • これらの工夫により、 高速・高精度なコード補完 を実現

小型特化モデルの意義と今後

  • 大規模汎用LLM が注目される中での 小型・特化型モデル の価値
  • 単一言語・単一目的に絞ることで、 省コスト・高精度・実用性 を両立
  • 開発現場での デバッグ・ログ記述の効率化 に大きく貢献
  • 今後も 小型特化モデル のアプリケーション拡大に期待

Hackerたちの意見

面倒で時間がかかる作業を自動化してくれるのがいいね。失敗を見つけて修正するのも簡単だし、気に入ってる。ただ、唯一の心配は(多分冗長さを除いて)ログを書く瞬間が、自分の書いたことをちょっと振り返る機会になって、問題を早めに見つけることができるかもしれないってことかな。

そうだね、AIが実際に価値を提供してくれたのはシンプルなことだよ。ログ、ドキュメンテーション文字列、CLI関連が一番の例かな。基本的なスケッチを作って、コードに集中して、後から質の高い部分を追加してもらえるんだ。

ここで好きなのは、ローカルで動くところ。次の単語の補完にはVimのキーワード補完をよく使ってるんだけど、周りのコードを見て良い提案をしてくれるのが似たような感じだね(もちろんLLMのことはなしで)。間違うことも多いけど、全体的に時間を節約できるから、役に立ってると思う。だから、これはそれの拡張版みたいな感じかな。クラウドの「超モデル」よりも、こういうローカルで動く小さな集中モデルがたくさんある未来の方が好きだな。少なくとも、そういう選択肢があるのはいいよね。

この一見シンプルなログには、認知的負担がいくつも重なってる。まず、logger.info(それともlogging.info?コードベースによってloguruとloggerを使い分けてるから、いつも混乱しちゃう)を打つために止まらなきゃいけない。次に、括弧、f-string自体、そしてブラケット内の変数。さて、five行上のyour_variableかyour_variable_with_editsだったっけ?df.headのサブセットにアクセスするための構文は何だっけ?君が言ってるのはプログラミングって呼ばれるものだよ。これ、マジで真剣なの?forループを書くときの認知的負担はどうなるの?イテレートしてる配列に何が入ってるか、他のコードベースの部分とどう関わってるかを覚えておかなきゃいけないし、ああ、面倒なインデックスはどうするの!0から始まるのか1から始まるのか?もう無理!AI、助けて!

君が言ってるのはプログラミングって呼ばれるものだよ。それが君が楽しんでるプログラミングの部分なの?loggerとloggingを覚えること?俺は技術的な挑戦やデザイン、顧客の問題を解決するのが楽しかったけど、結局は自分が好きな部分に集中するのが大事だよね。

俺は逆に、ログラインを書くのは全然分かってる。単に面倒なだけ。AIはほぼ自分が書くであろうものを自動で補完してくれるからね。

コンピュータやコンピュータサイエンスの好きなところの一つは、何世代にもわたって作られた多様なツールが、人々に複雑なアイデアを実現するための力を与えてくれるところだね。どういう方法であれ、彼らはそのツールを使って、細かいことにこだわらずに大きな目標に集中できる。君はプログラミングの考え方が違う人を見ているかもしれないけど、俺はコンピュータプログラムを作ることに喜びを見出している人を見ているし、彼らは以前よりももっと多くのアイデアを実現できるようになると思う。それは祝うべきことだと思うよ。

そうだね、驚くべきことに、ユーザーはログ用にf-stringを使うべきじゃないんだよね。INFOレベルが設定されているかどうかに関わらず、補完されちゃうから。特に、ホットループの中で動くデバッグログを書くときには、たくさんのデータを文字列に変換することでパフォーマンスに大きな影響が出るから、これは重要だよね。でも、まあ、気にせず楽しんで。

ロギングコードは自分で書けるけど、ログメッセージを「きれいに」フォーマットするのが面倒なんだ。俺の経験では、AIはきれいなログメッセージを書いて、関連する変数を自動でキャッチしてくれるから、手書きの文では見逃した重要な値を含めるために二度手間になることがないんだよね。

そうだね、認知負荷って本当に存在するよね。プログラムの状態についての一般的な情報を記録するための適切なフォーマットを考えなくていいって、ちょっとしたことに思えるかもしれないけど、それによって他の心配事に集中できるようになるんだよね。人間の脳は、同時に大体3〜5個の意味のあるアイテムを作業記憶に保持できるっていう研究もあるし。プログラミングの流れに乗っていると、無意識のうちに作業記憶から情報を追い出したり、目の前のコードを見て再取得したりしてると思う。著者は、特定のプロジェクトのログの仕組みを思い出すために、頭の中のキャッシュから何かを追い出さなくて済むという利点を正しく観察していると思うよ(特に、10個のコードベースでそれぞれ異なるロガーを使ってるときは、なおさら厄介だよね)。

著者は、ログを書くのが嫌いみたいで、そのために細かく調整されたモデルを作る労力をかけてるね。「作業を自動化するためのツールを作る」って、コンピュータの主な使い方の一つだと思ってたけど、もしかしたら間違ってるかも。

AIブームから明らかになったことの一つは、プログラミングを生業にしている人たちが、実はプログラミングがあまり好きじゃないってことだね。どうしてこの分野に入ったのか、正直よくわからない。ギターが嫌いな人がギタリストとしてのキャリアを始めるみたいな感じかな。でも、理由はどうあれ、もうプログラミングしなくていいチャンスを得られて、結構幸せそうだね。

あなたが説明しているのは、プログラミングと呼ばれるものだよ。そして、十分な経験を積むと、集中力を維持し、認知的な負荷を管理することが生産性に影響を与える重要な要素だと気づくんだ。でも、まだ配列を反復処理することにとらわれているみたいだから、この気づきはまだ数年先かもしれないね。

あなたが説明しているのは、プログラミングと呼ばれるものです。これが真剣なわけがない。 その発言が示しているのは、著者がかつてログを完全な非機能要件として考えていなかったということ。むしろ、オプションや非公式なサイドタスクのように思っていたんだ。私はかつてモバイルネットワーク向けのソフトウェアを作っている会社で働いていたけど、彼らのCコードベースはログの文でいっぱいだった。信号処理のほぼすべてのステップがログに記録されていた。おそらくトレースの一種で、自動計測の方が良い解決策だったかもしれないけど、彼らはちょっと古風だった。

Pythonプログラマーの皆さん、ログにはf-stringsを使わないで! # yes logger.info("Super log %s", var) # no logger.info(f"Super log {var}") 確かに、見た目は良くないけど、その利点は、ログシステムがvarがどんな値を取っても同じログだってわかることなんだ。これを使ってSentryが同じログを集約するんだよ。また、ログに含まれる変数が%sを含んでいると、f-stringバージョンは例外を投げることになる。f-stringsは速いから問題ないけど、%メソッドは怠惰で、ログにしないなら補間/フォーマットしないんだ。将来的には、これにテンプレート文字列が使えるようになるかもね。

理由をありがとう!f-stringsは追跡が簡単だから使ってたけど、君の意見はすごく説得力があるね(Sentryや似たようなシステムが%sを使ってログを集約することは考えてなかった)。

もしloguruを使ってるなら(ほんとにおすすめだよ、めっちゃいいから)、logger.info("Super log {var}", var=var)って使うことになるよ(キーなしで使うこともあるかも)。これも怠惰で、構造化されたログにはより効果的なんだ。

これにAIを使うのはちょっとやりすぎな気がする。loggerloggingが使えるかどうか、どの変数がスコープにあるかを意識した言語や環境を使えばいいんじゃないかな。プログラミングを単に次の文字をランダムに推測する以上のことにできるツールがあるんだ。むしろ、信頼できる方法でこのコンテキストを機械にオフロードできるようにしてくれる、型付き言語やオートコンプリートがあるからね。これが、今のLLMの有用性に対する見解の違いの一因かもしれない。すでに、タイプ中に文法的に有効な表現を教えてくれる言語を使っているなら、コンピュータが認知的な負担を軽減するアイデアはあまり新しくないかも。

ちょっと過剰に考えすぎてる気がする。ログを打って、タブでオートコンプリートを受け入れる方が、全部自分で書くより早いよ。たくさんのログステートメントを追加する必要があるとき、このツールがあれば作業が早くて面倒じゃなくなる。これは技術的なブレイクスルーか?いや、そうじゃない。開発者の時間を毎日何時間も節約するか?それも違う。でも、あると嬉しいよね。

Cursorのタブオートコンプリートは、slog.Infoを入力するときに、ログに何を記録したいかを驚くほどうまく推測してくれる。時間を節約できて嬉しいよ。K&Rのデバッガーについての意見には同意するね:本番環境でデバッグが必要なサービスを書くとき、ログが命綱になる。とはいえ、時にはインタラクティブなデバッガーの方がログを追加するよりも早いこともある。特に、特定のポイントに至るまでの正確なコールスタックが不明なときや、追跡が必要な情報がたくさんあって、すべてにログを追加するのが面倒なときなんかはね。でも、すぐにデバッガーで時間を無駄にするよりも、そのログを追加する方が早かったってことに気づくこともあるよね…。

うまくいくこともあるけど、時々全く間違ったことをすることもあるんだよね。でも、見た目はそれっぽい。みんなで結構複雑なバグをいくつか作り上げたよ。2ヶ月経ったけど、Cursorを使ってもコーディングスピードはあまり上がってない気がするし、「完璧だね、...」とか「その通りだよ、...」ってのも受け入れられない。カスタムルールで抑えようとしても、どうしてもそれをやめられないんだよね。

普通、人はログを読むためにAIを使ったり、面白いイベントやパターンを探したりするよね。これって昔からなんだ。マイクロソフトは90年代に、似たようなクラッシュダンプを分類してグループ化するために使ってたんだよ。Rustでは、各構造体にデフォルトのデバッグプリントを書くことができて、頼めば自動生成してくれる。だから、自分で全てのフィールドを書く必要がないんだ。それだけで面倒な部分は解決できるよ。

マイクロソフトが90年代に「AI」を使ってたの?

Visual Studioは少し前に一行のオートコンプリート機能を追加したけど、2日でオフにしたよ。頻繁に間違ってて、邪魔になるからね。ダブルタブでテンプレートを挿入する機能をよく使うけど、それも間違ったオートコンプリートを受け入れちゃうことが多くて、削除して再試行する羽目になった。

完全に同意するよ、その挙動はイライラする。コンプリートのトグル用にホットキーを設定して、また使えるようにしたんだ。

もしこれをレビューしてたら、RedisのURLをログに残してることを指摘してたと思う。大抵、そこには認証情報が含まれてるからね。普通、ブログのコードを批判するのはちょっと失礼だと思うけど、ここでは理由があるから言いたい。 「デバッグが終わった後も、プロダクションで価値があるから削除しないことが多い」って考えてみて。プロダクションの認証情報がどこに行くかを考えた方がいいよ。大抵、ログに残しても問題ないけど、パスワードをポストイットに書いておくのと同じで、ほとんどの場合は大丈夫。AIにメンタルオーバーヘッドを減らしてもらうっていうのは魅力的な意見だけど、これがよく言われるリスクの一つを示してる。自分で書いてないから、その影響を考えてないってこと。もしかしたら、著者はそれを考慮していて、ログに残すことが完全に安全だという良い理由があるのかもしれない。こういうことについては、他の開発者から反発を受けることが多いんだ。例えば、 - ログにアクセスできるのは俺たちだけだ(それでも、ログに認証情報を保存する理由はない) - RedisのURLにはIPしかない、認証情報はない。(設定が変わった時にこのログ行を更新することを覚えてるかな?) - プロダクションでは警告以上のログしか残さない(上の理由と同じ) もしかしたら、心配するのをやめてAIを愛することを学ぶべきなのかも?人間の開発者も同じことしてるしね。

ログを書くのがすごくイライラするのは分かるけど、大抵の人がログを見るのは、何かがうまくいかなかった時か、プログラムが不具合を起こしてるんじゃないかと疑って、正しい方向に進んでるかのサインを探してる時なんだよね。誰かの壊れたコードに何時間も費やした後に考えたくないのは、「これ、非決定論的なチャットボットが書いたのかな?」とか、「このログ、内部的に一貫性があるの?」、「なんでこのログに存在しないコードが書かれてるの?」ってこと。これが多くの開発者が一番嫌いな部分だってことは分かるけど、ログやエラーは揺るぎない真実の理解であるべきなんだ。壊れたスパゲッティコードや誤解の暗い部屋で、光を指し示すものなんだから。ユーザーやテスターの視点から考えてみて、どれだけのフラストレーションを感じるか想像できる?ほとんど理解できないテキストの壁を通して理解を追いかけて、開発者が助けることに興味がないことで赤いニシンに基づいていたことが分かるなんて。将来的に自分で生成する非バグの量も考慮しないといけないし、今はLLM生成の偽バグでバグバウンティが溢れてるから、ログが真実とほとんど関係ないなら、どうやって本物のバグを考えることができるの?

「これ、非決定論的なチャットボットが書いたのかな?」、「このログ、内部的に一貫性があるの?」、「なんでこのログに存在しないコードが書かれてるの?」 これはすべてのAI生成コードに対する同じ不満だね。シンプルな答えは、コミットする前に自分でコードをレビューしろってこと。もし本当のプロジェクトなら、他の誰かがレビューすることになるし、間違いがあるかもしれない他のコードと同じだよ。