言語の再帰的自己改善:約280言語にわたるコードインテリジェンスの磨き上げ
> 私たちは約280言語のコードインテリジェンスに対応しています。人間の手でそのすべてを監査することはできません。そこで私たちは、言語の再帰的自己改善ループ ―― 抜き取り検査、LLM-as-judge、1点修正、再検証 ―― を構築し、抽出が単に「グリーン」であるだけでなく実際に正しくなるまで、隔離されたエージェント群でこれを回し続けています。
この記事の数値は公開時点(2026年5月)のシステムを反映しています。最新の数値はチームページをご覧ください。
Maguyvaは、約280言語のソースコードからシンボル、参照、そして依存関係グラフを抽出します。言語ごとにカスタムのtree-sitterハンドラー ―― クエリ、ヒューリスティクス、エッジケース ―― が存在し、どのハンドラーもそれぞれ独自の形で微妙に間違っている可能性があります。メソッド呼び出しがreadとして出力される。関数が誤った包含スコープに帰属させられる。本来は存在しないはずの関係が生成される、といった具合です。
これを手作業で監査することはできません。どんなチームであっても、280種類の文法にまたがる抽出結果をすべて読んで、誤ったエッジを見つけ出すことはできません。だから興味深い問いは「私たちの抽出は正しいか」ではなく、「この規模で、すべてのループに人間を挟むことなく、どうやって間違いを見つけ出すか」なのです。私たちの答えは、言語エージェントが主導する品質ループと、判定者として振る舞うLLM、そして繰り返し学び直している1つのルール ―― グリーンであることと正しいことは同じではない ―― による、言語の再帰的自己改善です。
グリーンは正しさではない
どの言語にもフィクスチャ(テスト用固定データ)一式があり、リリースゲートは精度、構造的整合性、網羅性、品質、パフォーマンスという5つの次元でスコアを付けます。ある言語がGREENになるのは、そのフィクスチャ上でprecision(適合率)が0.95以上、recall(再現率)が0.99以上、F1が0.97以上、かつ統計的な信頼性のために期待エッジ数が20以上ある場合のみです。それを下回るとYELLOWまたはREDとなり、出荷されません。
このゲートは必要条件ではありますが、十分条件ではありません。フィクスチャは私たちが書いたフィクスチャに対して検証されるものです。つまり、私たちがすでに思いついたケースしか反映されていません。ハンドラーはフィクスチャ上では完璧でも、実際のコードにしか現れないパターン ―― マクロのイディオム、ジェネリック境界を持つメソッド、誰もフィクスチャを書かなかった言語機能 ―― をぐちゃぐちゃにしてしまうことがあります。GREENが意味するのは、フィクスチャが通ったということだけです。実際のリポジトリがきれいに抽出できることを意味するわけではありません。だからこのループは、フィクスチャを離れて野生のコードに目を向けなければならないのです。
内側のループ:抜き取り検査、判定、修正、証明
中核となるループは、一度に1言語ずつ実行されます:
┌──────────────────────────────────────────────────────────┐
│ │
▼ │
1. corpus run ── clone real-world repos, extract relationships │
│ │
▼ │
2. spot-check 100 edges (seed 42, then seed 123 to cross-check) │
│ │
▼ │
3. LLM judge classifies every sampled edge: │
CORRECT · FALSE_POSITIVE · TYPE_ERROR · │
SCOPE_ERROR · METADATA_ERROR │
│ │
▼ │
4. fix ONE thing — handler .py, .scm query, or config │
│ │
▼ │
5. re-validate — F1 + re-classify + manifest diff (no regressions)│
│ │
better? ──no──► revert, try a different fix ────────────────────┤
│ yes │
▼ │
6. promote the fix into fixtures (a permanent regression guard) ──┘
これが空回りせずに機能するのには、いくつかの理由があります。
判定者はAPI呼び出しではなく、エージェント自身です。 私たちが「LLM-as-judge」と言うとき、それは言語エージェント自身が、サンプリングされた各エッジを実際のソースコードと突き合わせて読み、固定の5カテゴリーからなるルーブリックで分類することを意味します。すなわち、そのエッジは正しいのか、偽陽性なのか、関係は正しいが型が間違っているのか、誤ったスコープに紐づいているのか、それとも誤ったメタデータを持っているのか、という分類です。このルーブリックがすべての鍵です。「エラー率23%」という数字は、それが本物の欠陥なのか、それとも判定者の数え間違いなのかがわからない限り、何の意味も持ちません。
1点だけ修正し、それを証明する。 各イテレーションは編集可能な資産をちょうど1つだけ変更し、固定のハーネスに対して再実行し、F1が改善し再分類の結果もよくなった場合にのみその変更を残します。そうでなければロールバックします。投機的な変更をまとめて行うことも、「よくなるはずだ」という思い込みもありません。変更はその価値を証明して初めて残るのであり、そうでなければ消えます。そして修正が定着すると、それはフィクスチャ一式に昇格します ―― これにより、修正したバグが静かに再発することは二度となくなります。この昇格のステップこそが、このループを単なる反復ではなく再帰的なものにしています。1回のパスごとに、次のパスが検証対象とするオラクル(基準)そのものが強化されていくのです。
繰り返し学び直している教訓:メトリクスは過大報告する
ここに落とし穴があり、私たちはまさにそこへまっすぐ踏み込んでしまいました。副次的なコーパスメトリクス ―― 抽出されたターゲットに解決可能なシンボルがない頻度や、いくつのシンボルが「孤立」しているように見えるか、といった指標 ―― は、問題を大幅に過大報告します。それらのほとんどは、バグではなく*パラダイム上のアーティファクト(現れ方の癖)*にすぎません。
もっとも分かりやすい例がllvmです。かつて「シンボルなしソース」率が73%を示し、壊滅的だと烙印を押されました。しかし掘り下げてみると、実際の精度は**98.5%**でした。「欠落しているシンボル」のほとんどは、標準ライブラリやフレームワーク、リポジトリの外にあるコードへの、正当な外部参照だったのです。このメトリクスが測っていたのは、ハンドラーの欠陥ではなく、その言語自体の性質でした。Zig、COBOL、Odinのような言語は65〜70%の「孤立」率を示しますが、まったく正しく、COBOLに至っては実際のエラーはゼロでした。
もしこの数字に作業を主導させていたら、すでに正しいハンドラーを何週間もかけて「修正」し続け、静かに本物のバグを抱えている言語を無視していたことでしょう。結論は率直です。集計メトリクスは、よくてもおおまかなトリアージ用のシグナルにすぎません。本当の品質シグナルは、エッジ分類つきの抜き取り検査です ―― 実際のリポジトリにある実際のエッジを1つずつ見て判断すること。直感よりデータを優先すべきですが、それはどのデータが真実を語っているかがわかって初めて成り立つのです。
外側のループ:マラソンではなく艦隊で
280言語すべてを一度に1言語ずつ処理していては永遠に終わりません。そこで内側のループは、多数を並列に実行する外側のループの中に包み込まれています。
pick a wave of near-GREEN / high-error languages
│
▼
fan out 10–15 agents, each ISOLATED in its own git worktree,
each grinding ONE language, committing to its own branch
│
▼
orchestrator integrates serially: file-scoped apply, then
`manifest diff` — any cross-language regression blocks the batch
│
▼
gated push (reviewed and confirmed) ──► rotate to the next wave
各エージェントは使い捨てのworktreeの中で作業するため、互いに干渉することはありません。オーケストレーターは、各エージェントの修正を1つずつ、フルマニフェストの回帰チェックを通した上で統合します。自分の言語には効果があっても、他の3言語を静かに壊してしまうような変更は取り込まれません。統合は何かをプッシュする前にゲートを通り、確認されます ―― 回帰ゲートが決めるのは何が安全かであり、何を出荷するかを決めるのは今も人間です。その後、プールは次の言語群へとローテーションし、同じプロセスがまた繰り返されます。
まだ不完全な部分
判定者は間違えることがあり、その間違い方には方向性があります。コンテキストが不足した状態で動いているエージェントは過大報告する傾向にあるのです。あるバッチでは8言語がエラー率5〜20%としてフラグ付けされましたが、調べてみると本物の言語固有バグだったのは1件だけで、残りはすべて、その言語固有のセマンティクスを判定者が見落としたことによる誤りでした(1行のソースが正当に複数のエッジを生成する、パラメータバインディングが代入としてモデル化される、識別子ごとに参照を持つ言語、など)。だからこそ私たちは2つのシードでサンプリングして相互チェックを行い、判定者とフィクスチャの間の不一致を、確定した判定としてではなくもっとも興味深いシグナルとして扱っています ―― ときには、間違っているのはフィクスチャの方だからです。
目標についても正直でありたいと思います。ゴールは正真正銘のゼロエラーであり、それ以上でも以下でもありません ―― しかし「ゼロ」はチェックボックスにチェックを入れて終わるものではなく、言語ごとに少しずつ磨き上げていく方向性です。常に、また別のイディオムを持つ別のリポジトリが存在するからです。
主張するのではなく、勝ち取る
Maguyvaがエージェントのために行うすべてのこと ―― シンボルを見つけること、依存関係をたどること、コードを引用しながら質問に答えること ―― は、その土台にある抽出が正しいという前提の上に成り立っています。280言語にわたって、「正しい」ということは主張できるものではなく、実際のコードに対して継続的に勝ち取るものでなければなりません。私たちがそれを勝ち取る方法がこのループです。自らのメトリクスを疑ってかかり、あらゆる変更を証明し、それぞれの修正を次の回帰に対する防御へと変えていく、自律的な抜き取り検査と修正のサイクル。華やかな仕事ではありません。しかしこれこそが、「あなたの言語に対応しています」と、本気でそう言い切るための土台となる仕事なのです。グリーンになるのは簡単です。正しさは、勝ち取るものです。
関連記事
Maguyva開発ログのその他の記事
コード検索をvoyage-4-largeへアップグレードした理由_
私たちはコード埋め込みをvoyage-4-largeへ移行しました ―― 現在、公開RTEBコード検索リーダーボードのトップに立つモデルです。正直に言うと:私たちが受け入れているトレードオフ、実際に何をインデックス化しているか、そしてなぜプレミアムな埋め込みにお金を払うのか。
マルチモーダル・フュージョン検索:あらゆるクエリに最適な検索エンジンを選ぶ_
「parseConfigはどこで定義されているか」のようなクエリと「認証はどう動いているか」のようなクエリでは、求められる検索の種類が異なります。Maguyvaは意図を分類し、それに応じて4つの検索モダリティに重みを付け、重み付き相互順位融合で結果を統合します。
エージェントオブザーバビリティ:フック、Alloy、Grafana_
Claude CodeとCodexを1つのGrafanaスタックにOpenTelemetryとAlloyで配線し、トレースとログを使ってエージェントの挙動の問題を根源から見つけて直す。