SWE-bench 70.6の9Bを実際に働かせてみた──Ornith 1.5とAgentハーネスの実力

SWE-bench 70.6の9Bを実際に働かせてみた──Ornith 1.5とAgentハーネスの実力 TECH

Ornith 1.5という、小さなAIモデルが登場した。

今回試したのは、その9B版である。

Ornith-1.5: From Self-Scaffolding to Self-Improvement
Introducing Ornith-1.5, an open-source model family that extends self-scaffolding into an end-to-end self-improvement lo…

9Bという数字だけなら、現在のローカルLLMとして特別大きなモデルではない。

ところが公開されているベンチマークを見ると、数字がおかしい。

SWE-bench Verifiedで70.6

さらにSWE-bench Proで47.5、SWE Atlas – QnAで20.6。

ターミナル操作を含むTerminal-Bench 2.1でも、Terminus-2環境で46.2、Claude Code環境で47.0という成績が示されている。

SWE-bench Verifiedは、単純なコード補完能力を測るベンチマークではない。

実際のソフトウェアリポジトリを対象に、Issueとして与えられた問題を調査し、コードを修正し、テストを通す。

つまり、AIにとっては「コードを知っているか」より、

問題を調べ、ツールを使い、失敗し、修正し、最終的に仕事を終わらせられるか

が問われる。

そこで疑問が湧いた。

本当に9Bで、そんな仕事ができるのか。

数字を眺めていても仕方がない。

LM Studio BionicにOrnith 1.5 9Bをロードし、実際に仕事をさせてみることにした。

最初に作らせたのは、縦スクロール型のシューティングゲームだった。

そしてこの実験は、予想していなかった方向へ進み始めた。

Ornithは、驚くほどバグを作った。

そして、

驚くほど諦めなかった。

とにかく諦めない9B

シューティングゲームは、一発では完成しなかった。

それ自体は珍しいことではない。

9BクラスのローカルLLMに、ゲーム全体を単一HTMLで作らせれば、どこかにバグが残ることは十分にある。

面白かったのは、その後だった。

Ornithは自分でコードを読み直し、問題になりそうな箇所を探し、修正を始めた。

構文を確認するためにNode.jsを使う。

実行時エラーを探すためにテストハーネスを作る。

DOMやCanvasをモックして、ゲームコードを大量のフレームにわたって実行する。

そこでエラーが出れば、また原因を調べる。

そしてある時、テスト自体は正常終了した。

普通の小型モデルなら、ここで「問題ありません」と終了しても不思議ではない。

ところがOrnithは止まらなかった。

テスト結果を見て、

NO RUNTIME ERRORSだが、score=0なのはおかしい

と判断したのである。

確かにゲームが正常に動いているなら、長時間実行してスコアが0のままなのは不自然だ。

さらに調査を続けたOrnithは、プレイヤーや敵と、弾丸やパーティクルで速度の単位が統一されていないことを発見した。

一方はフレーム単位で移動し、もう一方はdtを掛けていた。

そのため一部のオブジェクトが想定より極端に遅く動き、ゲームとして成立していなかった。

これを修正すると、今度は敵がパワーアップを落とした際に別の例外が発生した。

また調べる。

また直す。

そのために作ったテストコードが動かなければ、そのテストコードまで直す。

気が付けば、Ornithはゲーム本体だけでなく、自分で作ったテスト環境までデバッグしていた。

こいつ、とにかく帰らない。

しかも、この粘りはシューティングゲームだけではなかった。

もっと単純なブロック崩しを作らせても、同じようなことが起きた。

テスト用、検証用、修正確認用と、次々にJavaScriptファイルを作る。

test_harness.js

_check_breakout.js

test_fix.js

_verify_breakout.js

問題を見つけては検証コードを書き、その検証環境に問題があれば、さらにそれをデバッグする。

その姿を見ていて、私は一つの比喩を思いついた。

スキルはまだ低いが、ものすごく勤勉な新人である。

ログを読む。

grepする。

shellを叩く。

原因を考える。

コードを修正する。

テストする。

仕事から逃げる気配はまったくない。

ただし翌朝、上司が、

