コンテンツにスキップ

運用 Runbook

対象: CPersona 2.5.x。 このページは運用に関する正式リファレンスです: バックアップ、劣化検知、recall のチューニング、CJK の指針、コーパス索引の パターン。ここが依拠している挙動の事実は契約です — 挙動契約 を参照してください。

翻訳について: 正本は英語版です。記述が食い違う場合は英語版が優先です (右上の言語切替から参照できます)。


バックアップとリストア

データベースは WAL モードで動作する単一の SQLite ファイル (CPERSONA_DB_PATH) です。稼働中の WAL データベースを素の cp でコピーするとチェックポイントを またいで壊れたコピーができ得ます — スクリプト化しないでください。

推奨順:

  1. オンライン物理バックアップ (第一選択 — サーバー稼働中でも安全):
sqlite3 "$CPERSONA_DB_PATH" ".backup 'cpersona-backup.db'"
# または
sqlite3 "$CPERSONA_DB_PATH" "VACUUM INTO 'cpersona-backup.db'"

どちらも並行書き込み下で一貫したスナップショットを作ります。

  1. オフラインコピー: サーバーを停止し、.db-wal-shm の 兄弟ファイルごとコピーします。

  2. 論理バックアップ (低頻度の補完として推奨): export_memories は スキーマバージョンに依存しない JSONL を書き出し、import_memories は 冪等です (重複はスキップ)。したがってリストア訓練を安全に反復できます。 月次程度が妥当な頻度です。

.db はインスタンスの全体ではありません。 データベースの外に状態があり、 上のどのバックアップ手段もそれらに触れません:

  • <CPERSONA_DB_PATH>.calibration.json — エージェント別のベクトル閾値・ ゲート状態・スコアリング版、そしてエージェント別の set_recall_precision の beta。これ抜きで復元しても、測定値のほうは自力で復旧します: 既定の CPERSONA_CALIBRATE_ON_MODEL_CHANGE=true では sidecar が無い起動は フォールバックではなく再較正を行い、それが起きなかった場合は deep_checknever_calibrated を報告します。beta は復旧しません。 beta は測定値 ではなくポリシーの入力であり、述べられた選好を再導出する仕組みは存在しない ので、precision を調整していた運用者はその調整を無言で失い、再較正は全ゲート を既定の beta で測ります。sidecar をデータベースと並べてコピーするか、復元後 に set_recall_precision を再適用してください。
  • ~/.cpersona/operating-context.toml (または CPERSONA_OPERATING_CONTEXT_PATH) — 全クライアントに配られる運用者の指示。
  • CPERSONA_ACL_FILE を設定しているならその ACL ファイル — 抜きで復元すると 誰が接続できるかが変わります。
  • 外部ベクトル索引CPERSONA_VECTOR_SEARCH_MODE=remote かつ CPERSONA_STORE_BLOB=false の構成の場合。この構成では埋め込みがリモート索引 にしか存在しないので、データベースと上記 3 ファイルを全て戻してもベクトル腕 がゼロの状態で復元されます。check_healthno_local_vector_fallback と して報告します。索引も同じ頻度でバックアップするか、STORE_BLOB=true のまま にして .db を自己完結に保ってください。

稼働中のデータベースはクラウド同期フォルダの外に置いてください (Dropbox、Drive 等)。同期クライアントは SQLite の WAL ファイルと相性が悪い です。同期するのはバックアップの方にしてください。

埋め込みサーバー停止の検知

