Skip to content

ローカル LLM によるセッション・トリアージ(spec + 実装 + 実施結果) - #297

Open
tanimon wants to merge 15 commits into
mainfrom
docs/local-llm-session-triage-spec
Open

ローカル LLM によるセッション・トリアージ(spec + 実装 + 実施結果)#297
tanimon wants to merge 15 commits into
mainfrom
docs/local-llm-session-triage-spec

Conversation

@tanimon

@tanimon tanimon commented Aug 28, 2026

Copy link
Copy Markdown
Owner

概要

滞留する未 reflect セッション(240 件)を、ローカル LLM の一次スクリーニングで処理可能な件数まで絞り込む 3 層トリアージの spec・実装計画・実装・実施結果。

  • Layer 1(決定論・TypeScript): transcript → ダイジェスト(391 倍圧縮、202 件で計 59 万トークン)
  • Layer 2(ollama qwen3:8b): ダイジェスト 1 件 → JSON スキーマ強制の判定を triage.jsonl に追記のみ
  • Layer 3(Claude): レポート上位の evidence だけ読んで queue.md へ(接続試験済み・1 エントリ投入)

主な実施結果(詳細は results doc)

  • ベースライン①: ダイジェスト全 202 件が 1M コンテキストに収まる(Layer 2 の価値はコスト・プライバシー側)
  • Layer 2 (プロンプト v2): 低シグナル層 recall 100% (3/3) だが偽陽性 8/11。バッチ 40 件では 85% を true 判定し、絞り込みとしてはまだ弱い(正直に記録)
  • 8B/14B は recall 同値(ただし n=3 で識別力なし)→ スループットで 8B 採用

実装ノート

  • ビルドなし・依存ゼロの TypeScript(Node v24 型ストリッピング)。テストは node:test(just test-triage、CI ジョブ追加済み)
  • pending.jsonl は全スクリプトで読み取り専用(SessionEnd hook の並行追記と衝突しない)
  • 計画からの逸脱: batch.ts に import.meta.main ガード(テスト import でバッチが走る欠陥回避)、temperature 0 の反復縮退への retry フォールバック、gold set ラベルは人手ではなく Claude がダイジェストのみで付与

チェックリスト

  • just lint 通過(test-triage 13 tests 含む)
  • CI に triage-tests ジョブ追加(actionlint / zizmor 通過)
  • just scan-sensitive 通過(結果 doc に work-org パス・アカウント名なし)

🤖 Generated with Claude Code

tanimon and others added 15 commits August 27, 2026 18:27
開発合宿(6時間)でローカルLLMを使い、滞留している未reflectセッション
238件のトリアージを自動化する設計。

3層構成でローカルLLMは中央のみを担当する:
- Layer 1(決定論): transcriptのダイジェスト化。実測29MB→数十KB
- Layer 2(ローカルLLM): 1件1判断をJSONスキーマ強制で。triage.jsonlへ追記のみ
- Layer 3(Claude): Layer 2が指した根拠箇所だけを読みqueue.mdへ

pending.jsonlはLayer 2から構造的に触らせない(SessionEnd hookの並行追記
との競合を防ぐ)。評価はgold set 20件で、正解率ではなくrecallと偽陽性数を
別々に追う。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
TypeScript(依存ゼロ・ビルドなし)を採用。既存の statusline-command.ts が
node --experimental-strip-types で動いている前例に従う。Node v24系のため
型ストリッピングは既定で有効。oxlint/oxfmt が js_ts_files を自動で拾うため
lintにも自動で乗る。テストは node:test(標準搭載)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6時間の合宿を9タスクに分割。各タスクに時間枠と打ち切り時の退避策を持たせ、
最低ラインを「238件のダイジェスト化 + 40件以上の分類 + gold setの数字」に
置いた。

TDDの対象は決定論的な部分(transcriptパース、シグナル集計、バッチの
レジューム)に限定し、LLMを含む部分はgold setによる実測で代替する。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- justfileのtest-triageをグロブからディレクトリ指定に変更。まだ存在しない
  テストファイルにマッチせずzshが no matches found で落ち、Task 2以降
  just lintが赤いままになる問題を回避
- 合宿中はソースツリーから直接実行し、デプロイ済みコピーに依存しないことを
  Global Constraintsに明記
- calibrate.tsを追加。ベースライン①(ダイジェスト合計トークン数)を概算のまま
  残さず、ollamaのprompt_eval_countで較正して実測ベースにする

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
temperature 0 での反復縮退ループ(ollamaが応答を打ち切り不完全JSONが返る)への
リトライフォールバックを含む。プロンプトはgold set評価で「全件true」の定数分類器に
なったv1から、作業対象コードとエージェントプロセスの区別を明示したv2に調整済み。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
計画からの変更: CLI本体を import.meta.main で括った。テストが
loadProcessedIds を import しただけでバッチ全体(ollama呼び出し)が
走ってしまうため。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- lint.yml はレシピごとに独立ジョブを持つ構成のため、justfile の lint 依存に
  足すだけでは CI でテストが一度も走らない穴があった
- evaluate.ts の 238 件ハードコードを digests/ の実件数に置換
- 結果ドキュメント: 202 件換算の推定時間、n=3 の識別力の但し書き、
  pending.jsonl 未削除が次回 reflect で重複エントリを生む帰結を明記

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- classify.ts: v2評価で観測した偽陽性の典型(作業対象コードの発見・検証作業・
  セッション内文書化済みの事故)を反例として明示し、「ルール」の範囲を
  エージェント自身への指示に限定、severityのアンカーを定義
- report.ts: ランキングを severity+シグナル数の複合キーに変更し、comparator を
  export して node:test を追加。CLI 本体は import.meta.main でガード(import 時に
  CLI が走る batch.ts と同種の欠陥があった)
- evaluate.ts: severity 分布の出力を追加(縮退をその場で検知)
- pick-gold.ts: --extend モードを追加(既存 gold set を除外した追加抽出)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- gold set を40件に拡張(--extend、低シグナル陰性の検出力を倍増)
- v3系プロンプト3イテレーション: 低シグナル偽陽性 8/11→1/11(同一14件のlike-for-like)、
  severity縮退解消(medium 12 / high 6)
- ただしプロンプト単独では recall が 3/3→2/3 に退行し、3回の調整でも
  割り込み→言い直しクラスを8Bに安定して持たせられなかった
- 対策として Layer 3 候補選択を「LLM true ∪ interrupts>=1」の複合ルールに変更
  (isLayer3Candidate)。gold set 上 interrupts>=1 は 5/5 が真陽性・全体19/202件。
  複合ルールで低シグナル recall 3/3 を回復し合格基準を達成
- ベースライン②比較はLLM単独判定のみで数える(オーバーライド混入は
  シグナル規則の選出でLLMの上乗せを水増しする自己矛盾のため)
- evaluate.ts はLLM単独と複合ルールの両方を出力

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant