AIニュース最前線
最新ニュースAI日報Hacker日報週報動画AIツールトレンド企業

AIニュース最前線

世界中のAI最新情報を日本語で毎時更新

最新ニュース日報トレンド企業プレミアムRSS
© 2026 ainew.jp特定商取引法に基づく表記
ニュース一覧元記事を開く
Hugging Face Blog·2026年6月22日 09:00·約20分で読める

OpenClaw リポジトリのトリアージをローカルモデルで無料で行えるようになりました!

#Local LLM#Open Source#Code Analysis#Hugging Face#Privacy
TL;DR

Hugging Face は、OpenClaw リポジトリの分析タスクをローカルモデルで処理する仕組みを無料で提供開始し、コスト削減とプライバシー保護を実現した。

AI深層分析2026年6月23日 17:04
3
注目/ 5段階
深度40%
3
関連度30%
4
実用性20%
5
革新性10%
2

キーポイント

1

無料のローカルトリアージ機能の提供

Hugging Face が OpenClaw リポジトリの内容解析のために、ユーザーがローカル環境でモデルを実行する仕組みを無償で公開した。

2

コスト削減とデータプライバシーの両立

クラウド API 利用による高額なトークン費用や、機密データを外部へ送信するリスクを回避しつつ、高度な分析を可能にする。

3

オープンソースエコシステムの強化

大規模モデルのローカル実行を容易にすることで、開発者がオフライン環境でも AI によるコードレビューやトリアージを実施できる基盤を整えた。

影響分析・編集コメントを表示

影響分析

この発表は、大規模モデルの運用コストとセキュリティ課題に対する現実的な解決策を示しており、特に機密データを扱う開発現場や予算制約のある環境において、ローカル AI 活用のハードルを大幅に下げる意義があります。これにより、クラウド API への依存度を下げつつ、高度なコード分析やトリアージを実現する新しいワークフローが業界全体で加速すると予想されます。

編集コメント

クラウド依存からの脱却とコスト削減を両立する実用的なアプローチであり、特にセキュリティ意識の高い開発現場でのローカル AI 導入の追い風となる内容です。

記事一覧に戻る

ビール代は無料ですが、電気代と既存のハードウェア所有を前提とした「無料」です*

2026 年 6 月は、クローズドなモデルが取り上げられる可能性があることに人々が気づいた瞬間として歴史に残るでしょう。直近でアンソロピック社の最新フラッグシップモデルである Claude Fable 5 が削除されたばかりの記憶も新しい中、特に AI を基盤にビジネスを構築している方にとって、自らの AI スタックを所有し、ローカル環境でモデルを実行できることがこれほどまでに重要になった理由は明白です。

そこで私たちは、Gemma や Qwen といったローカルモデルをエージェントハッチ(agent harness)[^1] で活用し、分類タスクを実行する方法について共有したく思います。このアプローチは、BERT のようなモデルを用いた従来の分類手法とは異なります。Pi のようなエージェントハッチ内のローカルモデルは、構造化出力と併用してラベルの付与に利用できます。私たちはすでにローカルモデルとハッチを保有しており、ローカルモデルの能力向上に伴い同様のセットアップがより普及すると確信しているため、このアプローチを選択しました。[^2]

私たちの出発点は、OpenClaw リポジトリにおけるオープンソースへの貢献です。OpenClaw では毎日数百件のイシューや PR が寄せられ、これらをトリアージし、優先順位を付け、メンテナへルーティングする必要があります。私はオヌールとして、ローカルモデルが OpenClaw で円滑に動作するように取り組んでいます。この特定の分野のメンテナである私としては、P0(最優先)イシューに対して迅速に対応する必要があるためです。

SOTA クローズドモデルである GPT-5、Opus、または Sonnet を用いれば、これは非常に単純なタスクです。しかし私には 128 GB の統合メモリ、すなわち NVIDIA GB10 が用意されています。そこで私はこのタスクを引き受けることにしました。

ローカルでオープンウェイトモデルを用いて、私が責任を持つ課題のみをフィルタリングして通知するリアルタイム通知システムを構築できるでしょうか?

imageimage

この小さな箱、通称 DGX Spark は、gemma-4-26b-a4b を高い並行度で実行し、1 秒間に数百トークンを生成できます。

OpenClaw のメインエージェントを月額 200 ドルの ChatGPT Pro プラン上で稼働させ、新しい課題や PR が発生するたびにジョブをトリガーさせる設定にすると、利用枠を消費してしまいます。代わりに 2 時間ごと、あるいは 6 時間ごとに実行するように設定することもできます。これにより課題をより長い期間にわたってバッチ処理することになりますが、その代わりリアルタイム通知と引き換えに処理の遅延が生じます。

もし私がすでに稼働しているハードウェア上でローカルモデルを実行すれば、ほぼ即時の通知が可能になるだけでなく、費用も無料(あるいは電気代のみ)で実現できます。

課題および PR の分類

