Forge guardrails入門:ローカル8Bモデルのエージェント精度を53%→99%に引き上げるオープンソースガードレールフレームワーク
Forge guardrailsとは ForgeはTexas InstrumentsのAI DirectorであるAntoine Zambelliが開発したオープンソースのPythonフレームワーク(MITライセンス)で、ローカルLLMのエージェントタスク精度を劇的に向上させる。その主張はシンプルで強力だ:ローカルLLMの信頼性問題はモデル問題ではなくフレームワーク問題である。 2026年5月のShow HNでデビューし、686ポイント・252コメントを獲得、7日間にわたってHNフロントページを維持した。ACM CAIS 2026(サンノゼ、5月26-29日)でも論文が採択されており、97のモデル/バックエンド構成、18シナリオ、各50回の実験に基づく評価結果が学術的に裏付けられている。 なぜローカルLLMのエージェント精度が低いのか 8BクラスのローカルLLMをエージェントとして使うと、生の状態では精度が53%程度に留まる。これはモデルの知識不足ではなく、推論ループのエラーハンドリング不足が原因だ。Forgeの開発チームが発見した最も驚くべき事実は、同一のモデル重みでもバックエンド(推論サーバー)の違いによって7%〜83%の精度差(76ポイント差) が生じるという点である。モデル自体の改善ではなく、推論パイプラインの設計次第で精度が大きく変わることを示している。 5層のガードレールアーキテクチャ Forgeはモデル自体を一切変更せず、推論ループのラッパーとして5層のガードレールを挿入する。 1. リトライナッジ(Retry Nudges) ツール呼び出しが失敗した際に、失敗理由を説明して最大3回まで再試行させる。アブレーション実験ではこのレイヤーを無効にすると24〜49ポイントの精度低下が発生する — Forge全体で最も影響の大きいレイヤー。 2. ステップ強制(Step Enforcement) ワークフローにrequired_stepsとprerequisitesを定義し、依存関係のあるツールの実行順序を強制する。たとえば「検索→参照→回答」のような必須フローを守らせる。 3. エラー回復(Error Recovery) ツール実行エラー(例外・タイムアウト等)をモデルにフィードバックし、自己修復を促す。約10ポイントの精度貢献。 4. レスキュー解析(Rescue Parsing) JSONコードフェンスの誤記、Mistral括弧記法の混入など、フォーマット異常を救済する。あらゆるモデル・バックエンドで発生する問題に対応。 5. VRAM認識コンテキスト管理 nvidia-smiを参照してVRAM残量に応じたトークン予算を動的計算する。古いターンの階層的圧縮(Tiered Compaction:最新2ターンを完全保持、古いターンを予算内に圧縮)により、CPUフォールバックを防止する。 3つのデプロイモード Forgeは導入パターンに応じて3つのモードを提供する。 モード ユースケース 特徴 WorkflowRunner 新規プロジェクト バッテリー同梱。ツール定義・バックエンド接続・ガードレールを一貫提供。SlotWorkerによるマルチエージェントGPU共有スロット管理を含む Proxyサーバー 既存ツールチェーンへの透過導入 OpenAI互換API + Anthropic Messages API対応。opencode・Continue・aider・Claude Codeと連携可能 ガードレールMiddleware 独自オーケストレーションループ ResponseValidator・StepEnforcer・ErrorTrackerを個別コンポーネントとしてimport コード例で見る3パターン WorkflowRunner:最小構成 import asyncio from pydantic import BaseModel, Field from forge import ( Workflow, ToolDef, ToolSpec, WorkflowRunner, OllamaClient, ContextManager, TieredCompact, ) def get_weather(city: str) -> str: return f"72°F and sunny in {city}" class GetWeatherParams(BaseModel): city: str = Field(description="City name") workflow = Workflow( name="weather", description="Look up weather for a city.", tools={ "get_weather": ToolDef( spec=ToolSpec( name="get_weather", description="Get current weather", parameters=GetWeatherParams, ), callable=get_weather, ), }, required_steps=[], terminal_tool="get_weather", system_prompt_template="You are a helpful assistant.", ) async def main(): client = OllamaClient( model="ministral-3:8b-instruct-2512-q4_K_M", recommended_sampling=True, ) ctx = ContextManager( strategy=TieredCompact(keep_recent=2), budget_tokens=8192, ) runner = WorkflowRunner(client=client, context_manager=ctx) await runner.run(workflow, "What's the weather in Paris?") asyncio.run(main()) Proxyモード:ツール透過導入 # 自分でllama-serverを起動して連携 python -m forge.proxy --backend-url http://localhost:8080 --port 8081 # クライアント側(OpenAI互換API) from openai import OpenAI client = OpenAI(base_url="http://localhost:8081/v1") # → 以降、通常のOpenAI API呼び出しでForgeガードレールが透過適用 # Claude Code連携 ANTHROPIC_BASE_URL=http://localhost:8081 ANTHROPIC_AUTH_TOKEN=anything claude Middleware:独自ループへの組み込み from forge.guardrails import Guardrails guardrails = Guardrails( tool_names=["search", "lookup", "answer"], required_steps=["search", "lookup"], terminal_tool="answer", ) while True: response = my_custom_llm_call(messages) result = guardrails.check(response) if result.action == "retry": messages.append({"role": result.nudge.role, "content": result.nudge.content}) continue if result.action == "step_blocked": messages.append({"role": "user", "content": result.nudge.content}) continue if result.action == "fatal": raise RuntimeError(result.reason) execute(result.tool_calls) if guardrails.record([tc.tool for tc in result.tool_calls]): break ベンチマークとコスト Forgeの評価ハーネスは以下の結果を公表している: ...