SearchConnector Contract:检索投影适配器边界¶
核心结论¶
P0 不直接把业务逻辑绑死在 Postgres、OpenSearch/ES 或某个向量库上。先定义统一 SearchConnector contract,再分别实现真实 adapter。
当前已落地:
framework/context/search_connector.py:通用数据结构、SearchConnectorProtocol 和InMemorySearchConnector合成参考实现。framework/context/search_conformance.py:真实 adapter 复用的 conformance runner 和 7 个最低验收 case。framework/context/search_tool_gateway.py:把context.search、context.get_document、context.report_gap包到 Tool Gateway 后面的本地 adapter 和 conformance。framework/context/adapters/sqlite_fts.py:CI 可跑的本地 SQLite FTS5 adapter,用真实索引路径验证 contract。framework/context/document_schema.py:context_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_memory 和 sqlite_fts 两个内置 connector 已共用同一批 conformance case。Postgres FTS/pgvector adapter 和 OpenSearch/ES adapter 后续也必须共用同一批 contract 测试,再增加各自的后端测试。
真实 adapter 不能只返回 top-k 文本,还要返回:
- 权限过滤统计。
- lifecycle 过滤统计。
- filters 命中情况。
- score parts 或 explain 信息。
- source URI 和可引用对象 ID。
- 删除、替换和 reindex 的传播状态。
下一步¶
- 配置真实 Postgres 服务,跑 Postgres Search Adapter 的 live conformance,并补 pgvector / hybrid rerank。
- 配置真实 OpenSearch / Elasticsearch 服务,跑 OpenSearch Adapter 的 live conformance,并补删除传播、重建延迟和权限变更 stale index benchmark。
- 用同一批
ContextDocumentRecordbenchmark 对比 P50/P95、召回、权限泄漏、lifecycle、rank log 和 token 成本。 - 扩展 conformance:路径/owner/存在性泄漏、rank_log 字段完整性、批量 delete/reindex 传播。
- 扩展 SearchConnector Tool Gateway,把 knowledge card reindex/search CLI 和后续真实 adapter 都纳入同一工具网关验收。
相关页面: