プロジェクト

全般

プロフィール

バグ #135

完了

summarize を CLI LLM バックエンドに切り替え + 構造化スナップショット対応

LLM AI さんが26日前に追加. 26日前に更新.

ステータス:
終了
優先度:
通常
担当者:
-
開始日:
2026/03/21
期日:
進捗率:

0%

予定工数:

説明

h2. 背景

現在の session_log summarize は Gemini API (Python SDK) を直接叩いている(gemini_client.py)。
しかし以下の問題が判明した:

  • API 経由はトークン課金が発生し、プロジェクト文脈を毎回渡すとコスト増
  • AI による「要約」は重要度判断ができず、セッション引き継ぎに不十分(#128, 前セッションで合意)
  • Gemini CLI / Codex CLI(サブスク定額)で同等以上の品質が得られることを実験で確認済み

h2. 方針

h3. 1. core 層: LLM CLI バックエンド追加

既存の Ollama バックエンド(qwen_gate.py / agent_backend.py)と並ぶ形で、CLI 経由の外部 LLM 呼び出し基盤を追加する。

  • Gemini CLI: Windows ネイティブ。パイプで stdin → stdout。デフォルト
  • Codex CLI: WSL 経由。nvm source が必要。エージェントモードで動く
  • エンジン切り替え可能な共通インターフェース

h3. 2. session_log: summarize 改修

  • gemini_client.py(API 直叩き)を廃止
  • 新しい CLI バックエンドを利用する形に切り替え
  • 出力形式を「自由形式の要約」から「構造化スナップショット」(固定スロットの穴埋め)に変更
  • プロジェクト文脈(マスタードキュメント等)を自動付与して品質向上
  • デフォルトエンジン: gemini-cli

h3. 3. 構造化スナップショットのスロット

スロット 内容
CURRENT_STATE セッション終了時点のシステム・機能の状態
DISCOVERY 新たに判明した技術的事実や合意事項
DECISION 明示的に決定されたこと
NEXT_ACTION 次セッションで着手すべき具体的アクション
BLOCKED / PENDING 未解決の問題、保留事項
RISKS 注意すべきリスクや制約

h2. ドキュメント更新

  • docs/capabilities/session_log/要約転記仕様書.md → v0.2 に更新(CLI バックエンド利用、構造化スナップショット)
  • docs/reference/01_アーキテクチャ定義書.md → CLI LLM バックエンドの追記

h2. 実験結果(根拠)

同一の生ログ(529行, 40KB)に対して3パターンで実験:

条件 品質 コスト 実行時間
Gemini CLI + ログのみ 定額 数秒
Gemini CLI + ログ + マスタードキュメント 最良 定額 数秒
Codex CLI + ログのみ(WSL) 非常に高い 定額 長い(エージェントモード)

文脈を渡すと設計判断の抽出精度が明らかに向上した。

LLM AI さんが26日前に更新

h3. CLI LLM 実験スクリプトの記録

実験で使用した @tmp_codex_test.sh@ を一度コミットして履歴に残し、その後削除する。

このスクリプトは Codex CLI (WSL経由) の動作検証に使用したもの:

  • WSL 上の nvm 経由で Codex CLI を呼び出す方法の確立
  • @ChatGPT codex exec@ の非対話モードでの構造化スナップショット生成テスト

実験結果は本チケットの description に記載済み。スクリプト自体は実験完了後に削除する。

LLM AI さんが26日前に更新

h3. 実装前の設計判断 3点

h4. 1. source_file 未指定時の挙動

現行の「その場で save してから使う」を維持する。
session_logs/ の最新 .txt を使う方式だと、今回のセッション分が欠ける可能性がある。
source_file 指定時のみ明示ファイルを使う。要約転記仕様書 v0.2 の記述を実装に合わせて修正すること。

h4. 2. codex-cli は WSL 専用

WSL 専用とする。Windows 側へのフォールバックは不要。
理由: あきらさんが「Windows に直接載せるのはまだベータで WSL で動かせと言われた」と報告済み。
Windows 側に codex.exe があってもそれは別物なので、混在を避ける。

h4. 3. STARTUP_CONTEXT.md は最小テンプレートで上書き

毎回固定テンプレートに上書きする(スナップショットへのリンク + 一言まとめ)。
現状の補助資料表や注意書きを含む構造は維持しない。
理由: STARTUP_CONTEXT.md は「Butler だけが更新する」ルール(#128 で合意済み)なので、機械的に生成しやすい最小形が適切。必要なら人間が手で補足する。

LLM AI さんが26日前に更新

#135 対応を実装し、以下のコミットを作成しました。

commit: 21ce6bdf344381c451a7bb536623348e29db56e9
message: feat: switch session_log summarize to CLI LLM refs #135

実装内容:

  • butler/llm_cli.py を追加し、gemini-cli / codex-cli を呼ぶ CLI LLM バックエンドを実装
  • session_log summarize を Gemini API 直叩きから CLI バックエンド利用へ切り替え
  • source_file 未指定時は、現行方針どおり現在セッションを save してから summarize する挙動を維持
  • codex-cli は WSL 経由のみとし、Windows 側 codex.exe にはフォールバックしない
  • 出力を _snapshot.md に変更し、STARTUP_CONTEXT.md は最小テンプレート(最新スナップショットへのリンク + 一言まとめ)で更新
  • gemini_client.py を削除
  • skills_registry / 要約転記仕様書 / session_log テストを更新

確認結果:

  • python -m pytest tests/test_session_log_handler.py -q → 7 passed
  • python -m pytest tests/test_main_submit_sync.py::test_session_log_submit_task_is_synchronous -q → 1 passed
  • python -m pytest -q は実行済みですが、今回変更と無関係な既存失敗が 4 件ありました
    • tests/test_phase2_trilium_e2e.py::test_phase2_trilium_e2e
    • tests/test_wiki_handler.py::test_add_project_success
    • tests/test_wiki_handler.py::test_add_project_denied
    • tests/test_wiki_handler.py::test_sync_success

LLM AI さんが26日前に更新

h3. 実装レビュー結果

コミット @21ce6bd@ の実装をレビューした。結果: 合格

h4. 変更ファイル(6ファイル、+481/-143)

ファイル 変更内容
@butler/llm_cli.py@ 新規。core 層の CLI LLM バックエンド。gemini-cli / codex-cli の共通インターフェース
@butler/capabilities/session_log/handler.py@ summarize を CLI バックエンドに切り替え。構造化スナップショット対応
@butler/capabilities/session_log/gemini_client.py@ 削除(API 直叩き廃止)
@butler/skills_registry.py@ summarize の engine パラメータ追加
@docs/capabilities/session_log/要約転記仕様書.md@ 設計判断の反映(source_file、codex-cli WSL専用、STARTUP_CONTEXT最小テンプレート)
@tests/test_session_log_handler.py@ 新規テスト2件追加(明示ファイル / 現在セッションsave後使用)

h4. 設計判断との整合性

3点とも正しく反映されている:

source_file 未指定時は現在セッションを save してから使う(維持) ✔

codex-cli は WSL 専用(@wsl.exe bash -lc@ で呼び出し、フォールバックなし) ✔

STARTUP_CONTEXT.md は最小テンプレートで上書き(@_build_startup_context@ 関数) ✔

h4. コード品質

  • @llm_cli.py@ の構造が良い。@run_prompt()@ を公開インターフェースにし、エンジン切り替えは内部に閉じている
  • Codex CLI の WSL 呼び出しで nvm source が必要な問題を @_build_codex_wsl_script@ で対応済み
  • @_strip_outer_code_fence@ で LLM が余計なコードフェンスを付けた場合の対策もある
  • @_extract_first_meaningful_line@ で STARTUP_CONTEXT の「一言まとめ」を CURRENT_STATE から自動抽出
  • 環境変数 @BUTLER_GEMINI_CLI_MODEL@ / @BUTLER_CODEX_CLI_MODEL@ でモデルを外部から切り替え可能

h4. テスト

7件全パス(既存5件 + 新規2件)。run_prompt を monkeypatch で差し替えており、ユニットテストとして適切。

h4. 残作業

  • CLI 実接続の E2E テスト(Gemini CLI が実際に動く環境での確認)
  • Codex CLI 側の E2E 確認(WSL 上で実際に動作するか)

LLM AI さんが26日前に更新

h3. CLI 実接続 E2E の実施と追補修正

実接続 E2E を実施し、環境差分を吸収するための追補修正をコミットした。

commit: 20f0b04258362a0c3f53aa4ab5f1b2c4d35f9ee2
message: fix: harden CLI LLM runner for real E2E refs #135

h4. 追補修正の内容

対象: @butler/llm_cli.py@

  • Windows 側で @gemini@ が @subprocess.run()@ から見つからない環境に対応し、@gemini.cmd@ を優先解決するよう変更
  • Gemini CLI の出力で CP932 デコード例外が出たため、subprocess の文字コードを UTF-8 + replace に固定
  • WSL 経由の @bash -lc@ に渡すスクリプトで、@$HOME@ / @$PATH@ / @$candidate@ などの変数がホスト側で潰れないようエスケープを修正
  • WSL 内の @~/.nvm/versions/node/*/bin/codex@ を探索し、@codex@ を PATH へ明示追加するよう変更
  • Codex CLI が見つからない場合のエラーメッセージを明確化

h4. E2E 結果

いずれも @session_log summarize@ の実経路で確認した。
一時ワークスペースを作成し、@source_file@ と @docs/マスタードキュメント.md@ を置いた状態で Butler handler を実行。
確認対象は以下:

  • CLI 実行が成功すること
  • @_snapshot.md@ が生成されること
  • @STARTUP_CONTEXT.md@ が更新されること

h5. 1. Gemini CLI 実接続 E2E

  • status: ok
  • elapsed: 約 51.3 秒
  • 生成物:
    ** @claude_code_test_20260321T030000Z_snapshot.md@
    ** @STARTUP_CONTEXT.md@
  • 確認事項:
    ** 構造化スナップショット生成成功
    ** STARTUP_CONTEXT の最小テンプレート更新成功

h5. 2. Codex CLI 実接続 E2E (WSL)

  • status: ok
  • elapsed: 約 12.44 秒
  • 生成物:
    ** @claude_code_test_20260321T031000Z_snapshot.md@
    ** @STARTUP_CONTEXT.md@
  • 確認事項:
    ** WSL 経由で @ChatGPT codex exec@ が成功
    ** 構造化スナップショット生成成功
    ** STARTUP_CONTEXT の最小テンプレート更新成功

h4. 補足

E2E 実施後に @python -m pytest tests/test_session_log_handler.py -q@ を再実行し、7件 pass を確認した。
今回の追補修正は実環境差分の吸収が主で、既存 unit test は維持できている。

LLM AI さんが26日前に更新

h3. Brain 側からの Butler 実接続 E2E 確認

Codex が実施した E2E テスト(コメント #339)の後、Brain 側から実際に Butler 経由で @summarize@ を実行して確認した。

h4. 実行条件

  • Butler reload 後に実行
  • @source_file@: @session_logs/claude_code_9afce4ef-..._20260320T134357Z.txt@(前セッションの生ログ)
  • @engine@: @gemini-cli@
  • Butler 経由(@butler__submit_task@ → handler → @llm_cli.run_prompt@ → Gemini CLI)

h4. 結果: 成功

  • status: ok
  • 生成物:
    ** @session_logs/claude_code_9afce4ef-..._20260320T134357Z_snapshot.md@ — 構造化スナップショット(6スロット全て埋まっている)
    ** @STARTUP_CONTEXT.md@ — 最小テンプレートで上書き更新済み

h4. 品質確認

スナップショットの内容を確認:

  • CURRENT_STATE: summarize 機能の実装完了状態を正確に記述
  • DISCOVERY: AIの自律的記録の限界、チケット紐付けの不適切さなど、設計上の重要な発見を抽出
  • DECISION: 「機械的な引き継ぎフロー」「STARTUP_CONTEXT は Butler のみ更新」などの判断を正確に記録
  • NEXT_ACTION: 具体的な次ステップが列挙されている
  • RISKS: 「Gemini は会話内の言及のみ」「STARTUP_CONTEXT 競合」など適切

STARTUP_CONTEXT.md も「リンク + 一言まとめ」の最小テンプレートで正しく更新されている。

h4. 結論

実装は仕様通りに動作しており、#135 の主要作業は完了と判断する。
残るのは @google-generativeai@ パッケージの依存削除(gemini_client.py 廃止に伴う)程度。

LLM AI さんが26日前に更新

  • ステータス新規 から 終了 に変更

CLI LLM バックエンド実装・構造化スナップショット対応・旧 gemini_client.py 削除・ドキュメント更新・ E2E 検証すべて完了。残りのドキュメント負債は #136 に分離済み。

他の形式にエクスポート: Atom PDF