跳转至

SearchConnector Contract:检索投影适配器边界

核心结论

P0 不直接把业务逻辑绑死在 Postgres、OpenSearch/ES 或某个向量库上。先定义统一 SearchConnector contract,再分别实现真实 adapter。

当前已落地:

  • framework/context/search_connector.py:通用数据结构、SearchConnector Protocol 和 InMemorySearchConnector 合成参考实现。
  • framework/context/search_conformance.py:真实 adapter 复用的 conformance runner 和 7 个最低验收 case。
  • framework/context/search_tool_gateway.py:把 context.searchcontext.get_documentcontext.report_gap 包到 Tool Gateway 后面的本地 adapter 和 conformance。
  • framework/context/adapters/sqlite_fts.py:CI 可跑的本地 SQLite FTS5 adapter,用真实索引路径验证 contract。
  • framework/context/document_schema.pycontext_document 入库对象和 chunk schema,可投影为 SearchConnector 文档。
  • tests/test_search_connector.py:验证权限、lifecycle、gap report、supersede 行为。
  • tests/test_search_connector_conformance.py:验证 conformance runner 能发现错误 adapter。
  • tests/test_context_document_schema.py:验证 context document 字段、masking、chunk 和 SearchConnector 投影。

这个 contract 的重点不是检索质量,而是边界稳定:

  • 权限过滤必须发生在证据进入 Agent 上下文之前。
  • deleted / superseded 文档默认不参与搜索。
  • 搜索结果必须返回 source、scope、lifecycle、score_parts 和 rank_log。
  • 证据不足时必须能 report_gap
  • adapter 必须能解释命中原因,便于 debug 和审计。

最小接口

text search(SearchQuery) -> SearchResponse get_document(doc_id, allowed_scopes) -> ContextDocument | None report_gap(GapReport) -> GapReceipt explain(doc_id, SearchQuery) -> RankExplanation delete_or_supersede(doc_id, superseded_by=None) -> bool

核心数据结构

ContextDocumentRecord 是 Runtime Projection 中检索投影的入库对象:

text document_id raw_source_id source_type source_system source_uri source_hash object_type title summary body chunks permission_scope review_status lifecycle created_at updated_at owner department project tags entities pii_flags field_mask supersedes embedding_model ingest_pipeline_version metadata

SearchConnector.ContextDocument 是检索 adapter 接口对象,由 ContextDocumentRecord 投影得到。这样入库 schema 可以保留 review、PII、field mask 和实体字段,而搜索接口只拿需要进入检索和证据返回的字段。

SearchQuery 至少包含:

text query allowed_scopes top_k filters include_superseded min_score

EvidenceHit 必须回传:

text doc_id source_system source_uri object_type title snippet permission_scope lifecycle updated_at score score_parts metadata

当前合成验证

InMemorySearchConnector 只用于 contract 测试。它验证这些行为:

行为 验证
权限先过滤 restricted 文档不会进入 team 用户搜索结果
lifecycle 先过滤 deleted / superseded 默认不进入搜索结果
get_document 也检查权限 无 scope 时返回 None
gap 可记录 report_gap 返回稳定 gap_id 和 receipt
supersede 可见性 delete_or_supersede 后默认不搜到,显式 include_superseded=True 才可见

运行命令:

bash python -m unittest discover -s tests -p "test_search_connector.py" python scripts/search_connector_conformance.py python scripts/search_tool_gateway_conformance.py

对真实 adapter 的要求

当前 in_memorysqlite_fts 两个内置 connector 已共用同一批 conformance case。Postgres FTS/pgvector adapter 和 OpenSearch/ES adapter 后续也必须共用同一批 contract 测试,再增加各自的后端测试。

真实 adapter 不能只返回 top-k 文本,还要返回:

  • 权限过滤统计。
  • lifecycle 过滤统计。
  • filters 命中情况。
  • score parts 或 explain 信息。
  • source URI 和可引用对象 ID。
  • 删除、替换和 reindex 的传播状态。

下一步

  1. 配置真实 Postgres 服务,跑 Postgres Search Adapter 的 live conformance,并补 pgvector / hybrid rerank。
  2. 配置真实 OpenSearch / Elasticsearch 服务,跑 OpenSearch Adapter 的 live conformance,并补删除传播、重建延迟和权限变更 stale index benchmark。
  3. 用同一批 ContextDocumentRecord benchmark 对比 P50/P95、召回、权限泄漏、lifecycle、rank log 和 token 成本。
  4. 扩展 conformance:路径/owner/存在性泄漏、rank_log 字段完整性、批量 delete/reindex 传播。
  5. 扩展 SearchConnector Tool Gateway,把 knowledge card reindex/search CLI 和后续真实 adapter 都纳入同一工具网关验收。

相关页面: