Search Adapter State Benchmark:检索投影状态传播风险实验¶
生成时间:2026-06-14
数据分类:synthetic_internal_demo。样例使用合成 docs、finance、HR 文档;默认 CI 只跑本地 SQLite FTS5 状态传播 harness,Postgres/OpenSearch 作为可选 live adapter matrix 进入报告。
实验定位¶
这个实验验证 SearchConnector 检索投影在真实 Postgres/OpenSearch 服务接入前必须面对的状态传播风险:源数据已经删除、降权或 supersede,但索引尚未刷新时,旧索引会短暂返回不该进入上下文的证据。
实验目标不是假装这个窗口不存在,而是让 adapter 必须暴露 generation、stale_index、rank_log、延迟和成本,并验证 reindex 后能恢复安全状态。
当前结果¶
- Case 数:4
- Adapter 数:1
- 通过数:4
- 失败数:0
- 通过率:100%
- stale 检测数:3
- reindex 前暴露的 stale hit:3
- reindex 后恢复安全:4
- rank_log contract 通过:4
- 本地总延迟:0.7 ms
- 估算成本 units:70
Adapter Matrix¶
| Adapter | Kind | 状态 | 默认 CI | 不可用原因 |
|---|---|---|---|---|
| sqlite_fts | sqlite_fts_state_harness | available | yes | - |
| postgres_fts | postgres_fts_live_adapter | skipped_unavailable | no | psycopg or HARNESS_POSTGRES_DSN is not configured |
| opensearch | opensearch_live_adapter | skipped_unavailable | no | HARNESS_OPENSEARCH_URL is not configured |
Case 结果¶
| Adapter | Case | Stale Detected | Unsafe Before Reindex | Safe After Reindex | Rank Log | 结果 |
|---|---|---|---|---|---|---|
| sqlite_fts | delete_propagation_window |
yes | yes | yes | pass | pass |
| sqlite_fts | permission_change_window |
yes | yes | yes | pass | pass |
| sqlite_fts | superseded_requires_opt_in_after_reindex |
yes | yes | yes | pass | pass |
| sqlite_fts | rank_log_and_cost_contract |
no | no | yes | pass | pass |
关键结论¶
- 删除、权限降级和 supersede 都会产生源数据与索引之间的短暂不一致窗口;如果 Agent 直接信任旧索引,就可能把过期或越权上下文装入任务。
- 检索投影 adapter 必须暴露
source_generation、index_generation和stale_index,让上层在 stale 窗口选择降级、等待 reindex、报告 gap 或要求人工确认。 - reindex 后,deleted 文档必须被 lifecycle filter 阻断,restricted 文档必须被 permission filter 阻断,superseded 文档默认不可见且只能显式 opt-in。
rank_log不能只记录排序分数,还要包含过滤计数、adapter id、adapter kind、延迟和可比较的成本 units,后续 Postgres/OpenSearch live conformance 复用同一 contract。- 当前报告已经把 Postgres/OpenSearch live adapter 是否可用、为何跳过和是否进入默认 CI 变成结构化 adapter matrix;没有配置服务时不会伪装成已验证。
没证明什么¶
- 默认 CI 路径还不是真实 Postgres FTS/pgvector 或 OpenSearch 集群的网络 benchmark;只有配置
--include-live-adapters和对应服务时才会跑 live adapter。 - 这还没有验证真实事务、binlog/CDC、队列积压、并发 reindex 或跨进程锁。
- 这不表示 stale window 已经被产品完全解决;它只把风险变成可检测、可报告、可复跑的验收条件。
代码入口¶
- 实现:
framework/evals/search_adapter_state_benchmark.py - 测试:
tests/test_search_adapter_state_benchmark.py - 运行:
python scripts/search_adapter_state_benchmark.py --write-report - Live adapter 对照:
python scripts/search_adapter_state_benchmark.py --include-live-adapters - 输出:
vault/50-outputs/search-adapter-state-benchmark-analysis.md
下一步¶
- 在测试环境配置
HARNESS_POSTGRES_DSN/HARNESS_OPENSEARCH_URL后,用--include-live-adapters跑同一 state benchmark,比较真实服务的删除传播、权限变更传播、reindex latency 和 cost units。 - 把真实 adapter 的 stale state 接入 Context Router 的
projection_states,替换当前合成状态,并接入 Projection Remediation Queue 的真实 reindex worker。 - 把 reindex queue 从本地 JSON 替换为可恢复 worker / Postgres table,并记录 retry、idempotency 和 adapter failure。