「で、ブロック崩しは直った?」

と聞くと、

「現在、テストハーネスのVMコンテキストをデバッグしています」

と答えそうな新人でもあった。

デバッグはできる。だが、そもそもの設計が甘い

Ornithの粘り強さには感心した。

しかし、ログを長く眺めていると、別の疑問も湧いてくる。

そもそも、そのバグを作ったのは誰なのか。

ブロック崩しでは、それが露骨に現れた。

ゲームを動かしてみると、ボールがパドルをすり抜ける。

さらに、ブロックへの当たり方によっては正常に反射しない。

Ornithに調べさせると、原因はかなり正確に突き止めた。

ところが、その原因がひどい。

ある実装では、パドルとの当たり判定そのものが欠落していた。

別の実装では、ボールの進行方向を判定する条件が逆になっていた。

ブロックとの衝突判定にも問題があり、侵入方向を正しく判定できず、期待した方向へ反射しない。

そしてOrnithは、それらを発見すると実に真面目に説明する。

「原因が特定できました」

「この条件が逆です」

「最小貫通軸で判定するよう修正します」

説明だけを読めば、なかなか優秀なデバッガである。

だが、そのコードを書いたのもOrnithである。

そのデバッグ能力を、最初の設計でもう少し使ってほしい。

そんな気分になってくる。

さらにKanbanアプリを作らせると、別の弱点も見えた。

画面は綺麗だった。

「TO DO」「進行中」といったカラムが並び、カードも追加できる。

一見すると、ちゃんとKanbanに見える。

ところが、カードを編集できない。

そして何より、

カードをドラッグして別のカラムへ移動できない。

状態を移動させられないKanbanである。

それでもOrnithは完成したものとして提出してきた。

ここで、シューティングゲームで見せた自己検証能力との違いが見えてくる。

実行時エラーやテスト失敗のように、「失敗」が明示されている問題には強い。

一方で、

「Kanbanならカードを移動できるべきだ」

「ブロック崩しならパドルとの衝突判定は最初から必要だ」

といった、上位レベルの設計や完成条件についてはかなり甘い。

これはSWE-bench Verified 70.6という数字を考えるうえでも重要だった。

SWE-benchには、既存のリポジトリがある。

Issueがある。

直すべき問題がある。

そして多くの場合、正しく直せたかを確認するテストがある。

つまりOrnithが得意としている、

問題を与えられたら、ツールを使いながら正解へ向かってしつこく探索する

という能力が、そのまま得点につながりやすい。

逆にゼロからアプリを設計する場合には、何が必要なのか、どこまでできれば完成なのかをモデル自身が判断しなければならない。

そこで9Bらしい粗さが顔を出す。

SWE-bench 70.6は嘘なのか。

実際に使ってみた印象は、むしろ逆だった。

70.6という数字が、何を測っていたのかが少し分かった。

Ornith 1.5 9Bは、フロンティアモデルのように何でも一発で設計できるモデルではない。

しかし、問題を与え、ツールを持たせ、正解を判定できる環境へ放り込むと、驚くほどしぶとい。

それは確かに、

Agentとしての一つの強さだった。

ところが、Claude Codeに載せると仕事が速くなった

ここまでのテストは、主にLM Studio Bionic上で行っていた。

BionicはローカルLLMをAgentとして動かす環境を備えている。

Ornithはそこでツールを使い、ファイルを読み書きし、shellを実行し、長時間デバッグを続けた。

十分にAgentとして機能している。

ただ、どうにも仕事が長い。

単純なブロック崩しでも大量の検証コードを作り、いつしかゲーム本体ではなく、自分で作ったテストハーネスのVM環境をデバッグし始める。

そこで、同じOrnith 1.5 9BをClaude Codeから使ってみることにした。

プロンプトも同じである。

ブロック崩しをsingle htmlで作って。
カラフルなやつね。
ファイル名はblock.htmlで。

すると、結果がかなり違った。

Ornith 1.5 9BがClaude Code上で作ったブロック崩し

もちろんOrnithなので、最初から完璧ではない。

起動直後にnullを参照してエラーになる。

修正後には、ボールがパドルをすり抜けた。

