Java 知识库检索服务:认证、文档版本、权限与证据返回
这个项目把检索边界放进真实 HTTP 服务:登录取得服务端身份,写入有版本的文档,再检查“当前用户能用哪些原文回答这个问题”。源码围绕认证、数据库事务、文档状态和检索过滤展开,可以沿请求链路理解这些模块如何协作。
本页整理源码阅读路径、接口约定与已有验证证据。需要逐步启动时,可查本地运行与 API 调用说明,其中给出环境、身份、创建文档、版本更新、拒答和权限对照的完整命令。
默认模式采用 H2 文件数据库与本地词项检索,不需要模型密钥或 Docker。它返回原文摘录;语义向量检索使用单独的 Spring AI / pgvector 模式,运行条件与验证范围见下文和包内 README。
本地运行
需要 JDK 21 与 Maven 3.9+。下面是包内默认启动方式,默认端口为 8085、数据库为当前目录的 data/knowledge.mv.db。首次跟做请优先使用教程里的 18085 与临时数据库命令,不要同时执行两套启动步骤。
完整解压后进入 knowledge-service 目录,在 Windows 执行:
.\start.cmd
# 或者
mvn.cmd -B -ntp spring-boot:runLinux/macOS 使用 sh start.sh。启动后打开 http://127.0.0.1:8085/,在项目控制台登录、添加文档并查询。健康检查路径为 /api/health。
本地演示用户写在包内 README。控制台默认使用 H2,数据保存在启动目录的 data/knowledge.mv.db;重启后可以继续查看。相同数据库文件不能同时由多个服务进程占用。
首次遇到依赖下载、端口或 JDK 问题,按使用帮助记录第一条错误。网站本身提供代码和说明,不会自动连接你电脑上的服务。
可以沿着哪条链路读源码?
| 环节 | 实现重点 | 验证要点 |
|---|---|---|
| 认证 | 密码校验、不透明 Bearer token、过期与退出撤销 | 未认证请求被拒绝,退出后的 token 不再可用 |
| 身份 | 每个请求从数据库取得用户租户和角色 | 客户端伪造 tenant/role 不能改变权限 |
| 文档 | 当前版本、历史版本、访问级别与删除墓碑 | 更新后不读取旧版本,删除后不回退旧文 |
| 并发修改 | expectedVersion 与数据库事务 | 旧版本写入得到冲突,避免静默覆盖 |
| 检索 | 允许文档集、词项或向量候选、当前状态再核对 | 引用能对应原文、版本和允许的角色 |
| 无证据 | 明确拒答与空引用 | 文档里没有答案时,不拼接不存在的资料 |
| 错误 | 参数限制、未知字段、状态码与错误响应 | 空输入、错误类型、越权与版本冲突可区分 |
本地演示的身份初始化、单机数据和检索规模都有明确边界。公开部署需要另外设计身份管理、TLS、限流、审计与迁移,不能将演示凭据直接用于实际业务。
一组可以照着调用的接口
完整请求体、登录步骤和复制示例在包内 API.md。以下用于定位代码:
| 方法 | 路径 | 作用 |
|---|---|---|
| POST | /api/auth/login | 校验用户名和密码,签发 token |
| GET | /api/me | 查看服务端认定的身份 |
| GET / POST | /api/documents | 查询可见文档 / 创建文档 |
| GET / PUT / DELETE | /api/documents/{id} | 读取 / 创建下一版本 / 墓碑删除 |
| POST | /api/search | 提交问题,返回摘录、引用或拒答 |
| POST | /api/auth/logout | 撤销当前 token |
删除请求携带 expectedVersion,更新请求也必须明确预期版本。默认模式中,每份文档作为一个检索单元,未实现生产规模的分块和索引调度。
三个值得实际执行的场景
1. 同名文档属于不同租户
以两个租户分别写“年假规则”,内容不同。使用各自已认证用户查询相同问题,保存 answer、引用文档 ID 和版本。检查隔离发生在进入检索候选之前,而不只是最终答案改写。
2. 更新与删除后,不回退旧版本
把一份规则从五天改为十天;查询时只应使用当前允许的版本。再删除当前文档并重复提问,检查旧版本不会重新变成有效证据。用数据库记录、实际响应和相同输入的复跑结果解释结论。
3. 权限收紧会影响后续请求
将原本可读的内容调整为更高访问级别,或修改用户角色,再用已有会话发新请求。核对身份读取、候选过滤和返回证据这几个位置,记录权限变化的实际生效边界。
可以直接使用 7 天练习单和手册中的用例表。它们提供待验证目标,自己的实际结果需要亲自执行后填写。
Spring AI 与真实向量库存储
项目另外提供 ai Maven / 运行 profile,使用 Spring AI 官方 EmbeddingModel 与 PgVectorStore 接口。需要独立 PostgreSQL/pgvector 与相应模型配置;包内 README 给出环境变量和启动命令。
向量候选仍需检查权威数据库中的当前版本、删除状态和允许角色;索引过滤不能替代业务授权。启用该模式不会悄悄回退本地检索来掩盖外部依赖失败。
既有 pgvector 实测使用真实 PostgreSQL/pgvector 和确定性的三维 fixture 向量,验收的是存储、过滤、更新、删除与旧候选防回退。真实 embedding 模型调用、语义质量与生成回答均未验收;即使启用 ai 模式,当前实现也只返回原文摘录,没有调用聊天模型。首轮教程只运行默认 H2 模式,不重跑 pgvector。
已运行的验证
本次记录时间:2026-11-05T19:31:18.856781+00:00。源码 SHA-256:cf9d696b5fe2ead1108ba05fafdca5ebd92868fc7e8b004dd7a827ffd2d44e61。
| 验证项 | 实际结果 |
|---|---|
| Maven 测试 | 共 22 项,通过 21,跳过 1,失败 0,错误 0 |
ApiIntegrationTest | 16 通过,0 跳过 |
LiveEmbeddingTest | 0 通过,1 跳过 |
PersistenceIntegrationTest | 1 通过,0 跳过 |
PgVectorIntegrationTest | 4 通过,0 跳过 |
| 独立 Java 进程 HTTP 回放 | passed;完整输入和响应保存在下载包的 verification 目录 |
本次向量集成使用真实 PostgreSQL/pgvector 与明确的确定性测试向量,检查存储、过滤、更新与删除。需要真实模型账号的测试若未配置则跳过;它们不构成语义质量、模型回答效果或生产性能的测量。具体运行模式及条件以原始报告为准。
报告与源码通过哈希对应,下载包保留 Maven 日志、JUnit XML 和独立进程 HTTP 回放。修改源码后应重新执行包内验证工具,再更新报告;站点打包不会为未测试源码补造通过结果。
源码摘要继续以以上生成片段中的 SHA-256 为准。本次 2026-11-06 的首轮教程核验单独记录于仓库 docs/verification/first-run-guide.json 与 docs/verification/first-run-guide/README.md,不替换上述密封报告,也不把一次教学命令回放计入原有 Maven 测试数。
把练习整理成项目经历
先写“运行和阅读了哪些部分”,再单独列“我新增或修复了什么”。涉及收益或性能,只使用自己按明确条件实际测量的数字。
可以对照项目证据模板,把一次版本或权限问题写成“输入 → 失败 → 改动 → 复跑 → 边界”。对源码仅作运行、阅读时,如实写学习实践。