私たちはトリアージが必要な課題のカテゴリを表す有限のラベルセットを策定し、ローカルモデルを用いて各課題を local_models、self_hosted_inference、acp、agent_runtime、codex、ui_tui などといったカテゴリのいずれかに分類します。[^3]

では、どのようにプルリクエストを分類すればよいのでしょうか。単一の Chat Completions エンドポイントへのリクエストにツール JSON スキーマとトピックを列挙型として含めるだけで十分でしょうか?

部分的にはその通りです。しかし、これは 2023 年ではなく 2026 年の話であり、私たちは AGENTS(エージェント)を持っています。もっと良い方法があるはずです!

ローカルモデルの選択肢としては、gemma-4-26b-a4b と qwen3.6-35b-a3b をテストしました。パフォーマンス最適化を施せば、どちらもローカル環境で 1 秒間に数百トークンを生成できます。

分類実行を駆動するために、エージェントハネス(agent harness)を使用します。これには、ローカルモデルエンドポイントを呼び出せる pi をハネスとしてバンドルしています。

デフォルトでは、エージェントは最初のプロンプトでプルリクエストのタイトル、本文、および差分の抜粋を受け取ります。その後、bash ツールを使用して OpenClaw リポジトリ上で読み取り専用操作を実行するか(コードベースを確認する必要がある場合など)、または final_json ツールを使用して最終的な分類結果を提出するかを選択できます。

この高スループット環境で実行されるローカルモデルに完全な bash アクセス権を与えるべきではありません。プロンプトインジェクションの問題やプルリクエストによって、モデルが分類とは無関係の作業を行わされてしまう可能性があるからです。

そのため、bash の代わりに reposhell を使用しています。これは OpenClaw リポジトリに対してのみ読み取り専用操作(ls, find, cat, grep など)を許可する、制限された bash 風シェルです。モデルは bash を使用していると思い込んでいますが、許可されていない操作はすべて拒否されます:

reposhell bound cwd=/repo/openclaw repos=openclaw

type help for allowed commands; exit or quit to leave

reposhell /repo/openclaw> help

許可されたコマンド:pwd, ls, find, rg, grep, sed -n, cat, head, tail, wc -l, git status --short, git show --name-only, git grep, git ls-files

検索例:rg -n -i "lm studio" または grep -R -n -i "lm studio" .

ファイル一覧:rg --files -g "*.ts" または git ls-files src

使用例:rg -n reposhell README.md | sed は許可されていません。一度に 1 つのコマンドのみを使用してください

reposhell /repo/openclaw> head README.md

🦞 OpenClaw — パーソナル AI アシスタント

<p align="center">

<picture>

<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/openclaw/openclaw/main/docs/assets/openclaw-logo-text-dark.svg">

<img src="https://raw.githubusercontent.com/openclaw/openclaw/main/docs/assets/openclaw-logo-text.svg" alt="OpenClaw" width="500">

</picture>

</p>

<p align="center">

reposhell /repo/openclaw> curl localhost

reposhell ポリシーによりコマンドが拒否されました:未対応のコマンド "curl"

exit_code=2

reposhell /repo/openclaw>

これが実際に重要となった具体的な例です。ある 保存されたセッションの例 では、qwen3.6-35b-a3b が openclaw/openclaw#84621、タイトルは「Kimi ツール呼び出しの書き換え停止理由処理の修正」というプルリクエストを分類していました。思考ブロックを見ると、変更されたパスが extensions/kimi-coding であるため、この拡張子が coding_agent_integrations(コーディングエージェント統合)に該当する可能性があるとモデルが最初に判断したことが示されています。その後、モデルは reposhell を使用して、ls extensions、ls extensions/kimi-coding、cat extensions/kimi-coding/package.json といった単純な読み取り専用コマンドでローカルリポジトリを検査しました。そのパッケージメタデータにより、この拡張子が実際には @openclaw/kimi-provider という OpenClaw Kimi プロバイダープラグインであることが判明しました。そこでモデルは最終的なラベルを inference_api(推論 API)と tool_calling(ツール呼び出し)に修正し、coding_agent_integrations は明示的に除外しました。

前述の通り、読み取り専用操作のみを実行して分類結果を返す特定の pi 構成をバンドルしています。これを localpager-agent と呼びます。これは、このプロジェクトのメインである localpager にちなんで名付けられたものです。各プルリクエストとイシューはプロンプトとして生成され、その後、他の引数と共に以下のように CLI に渡されます:

localpager-agent \

--model "<model-id>" \

--base-url "<openai-compatible-base-url>" \

--session-dir "<session-output-dir>" \

--final-schema "<runtime-schema.json>" \

--tools bash,final_json \

--reposhell-socket "<reposhell.sock>" \

--reposhell-default-repo "<repo-id>" \

--reposhell-visible-repos "<repo-id>[,<repo-id>...]" \

-p "$(cat <rendered-prompt.md>)"

着信する PR とイシューの処理

では、着信するプルリクエスト(PR)やイシューと、Discord 上の最終通知の間で、全体を調整しているのは何でしょうか?