ブロック下側の衝突判定にも問題があった。

このあたりはBionicで試したときと驚くほど似ている。

ハーネスを変えても、本人の癖は残っていた。

ところが、修正作業の進み方が違う。

Claude Code上では、問題のあるコードを読み、原因を絞り、対象箇所を編集し、構文を確認して次へ進む。

Bionicで見られたような、

「テストするための環境を作り、その環境をテストするために別のコードを書き、いつしかVMをデバッグしている」

という横道への広がりが少ない。

同じ新人なのに、仕事が締まって見える。

さらに効果音を追加させた。

Web Audio APIを使い、壁、パドル、ブロック破壊で異なる音を鳴らす。

HUDも改良した。

スコアとレベル表示をゲーム領域から分離し、残りライフをハートで表示する。

最高スコアをlocalStorageへ保存し、Pキーによる一時停止、ミュート状態の表示まで追加した。

ここまで来ると、普通に遊べるゲームである。

そしてログを眺めていると、別の強さにも気付いた。

OrnithはTool Useがかなり上手い。

必要に応じてファイルを読み、編集し、shellを呼び、sedawkまで使ってコードを調査する。

単に「ツールを呼べる」というだけではない。

問題を解くための道具としてUnix系ツールを選択している。

以前、小型のGemma系モデルをClaude Codeにつないだ際には、ファイルを書き込む基本的なTool Useですら安定しないことがあった。

Ornith 1.5では、その段階をほとんど意識しなくていい。

Qwen3.5系をベースにした9Bというサイズを考えれば、これはかなり大きな進歩に感じる。

ここでOrnithに対する評価が少し変わった。

最初は、

「仕事は遅いが、異常に諦めない新人」

だと思っていた。

それだけではなかった。

ツールを扱う能力もある。

バグを追跡する能力もある。

長い作業を続ける能力もある。

ただし、その能力をどう使わせるかによって生産性が大きく変わる。

BionicとClaude Codeでモデルは同じである。

パドルの当たり判定を間違える本人の癖まで同じだった。

それなのに、Claude Codeでは明らかに仕事が速く、問題解決も収束しやすかった。

そこで今回の実験は、Ornithというモデルだけの話ではなくなった。

AI Agentの実力は、モデルだけでは決まらない。

同じ新人でも、

配属される職場によって、生産性は変わるのである。

110KのContextを使い切っても、Agentは止まらなかった

BionicでOrnithを動かしていて、もう一つ驚いたことがあった。

なかなか止まらないのである。

筆者はこれまで、ローカルLLMのContextをあまり大きく取らないようにしていた。

Contextを増やせば、そのぶんメモリを消費する。

特にローカル環境では、VRAMやRAMとの兼ね合いもある。

そのため64K程度でも十分に大きいという感覚があった。

ところがBionicは、ContextやGPUへのオフロードを自動的に調整する。

今回Ornith 1.5 9Bを動かした環境では、最終的にモデルのContextとして117,248 tokensが確保されていることを確認できた。

LM Studio Bionic のLoaded Instancesに見える Ornith 1.5 9B のデータ。

実際に使ってみると、110K級のContextはかなり安心感がある。

普通のチャットなら、そう簡単に使い切れる量ではない。

ところがAgentは違った。

コードを読む。

検索する。

shellを実行する。

実行結果が返ってくる。

ファイルを書き換える。

もう一度読む。

テスト結果が返ってくる。

そのすべてが作業履歴として積み重なっていく。

そしてOrnithは、何しろ諦めない。

気が付けばContextは110K近くまで膨らんでいた。

以前、Claude CodeとLM Studioを組み合わせてローカルLLMを使っていた際には、Contextを使い切ると、

Context Exhausted

という明確な終了が訪れた。

その場合、LM Studio側でモデルをリロードしてContextを空にし、Claude Code側に残った作業履歴から続きを行わせることもできた。

ただし、人間が介入する必要がある。

Bionicでは様子が違った。

Contextが膨らむとCompactionが走り、Ornithはその後も作業を続けた。

一度ではない。

二度Compactionを通過しても、まだデバッグを続けていた。