ベクトル検索は最も強い検索層ですが、誰も見張っていなければネットワーク境界で 静かに劣化します。検知面は 3 つあり、呼び出し側のエージェントには 1 番目を 見るよう指示してください:

  1. recall 応答の advisory (v2.4.33 以降、主たる検知面)。状態機械が実際の 埋め込み失敗を観測し、劣化した recall には advisory = {degraded, severity, reason, evidence, runbook, advisory_scope} が付きます — 「ベクトル層が落ちている。FTS + keyword のみで応答中」という 意味です。このフィールドをユーザーに提示し、その runbook に従うよう エージェントに指示してください (通常は「埋め込みサーバーを起動または 向け直してから再度 recall する」)。runbook が短縮されている場合は「もう 伝えた」という意味ですが、その「誰に」を述べるのが advisory_scope です — プロセスが自分専用なら session、HTTP トランスポートでは状態がサーバー全体の ものなので process になります。共有サーバーでは、fault は自分のセッションが 見たと仮定せず完全版 runbook を繰り返します (bug-251)。 CPERSONA_DEGRADED_ADVISORY=false での無効化は、 意図的に keyword のみで運用する場合に限ってください。設計: DEGRADED_ADVISORY_DESIGN
  2. store 応答の embedded 全ての書き込みが、自分の埋め込みが永続化された かどうかを報告します。サーバー停止中に行われた書き込みは embedded: false で返り、それらの行は修復可能です (次項)。
  3. check_health(agent_id, fix=true) は埋め込みが NULL のまま保存された行を 検出し、サーバー復帰後に再埋め込みします。注意: チェック時点で埋め込み エンドポイントに到達できない場合、次元チェックは失敗ではなくスキップされ ます。「エンドポイント到達不能」そのものに対する専用の赤いチェックは現時点で 存在しないため、check_health が緑であることを埋め込みサーバー稼働の証拠と 読まないでください。生存を見張っているのは advisory の面です。

recall のチューニング

つまみを、手を伸ばすべき順に:

  1. set_recall_precision(agent_id, precision) — 主たる (そして既定の融合 モードでは事実上唯一の) ポリシーつまみ。融合品質ゲートの動作点 β を動かし ます: strict=2.0 (混入が減り、取りこぼしが増える)、balanced=1.0 (既定)、 lenient=0.5 (取りこぼしが減り、混入が増える)。即時反映で再起動は不要です。
  2. calibrate_threshold(agent_id) — コーパスからゲート位置を導出し直します (ラベル不要)。agent_id 付きで (かつ融合ゲート有効で) 呼ぶと、ベクトル 閾値と融合ゲートの両方を較正します。付けずに呼ぶとベクトル閾値のみを 較正します。表示される値はベクトル側の閾値ですが、融合モードで実際に結果を 切っているのは融合ゲートです。コーパスが大きく変わった後、一括 (再) 構築の 後、埋め込みモデルを変えた後に再実行してください。
  3. CPERSONA_AUTOCUT_MIN_RESULTS — autocut は類似度スケールのシグナルに 対して発火します: confidence スコアリング下、あるいは生の cosine だけで 構成された均質なリスト (cascade が作るのがそれで、confidence の on/off は 問いません) に対してです。rsf / rrf では意図的に不活性なので (契約 §6)、 既定構成ではこのつまみは何もしません — ただしそれを決めているのは融合モード であって confidence フラグではありません。
  4. CPERSONA_FUSED_GATE_ENABLED=false — 最後の手段。ゲートが無いとフィルタ はプール規模のヒューリスティック (_adaptive_min_score) にフォールバック しますが、それでも弱い一致は弾かれます — 開けっ放しになるのではなく、粗い ゲートになるということです。失うのはこのコーパスに対して測定された動作点 です。

precision の選び方: トレードオフは用途ごとに非対称です。索引的なコーパス (recall が、無関係な行を捨てられる AI に供給される) では取りこぼしの方が 混入より悪いので、数日 lenient で運用し、混入が実コストになった場合にのみ balanced に戻してください。混入に敏感な文脈 (狭い窓に recall を注入する) では balanced / strict を選んでください。

recall に頼らないという選択

確率的検索は負けることがあります。文脈に無いこと自体が害になる事実 — 現在の 最優先の決定、常時有効な安全ルール — は、記憶ではなく決定的に注入される面 (CLAUDE.md、システムプロンプト、エージェントが常に読む索引ファイル) に置いて ください。有用な切り分けは、問われずに発火すべきものは決定的注入へ、問われた ときに見つかればよいものは記憶へです。系が 2 つあります:

  • 決定の更新は追記でなく上書きで行う。 決定が変わったら古い行を update_memory してください (自動で再埋め込みされます)。古くなった決定が recall に勝つのを止める最も確実な方法は、それが検索空間に存在しないことです。
  • lock_memory は消失からは守りますが、順位で負けることからは守りません (契約 §9)。