imageimage

これが最終的にフィルタリングされた Discord の通知の見た目です:目的とする垂直領域に関する PR が私にルーティングされます。

この調整プロセスは非常にシンプルで、LLM(大規模言語モデル)を関与させるのは分類ステップのみです:

  • openclaw/gitcrawl を使用して、リポジトリのローカルミラーとして機能させます。新しい PR やイシューが発生するたびに、各アイテムは同じ形式に正規化され、localpager 独自の SQLite データベースに書き込まれます。アイテムが新規の場合、localpager はそれに対して分類ジョブを作成します。
  • ワーカーがそのキューからジョブを引き受けます。そして、イシューまたは PR のタイトル、本文、ラベル、著者、ステータス、およびオプションでコメント、変更されたファイル、選択された差分抜粋を含む GitHub コンテキストオブジェクトを構築します。つまり、ローカルモデルは通常、GitHub を閲覧したり URL を直接開いたりする必要はありません。関連するコンテキストがすべて渡されるのです。
  • コンテキストオブジェクトは、前節で説明した通りプロンプトに変換され、localpager-agent に渡されます。このエージェントは思考し reposhell を使用できますが、最終的には定義されたスキーマに従って分類結果を出力しなければなりません。
  • 出力は localpager SQLite データベースに保存され、ユーザーが設定した通知ポリシー(例:これらのトピックには通知するが、他のトピックには通知しない)に基づいて Discord に中継されます。

以下は、localpager の全体アーキテクチャを示す図です:

imageimage

このアーキテクチャは半自律型(semi-agentic)です。ラベル付けはエージェントによって行われますが、通知の送信は決定論的なルールによって処理されます。これは、タスクの中で最も単純な部分に対して推論が必要なくなることで、通知パイプラインを高速化するためです。ローカルでの推論は無料ですが、各タスクにはリソース競合のコストが伴います:GPU バンド幅は、推論が絶対に必要なタスクのために確保しておく必要があります。これにより、通知に関するエラーの発生確率も低減されます。

ローカルモデルで PR のトリアージは可能か?

率直に言いましょう:このシステムの最初のローカル版はノイズが多かったです。最初にテストされたモデルである gemma-4-e4b-it は、エンドツーエンドのローカルパイプラインを動作させるには有用でしたが、PR やイシューに対して関連性の低いラベルを付けすぎる傾向がありました。誤って付与されたラベルは Discord のフィードにノイズを生じさせ、私が注力すべき適切なイシューに集中できなくなります。このことが、以下の 330 行の評価セットにおいて、gemma-4-26b-a4b や qwen3.6-35b-a3b など、より大規模なローカルモデルのテストへと私たちを駆り立てました。

初期のプロンプト作業では、DeepSeek-V4-Flash を antirez の DS4 実装[^4]を通じて使用し、以前のデータセットラベルを作成しました。この設定では、CUDA 上の DS4 サーバーを利用していました。最終的に、DS4 は実行ごとに一貫したラベリングを行わないため、ラベラーとしての利用を断念しました。また、DS4 を主要なローカルページャーエージェントモデルとして採用しなかったのは、ハードウェア上で十分なスループットを得るには大きすぎたからです:DS4 サーバーは 1 秒あたり約 14 トークンの速度で、最大並行処理数は 1 でした。

モデルのパフォーマンスを検証するため、330 の GitHub イシューと PR を選択し、ラベルを生成しました。各項目は 5 回ラベル付けされ(GPT-5.5 を 3 回、Opus 4.8 を 2 回)、モデル間で合意が得られた場合にのみ採用されました。このプロセスには、手動による裁定、ラベル定義の改善、およびモデルに対する内部製品設計の選択を強調する作業が含まれていました。これにより、より小規模なモデルと比較するための安定した再現可能なラベルセットが得られました。

gemma-4-26b-a4b や qwen3.6-35b-a3b において、この評価セットで有用な結果を得る前にプロンプト最適化を行う必要はありませんでした。同じルーティングプロンプトを使用した場合、Gemma は再現率が高く、行あたりの実測時間が短かったのに対し、Qwen は精度が高く、完全一致率も高く、偽陽性も少なかったです。また、DeepSeek-V4-Flash を同じセットで参照として実行しました。このモデルは偽陽性が最も少なかったものの、モデルサイズとスループットの問題から、NVIDIA GB10 上でリアルタイムにこれらのタスクを実行するには現実的ではありません。各行には複数のラベルが含まれる可能性があるため、偽陽性と偽陰性は全行にわたる総ラベル数としてカウントされます。以下の Qwen の結果は、最終的な final_json を呼び出す前に出力トークンが不足して構造化出力に失敗した場合の再試行後のものです。Gemma と Qwen については、反復実行メトリクスは 3 回の実行における平均±標本標準偏差で報告されています。DeepSeek-V4-Flash は参照として 1 回のみ実行されました。

Metric

gemma-4-26b-a4b

qwen3.6-35b-a3b