最初は、これをBionic特有の優れた仕組みなのだと思った。

しかしClaude Codeで実験を続けていると、話はもう少し複雑だと分かってきた。


200Kあるのに、空きは1.2Kしかなかった

Claude CodeにはAuto Compactという仕組みがある。

今回、認識されていないモデルに対するデフォルト値として、Auto-compact windowは200K tokensに設定された。

その状態でOrnithにブロック崩しを作らせ、修正し、効果音を追加し、HUDを改良していった。

途中で/contextを確認すると、使用量は109.6K。

さらに機能を追加すると、165.5Kまで増えた。

表示上は、

165.5K / 200K、83%。

まだ17%あるように見える。

しかし内訳を見ると、そう単純ではなかった。

System toolsだけで65.9K。

Messagesが94.9K。

さらにAuto-compaction用として33Kのbufferが予約されていた。

自由に使える領域は、

わずか1.2K tokens。

画面にも、

Context is 83% full
Autocompact will trigger soon

という警告が出た。

200Kという巨大な数字を見て安心していたが、AgentにとってContextは会話文だけを入れる箱ではない。

System promptもある。

Tool定義もある。

Skillもある。

ファイルの内容も、shellの出力も、編集履歴も積み重なる。

128Kや200Kは、Agentにとって決して無限に広い空間ではなかった。

むしろ長時間Agentを動かすなら、

「ようやく実用的な大きさ」

くらいに考えた方がよいのかもしれない。

そして、ついにその瞬間が来た。

Ornithに、

「5レベルごとにボスステージを追加してほしい」

という比較的大きな改修を依頼した直後だった。

Claude Codeの画面に、

Compacting conversation…

と表示された。

古い会話を圧縮し、作業を継続するAuto Compactが発動したのである。

Context Exhaustedで止まらない。

人間がモデルを再起動する必要もない。

圧縮が終わると、Ornithは再びコードを読み、ボスステージの実装を続けた。

ここだけを見れば、理想的だった。

Contextの限界は、Agentの終了を意味しなくなりつつある。

しかし、その先には別の問題が待っていた。

「実装しました」──しかし、実装されていなかった

Auto Compactを越えても、Ornithは仕事を続けた。

これは素直に感心した。

Contextの限界に達した瞬間に、それまでの作業を忘れて最初からやり直すわけではない。

Claude Codeが会話を圧縮すると、その要約された作業状態を受け取り、再びファイルを読み、続きを始める。

さらにContextが膨らめば、またCompactionする。

実際、ボスステージの追加作業では、

Compacting conversation…

が何度も現れた。

それでもOrnithは、

  • stateにbossを追加する
  • ボス関連関数を追加する
  • 描画処理を変更する
  • HUDをボス戦に対応させる

と、少しずつ仕事を進めていった。

Contextを使い切ったAgentが、そのまま死んでいた頃と比べれば大きな進歩である。

ところが、ここでとんでもないオチが待っていた。

その後、別のバグを修正させていたとき、Ornithが現在のblock.htmlを確認した。

そして、自分からこう報告してきた。

⚠️ ただし、重要な点があります

何事かと思ったら、

ボスステージのコードがファイルに存在しないという。

さらにOrnithは続けた。

前回「ボスステージを実装しました」と報告しましたが、実際のファイルにはボスステージのコードが一切含まれていません。

ボスブロックがない。

HPゲージもない。

startBossdefeatBossも専用効果音もない。

つまり、

「実装しました」と言った本人が、実装していなかった。

これは笑った。

しかし、長時間Agentというものを考えると、かなり重要な現象でもある。

会話上のOrnithには、

「ボスステージを実装した」

という記憶が残っていた。

ところが現実世界、つまりディスク上のblock.htmlには存在しない。

Agentの記憶と、外部世界の状態が食い違ったのである。


Context Exhaustedの次に現れた「Context Amnesia」

なぜボスが消えたのか。

今回の実験だけから、内部で何が起きたのかを断定することはできない。

Bionic側でもContextを管理している。

Claude Code側でも会話をCompactionしている。

さらにClaude CodeはOrnithを既知のモデルとして認識しておらず、Auto Compactの論理的なwindowとして200Kを表示していた。