日本語 / CJK コーパス

  • CPERSONA_RECALL_MODE=rsf を設定してください。FTS5 は CJK のトークン化が 苦手ですが、rsf はマージの際に keyword チャネルのスコアの大きさを保持し、 それが補償するシグナルになります。これ以外に CJK 固有の設定はありません。
  • jina-v5-nano — 本プロジェクトが動かしているモデルであり、参照実装の埋め込み サーバーが既定でダウンロードするモデル — の日本語における既知の特性 (長期の 本番運用で確認済み): クエリと記憶の間に固有名詞や識別子のアンカーが 1 つ 以上重なるときは強い一方、共有語彙のない純粋な概念一致には弱いです。 具体的なアンカー語を含めてクエリを書くこと (「キーワードアンカリング」) は、 現行モデルに対する正しい適応であって、後ろめたく思うべき回避策ではありま せん。
  • モデルスロットは差し替え可能です (CEmbedding プロバイダ)。埋め込みモデルを 入れ替える場合は、コーパス全体を再埋め込みしてから calibrate_threshold を 実行してください。サーバーは次元が変わったときは自動で再較正しますが、 同一次元のモデル入れ替えでは手動の再較正が必要です。

コーパス索引と同期のパターン

CPersona の第一の設計中心は、会話から積み上がる記憶です。正本の Markdown ファイルに対する検索索引として使うことも可能ですが、正しいパターンは 2 つの 事実に規定されます: CPersona は受動的なサーバーであること (ファイル監視は なく、取り込みは常に呼び出し側が駆動する) と、重複排除が upsert ではなく skip であること (契約 §5)。

パターン A — 索引を使い捨ての射影として作り直す (まずはこちらを推奨)。

  1. 索引に専用の agent_id を与えます (例: md-index)。索引チャンクを会話 エージェントの記憶に混ぜないでください。分けておけばエピソード境界の機構も 絡んできません。
  2. 元ドキュメントが変わったら delete_agent_data(agent_id="md-index") → 全チャンクを再 store
  3. 再構築のたびに calibrate_threshold を再実行してください (set_recall_precision を使っているならそれも再適用): delete_agent_data はその agent の行と一緒に 較正状態も破棄します。再構築が夜間バッチなら、再較正もバッチの一部です。
  4. コスト: 数千チャンクの再埋め込みは CPU で数分〜数十分です (環境依存)。 得られるもの: 差分ロジックが不要になり、再構築が終わった時点で索引がソースと 一致します。再構築の最中は一致しません: delete_agent_data は再 store が始まる前にコミットするので、その窓の中で発行された recall は部分的な索引か、 何も無い索引を見ます。誰も問い合わせていない時間に再構築するか、第 2 の agent_id の下で構築して完成後に読み手を切り替えてください。

パターン B — 外部の内容ハッシュ台帳による差分更新。

  1. 各チャンクを安定した msg_id (例: path#heading) と、source.id に元 ドキュメントを入れて store します — こうすると recall の source_id 引数 (前方一致) がドキュメント単位のフィルタとしても使えます。
  2. 呼び出し側で キー → 内容ハッシュ の台帳を保持し、ハッシュが変わった チャンクだけを処理します。
  3. 変更されたチャンクは必ず update_memory (または delete_memory + store) を通してください — 同じ msg_id で変更後の内容を再保存しても 黙ってスキップされます。変更のないチャンクは何も考えずに再投入して構いま せん。完全一致の重複排除がそれを無害だと保証します。

再構築時間が実際に痛くなるほどコーパスが大きくなるまでは A を選んでください。 壊れる台帳がなく、drift するモードもありません。

スケール

成長にアーカイブや間引きの定期処理は不要です。ベクトル層は新しい順のウィンドウ (CPERSONA_MAX_MEMORIES、既定 10,000 — 大きなコーパスでは環境変数で上げて ください。契約 §4) を走査し、FTS と keyword のチャネルは全履歴に届き、古い行は削除されるのではなく ウィンドウと減衰によって沈んでいきます。

メンテナンスの頻度

  • 月次: check_health(agent_id, fix=true) — 決定的な整合性チェックと 自動修復。意味的なパスには deep_check(agent_id, fix=true)。加えて export_memories による論理バックアップ。
  • コーパスの大変動の後 (一括インポート、再構築、モデル変更): calibrate_threshold(agent_id)
  • バージョンアップ: スキーマは自身で前方マイグレーションします。較正は スコアリング関数と埋め込み次元に対して fingerprint されており、どちらかが 変わると初回起動時にサーバーが再較正します (v2.5.2 以降)。