🐙

Jules は最強のメンテナー説

に公開

Jules を1日触ってみた感想は、アクティブな開発には向かないが保守フェーズに入ったアプリやライブラリに最適では? です。ウェブサイトに書いてある「貴方のやりたくないことを代わりにやります」のキャッチコピー通りですね。

メンテナーとして Jules を使うのが良さそう

  • Slack チャンネルに専属メンテナーが常駐してる感じの使い勝手
  • ブラウザ閉じて数時間ほっぽっといても続きからチャット(タスク)を再開できる
  • 並列で動くし、タスク ≒ ブランチなので管理が楽
  • UX 終わってる CLI アプリにおさらば出来る
  • Gemini 2.5 Pro は「既に完成して動いてる」アプリの「作業内容が具体的」なタスクに十分な性能
    • 性能は問題ないが処理速度は GPU 使ってないローカル LLM って感じ

既存のコードの仕上げ/修正にも使えそう

  • 「不足してるテストがあったら実装して」とか、そういうタスク
    • ただしコードをゴリゴリに弄り回すので強めの制約が必須
  • AI ガチャの振れ幅が激しい(印象)
    • 複数インスタンスを起動して同じプロンプトを投げて良い方を採用する

タスク数のカウントはおおらか

  • 1日15タスクも使いきれない
  • 1タスク = git のクローン1回(VMインスタンス起動)
  • AGENTS.md 更新したから main ブランチをプルして 👈 出来ない
  • クローンしたブランチで延々とチャットして修正を繰り返す 👈 おk
  • 複数回の PR 作成やブランチへのプッシュも1タスクの中に収まってるっぽい

C# プロジェクトでも使える

ただし、デフォルトでは dotnet コマンドが使えない。インストール自体は出来るがタスクごとにリセットされるので毎回指示する必要がある。

curl -LO https://dot.net/v1/dotnet-install.sh

chmod +x ./dotnet-install.sh
./dotnet-install.sh --version latest

rm ./dotnet-install.sh  # 消さないと PR に含まれちゃう

セットアップが済めば dotnet test じゃなくて dotnet run --TEST でテストを行うような、ちょっと特殊なプロジェクトにもちゃんと対応できる。

過剰な最適化

  • パターン通りの最適化をノープランで適用するので普通にロジックエラーが混入する
  • 意図的に HEAD と GET でアクセスする URL を変えているのに一つにまとめる等、かなり強い最適化が行われる(そしてバグる)
    • ※ 「テストが完璧に実装されている」という前提で、適当に最適化してミスったとしてもテスト通らんからダイジョブやろって発想(間違ってないが)
  • まず最初に Jules にテスト書かせてから始めたほうが良さそう

Go フォーマッター並みの強い思想

  • とにかくコードを書き替えまくる
  • 止めないと地獄
    • 必要が無くてもローカル関数をメンバー関数に変える
    • 意図的にスルーしてる提案(このメソッド static に出来ますよ等)を無効にするための #pragma をガンガン消す
    • (言語仕様が安定している Go と違って、C# は後方互換性のみ注力で言語仕様にサクッと手を入れるから同じようには出来ないよ)
  • そもそも Jules で C# 扱うこと考えてないと思う

GitHub 上でのやり取りは不要/出来ない

  • PR 作ってもらってそれにコメントを付けて差し戻しても「プルリクのコメント読めないんで代わりに読んでもらって良いですか?」
  • 全部 Jules のチャットで完結させる必要アリ
  • メンテナーと Slack で話してると考えれば自然
  • 人間の手を離れたコードの修正指示を GH で全員と共有する意味が薄い
    • 共有するという目的が無いなら GH のプルリクページはチャットより使い勝手が悪いだけの何か
    • 編集履歴は GH の方が見やすいので必要に応じて Publish Branch する

依頼内容は長文でもおk

Jules に Issue の本文コピペして雑にタスク丸投げとか出来そう。

今回試した依頼内容

プログラミング言語は不要になって英語力が必要な時代。何とかしたい。

AppCore.cs needs updated to abstract local, https and github access.
- create IContentTransformer and IFileProvider interface.
    - IFileProvider.TryGetLastModifiedDate to get last modified date (HEAD request for remote resources)
        - null if remote file not found
        - DateTimeOffset.Now if no Last-Modified header found in response message
    - IFileProvider.TryGetContent to download actual content from remote location.

AppCore.cs logic update
- get and compare lastModified date of source and dest file and then overwrite if requested
- apply IContentTransformer (TypeMigrator, etc.)
- write file.

無駄な修正を止めるための AGENTS.md

ざっくりまとめると
  • 全部入りの PR 作らないで、以下の要領で分けて
    • 機能の追加・更新や削除
      • 機能に関係ない編集は含めないで(コメントの削除やコードスタイルの編集等)
    • セキュリティー関連
    • 最適化/効率化
      • 編集するコードがテストでカバーされてるか必ず確認して
        • カバーされてなかったら PR 作んないで
        • 代わりに「編集対象をカバーするためのテスト」を作って PR を送って
          • その PR に最適化/効率化したコードを同時に含めないで
    • その他
      • ドキュメントとかリファクタリングとか
      • 良い感じのタイトル付けて PR 送って

https://github.com/sator-imaging/DotnetTool-StaticImport/blob/main/AGENTS.md

指示書ナシの結果はコチラ

強い思想が見て取れます。

Ctrl+M → O からのホイールコロコロで目に付きやすいように複数の空白行を入れてる部分は全部消されるし、ブロック内の行数が少ない場合の空白行も消される。セミコロン後のコメントも消されがち。ローカル関数もメンバー関数に勝手に変えられる。

https://github.com/sator-imaging/DotnetTool-StaticImport/commit/6588f309d9687ac55c011b7609bf087ef101ebd6

Go みたいに登場当初からガチガチにコードスタイルを制約してる言語は AI エージェント時代にあってるのかも。ブレが一切ないし同じことを別の書き方で~~も無いから学習ソースが安定しそう。

おわりに

程々の Ryzen で Linux マシン組んで gpt-oss 使えるようにしようかなーって思ってたけど Jules タダ乗りで良さそうですw

以上です。お疲れ様でした。

Discussion