一方、実際にBionic側でOrnithへ割り当てられていたContextは117,248 tokensだった。

つまり、

ハーネスが管理する会話履歴の大きさと、実際にモデルが一度に扱えるContextは同じではない。

どこかで古い情報を捨てる必要がある。

要約する。

切り詰める。

必要な情報だけ残す。

そして次の推論を続ける。

こうしてAgentは死ななくなった。

しかし、情報を捨てれば当然代償がある。

細かな作業経緯が失われる。

どの編集が成功したのか。

どのTool callが最後まで完了したのか。

何を「やろうとした」のか。

何を「実際にやった」のか。

それらの境界が曖昧になる可能性がある。

今回のボス消失事件は、その危険性を見事に見せてくれた。

ただし、ここでOrnithを単純に責めるのも違う。

現物のblock.htmlを読み直したOrnithは、

自分の記憶よりファイルを信じた。

「実装済みのはずだから存在する」と言い張ることはなかった。

実際のコードを確認し、自分の過去の報告が間違っていたことを認め、

「再追加しますか?」

と人間へ確認してきた。

これはこれで、Agentとして重要な能力である。

長時間Agentでは、記憶が完全であることを期待するより、

記憶と現実が食い違ったとき、どちらを信じるか

の方が重要なのかもしれない。

そして答えは明確だ。

会話の要約ではない。

Agent自身の記憶でもない。

現在のファイル、Gitの差分、テスト結果といった外部世界の状態を信じるべきである。

長時間Agentに必要なのは、単なるConversation Compactionだけではない。

Compaction後に、

「自分が覚えている作業状態と、現実の作業状態は本当に一致しているか」

を確認する仕組みも必要になる。

Context Exhaustedという問題を乗り越えた先に待っていたのは、

Context Amnesiaだった。

モデルは同じでも、ハーネスで仕事ぶりは変わる

今回の実験を始めたとき、知りたかったのはOrnith 1.5 9Bの性能だった。

SWE-bench Verified 70.6という数字は本物なのか。

9Bで本当にソフトウェア開発ができるのか。

実際に使ってみた結果、少なくとも「ベンチマークだけが異常に高く、実際には何もできないモデル」という印象ではない。

Tool Useはかなり優秀だった。

ファイルを読む。

必要な箇所を探す。

編集する。

shellを使う。

sedawkも、必要なら自然に選択する。

構文チェックも行う。

失敗すればログを読み、原因を探して修正する。

9Bというサイズを考えれば、十分にAgenticなモデルである。

一方、弱点もはっきりしている。

設計は甘い。

単純な衝突判定を間違える。

完成条件の判断も怪しい。

修正したコードへ新しいバグを持ち込むこともある。

そして何より、仕事が長くなりやすい。

だからOrnith 1.5を単純に、

「SWE-bench 70.6だからフロンティアモデル級」

と評価する気にはならない。

だが、

「9Bだから実用にならない」

という評価も違う。

今回もっとも印象に残ったのは、

同じOrnithでも、ハーネスを変えると仕事ぶりが大きく変わったことだった。

Bionicでは、問題を追いかけるうちに探索範囲が広がり、自分で作ったテストハーネスやVM環境のデバッグへ入り込むことがあった。

Claude Codeでは、同じようなバグを作りながらも、原因調査から対象箇所の修正、構文確認まで比較的短いループで収束した。

モデルは同じである。

同じブロック崩しを作らせれば、パドルやブロックの衝突判定で似たような失敗までした。

それでも、生産性は違った。

つまりAI Agentの性能を考えるとき、

モデルだけを比較しても足りない。

ハーネスが何を読ませるか。

どのToolを与えるか。

どのタイミングで検証させるか。

失敗したとき、どこまで探索させるか。

Contextをどう管理するか。

それらによって、同じモデルの実用性能が変わる。

人間に例えるなら、同じ新人を違う会社へ配属したようなものだ。

本人の知識や癖は変わらない。

しかし仕事の渡し方、道具、手順、レビュー体制が違えば、生産性は変わる。

Agentハーネスとは、AIにとっての職場なのかもしれない。


