Grounded Access
面向企业知识库的权限感知检索参考系统。它把授权编译进检索查询本身,并要求每一次检索改动都在公开评测上拿出证据。
它想解决什么
多数 RAG 项目的做法是:先从索引取回 top-k,再在应用代码里把用户无权查看的结果剔除。这带来两个问题:
- 泄漏面:未授权的内容已经进入应用内存,接下来会流向重排模型、prompt、日志和 trace,任何一处疏忽都是一次泄漏;
- 召回损失:被剔除的正是索引已经选中的 top-k,用户看到的结果因此变少,而且这种损失在指标上不可见。
Grounded Access 的主张是:授权属于检索环节。身份被编译成一个 SQL 谓词,关键词通道与向量通道都带着它,未授权的行从不离开数据库。
第二个主张是:检索质量要被测量。项目自带一份带人工标注的虚构语料,每次运行都记录数据集版本、commit、策略与运行平台,报告由提交在仓库中的结果文件生成。
当前能做什么
项目按 M0–M4 推进,M0(walking skeleton)与 M1a(评测基线)已完成。下表区分「现在已实现」与「计划中」,避免把设计当成现状。
| 能力 | 当前已实现 | 计划中 |
|---|---|---|
| 检索内授权 | 租户、密级、部门、项目四条规则,每次请求编译一次,写进每条通道的 SQL;用基于属性的测试对照参考实现验证 | 适用范围过滤、审计事件、带标签的评测数据(M2) |
| 检索 | sparse-only(PostgreSQL FTS)、dense-only(pgvector 精确检索)、hybrid-rrf(RRF 融合并去除重叠 chunk),响应带检索配置哈希 | cross-encoder 重排(M3) |
| 入库 | Markdown 与纯文本切分(长段落按句拆分、小节内重叠);异步任务(202 + 轮询)、SKIP LOCKED worker、有限重试与断点续跑;内容哈希幂等、原子版本切换、并发安全 ;停用与删除对下一次查询生效,后台清理不可达版本 | 带重叠的 chunker v1(M1b) |
| 评测 | 28 篇带标签的文档、108 条用例(含 30 条授权负例)、BM25 参考行、bootstrap 置信区间与配对比较;CI 安全门禁逐个检查返回的 chunk 和每个身份的完整可见列表 | 适用范围与时间相关的用例(M2) |
| 回答 | /api/v1/retrieval/search 返回排序后的证据 | 带引用与拒答的 /api/v1/query(M3) |
| 可观测性 | 结构化日志、Docker Compose、每个 PR 的 CI | trace、审计事件、dashboard(M2–M4) |
尚未端到端验证的设计目标:隐藏无权内容的存在性(M2–M3)、基于属性的访问决策(M2)、回答只引用模型实际看到的内容(M3)。
技术选型
| 部分 | 选择 | 理由 |
|---|---|---|
| 控制面 | Java 21、Spring Boot 4.1 | 身份、授权、事务、入库与 API 编排;作者的后端工程能力所在 |
| 数据存储 | PostgreSQL 17 + pgvector | 关键词与向量检索共用同一套事务和过滤面,授权谓词只需写一次 |
| 模型服务 | Python 3.12、FastAPI、ONNX Runtime | embedding 与后续重排;不引入 PyTorch,CPU 可跑,权重打进镜像 |
| 评测 | Python CLI ga-eval | 通过公开 API 以不同身份调用,不读数据库 |
| 数据访问 | Spring JdbcClient + Flyway | 授权谓词需要手写、可审查的 SQL,不引入 ORM |
Java 与 Python 之间只通过带版本的 OpenAPI 契约通信,模型服务不持有任何身份信息,也不访问数据库。
文档地图
| 文档 | 内容 |
|---|---|
| 快速开始 | 三条命令跑起来,看到同一问题在不同身份下的不同结果 |
| 检索时授权 | 三条不变量、决策表、编译后的 SQL、当前验证到哪一级 |
| 检索通道 | FTS 的 OR 改写、pgvector 精确检索、排序确定性、为什么不叫 BM25 |
| 评测方法 | 用例格式、span 标注、指标与安全门禁、可复现规则 |
| 架构与边界 | 组件划分、数据模型、版本切换、并发入库、故障行为 |
| 路线图与非目标 | M0–M4、明确不做的事、待决问题 |
与 Domain Driven Kit 的关系
Domain Driven Kit 解决的是「Java 项目如何把 DDD 分层与架构约束沉淀成可复用代码」;Grounded Access 解决的是「AI 检索系统如何把权限与质量证据做进工程」。两者没有代码依赖,共享的是同一套工程习惯:架构规则写成测试、空安全由编译器保证、CI 门禁不可绕过。
状态与许可证
- 仓库:https://github.com/poppycoderr/grounded-access,代码 Apache-2.0,虚构语料 CC BY 4.0
- 当前阶段:M0 与 M1a 完成并在 CI 中运行;尚未发布 release
- demo 身份体系使用公开的本地签名密钥,按设计就是不安全的,仅用于本地演示