DeepSeek-V4-Flash

Precision

0.716 ± 0.010

0.831 ± 0.007

0.938

Recall

0.905 ± 0.004

0.818 ± 0.006

0.714

F1

0.800 ± 0.008

0.824 ± 0.002

0.811

Exact match

0.410 ± 0.014

0.540 ± 0.014

0.509

False positives

227.0 ± 10.5

105.7 ± 6.4

30

False negatives

60.0 ± 2.6

115.3 ± 4.0

181

Wall seconds / row

1.41 ± 0.04

13.51 ± 0.79

144.14

Output tok/s / worker

25

50

13

Output tok/s aggregate

402.6

145.3

13

Concurrency

16

4

1

Total parameters

26B

35B

284B

Active parameters

4B

3B

13B

ここで示すスループットおよび実時間(wall-clock)の数値は、このハードウェア上でこれらのモデルが達成しうる絶対的な最大性能を示すものではありません。これらは当時利用可能な最適化を適用した際に使用した設定です。例えば、別の検証実験では、gemma-4-26b-a4b も並行度 32 をサポートし、1 秒あたり 700 トークンを超える集計出力トークンを達成しました。

image
image

330 行のラベルセット全体にわたるベンチマーク比較。各パネルは独自の縦軸スケールを使用しており、青色はその指標における最良値を示します。Precision(精度)および Recall(再現率)のエラーバーは、Gemma および Qwen の 3 回の実行におけるサンプル標準偏差を表しています。

Gemma ベンチマークでは、gemma-4-26b-a4b を vLLM でサーブし、このセットアップで利用可能な最適化を適用しました。その大きな要素の一つが NVFP4 量子化です。GB10 クラスの Blackwell ハードウェア上では、これは単にモデルファイルサイズが小さくなるだけでなく、ポータブルな GGUF 量子化(Q4_K_M など)よりも NVIDIA/vLLM の実行パスをより直接的に活用できるハードウェアフレンドリーな形式となります。実務的には、これによりメモリアクセス量が削減され、バッチ処理の余地が増加します。また、プレフィックスキャッシュ、FP8 KV キャッシュ、CUTLASS MoE バックエンド、および言語モデル専用モードも有効化しました。330 行分の完全な実行は、並行度 16 で約 7.5 分で完了しました。

OpenClaw を用いたリアルタイムパフォーマンスの追跡と検証

以前、新しい課題やプルリクエストごとにローカルモデルでジョブを実行するのではなく、OpenClaw で動作している SOTA クラウドモデル(例:GPT-5.5)をバッチ処理として n 時間ごと(例えば 2 時間ごと)に実行することで、同じ結果を得られる可能性について言及しました。[^5]

その場合、ChatGPT Pro プランが必要となります。このモデルは SOTA(State-of-the-Art:最先端技術)であるため、2 時間の課題やプルリクエストをまとめてバッチ処理しても、依然として十分に良好なパフォーマンスを発揮すると期待できます。

ローカル分類器が GPT-5.5 と比較してどの程度機能するかを確認するため、両者を同時に実行し、GPT-5.5 を判定者(ジャッジ)として、2 時間ごとに偽陽性(False Positives)と偽陰性(False Negatives)の検証を行います。

安全性を確保するため、OpenClaw のジョブはサンドボックス内で実行され、結果報告先の 公開リポジトリ へのアクセスのみが許可されています。具体的には、OpenClaw ジョブが機械可読なファイルを更新し、その後、シンプルなスクリプトが Codex が割り当てたラベルを読み取って偽陽性・偽陰性のステータスを計算します。出力例は以下の通りです:

偽陰性(False negatives)

  • 課題 #88499 openai-responses プロバイダー: store=false(デフォルト)時の previous_response_id で 404 エラーが発生

インベントリ領域:OpenAI 互換/プロキシ; ノティファイアトピック:agent_runtime, api_surface, sessions; 通知:なし

偽陽性(False positives)

  • プルリクエスト #88275 fix(models-config): models.json で apiKey を指定しないセルフホスト型プロバイダーを許可する (#88267)

ノティファイア関心度:i0; トピック:self_hosted_inference, local_model_providers, config; 通知:送信済み

  • PR #88266 リファクタリング:モデルカタログのコアパッケージを抽出

通知対象者:i1; トピック:設定、API サフェース、ローカルモデルプロバイダー; 通知:送信済み

  • PR #88247 機能追加:ホスト型モデルプロバイダーの追加

通知対象者:i0; トピック:ローカルモデルプロバイダー、モデルサービング、ドキュメント、API サフェース; 通知:送信済み

分類方法や機械可読ファイルの編集方法、スクリプトを使用して偽陽性(false positives)と偽陰性(false negatives)を取得する方法に関する手順は、2 時間ごとに実行される OpenClaw クロンジョブ で参照されている エージェントスキル に記載されています。その後、OpenClaw エージェントは新しい課題やプルリクエストをインポートし、適切なラベルをつけて JSON ファイルに追加し、スクリプトを実行して、同じ Discord チャンネルで報告を行います。これにより、数時間ごとにローカルモデルのパフォーマンスを観察でき、見落としが発生した際に通知を受け取ることができます。