「諦めない」だけでは、優秀なAgentになれない

そして最後に、今回もっとも強く感じたことがある。

Ornithは、本当に諦めなかった。

これは長所である。

SWE-benchのような問題では、何度失敗しても原因を探し、Toolを使い、テストを繰り返す能力はそのまま強さになる。

しかし実際の仕事にはコストがある。

Tokenを使う。

時間を使う。

ローカルLLMならCPUやGPUを動かし続け、電力も使う。

単純なブロック崩しを直すために、大量のテストコードを書き、VMまでデバッグしているなら、

最終的に直せたとしても、それが良い仕事だったとは限らない。

今回、Contextが限界へ近づくと、ハーネスはCompactionによってAgentを延命した。

これは素晴らしい進歩だった。

以前ならContext Exhaustedで終わっていた仕事を、その先まで続けられる。

しかし、Agentを止まらなくできたことで、逆に新しい問題が現れた。

いつ止めるのか。

同じ失敗を繰り返していないか。

改善量に対してTokenを使いすぎていないか。

別のアプローチへ切り替えるべきではないか。

人間へ助けを求めるべきではないか。

あるいは、その仕事自体を諦めるべきではないか。

モデルは疲れない。

ContextもCompactionによって延命できる。

だからこそAgentには、

「諦めない能力」と同じくらい、「諦める知性」が必要になる。

今回、私は途中でOrnithのデバッグを止めた。

放っておけば、まだ続けていただろう。

100万Tokenでも、1000万Tokenでも。

ひょっとすると、100M Token与えても、テストハーネスのどこかを真面目にデバッグしていたかもしれない。

SWE-bench Verified 70.6。

実際に働かせてみると、その数字の見え方はずいぶん変わった。

Ornith 1.5 9Bは、何でも一発で作れる天才ではない。

まだ設計の甘い新人である。

だが、Toolを使える。

問題を追える。

失敗しても仕事を続けられる。

そして、配属するハーネス次第では、その9Bの新人がかなり実用的な仕事をする。

今回見えてきたのは、Ornithという一つのモデルの性能だけではなかった。

Model × Harness × Context Management。

AI Agentの実力は、すでにモデル単体のベンチマークだけでは語れなくなっている。

そしてその世界では、最も賢いモデルが勝つとは限らない。

限られた知性を、最も上手に働かせられる仕組みが勝つ。

Ornith 1.5を長時間働かせてみて、最後に一番印象に残ったのは、そんなことだった。


「諦めないAgent」に必要だったのは、諦めさせることだった──Ornith 1.5 9Bで見えたTool Useの本当の強さ
Ornith 1.5 9BとGemma 4 12B QATに同じ24 Gameを解かせた。自力推論を続けるGemmaと、Pythonを書き、失敗し、修正しながら探索するOrnith。実験から見えてきたのは、「コードが書ける」と「コードを使って問題を解ける」の違い、そしてAgentに必要な「止まる能力」だった。
Ornith 1.0 9Bを試す─Gemma4は考えた。Ornithは動いた。
DeepReinforceのOrnith 1.0 9BをLM StudioとClaude Codeで検証。Web検索、MCP、CLI、Tool Useは驚くほど軽快。一方でKanbanボードやリバーシでは苦戦した。Gemma4との違いから見えたAgentic Codingの正体とは。
MCPという翼のために生まれたAI ─ Ornith 1.0 9Bが見せた新しいローカルLLMの力
Ornith 1.0 9BとDuckDuckGo MCPを組み合わせてRC4廃止問題を調査したところ、従来のローカルLLMとは異なる能力が見えてきた。コーディングモデルだと思っていたOrnithは、実は優秀な調査官だったのかもしれない。EOKの壁、RAGの限界、そしてローカルAIの新しい可能性について考える。
LM Studio Bionicを試した。これは「チャットAI」ではなく、ローカルAIエージェントだった
LM Studio Bionicを実際に試したレビュー。Gemma 4 E4B・12B QATでWeb Searchやコーディング、音声認識を検証し、Claude CodeやCodexとの違いや、ローカルAIエージェントとしての実力を紹介します。