ADR-0169 Phase 3 PR-5 で新設 (VETO #3 対応)。 intake-chat が evidence を引き寄せる 3 つの経路を、どのシーンでどれを叩くかを一枚で示す。

3 系統の役割

系統実体使う場面典型 latency
R9 RecallerDRP 内部 pre-gate node審査 run の pre-gate で類似案件を proactive に想起数百 ms (DRP 内)
docs-searchCloudflare Worker (docs-search-worker)docs サイトの全文検索・軽い問合せ100-300 ms
archive_usBQ archive_us dataset + archive-mcp (Cloud Run)intake-chat の evidence 参照 (ADR/RQ/docs/D1 telemetry 統合検索)warm 1.5-6 秒

使い分け表

  • 審査 run 中に類似案件を出したい → R9 (DRP 内 pre-gate で自動発火・intake-chat から直接叩かない)
  • docs サイトで文字列を探したい・見出しから辿りたい → docs-search
  • intake-chat が質問に答える際に一次情報 (ADR / RQ / docs / D1 telemetry) を引きたい → archive_us

3 系統は独立で、相互に fallback しない。intake-chat が「回答に根拠を付ける」タスクは archive_us が SSoT

archive_us (本 Phase 3)

  • endpoint: archive-mcpPOST /retrieve (Cloud Run · PR-8 で deploy)
  • corpus: chunks 60,866 (adr 2,124 / rq 3,259 / docs 299 / docs-internal 4,246 / claude-code 49,736 / claude-ai-chat 842 / d1_telemetry 360)
  • retrieval 段構成: BQ VECTOR_SEARCH → server-side filter (VETO #1) → Vertex Ranking → Gemini 生成 → Check Grounding
  • 応答: { chunks, answer, citations, support_score, grounding_error_count, filter_dropped_count, ...latency 各種 }
  • 典型 request:
    • 高精度: { q, topk: 5, source_filter: ["adr","rq"], rerank: true, include_answer: true }
    • コスト抑制: { q, topk: 3, rerank: false } (BQ 単体 · Gemini/Grounding skip)

server-side filter (VETO #1)

  • source == d1_telemetry かつ chunk_text に verdict キーワード (verdict / reject / skip / approved / cross_validation_verdict 等 14 個 · archive-mcp/src/lib/server_side_filter.mjs) が含まれる chunk は除外
  • 除外目的: 過去 verdict を LLM に「事実」として引用させない (審査バイアスの伝播防止)
  • filter_enabled: false で無効化可 (デバッグ用途)
  • fail 時: fail-safe = 元の chunks を pass-through + filter_error に error message · Cloud Monitoring filter_fail: prefix で即時発報 (PR-8 で組込み)

R9 Recaller

  • 場所: DRP 内 Gate 0-6 のいずれかで実行される pre-gate node (詳細: docs/_config.json R9 定義 · docs/research/rq-107-organizational-decision-roles-synthesis.md)
  • 目的: 審査 run の入力に対し類似する過去案件を proactive に想起し、審査官の盲点を予防
  • intake-chat から呼ばない: R9 は DRP 内で自動発火する node であり、intake-chat の tool として呼ぶ想定はない
  • endpoint: docs-search-worker (Cloudflare Worker)
  • corpus: docs/ 全 md の title / heading / 本文 (public docs サイト全文)
  • 応答: 文字列一致 + rank
  • intake-chat から呼ぶ場面: 「あの docs の URL 教えて」「見出し検索」のような lightweight クエリ · evidence 参照には向かない (根拠の重み付けは archive_us が担当)

VECTOR INDEX 再構築手順 (archive_us)

archive_us.chunk_embeddings_v2_doc_idx (chunk_embeddings_v2_doc に対する IVF index) が corruption / stale / ACTIVE でなくなった場合の再構築手順。

状態確認

SELECT
  index_name,
  index_status,
  coverage_percentage,
  last_refresh_time,
FROM `bizlp-gas-accounting-dev.archive_us.INFORMATION_SCHEMA.VECTOR_INDEXES`
WHERE table_name = 'chunk_embeddings_v2_doc';
  • index_status = ACTIVE + coverage_percentage = 100 が正常
  • ACTIVE でない or coverage < 100 なら再構築

再構築 (drop + recreate)

DROP VECTOR INDEX IF EXISTS `bizlp-gas-accounting-dev.archive_us.chunk_embeddings_v2_doc_idx`;

CREATE VECTOR INDEX `chunk_embeddings_v2_doc_idx`
ON `bizlp-gas-accounting-dev.archive_us.chunk_embeddings_v2_doc` (embedding)
OPTIONS (index_type = 'IVF', distance_type = 'COSINE', ivf_options = '{"num_lists": 250}');
  • 60K rows で index 作成は 5-15 分
  • 作成中は VECTOR_SEARCH が非 index scan (brute force) にフォールバック = latency 悪化するが機能はする

トラブルシュート

/retrieve が 500 で落ちる

  1. GET /healthz で服の生存確認 → ok なら retrieve 固有の問題
  2. GET / で config dump 取得 → BQ dataset name / Vertex project が正しいか確認
  3. ADC 確認: gcloud auth application-default print-access-token が返るか (local dev)
  4. Cloud Run では default SA に roles/bigquery.dataViewer / roles/bigquery.jobUser / roles/aiplatform.user / roles/discoveryengine.viewer が付与されているか

latency が P95 5 秒を超える

  1. rerank: false に落として BQ 単体 latency を測定 (期待: warm 1-2 秒)
  2. source_filter: ["adr","rq"] を指定して corpus 絞込み (全 60K scan は BQ 3-5 秒)
  3. include_answer: false で Gemini + Grounding を skip (期待: warm 1.7 秒)
  4. Cloud Run min-instances=1 検討 (cold start 排除 · 追加 ~$5/月 · PR-8 の判断項目)

grounding_error_count が急に増える

  • Gemini answer の claim 分割が細かい場合の副作用で false-alert 傾向 (0-15 程度は正常範囲)
  • support_score >= 0.6 を維持していれば実質引用率は十分
  • 100 超え or support_score < 0.4 が続く場合: Vertex Check Grounding の SDK / prompt 変更を疑う → planning file 加筆 + amend PR

filter_dropped_count が想定より多い

  • verdict キーワード誤検出の可能性 (skip は一般語) → archive-mcp/src/lib/server_side_filter.mjsVERDICT_KEYWORDS を絞る amend PR
  • filter_enabled: false で全 pass-through させて比較

Vertex Ranking / Gemini / Grounding の quota / rate limit

  • Cloud Console → APIs & Services → Quotas で該当 API の usage 確認
  • LiteLLM Gateway 経由への fallback は本 Phase 3 では採らない (Cloud Run では直叩き構成 · secret 依存排除)
  • 一時的な緩和: rerank: false + include_answer: false で BQ 単体運用

参考

  • ADR-0169: docs/adr/0169-add-citation-rag-to-sounding-board.md
  • planning: tasks/adr-0169/phase-3-archive-mcp-plan.md
  • server-side filter 実装: archive-mcp/src/lib/server_side_filter.mjs
  • R9 Recaller: docs/research/rq-107-organizational-decision-roles-synthesis.md
  • docs-search worker: .github/workflows/deploy-docs-search-worker.yml