結論

私たちは、issue/PR のトリアージタスクは、「高スループット・トリアージ」と呼ぶより広範なタスクセットの特定ケースであると捉えています。本稿では、ローカルモデルを用いてリアルタイムで情報をフィルタリングするアイデアを、オープンソースへの貢献という単一のドメインに限定して探求しました。gemma-4-26b-a4b や qwen3.6-35b-a3b といった中規模のローカルモデルが、ファインチューニングを一切必要とせずワンショット分類で高い精度を発揮できる能力は、よりコスト効率の高い従来の分類器モデルに移行する前に、迅速なプロトタイピングのための最初の選択肢として最適であることを示しています。

しかしながら、同じアプローチは他のドメインにも適用可能です:

  • 報道におけるニュースの分類
  • X や Reddit などのソーシャルメディアやフォーラムでの関心のある投稿のフィルタリング
  • カスタマーサポートチケットのトリアージ
  • コンテンツモデレーションへの異議申し立てのトリアージ
  • セールス活動中の潜在的なアウトリーチのフィルタリング
  • 研究における arXiv 上の特定トピックのフィルタリング

このリストはさらに拡張可能ですが、アイデアの本質は明確であると考えます。

トリアージ以外にも、安全に高速ローカルモデルを実行するエージェントハーンスを用いた分類の実現方法についても探求しました。このアプローチの適切な名称は「アジェンティック・クラシフィケーション(agentic classification)」です。これは、モデルが構造化データを返す前に、すべての情報を一度に与えられるのではなく、より多くの文脈を検索できるという特徴があります。この手法を完全に新規のものと呼ぶことはできませんが、本ブログ記事が特定の Pi+ 制限付きシェル + final_json のレシピに関する良い参照資料となることを願っています。

この投稿のユースケースにおいて、PR/Issue を分解し、プロダクトの表面を正しく理解してラベル付けする方法は困難な問題であることが判明しました。

テストではそうではありませんでしたが、モデルが次のステップとして情報を収集するために外部分類器を使用するという結論を下すことは非常に合理的です。エージェント型のアプローチと従来のアプローチは排他的なものではありません。

トピックの完全リストおよびその他の設定についてはこちらをご覧ください。

私たちは antirez/deepseek-v4-gguf から DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2.gguf を使用しました。

LLM(大規模言語モデル)をジャッジとして使用することが「無料」という側面を否定することを知っていますが、私たちの特定のこの実装は研究目的で行っています。実際には、試行期間中により大型で高価なモデルを併用してキャリブレーションを行い、その後システムを完全に小型モデルへ移行させることができます。最近の実行では、この監査ループは 2 時間のチェックあたり合計約 40k の GPT-5.5 トークンを消費しました(主にキャッシュされたコンテキスト)。API 価格では 1 回あたり約 2〜3 セント、1 日 12 回の実行で月間約 9 ドルでした。これはすべての新規アイテムにわたる単一のバッチ監査であり、各アイテムごとにジャッジを呼び出すものではありません;これを各アイテムごとに行うと、コストは数倍になる可能性があります。

原文を表示

Back to Articles

**Free as in beer, excluding the cost of electricity, and assuming you already own the hardware*

June 2026 will go down as the moment that people realized closed models can be taken away. With the removal of Anthropic's latest flagship model Claude Fable 5 fresh in memory, one can see why it is more important than ever to own your AI stack and be able to run models locally, especially if you are building your business on top of AI.

In that light, we wanted to share how we use local models like Gemma and Qwen in an agent harness, to run classification tasks[^1]. This approach is different from using a model like BERT for classification. A local model in an agent harness like Pi can be used in tandem with structured outputs, to assign labels. We chose this approach because we already had local models and the harness on hand, and have conviction that similar setups will increase in popularity as local models improve in capability.[^2]

Our starting point was open source contributions in the OpenClaw repo. OpenClaw gets hundreds of issues and PRs every day, which need to be triaged, prioritized and routed to maintainers. I, Onur, am working to make local models work well with OpenClaw. Being a maintainer of this specific vertical, I need to react quickly to any P0 issues.

With SOTA closed models like GPT-5, Opus, or Sonnet, this is a pretty straightforward task. But I happen to sit on 128 GB of unified memory, namely an NVIDIA GB10. So I took on the task:

Can I build a real-time notification system that filters and notifies me for only the issues that I am responsible for... with local open-weight models?

This tiny box, a.k.a. DGX Spark, can run gemma-4-26b-a4b with high concurrency and generate hundreds of tokens per second.
This tiny box, a.k.a. DGX Spark, can run gemma-4-26b-a4b with high concurrency and generate hundreds of tokens per second.

