予測フック
予測フック
フックを使うと、Laya をフォークすることなく、すべての意思決定を観察・制御できます。
フックは、実際のデプロイが必ず必要とするもののための拡張点です。監査ログ、推論前の PII 秘匿化、キャッシュ、メトリクス、信頼度ゲート、ルーティングの上書き、外部サービスへの意思決定の転送。これらはオプトインです。フックを何も設定しなければ、Agent・Router・ONNXAgent の挙動は変わりません。
直接呼び出しのためだけのものではありません。各 LangChain と LangGraph の Runnable は同じ 5 つの呼び出しごとの引数を受け取るので、エージェント全体ではなくグラフの 1 ノードにフックを付けられます。
このフォルダが完全なリファレンスです。ここから始めて、必要なページへ進んでください。
| ページ | 内容 |
|---|---|
| API リファレンス | すべてのクラス・フィールド・パラメータ・既定値 |
| ライフサイクル | 各フックが実行される正確なタイミング(フローチャート付き) |
| エラー | hooks_raise、on_error、例外チェーン、失敗行列 |
| パターンとアンチパターン | やるべきこと、避けるべきこと、その理由 |
| 例 | すべてのユースケース向けのコピー&ペースト集 |
| トレーシング | run_id、span 相関、OpenTelemetry |
クイックスタート
import laya
def log(ctx):
print(ctx.model, ctx.results[0]["answers"], ctx.elapsed_ms)
agent = laya.load("convaiinnovations/laya", on_predict_end=log)
agent.system_one("I was charged twice.", {"urgent": {"type": "noul", "instructions": "Urgent?"}})
オブジェクトはライフサイクルイベントの任意の部分集合を実装できます。
class Audit:
def on_predict_start(self, ctx):
print("start", ctx.run_id)
def on_predict_end(self, ctx):
print("end", ctx.run_id, ctx.usage, ctx.elapsed_ms)
def on_error(self, ctx):
print("failed", ctx.run_id, ctx.error)
laya.load("convaiinnovations/laya", hooks=[Audit()])
フックは後から追加したり、ブロックにスコープしたりもできます。
agent.add_hook(tracer) # attach at runtime
with agent.hooks_installed(debug): # installed for the block, removed on exit
agent.system_one(state, questions)
実行時登録を参照してください。すべての呼び出しに通さずにどこでも適用したいフックは、プロセス全体の既定値で一度登録します。
from laya import hooks
hooks.set_default_hooks(hooks=[Tracer()])
メンタルモデル
考え方は 3 つです。
-
フックは callable かオブジェクトです。 単純な関数は 1 つのイベントに便利で、オブジェクトは複数のイベントに便利です。どちらも
hooks=/on_predict_start=/on_predict_end=に渡します。 -
1 回の呼び出しのすべてのフックが 1 つの可変な
PredictContextを共有します。 そこには states・questions・results・ルーティング判断・モデル名・usage・タイミング・エラーが入ります。1 回の呼び出しは多数の state を同時に運べるので(predict_batch)、すべての意思決定を対象にしたいフックはctx.statesとctx.resultsを反復する必要があります。ctx.usageとctx.elapsed_msはその呼び出しの合計です。コンテキストは可変なので、フックは呼び出しを観察するだけでなく形成できます。state を秘匿化し、questions を書き換え、result を差し替え、キャッシュした答えで推論をスキップできます。 -
スコープは 2 つあります。
Agentのフックはフォワードパスを包み、Routerのフックはルーティングと推論を包み、モデルのライフサイクル(on_route、on_load、on_evict)も見られます。これは他のエージェントフレームワークにおける「run フック」と「agent フック」の分割に対応します。
Router.predict(state, questions)
┌──────────────────────────────────────────────────────────────────────────┐
│ route() │
│ ├─ detect language / workflow │
│ └─ on_route ctx.decision (a hook may replace it) │
│ │
│ load(decision.model) │
│ ├─ build checkpoint on first use ──► on_load ctx.model, ctx.agent │
│ └─ evict LRU checkpoint ───────────► on_evict ctx.model │
│ │
│ on_predict_start ctx.states, ctx.questions, ctx.decision │
│ │ │
│ ├── ctx.skip(results)? ──► skip the forward pass │
│ │ │
│ └── Agent.system_one(...) ──► Agent-level hooks run here │
│ on_predict_start ─► forward ─► on_predict_end │
│ │
│ result["routing"] = decision │
│ on_predict_end ctx.results, ctx.usage, ctx.elapsed_ms │
└──────────────────────────────────────────────────────────────────────────┘
any failure on the way ──► on_error, then on_predict_end
スコープの一覧
Agent / ONNXAgent |
Router |
|
|---|---|---|
on_predict_start |
あり | あり |
on_predict_end |
あり | あり |
on_error |
あり | あり |
on_route |
なし | あり |
on_load |
なし | あり |
on_evict |
なし | あり |
laya.serve と MCP サーバーは Router.predict を呼ぶので、Router のフックは自動的に発火します。Agent のフックは、Router が付属または内蔵のエージェントを実行するたびに発火します。
互換性
- フックを何も設定しなければ挙動は変わりません。未設定の経路は回帰テストされています。
- すべてのフックパラメータは既定値付きのキーワード引数なので、既存の呼び出しはそのまま動きます。
laya/hooks.pyは純粋な Python です。import layaがこれを理由に torch を引き込むことはありません。- フックは既定で同期です。
async defのイベントはAsyncHookで包むか、そのまま非同期 callable として渡せます。完走はランタイムが行います。 hooks_timeoutは遅いフックを制限し、配信中のリクエストをハングさせないようにします。- フックは速く、ノンブロッキングに保ってください。
laya.serveへの影響はエラーとパターンにあります。
関連項目
examples/hooks/:実行可能な audit・redact・cache・metrics フック。tests/test_hooks.py:挙動の仕様。tests/test_hooks_api.py:API 安定性のガード。laya/hooks.py:実装。