DocMind项目答题卡#
一句话答案#
DocMind 是一个面向研发团队的 Agentic RAG 知识问答系统(Spring Boot + Vue 3),采用 Supervisor-Worker 架构编排 6 步 Agent 流水线,通过混合检索(BM25+向量+RRF)+交叉编码重排+条件自反思,实现 Recall@5 从 0.673 提升至 0.788、MRR 从 0.421 提升至 0.731、Faithfulness +0.037。
核心要点
一、项目三级概述
| 版本 | 内容 |
|---|---|
| 30字 | Agentic RAG 知识问答系统,Supervisor-Worker 架构,MRR 0.731 |
| 50字 | 面向研发团队的 Agentic RAG 系统,6 步 Agent 流水线+混合检索+条件自反思,MRR 从 0.421 提升至 0.731,支持 MCP 协议 IDE 集成 |
| 100字 | 基于 Spring Boot 3.4 + Spring AI 自研的 Agentic RAG 知识问答平台。采用 Supervisor-Worker 架构编排意图识别→混合检索(BM25+向量+RRF)→交叉编码重排→LLM生成→条件自反思的 6 步流水线,Recall@5 提升 17%、MRR 提升 74%、修复 8 处幻觉。通过 MCP 协议实现 IDE 集成,支持 5 工具/6 端点双路径调用 |
二、核心数字速查
| 指标 | 数值 | 来源 |
|---|---|---|
| Recall@5 | 0.673→0.788 (+17%) | V1→V2 (加入BM25+RRF) |
| 事实类 Recall@5 | 0.733→0.933 (+27%) | BM25 贡献 +0.200 |
| MRR | 0.421→0.731 (+74%) | V1→V3 (完整流水线) |
| Faithfulness | 0.812→0.849 (+0.037) | V3→V4 (条件自反思) |
| 缓存命中率 | 45% | 语义相似度≥0.92 + 知识库版本校验 |
| 单次查询成本 | ¥0.005-0.007 | 双模型+短路+缓存降本50% |
| 评测集规模 | 52 queries × 7 类别 × 4 配置 × 3 次 | 624 数据点 |
| 代码规模 | 143 Java 文件 (~18.2k行) + 35 前端文件 | RAG 核心 29 文件 |
| MCP 工具 | 5 工具 / 6 端点 | 双路径(内部Agent+外部IDE) |
| 迭代次数 | 20 次 | 每次有量化增益记录 |
三、技术栈与核心决策
| 决策 | 选择 | 原因 |
|---|---|---|
| 框架 | Spring Boot 3.4 + Spring AI | 理解每层原理而非调用API;Java生态统一 |
| 不用LangChain/Dify | 自研核心链路 | 能手写RRF公式、解释BM25 k1/b、控制reranker降级 |
| 检索策略 | BM25+向量+RRF融合 | 纯向量语义漂移;RRF rank-based避免归一化问题 |
| 重排 | 交叉编码器(DashScope gte-rerank) | MRR+0.137;“不发现新文档,把相关文档推到top-1” |
| 编排 | Supervisor-Worker | 新Worker只加1个文件;5-action fallback cascade |
| 自反思 | 条件触发(非全量) | 三层过滤:65%短路+50%通过+15%触发重写 |
| 分块 | Markdown-Aware (块感知) | 保护表格/代码完整性;增量索引SHA-256去重 |
| 路由 | 规则引擎(Iter#17) | <1ms 100%确定性 vs LLM 300ms |
四、10 大必问追问 + 标准答法
-
“Agent 不是过度设计吗?固定流水线不行?” → 工具选择(4工具×4信号)约10组合,可以规则化;但编排决策(继续/切换/终止)需要置信度判断,ReAct loop 天然适合。证据:Phase2 Supervisor 支撑 5-action fallback cascade,新 Worker 只加 1 个文件。
-
“为什么不用 LangChain/Dify/RAGFlow?” → 目标是理解 RAG 每层而非调用 API。我能手写 RRF 公式
score=weight/(k+rank),解释为什么不用加权和(向量0-1 vs BM25无界),知道 Cross-Encoder 替换的是 rerank 阶段而不是检索阶段。 -
“RRF 公式手写一下” →
score(d) = weight / (k + rank_i),k=60 (Cormack 2009)。不用加权和因为向量相似度0-1而BM25得分无界,RRF 只用排名避免归一化。配置 rrfK=60, vectorWeight=1.0, bm25Weight=1.0。 -
“Cross-Encoder 387ms 太慢,为什么不重排 top-100?” → 不是瓶颈:LLM 生成 ~1843ms 才是大头。MRR+0.137 > Recall+0.077 说明 rerank 把已有相关文档推到 top-1,不是发现新文档。只重排 top-5 已经够用。
-
“自反思 +0.037 区分不开噪声?” → 重复 3 次取中位数,测量噪声 ±0.028 std,+0.037 > 1σ。且 8/8 被重写的 query 都有改善。关键:首次评测发现 0 增益(流式push问题),修复后(Iter#11)才复现。
-
“多跳召回只有 0.50,怎么办?” → 两个子语义稀释单 embedding(如”比较IVF和HNSW”)。Query Decomposition(已实现 Iter#4)拆分后并行检索,预计 V5 +0.35 提升,待评测验证。
-
“52 条评测集太小?” → 确实 ±0.05 置信区间,<0.05 差异不显著。但核心 V1→V4 差异都 >0.10;单人标注偏差通过诚实披露+下轮交叉验证缓解。计划扩展到 200 条 + 2 人 Cohen’s Kappa。
-
“LLM 给 LLM 打分不是循环论证?” → qwen-plus 回答,qwen-turbo 评分(同系不同模型)。验证:30 样本 plus+turbo 交叉评分 Pearson r=0.91,相对排名稳定。一致性应用于所有配置 → 相对比较有效。
-
“为什么 BM25 对事实类 +0.200 但推理类 +0.000?” → 事实类如”RRF k 默认值?“含关键词”k”/“60”,BM25 精确匹配。推理类如”top-1正确但答案差,为什么?“无字面重合,BM25 空结果。RRF 融合:空+向量=纯向量,所以零提升。
-
“项目用户规模多少?商业价值?” → 内部团队自用(self-dogfooding),设计支撑 50-200 人团队。商业价值在于验证 Agentic RAG 在技术文档场景的工程可行性,不是追求用户规模。诚实承认规模有限,但工程深度和评测严谨性是核心卖点。
五、已落地 vs 规划中(关键边界)
| 能力 | 状态 | 证据 |
|---|---|---|
| RRF 混合检索 | ✅ 已落地 | 评测 Recall+0.115 |
| Cross-Encoder 重排 | ✅ 已落地 | 评测 MRR+0.137 |
| 条件自反思 | ✅ 已落地 | Iter#11 修复后 Faithfulness+0.037 |
| Markdown-Aware 分块 | ✅ 已落地 | 增量索引 SHA-256 |
| MCP IDE 集成 | ✅ 已落地 | Cursor IDE 验证 5 工具 |
| Supervisor-Worker | ✅ 已落地 | 16 文件,5-action fallback |
| Scope Routing + CRAG | ✅ 已落地 | Iter#16 修复 meta-dialogue bug |
| 规则引擎路由 | ✅ 已落地 | Iter#17,<1ms |
| Langfuse OTel Tracing | ✅ 已落地 | 7 步 trace + ChatModelObservationFilter |
| 完整 RBAC 多角色 | ⚠️ 设计中 | 有权限模型但未完整实现 |
| 多租户隔离 | ⚠️ 规划态 | 架构支持但未验证 |
| MCP 外部生产级加固 | ⚠️ 规划态 | 内部调用已通,外部暴露未做 |
| Query Decomposition 评测 | ⚠️ 代码在但未评测 | Iter#4 实现,V5 评测待做 |
⚠️ 面试红线:规划态能力不要主动讲成已落地,被问到时说”架构上预留了,但还没完整实现和验证”
六、缺陷自洽表达
| 面试官质疑 | 自洽回应 |
|---|---|
| ”用户规模小" | "自用项目重工程深度不重规模,我的卖点是评测严谨性和迭代方法论" |
| "评测集太小" | "承认局限,但核心差异>0.10远超噪声;已规划扩展到200条+多人标注" |
| "自反思最初无效" | "这恰恰说明我真做了评测——如果不评测永远不知道无效,修复后才有+0.037" |
| "不如用成熟框架" | "用框架是调参,自研是理解每层原理,面试能手写RRF/解释BM25参数这是区别” |
面试回答(2分钟版)
DocMind 是我做的一个面向研发团队的 Agentic RAG 知识问答系统。核心问题是技术文档散落在 Confluence、飞书、Git 各处,新人 onboarding 慢、查文档效率低。我用 Spring Boot 3.4 + Spring AI 自研了核心链路,采用 Supervisor-Worker 架构编排 6 步流水线:意图分类、混合检索、交叉编码重排、LLM 生成、条件自反思。检索层用 BM25+向量+RRF 融合,Recall@5 从 0.673 提到 0.788,其中 BM25 对事实类查询贡献 +0.200。重排层用交叉编码器把 MRR 从 0.421 拉到 0.731。自反思是我做的比较有意思的一个点:第一次评测发现 +0 增益,排查发现是流式输出导致反思结果没生效,修复后条件触发重写使 Faithfulness +0.037、修复了 8 处幻觉。整个系统通过 MCP 协议支持 IDE 集成,在 Cursor 里直接调用 5 个工具。我最大的收获是学会了用评测驱动迭代——20 次迭代每次都有量化数据,而不是凭感觉调参。
追问与易错
追问方向:
- “并发和性能怎么处理?”→ ThreadLocal 封装 AgentToolContext 保证线程安全 + SSE 流式输出减少用户等待感知 + CompletableFuture 拓扑排序实现多工具并行调用
- “成本怎么控制?”→ 双模型级联(简单任务用小模型、复杂任务才调大模型)+ 反思短路(70% 的 query 质量达标直接跳过反思步骤)+ 语义缓存(45% 命中率),综合降本约 50%
- “降级怎么做?”→ 每个外部依赖都有降级方案:LLM 调用失败→回退到规则路由、rerank 失败→关键词 BM25 打分兜底、embedding 失败→跳过向量路径走关键词检索
- “增量索引怎么做?”→ 对每个文档块计算 SHA-256 content_hash,更新时对比 hash 只重新计算变化的块的 embedding;100 页文档改 1 个字只需重算 1 个 embedding 而非全量重建
- “为什么选 Spring AI 不用 Python?”→ Java 生态统一(和现有微服务同技术栈)、团队 Java 背景上手快、Spring 生态集成方便(事务/缓存/监控)、性能瓶颈在 LLM API 调用而非语言本身
易错点:
- ❌ 把规划态能力说成已落地——面试官追问细节会穿帮
- ❌ 只讲架构不讲数字——必须记住关键指标及其来源
- ❌ 回避缺陷——主动讲”评测集小""自反思最初无效”反而加分
- ✅ 核心卖点:评测驱动迭代 + 每个决策有量化依据 + 能解释每层原理