If I set up my OpenClaw main agent running on a $200/mo ChatGPT Pro plan to trigger a job on every new issue or PR, that would use up my quota. I might instead set it to run every 2 hours, or 6 hours. This would batch issues over longer periods, so we would be trading real-time notifications for delayed processing.

If I were to run this on a local model on the hardware I already have up and running, I would not only have near-instantaneous notifications, I would also be able to do it for free (or rather, for the cost of electricity).

Categorizing issues and PRs

We came up with a finite set of labels representing the categories of issues we need to triage, and then use a local model to classify each issue into one of those categories, like local_models, self_hosted_inference, acp, agent_runtime, codex, ui_tui and so on.[^3]

But how do we classify pull requests? A simple single request to a Chat Completions endpoint with a tool JSON schema, with the topics as an enum?

Kind of. But this is 2026, not 2023, and we have AGENTS. We can do better!

For the local model choices, we tested gemma-4-26b-a4b and qwen3.6-35b-a3b. With performance optimizations, both can generate hundreds of tokens per second locally.

We use an agent harness to drive the classification run. For this, we bundle pi as a harness that can call local model endpoints.

The agent by default receives the PR title, body and a truncated excerpt of the PR diff in the first prompt. Then, it can choose to use the bash tool to perform read-only operations on the OpenClaw repo (in case it needs to look at the codebase), or the final_json tool to submit the final classification result.

You wouldn't want to give full bash access to a local model running in this high-throughput setting, because a prompt-injected issue or PR could otherwise steer the model into doing something unrelated to classification.

For that reason, we use reposhell instead of bash: a restricted bash-like shell that only allows read-only operations (ls, find, cat, grep, etc.) on the OpenClaw repo. The model thinks it is using bash, but any operation that is not allowed is rejected:

code
reposhell bound cwd=/repo/openclaw repos=openclaw
type help for allowed commands; exit or quit to leave

reposhell /repo/openclaw> help
allowed: pwd, ls, find, rg, grep, sed -n, cat, head, tail, wc -l, git status --short, git show --name-only, git grep, git ls-files
search: rg -n -i "lm studio" or grep -R -n -i "lm studio" .
files: rg --files -g "*.ts" or git ls-files src
examples: rg -n reposhell README.md | sed is not allowed; use one simple command at a time

reposhell /repo/openclaw> head README.md
# 🦞 OpenClaw — Personal AI Assistant

<p align="center">
    <picture>
        <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/openclaw/openclaw/main/docs/assets/openclaw-logo-text-dark.svg">
        <img src="https://raw.githubusercontent.com/openclaw/openclaw/main/docs/assets/openclaw-logo-text.svg" alt="OpenClaw" width="500">
    </picture>
</p>

<p align="center">

reposhell /repo/openclaw> curl localhost
reposhell policy denied command: unsupported command "curl"
exit_code=2

reposhell /repo/openclaw>

Here is a concrete example where this mattered. In one saved session example, qwen3.6-35b-a3b was classifying openclaw/openclaw#84621, titled Fix Kimi tool-call rewriting stop reason handling. The thinking block shows the model initially considering coding_agent_integrations because the changed path extensions/kimi-coding made it look plausible. The model used reposhell to inspect the local repo with simple read-only commands like ls extensions, ls extensions/kimi-coding, and cat extensions/kimi-coding/package.json. That package metadata showed the extension was actually @openclaw/kimi-provider, an OpenClaw Kimi provider plugin. So the model corrected the final labels to inference_api and tool_calling, and explicitly excluded coding_agent_integrations.

We have mentioned earlier that we bundle a specific pi configuration that can only perform read-only operations and return classification output. We call it localpager-agent, named after localpager, the main project here. Each PR and issue generates a prompt, which is then passed to the CLI like below, alongside other args:

code
localpager-agent \
  --model "<model-id>" \
  --base-url "<openai-compatible-base-url>" \
  --session-dir "<session-output-dir>" \
  --final-schema "<runtime-schema.json>" \
  --tools bash,final_json \
  --reposhell-socket "<reposhell.sock>" \
  --reposhell-default-repo "<repo-id>" \
  --reposhell-visible-repos "<repo-id>[,<repo-id>...]" \
  -p "$(cat <rendered-prompt.md>)"

Processing incoming PRs and issues

So then what orchestrates everything in between the incoming PR/issue and the final notification on Discord?

This is what the final filtered Discord notification looks like: a PR about the desired vertical gets routed to me.
This is what the final filtered Discord notification looks like: a PR about the desired vertical gets routed to me.

The orchestration around this is very simple; only the classification step involves an LLM:

  • We use openclaw/gitcrawl to act as a local mirror for the repo. Whenever there is a new PR or issue, each item is normalized into the same shape and written into localpager's own SQLite database. If the item is new, localpager creates a classification job for it.
  • A worker then claims jobs from that queue. It builds a GitHub context object containing the issue or PR title, body, labels, author, state, and optionally comments, changed files, and selected diff excerpts. That means the local model does not need to browse GitHub or open the URL itself most of the time. It is handed all the relevant context.
  • The context object is rendered into a prompt and passed to localpager-agent as described in the previous section. The agent can think and use reposhell, but must eventually output a classification result in the defined schema.
  • The output is stored back in localpager SQLite database, and relayed to Discord based on the notification policy configured by the user (i.e. notify me for these topics, but not these other ones).

