Openhandsリポジトリのcommit履歴から自律型コーディングエージェントの現在地を知る
きっかけ
コーディングエージェントがどこまでできるか調べている最中に
Openhandsでのopenhands-agentのcommit履歴が
Devinなどの運用のためのデータとして良いと判断したので調べてみた
おそらく使っているモデルも常に最新のものではないので
Devin運用などの「最低限」を担保できそう
Openhandsとは
Devinを意識したOpen Devinという名前で始まって(色々あって)OpenHandsという名前になった自律型コーディングエージェント
Openhandsはopenhands-agentをOpenhands自体の整備に用いている
ざっくりとした各種統計
※Openhandsの実装体制で間に合っておらず自動でcloseされているものなどもあるので、あくまでも目安として確認してください。(特にDocumentationに多い)
人間とAgentの比較
Agentの中の内訳(共同も含む)
MergePRの中の内訳
カテゴリ別
ここから読み取れることは
- まだ主役にはなれないのでエージェントに対する期待値を高く持ちすぎない
- 小粒で対処しやすい保守系タスクの方が多くMergeされている
- 管理しやすいようにcommitメッセージを定型にしておくと良い
ということわかります。
次に実際どのようなPRがMergeされていて、どのようなPRだと難しいのかを
Bugfixの具体例から見ていきます。
補足 Mergeにかかった時間の表
区分 | <2 日 | 2–7 日 | 1–4 週間 | ≥1 か月 |
---|---|---|---|---|
件数 | 10 | 9 | 4 | 2 |
MergeされているBugfixのPRの代表例
代表PR (リンク) | 不具合内容 → 修正ポイント | 主要差分(抜粋) | テスト追加 | マージまで |
---|---|---|---|---|
#7827 ChatInput が 4 行で窮屈 |
maxRows デフォルトを 4 → 16 に拡大 |
diff<br>- maxRows = 4<br>+ maxRows = 16 :contentReference[oaicite:0]{index=0} |
chat-input.test.tsx にデフォルト行数をチェックするケースを追加 :contentReference[oaicite:1]{index=1} |
Issue登録〜マージ 3日 |
#7984 EventStream で dictionary changed s (Fix issue #7826: [Bug]: Chat input box is too small by openhands-agent · Pull Request #7827 · All-Hands-AI/OpenHands · GitHub)ion 例外 |
イテレータ中に辞書が変化するのを回避 |
python<br># c ([Fix issue #7826: [Bug]: Chat input box is too small by openhands-agent · Pull Request #7827 · All-Hands-AI/OpenHands · GitHub](https://github.com/All-Hands-AI/OpenHands/pull/7827/files)) error<br>callback_ids = list(callbacks.keys()) :contentReference[oaicite:2]{index=2} |
tests/unit/test_event_stream.py に再現テストを新設 :contentReference[oaicite:3]{index=3} |
同日マージ |
#6037 Reso (Fix dictionary changed size during iteration error in EventStream by malhotra5 · Pull Request #7984 · All-Hands-AI/OpenHands · GitHub)amer が AttributeError で落ちる |
デストラクタで `stdout_ (Fix dictionary changed size during iteration error in EventStream by malhotra5 · Pull Request #7984 · All-Hands-AI/OpenHands · GitHub) |
python<br>- if self.stdout_thread and self.stdout_thread.is_alive():<br>+ if hasattr(self, 'stdout_thread') and self.stdout_thread and self.stdout_thread.is_alive(): :contentReference[oaicite:4]{index=4} |
120 行超の新規ユニットテストで異常系を網羅 :contentReference[oaicite:5]{index=5} | 1 月15日 PR生成 (Fix issue #6037: [Bug]: [Resolver] crashes on main by openhands-agent · Pull Request #6284 · All-Hands-AI/OpenHands · GitHub)ー) |
#7660 LLM が ([Fix issue #6037: [Bug]: [Resolver] crashes on main by openhands-agent · Pull Request #6284 · All-Hands-AI/OpenHands · GitHub](https://github.com/All-Hands-AI/OpenHands/pull/6284/commits/cbe1150c56de5bdb4e72c00744895ea53a5ab694))ationError を返すと UI に誤報 |
① Controller で新エラー種別を捕捉 ② i18n 文字列を追加 |
python<br>elif isinstance(e, ContentPolicyViolationError)…<br> err_id = 'STATUS$ERROR_LLM_CONTENT_POLICY_VIOLATION' :contentReference[oaicite:6]{index=6}+ translation.json 多言語追記 :contentR (Fix issue #7658: [Bug]: BadRequestError from ContentPolicyViolationError by openhands-agent · Pull Request #7660 · All-Hands-AI/OpenHands · GitHub)7]{index=7} |
`test_agent_con (Fix issue #7658: [Bug]: BadRequestError from ContentPolicyViolationError by openhands-agent · Pull Request #7660 · All-Hands-AI/OpenHands · GitHub)外ハンドリングの回帰テスト追加 :contentReference[oaicite:8]{index= (Fix issue #7658: [Bug]: BadRequestError from ContentPolicyViolationError by openhands-agent · Pull Request #7660 · All-Hands-AI/OpenHands · GitHub)2日** |
特徴
-
タイトルは常に規約どおり
Fix issue #xxxx: [Bug] …
の書式で生成され、Issue 番号とタグ([Bug] など)がひと目で分かる。 (Fix issue #7826: [Bug]: Chat input box is too small by openhands-agent · Pull Request #7827 · All-Hands-AI/OpenHands · GitHub) -
“1 Issue = 1 ブランチ = 1 PR” を徹底
ブランチ名はopenhands-fix-issue-xxxx
固定なので参照が迷子にならない。 (Fix issue #7826: [Bug]: Chat input box is too small by openhands-agent · Pull Request #7827 · All-Hands-AI/OpenHands · GitHub) -
差分は最小限かつ安全志向
変更行数は ±10〜100 行が大半――例:#7827 は +1/-1 行でmaxRows 4→16
。 (Fix issue #7826: [Bug]: Chat input box is too small by openhands-agent · Pull Request #7827 · All-Hands-AI/OpenHands · GitHub) -
必ず回帰テストを同梱
追加・更新されたユニットテスト (tests/unit/...
) で修正が再現することを保証し、CI を通してからレビューに回る。 (Fix issue #7826: [Bug]: Chat input box is too small by openhands-agent · Pull Request #7827 · All-Hands-AI/OpenHands · GitHub) -
PR 本文が詳細
エージェントが生成する説明には「問題の再現手順 / 修正方針 / 影響範囲」が箇条書きされ、レビュアーの負荷を軽減する。 (Fix issue #7826: [Bug]: Chat input box is too small by openhands-agent · Pull Request #7827 · All-Hands-AI/OpenHands · GitHub) -
マージ確定は必ず人間
エージェントは Draft→Checks 合格までを担当し、最終的にはメンテナー(例:xingyaoww)が Merge ボタンを押す運用。 (Fix issue #7826: [Bug]: Chat input box is too small by openhands-agent · Pull Request #7827 · All-Hands-AI/OpenHands · GitHub) -
取り込みが迅速
BugFix PR の 76 % は 1 週間以内にマージ済み。小粒パッチ+テスト付きで判断が速い(前回集計より)。
MergeできなかったPRの代表例
例 | PR/Issue | 提案内容(抜粋) | なぜ閉じられたか | 主要ソース |
---|---|---|---|---|
1 |
#8164 Fix issue #8162 config.template.toml で max_tokens → max_output_tokens に修正 |
+1/-1 行の TOML テンプレ修正だけで CI は 全緑 | Issue は「テンプレの誤記」で ドキュメント扱いに切り替え。 メンテナ (enyst) が別 PR で Docs ラベルへ移行したためクローズ |
:contentReference[oaicite:0]{index=0} |
2 | ** (Fix issue #8162: [Bug]: Correct name for max_tokens for condenser in config.template.toml by openhands-agent · Pull Request #8164 · All-Hands-AI/OpenHands · GitHub)sue #7968 o4-mini の 1024 文字制限に合わせて関数説明をトリミング |
LLM 呼び出し前に truncate() を追加しテストも同梱 |
同時期にモデル呼び出しロジックの全面リファクタ (#8003,#7999) が進行中。 設計衝突を避けるため Draft のまま Close |
:contentReference[oaicite:1] (Fix issue #7968: [Bug]: o4-mini is incompatible and throws an error. by openhands-agent · Pull Request #8018 · All-Hands-AI/OpenHands · GitHub) #7948Fix issue #7947 Resolver が Action serialization 失敗で落ちる |
4 |
#6350 Fix issue #6223 pyproject.toml の検索パス修正 |
get_hash_for_lock_files() に Fallback 追加 |
エージェントは「Docker テスト失敗は無関係」と主張したが、 ファイル I/O まわりの実装方針に懸念 → レビュー (Fix issue #6223: [Bug]: fix-me-experimental fails with "no such file or directory pyproject.toml" by openhands-agent · Pull Request #6350 · All-Hands-AI/OpenHands · GitHub)entReference[oaicite:3]{index=3} |
|
5 |
#6941 Fix issue #6940 設定トグル名の誤表記修正 |
React のラベル文字列 1 行変更 | PR 作成後 30 日間無アクシ (Pull requests · All-Hands-AI/OpenHands · GitHub)より自動 Close | :contentReference[oaicite:4]{index=4} |
6 | #548x 系(#5480 issue) | 「Agent stuck in loop」を検知して UI で再実行ボタンを出す | スタック検知ロジックを UI と Runtime の両方に追加 | **修正範囲が 300 行 ([Bug]: Cannot recover from "Agent stuck in loop" #5480 - GitHub)Draft のまま放置、のち Close |
特徴
-
設計衝突/重複 (14 件)
同時期に人間主導の大規模リファクタや別 PR が進んでおり、エージェント案は方向性が合わずクローズ。
例)Fix issue #7968
― o4-mini 文字数制限対応 PR #8018 は、並行して動いていた新 LLM 呼び出しリファクタ (#7999 など) と衝突して Draft のまま Close。 (Fix issue #7968: [Bug]:o4-mini
is incompatible and throws an error. by openhands-agent · Pull Request #8018 · All-Hands-AI/OpenHands · GitHub) -
テスト/CI 失敗 (8 件)
追加したユニットテストは通過しても Docker/E2E テストで落ち、修正コストが見合わずクローズ。
例)Fix issue #6223
― pyproject.toml の探索パス修正 PR #6350 は CI の Docker ジョブが赤いままレビュー停止。 (Fix issue #6223: [Bug]: fix-me-experimental fails with "no such file or directory pyproject.toml" by openhands-agent · Pull Request #6350 · All-Hands-AI/OpenHands · GitHub) -
ステール(30 日無反応) (6 件)
メンテナのレビュー待ちで 30 日以上経過し、stale-bot が自動 Close。
例)Fix issue #6940
― Provider 名表記バグ修正 PR #6941 は CI 緑でも担当者不在で放置 → bot により Close。 (Fix issue #6940: [Bug]: Incorrect Provider Name on Advanced Setting Toggle by openhands-agent · Pull Request #6941 · All-Hands-AI/OpenHands · GitHub) -
複雑バグ → 作業断念 (5 件)
根本原因が深く、エージェントが「試したが解決できず」と Issue に報告した後、自ら PR を Close(#5601 系列など)。※複数 PR が同パターンで存在。 -
ドキュメント扱いへ移行 (3 件)
実質はテンプレ/ドキュメントの誤記で、Bug ラベルを外して人間の Docs PR に吸収。
例)Fix issue #8162
―config.template.toml
のパラメータ名誤りを直す PR #8164 は、Docs ラベル付きの別 PR に統合されたため Close。 (Fix issue #8162: [Bug]: Correct name for max_tokens for condenser in config.template.toml by openhands-agent · Pull Request #8164 · All-Hands-AI/OpenHands · GitHub)
まとめ
いくつかの統計と具体例を通してOpenhandsがどこまで実現しているかの現在地をまとめられたかなと思います。
Devinなどの導入を検討している、あるいは運用しているチームには「最低限ここまではできる」というラインの提示に使ってもらえれば幸いです。
おまけ
よければフォローお願いします(最近はQwen3がいい感じ的なツイートをしています)
Discussion