Below is a figure showing the overall architecture of localpager:

Localpager architecture
Localpager architecture

The architecture is semi-agentic. Labeling is done agentically, while sending a notification is handled by deterministic rules. This is to make the notification pipeline faster by removing the need for inference for the most straightforward parts of the task. Local inference is free but each task has a resource contention cost: GPU bandwidth should be reserved for tasks where inference is absolutely needed. This also reduces chance of errors from notification.

Can local models triage PRs?

Let's be frank: the first local versions of this system were noisy. The first model tested - gemma-4-e4b-it was useful for getting the end-to-end local pipeline working, but it also had a tendency to put too many unrelated labels on a PR or issue. False positive labels make the Discord feed noisy and don't focus my attention on the right issues. That pushed us toward testing larger local models, including gemma-4-26b-a4b and qwen3.6-35b-a3b, on the 330-row evaluation set below.

For early prompt work, we also used DeepSeek-V4-Flash through the antirez DS4 implementation[^4] to create the earlier dataset labels. That setup used the DS4 server over CUDA. We eventually gave up on DS4 as the labeler because it was not labeling consistently across runs. We also did not consider it as the main localpager-agent model because it was too big to get enough throughput on our hardware: the DS4 server gave us around 14 tokens per second, with maximum concurrency of 1.

To test model performance, we selected and generated labels for 330 GitHub issues and PRs. Each item was labelled five times (3x GPT-5.5 and 2x Opus 4.8) with the models needing to be in agreement to be accepted. This process involved hand adjudicating, improving label definitions and highlighting internal product design choices for the models. This gave us a set of stable, reproducible labels to compare our smaller models against.

We did not need to do prompt optimization for gemma-4-26b-a4b or qwen3.6-35b-a3b before getting useful results on this evaluation set. Using the same routing prompt, Gemma had higher recall and lower wall-clock time per row, while Qwen had higher precision, higher exact match, and fewer false positives. We also ran DeepSeek-V4-Flash on the same set as a reference. It had the fewest false positives, but the model size and throughput make it impractical for executing these tasks in real time on the NVIDIA GB10. Since each row can have multiple labels, false positives and false negatives are total label counts across all rows. The Qwen results below are after retrying structured-output failures where the model ran out of output tokens before calling final_json. For Gemma and Qwen, repeated-run metrics report mean ± sample standard deviation across three runs. DeepSeek-V4-Flash was run once as a reference.

Metric

gemma-4-26b-a4b

qwen3.6-35b-a3b

DeepSeek-V4-Flash

Precision

0.716 ± 0.010

0.831 ± 0.007

0.938

Recall

0.905 ± 0.004

0.818 ± 0.006

0.714

F1

0.800 ± 0.008

0.824 ± 0.002

0.811

Exact match

0.410 ± 0.014

0.540 ± 0.014

0.509

False positives

227.0 ± 10.5

105.7 ± 6.4

30

False negatives

60.0 ± 2.6

115.3 ± 4.0

181

Wall seconds / row

1.41 ± 0.04

13.51 ± 0.79

144.14

Output tok/s / worker

25

50

13

Output tok/s aggregate

402.6

145.3

13

Concurrency

16

4

1

Total parameters

26B

35B

284B

Active parameters

4B

3B

13B

The throughput and wall-clock numbers here are not definitive maximum performance numbers for these models on this hardware. They are the settings we used at the time with the optimizations we had available. For example, in a separate probe, gemma-4-26b-a4b also supported concurrency 32 and reached over 700 aggregate output tokens per second.

Benchmark comparison across the 330-row label set. Each panel uses its own vertical scale; blue marks the best value for that metric. Error bars on Precision and Recall show sample standard deviation across three runs for Gemma and Qwen.
Benchmark comparison across the 330-row label set. Each panel uses its own vertical scale; blue marks the best value for that metric. Error bars on Precision and Recall show sample standard deviation across three runs for Gemma and Qwen.

For the Gemma benchmark, we served gemma-4-26b-a4b with vLLM using the optimizations we found available for this setup. A big part of that is the NVFP4 quantization: on GB10-class Blackwell hardware, it is not just a smaller model file, but a hardware-friendly format that can use the NVIDIA/vLLM execution path more directly than a portable GGUF quantization like Q4_K_M. In practice, that means less memory traffic and more room for batching. We also enabled prefix caching, FP8 KV cache, the CUTLASS MoE backend, and language-model-only mode. The full 330-row run finished in about 7.5 minutes at concurrency 16.

Tracking and validating real-time performance using OpenClaw

We have mentioned earlier that instead of running a job with a local model for every new issue or PR, we can run a batch job with a SOTA cloud model, like GPT-5.5 running in OpenClaw, every n hours (e.g. every 2 hours) to achieve the same end.[^5]

In that case, we would need a ChatGPT Pro plan. Since the model is SOTA, we can still expect it to perform reasonably well, despite batching 2 hours of issues/PRs together.

Because we want to see how well the local classifier performs against GPT-5.5, we run both simultaneously, and let GPT-5.5 be the judge of false positives and negatives, every 2 hours.

To be safe, we run the OpenClaw job in a sandbox, with only access to the public repo we report results to. In our case, we let the OpenClaw job update a machine-readable file, then a simple script reads the Codex-assigned labels and computes the false positive/negative status. Example output:

False negatives

Issue #88499 openai-responses provider: 404 on previous_response_id when store=false (default)

inventory area: OpenAI-compatible/proxy; notifier topics: agent_runtime, api_surface, sessions; notification: none

False positives

PR #88275 fix(models-config): allow self-hosted providers without apiKey in models.json (#88267)

notifier interest: i0; topics: self_hosted_inference, local_model_providers, config; notification: sent

PR #88266 refactor: extract model catalog core package

notifier interest: i1; topics: config, api_surface, local_model_providers; notification: sent

PR #88247 feat: add hosted model providers

notifier interest: i0; topics: local_model_providers, model_serving, docs, api_surface; notification: sent

The instructions on how to classify, edit the machine-readable file, get the false positives and false negatives using a script are present in an agent skill which is referenced in an OpenClaw cron job that runs every 2 hours. The OpenClaw agent then ingests any new issues or PRs, adds them to the JSON file with appropriate labels, runs the scripts and reports back in the same Discord channel. This way, we can observe the local model's performance every few hours, and get notified of the misses.

Conclusion

We think that the issue/PR triage task is a specific case of a broader set of tasks which we call "high throughput triage". This post explored the idea of using a local model to filter out information in real time in only one domain, that is, open source contributions. The ability of medium-sized local models like gemma-4-26b-a4b and qwen3.6-35b-a3b to one-shot classify with good accuracy without any need for fine-tuning makes them a good first choice for quick prototyping, before one moves on to more cost-efficient traditional classifier models.

However, the same approach can be applied to other domains as well:

  • News categorization in journalism
  • Filtering for posts of interest in social media and forums like X or Reddit
  • Triaging customer support tickets
  • Triaging content moderation appeals
  • Filtering potential outreach while doing sales
  • Filtering for certain topics on arXiv while doing research

The list can be extended, but we think that the idea should be clear.

Besides triaging, we have also explored how classification can be performed with agent harnesses running fast local models in a secure manner. A good naming for the approach would be *agentic classification*: the model is not fed the entire body of information upfront, but can search for more context before returning structured data. While we cannot exactly call this a novel approach, we hope for this blog post to be a good reference for the specific Pi+a restricted shell+final_json recipe.

[^1]: For the use case in this post, we have discovered that breaking down a PR/Issue in a way that means the product surface is understood and labelled correctly is a hard problem.

[^2]: Although in our testing we didn't---it would be quite reasonable for a model to conclude a next-step to gather info, use an external classifier. The agentic approach and the traditional approach are not mutually exclusive.

[^3]: See full list of topics and other configuration here

[^4]: We used DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2.gguf from antirez/deepseek-v4-gguf.

[^5]: While we are aware that using an LLM as a judge negates the "free" aspect, our specific implementation does this for research purposes. In practice, a bigger and more expensive model can be used in tandem during a trial period for calibration, after which the system would transition fully to the smaller one. In recent runs, this audit loop used roughly 40k total GPT-5.5 tokens per 2-hour check, mostly cached context, costing about 2-3 cents per run at API pricing, or roughly $9/month at 12 runs per day. This was a single batch audit across all new items, not one judge call per item; doing it per item would likely be several times more expensive.

この記事をシェア

関連記事

Hugging Face Blog★42026年6月22日 22:18

Hugging Face に PP-OCRv6 を公開:150 万パラメータから 3450 万パラメータへ拡張した 50 カ国語対応 OCR

Hugging Face が、PP-OCRv6 モデルを公開しました。このモデルは、パラメータ数を 150 万から 3450 万に増やすことで、50 の言語に対応する高精度な OCR(光学文字認識)機能を実現しています。

Hugging Face Blog★42026年6月18日 09:00

エージェント性は十分か?独自ツールを用いたオープンモデルのベンチマーク調査

Hugging Face が、独自に構築したツール環境において、オープンソースモデルがどれほど「エージェント性」を発揮できるかを評価するベンチマーク手法を発表しました。

Hugging Face Blog★42026年6月17日 19:18

Hugging Face Hub からロボットハードウェアへ:Strands Agents と LeRobot の連携

Hugging Face が、同社のプラットフォーム上で開発された Strands Agents および LeRobot を活用し、AI モデルを直接ロボットハードウェアに展開する取り組みを発表した。

今日のまとめ

AI日報で今日の重要ニュースをまとめ読み

ニュース一覧に戻る元記事を読む