Skip to content

简历素材与 STAR 故事

本文档为简历编写和面试叙事提供结构化素材。 所有数据均来自项目真实评测和代码(详见 04、10),非估算。


一、项目一句话描述

30 字版

设计并实现企业级 Agentic RAG + MCP 知识问答系统,支持多格式文档智能检索与自反思纠错。

50 字版

独立设计并实现 Agentic RAG + MCP 知识问答系统(Java 全栈),涵盖 Supervisor-Worker 多 Agent 架构、混合检索、Cross-Encoder 重排、Self-Reflection 条件重写,经 52 条离线评测验证。

100 字版

独立设计并实现面向研发团队的 Agentic RAG + MCP 知识问答系统。后端 Spring Boot 3.4 + Spring AI(143 文件),前端 Vue 3 + TypeScript(35 文件)。核心架构为 Supervisor-Worker 多 Agent,6 步流程(Query Understanding → Scope Routing → Path Decision → Supervisor-Worker Retrieval → Prompt Assembly → LLM + Self-Reflection)。实现双层范畴路由(规则+LLM)、规则引擎工具选择(<1ms)、CRAG 三档检索评分、混合检索 RRF 融合、Cross-Encoder 重排、HyDE、Self-Reflection 条件重写。Langfuse OTel 全链路追踪。52 条离线评测量化每层增量价值。MCP 协议暴露 5 工具给 IDE。

English (50 words)

Designed and built an enterprise Agentic RAG + MCP knowledge Q&A system (Java full-stack). Features Supervisor-Worker multi-agent architecture, hybrid retrieval (Vector + BM25 + RRF), Cross-Encoder reranking, self-reflection with conditional rewrite, and a 52-query offline evaluation framework. Exposed tools via MCP protocol for IDE integration.


二、技术亮点 Bullet Points(简历用)

每条格式:动词 + 技术 + 量化结果,可直接复制到简历。

  1. 设计 Supervisor-Worker 多 Agent 架构,将 1400 行单体 Agent 拆分为 16 个职责单一的文件(Supervisor + 4 Worker + 状态机),新增 Worker 仅需实现接口 + 注册,改动文件数从 ≥3 降为 1

  2. 实现 Vector + BM25 混合检索 + RRF 加权融合,Recall@5 从 0.673 提升至 0.788(+0.115),事实类查询 Recall@5 从 0.733 提升至 0.933(+0.200,BM25 贡献)

  3. 集成 Cross-Encoder 语义重排(DashScope gte-rerank),MRR 从 0.594 提升至 0.731(+0.137),核心价值为将相关文档推至 top-1 位置,利用 LLM 注意力分布优势

  4. 设计 Self-Reflection 条件重写机制,反思评分不通过时注入具体 issues 触发主模型流式重写,忠实度 +0.037(0.812→0.849),8 条幻觉/遗漏被修正,三层过滤使 85% 查询零额外成本

  5. 搭建 52 条 × 4 档对照的离线评测框架,覆盖 7 类查询(事实/操作/对比/推理/对抗/超范围/多跳),产出 Recall@5、MRR、忠实度、相关性等 11 维指标报告,单次评测成本 ¥18.4

  6. 实现 Markdown-Aware 双层切块 + 增量索引,表格/代码块原子保留不切碎,SHA-256 content_hash 实现增量更新(100 页文档改 1 字仅需 ~1 次 embedding,原需 200-400 次)

  7. 集成 MinerU 多模态文档解析,统一 PDF/PPT/图片/网页为 Markdown 后入 RAG,下游检索链路零行改动;按格式分级降级(PDF 降级 PDFBox,PPT/图片 fail-fast 不静默)

  8. 实现自适应检索参数(QueryProfiler),Complexity × Specificity 二维矩阵映射 8 套检索预设,精确查询 BM25 权重 0.7、语义查询向量权重 0.6,纯规则零 LLM 成本

  9. 通过 MCP 标准协议暴露 5 个工具 / 6 端点(doc_search / keyword_search / web_search / recall_memory / store_memory / kb_meta),同一套工具代码同时服务内部 Agent 循环和外部 IDE 插件(Cursor),零代码重复

  10. 实现链路成本优化,双模型策略(主回答 qwen-plus / 决策类 qwen-turbo)+ 反思高分短路 + 语义缓存,单查询成本从 ¥0.012 降至 ¥0.005-0.007(-50%)

  11. 基于真实 bug 调研业界做法补上路由分层(Phase 5),起点是用户输入"总结上面的对话"被错误送入向量检索召回 12 条无关切片。调研 12 个生产级框架(LangGraph / Bedrock / Perplexity / LinkedIn 等)+ 3 篇论文(CRAG / Self-RAG / Adaptive-RAG)后,加四道闸:规则快路径 + 模型范畴判定 + CRAG 风格三档评估 + 自纠错切题度检查。元对话路径完全跳过检索,灰区仲裁用 reranker 单对打分(50ms)替代小模型生成(300ms)

  12. 实现 PathDecision 规则引擎替代 LLM 路由(Phase 5),工具选择从 LLM Function Calling(~300ms、不确定、不可测试)改为 RetrievalPlanner 纯规则引擎(<1ms、100% 确定性、单元测试可断言),PathDecision record 统一路径决策输出 + reason 字段写入 trace 可追溯

  13. 集成 Langfuse OTel 全链路追踪(Phase 6),Agent 7 步执行(understanding → routing → retrieval → reranking → grading → generation → reflection)通过 OpenTelemetry 协议上报 Langfuse,TracedOp 消除 span 样板代码,RootNameFilteringSpanProcessor 白名单过滤 Spring 框架噪音,ChatModelObservationFilter 自动采集 LLM prompt/completion/token 用量


三、量化成果总表

指标数值对比基线来源
Recall@5 提升+0.115(0.673→0.788)V1 朴素 → V2 RRF 融合评测 52 条 × 3 轮
事实类 Recall@5+0.200(0.733→0.933)BM25 对事实类的贡献评测分类切片
MRR 提升+0.310(0.421→0.731)V1 朴素 → V3 +重排评测全链路
忠实度提升+0.037(0.812→0.849)V3 → V4 条件重写评测复测
相关性提升+0.027(0.834→0.861)V3 → V4 条件重写评测复测
被重写查询忠实度+0.230(0.510→0.740)8 条被修正查询平均评测明细
对抗查询拒答率100%(5/5)提示词注入变体评测
单查询成本降低-50%(¥0.012→¥0.006)双模型+短路+缓存成本估算
缓存命中率提升+50%(30%→45%)阈值 3→2线上观测
增量索引效率-99%(200次→1次 embedding)100 页改 1 字场景设计分析
路径决策延迟<1ms(vs LLM ~300ms)RetrievalPlanner 规则引擎替代 LLMPhase 5
对比类 decompose 触发率100%(vs 60%)确定性后处理兜底 LLM 漏判Phase 5
代码规模143 Java + 35 前端文件-源码统计
核心 RAG 组件29 个文件-wc -l
优化迭代数20 次,每次有评测数据-迭代记录
评测数据集52 条 × 7 类 × 4 档 × 3 轮-评测框架
评测报告624 行 Markdown-评测产物

四、STAR 故事(8 则核心 + 3 则补充)

STAR-1:Self-Reflection 从 noop 到条件重写(最推荐讲述)

Situation:搭建离线评测框架后,跑出一个反直觉结论——V3(+重排)和 V4(+反思)在忠实度、相关性上数值完全相同(保留 3 位小数也一样)。Self-Reflection 贡献了 956ms 延迟(占总耗时 29%),对答案质量的贡献是零。

Task:必须解决这个问题——面试中讲"Self-Reflection 提升答案质量"却拿不出数据,会被直接击穿。

Action

  • 抽取 5 个样例的完整执行记录,确认反思模块确实只输出了置信度评分,不返回修改后的答案
  • 定位根因:流式模式下 token 已经逐个 flush 给前端,反思在流式完成后执行,"发现问题但改不了"
  • 设计 post-stream conditional rewrite 方案:流式完成后,小模型做四维评分;不通过时,将审查发现的具体 issues(如"编造了不存在的三阶段降级策略""Milvus HNSW 参数描述与来源不一致")注入 rewrite prompt,主模型重新流式生成
  • 成本控制设计三层过滤:高分短路跳过 65%、评分通过跳过 50%、仅 15% 查询触发重写
  • 前端新增 3 个 SSE 事件(reflection_start / reflection_token / reflection_done),实现答案无缝替换

Result

  • 忠实度 +0.037(0.812→0.849),V4 首次与 V3 拉开可量化差距
  • 8 条被重写查询的忠实度平均从 0.510 提升到 0.740(+0.230)
  • 修正了具体问题:Milvus HNSW 参数错误、编造不存在策略、遗漏关键步骤、幻觉修正("运行 11 个月"→"知识库中未找到")
  • 成本增量仅 ¥0.004/查询,因为三层过滤使 85% 查询零额外成本

面试追问预判

  • "为什么不在生成前做反思?" → 流式体验和质量的权衡;前置反思需要先完整生成再评估,延迟更高
  • "15% 的重写率够高吗?" → 这恰好说明系统在大多数情况下首次生成质量已经足够好;重写集中在中等置信度区间(rerank 0.5-0.7),正好是最需要修正的场景

STAR-2:BM25 索引未刷新导致 V2 < V1(评测暴露运维缺口)

Situation:首轮评测跑出反常数据——加入 BM25 混合检索的 V2 在事实类上 Recall@5 = 0.667,低于纯向量检索 V1 的 0.733。加了组件反而变差。

Task:定位这个反常数据的根因,确认是算法问题还是工程问题。

Action

  • 第一步怀疑 RRF 公式实现有误,写单元测试用教科书例子验证 → 公式正确
  • 第二步单独调用 BM25Retriever 检索 "text-embedding-v3 维度" → 返回 0 条结果
  • 第三步检查 Lucene 索引文件时间戳 → 最后修改 2026-04-12,比知识库最近一次入库(2026-04-29)早了 17 天
  • 定位根因:迭代 #9 通过 MinerU 重新入库时,processDocument() 调用了 MilvusService.insertChunks() 但遗漏了 BM25Retriever.rebuildIndex(),切片进了 Milvus 但没进 Lucene
  • 修复后全量重建索引,重跑评测 → V2 事实类 Recall@5 = 0.933

Result

  • 发现并修复了一个真实的生产级 bug(文档入库后 BM25 不可用)
  • 如果没有评测,这个问题要等用户反馈"最近上传的内容搜不到"才能暴露
  • 最终 RRF 融合在事实类上贡献了 +0.200 的 Recall 提升(0.733→0.933)

核心叙事:评测的价值不只是产出数字,更是暴露运维缺口——光为了让评测正确运行就发现了一个真实 bug。


STAR-3:从单体 Agent 到 Supervisor-Worker 重构

Situation:DocMindAgent 膨胀至 ~1400 行,检索编排决策和执行逻辑耦合在一个类中。新增检索策略(HyDE、多文档对比)需要修改核心类,且单次 ReAct 循环没有置信度反馈机制。

Task:重构为可扩展的多 Agent 架构,不破坏现有 SSE 事件协议和 API 签名。

Action

  • 设计 Supervisor-Worker 两层拓扑:SupervisorAgent 做编排决策(3 路策略:迭代 ReAct / Plan-and-Execute / 子问题拆解),Worker 做执行
  • 定义统一 Worker 接口(execute + name),4 个 Worker 实现(Retrieval/Web/Memory/Analysis)
  • IterationDecider 基于置信度轨迹做终止判断(够好就停 + 停滞检测 + 策略切换)
  • PlanExecutor 按 dependsOn 做拓扑排序,同层步骤 CompletableFuture 并行
  • ObservationEvaluator 产出 5 种精确降级动作(空召回→Web、低分→HyDE、冲突→Analysis)

Result

  • DocMindAgent 从 ~1400 行重构(当前 ~1510 行,含 Phase 5/6 新增的范畴路由 + 路径决策)
  • 新增 16 个文件,每个 80-300 行,职责单一
  • 新增 Worker 仅需 1 个文件(实现接口 + 注册),原来需要改 ≥3 个核心文件
  • 新增 3 种执行策略(迭代/计划/拆解)和置信度反馈机制
  • SSE 事件协议、API 签名完全不变,前端无感知

STAR-4:fail-silent → fail-fast(随机向量 bug)

Situation:Review 代码时发现 VectorRetriever.embed() 在 Embedding API 失败时返回 1024 维随机向量,用这个随机向量去 Milvus 检索会返回无意义的垃圾结果,但下游完全不知道——它们带着正常的相似度分数混入 RRF 融合和最终 Prompt。

Task:消除这个 fail-silent 反模式,建立正确的降级语义。

Action:将 catch 块从"返回随机向量"改为"抛出 RuntimeException",异常向上传播到 retrieve() 被外层 catch 捕获,返回空列表。空列表进入 RRF 融合不污染结果,系统自然降级为只用 BM25。

Result

  • Embedding 正常时行为不变
  • Embedding 异常时向量检索被跳过,只用 BM25 结果,答案质量下降但不会出现幻觉来源
  • 建立了项目的核心原则:宁可少返回结果,不返回错误的结果

STAR-5:双模型策略 + 热切换

Situation:链路成本估算显示单查询 ¥0.012,主回答占 50%、Self-Reflection 占 30%、工具选择占 15%。但反思和工具选择都是轻决策类任务,用主模型是浪费。

Task:在不引入额外运维复杂度的前提下降低成本。

Action

  • 不维护两套 ChatModel 实例,复用主模型的 OpenAiApi 连接
  • 通过 OpenAiChatOptions.builder().model("qwen-turbo").build() 实现 per-call 模型覆盖
  • AtomicReference 实现 LLM 模型热替换,旧引用被正在进行的 SSE 流持有,自然完成后 GC 回收
  • 反思高分短路(rerank top-1 ≥ 0.85 跳过),覆盖 70% 查询
  • 缓存阈值从 3 调到 2,命中率从 30% 提升到 45%

Result

  • 单查询成本从 ¥0.012 降至 ¥0.005-0.007(-50%)
  • 每项优化有独立的 admin 开关,可运行时回退
  • 小模型 function calling 失败时自动降级到规则路由

STAR-6:Markdown-Aware 切块 + 增量索引

Situation:MinerU 输出了结构化 Markdown(带 heading、表格、代码块),但 TextChunker 还在按 \n\n 朴素分段——表格被切碎、代码块被英文句号 . 切碎、heading 层级丢失(DB 里 chapter 字段一直是空字符串)。同时文档更新只能整库重建,100 页 PDF 改 1 字要重新 embedding 200-400 次。

Task:重写切块器保留结构化语义,同时实现增量索引。

Action

  • 重写为 block-aware 装配器:逐行扫描识别 5 种 block(HEADING/TABLE/CODE/IMAGE/PARAGRAPH)
  • 表格和代码块原子保留不切碎,即使超过 600 字目标值——结构完整性优先于大小均匀性
  • heading 切换强制 flush buffer 防止跨章节误合并(这个 bug 被自己写的单测抓出来)
  • SHA-256 content_hash 做增量 diff:同 hash → 复用 vector_id 跳过 embedding,新 hash → 才 embedding
  • 打通 MySQL ↔ Milvus 的 vector_id 对齐(原来两端 ID 断开,只能整库 wipe)

Result

  • 表格完整保留、代码不被切碎、chapter 字段有值("第一章 > 第一节 > 概念定义")
  • 100 页文档改 1 字:embedding 从 200-400 次降到 ~1 次
  • 9 个单测覆盖各种结构化场景

补充 STAR-7:离线评测框架搭建

核心叙事:面试中"数据呢?"这个问题的根本解法。搭建 52 条 × 4 档对照 × 3 轮的评测框架,不复用 DocMindAgent(避免缓存/早停/短路污染对照),组件拆开按 variant 重新组合。最大发现不是数字,而是推翻了 3 个"我以为有用"的假设。

补充 STAR-8:MinerU 多模态文档统一入库

核心叙事:用一个外部依赖解决整个"多模态文档入库"问题。关键洞察是 MinerU 把 PDF/PPT/图片/HTML 统一输出 Markdown,下游 RAG 链路零行改动。降级按格式分级:PDF 降级 PDFBox(次优可用),PPT/图片 fail-fast(Java 生态无等价替代,静默降级比报错更危险)。

补充 STAR-9:对抗查询 100% 拒答的"虚假安全感"

核心叙事:5/5 拒答看起来完美,但查执行记录发现功劳属于 qwen-plus 的安全对齐训练,不是 SafetyGuard 拦截的。换安全对齐弱的模型可能 0/5。评测的价值不只是展示好指标,更是对漂亮数字提出质疑


STAR-10:规则引擎替代 LLM 路由——确定性 vs 智能的取舍

Situation:Phase 2 的 SupervisorAgent 使用 LLM Function Calling 决定调用哪些工具(doc_search / keyword_search / web_search / recall_memory),延迟 ~300ms,且结果不稳定——同一个查询两次可能选出不同的工具组合。路径判定逻辑散落在 DocMindAgent 和 SupervisorAgent 中,用隐式布尔开关推断路径,出了问题不知道走了哪条路。

Task:用确定性方案替代 LLM 工具选择,同时保证覆盖度——不能因为去掉 LLM 就漏选工具。

Action

  • 分析工具选择的决策空间:本质是 4 个信号(isAmbiguous / specificity / timeAware / memoryAware)到 4 个工具子集的映射,规则空间只有十几种组合
  • 设计 PathDecision record 统一封装路径决策输出:3 种模式(SELECTED_DOC / DECOMPOSED / RULE_PLANNER),reason 字段记录机器可读的判定原因
  • 实现 RetrievalPlanner 纯规则引擎:4 个 if 判断 <1ms,双源时效性校验(原始+改写问题同时检查时效关键词,防止改写丢失时间词)
  • ambiguous 保守策略:QueryClassification 降级时 isAmbiguous=true → 强制加 keyword_search 防向量漂移

Result

  • 路径决策延迟从 ~300ms 降到 <1ms
  • 100% 确定性:同一输入永远产出相同工具组合
  • 可单元测试:assertEquals(expected, planner.plan(classification))
  • 可追溯:PathDecision.reason 写入 agent trace + SSE routing 事件

核心叙事:不是所有决策都适合交给 LLM。工具选择的规则空间小且变化慢,LLM 在这上面的表现不比 if-else 好,但贵 300ms + 不确定 + 不可测试。


STAR-11:CRAG 评分机制——检索质量的最后一道闸

Situation:检索召回低质量切片(rerank 顶分 0.2-0.3)时,LLM 仍然基于这些切片生成答案——因为 LLM 不知道切片质量差,它只会"尽力回答",结果大概率是基于不相关内容编造的幻觉。Self-Reflection 能事后检查事实一致性,但它检查不了"检索到的内容跟问题不是同一主题"这种根源问题。

Task:在 generation 前加一道检索质量评估,LOW 质量时主动降级避免幻觉,AMBIGUOUS 时触发补偿检索。

Action

  • 参考 CRAG 论文(Yan et al. 2024)设计三档评分:HIGH(≥0.65 直接生成)/ AMBIGUOUS(灰区仲裁)/ LOW(≤0.25 降级 prompt)
  • 灰区仲裁选 heuristic 模式(默认):利用 rerank 阶段已产出的 per-chunk 分数做分布分析——top1 强且与 top2 差距 ≥0.15 → HIGH;avg ≤0.30 → LOW;其余 AMBIGUOUS。0ms 延迟,零额外调用
  • cross_encoder 模式作为可选:把 top-3 切片拼成上下文让 reranker 单对打分,~50ms,比论文里的小模型仲裁(~300ms)快 6 倍
  • AMBIGUOUS + 未尝试 web → 触发 WebWorker 补偿 → 补充后重新评分
  • 全部阈值放入 sys_ai_config 热配表(grader.high_threshold / grader.low_threshold / grader.arbitration_mode)

Result

  • LOW 质量切片不再进入 generation,直接走降级 prompt 明确告知"证据不足"
  • AMBIGUOUS 触发 Web Search 补偿,覆盖知识库盲区
  • 灰区阈值(0.65/0.25)是在 Langfuse trace 里看 rerank 分数分布后调出来的——Phase 6 可观测性的直接收益
  • 前端 grader 事件展示三色徽章,用户一眼可见检索质量

核心叙事:CRAG 解决的是"检索到了但不相关"的问题——Self-Reflection 检查答案质量,CRAG 检查检索质量,两者在链路中的位置不同、解决的问题不同,是互补关系不是替代。


STAR-12:从一个真实 bug 到调研业界做法补上路由分层(推荐讲述)

Situation:一次正常使用中遇到 bug。先做了一段普通的知识问答,再问"总结上面的对话"。系统的实际处理是:

  • 把"总结"、"上面"、"对话"当成检索关键词去 Milvus 查询,召回 12 条与对话内容毫无关系的切片
  • 自纠错判断置信度 65% 不达标,触发重写
  • 重写仍然基于同一批跑题切片,置信度降到 0%
  • 0% 置信度的回答还是被推送到前端

Task:定位根因后修掉这个 bug。但更重要的是判断这是个孤立 bug,还是设计上的结构性缺陷——后续是否还有类似问题(比如"你刚才说了什么"、"翻译你的回答"等)。

Action

第一步是确认结构性缺陷。读代码发现意图分类只有一层(factoid / procedural / comparison / opinion / chitchat),五个取值都默认要去查知识库。"总结上面的对话"被归入 factoid 或 chitchat,但下游不区分意图,照常调用 RetrievalWorker。自纠错只检查事实一致性,无法识别"检索到的内容跟问题完全不是一个主题"。所以这不是孤立 bug。

第二步是调研业界做法。看了 12 个生产级框架/产品和 3 篇核心论文:

  • LangGraph Adaptive RAG 教程:用结构化输出做条件路由 + 检索后再加一道闸
  • AWS Bedrock Agents:6 个内置提示词模板,Pre-processing 是独立阶段
  • Perplexity 工程博客:把追问先重写为独立查询,引用历史对话的请求在重写阶段就识别
  • LinkedIn 工程博客:路由 → 检索 → 生成三段式,路由用小模型决定是否在范围内
  • CRAG 论文(Yan 2024):检索后用独立评估器分三档
  • Self-RAG 论文(Asai 2023):在词表加反思 token 让模型自己决定是否检索(需要微调,未采用)

被弃用的方案也很明确:纯靠模型函数调用决定是否检索,LinkedIn / Airbnb v1→v2 / Microsoft Semantic Kernel 都从这个路径迁出。

第三步是设计与实现:

  • 加一层范畴判定区分四种情况:要查知识库、要看历史对话、闲聊、超出范围
  • 判定走两级——先用正则识别高置信度模式(命中即跳过模型调用),不命中再走模型
  • 元对话路径完全不进检索流程,只基于历史对话生成回答
  • 检索完成后加 CRAG 风格三档评估:rerank 顶分 ≥ 0.65 直接 HIGH,≤ 0.25 LOW,灰区做仲裁
  • 仲裁的实现选择上没用论文里的小模型评估器,而是把 top-3 切片拼成上下文让 reranker 重新单对打分。一次调用 50ms,是模型生成的 1/5 时延

第四步是工程优化。范畴判定原本设计成独立组件方便排错,跑通后做了第二轮——把它合并进 QueryUnderstanding 的同一次模型调用,只在提示词里加了一个 scope 字段。知识查询路径的路由调用次数从 2 次降到 1 次,省 ~250ms。要排错时一个开关切回拆分模式即可。

整套改造严格遵循一个原则:每一道闸都做了降级路径,任何一道判错或调用失败都会回到原来的流程,不会比改造前更糟。

Result

  • 检索越界 bug 修复,复现率从 100% 降到 0
  • 元对话路径调用 Milvus / BM25 / reranker 次数从各 1 次降到 0
  • 知识查询路径路由调用次数从 2 次降到 1 次
  • 灰区仲裁延迟从 ~300ms 降到 ~50ms
  • 新增 23 条单元测试覆盖(11 条规则路径 + 12 条三档评估各种模式)
  • 整个改动 ~825 行,不动 SupervisorAgent / Worker 现有逻辑、前端零改动可向后兼容

为什么推荐讲这个 STAR

  1. 真实:起点是一个能复现的 bug,不是"我想做这个"
  2. 方法论:bug → 判断是否结构性 → 调研业界 → 决策 → 实现 → 二次优化,链条完整
  3. 取舍:能讲清楚为什么没用 Self-RAG(要微调)、为什么没用纯函数调用路由(业界已弃)、为什么仲裁不用小模型而用 reranker(成本/延迟权衡)
  4. 避坑意识:先做独立组件再合并,便于排错;每一道闸都做降级,不比改造前更糟

五、项目时间线

2026-04 初    项目启动,基础 RAG + Web UI(Spring Boot + Vue 3)

    ├── 迭代 #1   fail-silent → fail-fast(随机向量 bug)
    ├── 迭代 #2   Langfuse OTel 可观测性集成
    ├── 迭代 #3   Self-Reflection 置信度标记
    ├── 迭代 #4   Query Decomposition 多跳检索
    ├── 迭代 #5   QueryProfiler 自适应检索参数(8 套预设)
    ├── 迭代 #6   双执行路径合并(删 1100 行 dead code)
    ├── 迭代 #7   成本优化 Tier 1(双模型+短路+缓存,-50%)
    ├── 迭代 #8   MinerU 多模态文档统一入库
    ├── 迭代 #9   Markdown-Aware Chunker + 增量索引

2026-05-02    离线评测框架搭建 + 首轮评测

    ├── 迭代 #10  离线评测框架(52 条 × 4 档 × 3 轮)
    ├── 迭代 #11  Self-Reflection 条件重写(忠实度 +0.037)
    ├── 迭代 #12  Phase 1: 扩大候选池 + MMR + 元数据丰富化
    ├── 迭代 #13  Phase 2: Supervisor-Worker 多 Agent 架构
    ├── 迭代 #14  Phase 3: HyDE 假设文档生成
    ├── 迭代 #15  Phase 3: Parent Document Retrieval 双层切块

2026-05-06    Phase 4 完成,文档整理

    ├── 迭代 #16  Phase 5: 范畴判定层 + CRAG 三档检索置信度评估
    │            (起点:用户输入"总结上面的对话"被错误送入向量检索)
    ├── 迭代 #17  Phase 5: PathDecision 规则引擎替代 LLM 路由
    ├── 迭代 #18  Phase 5: QueryUnderstanding 确定性后处理

2026-05-09    Phase 6 完成

    ├── 迭代 #19  Phase 6: Langfuse OTel 全链路追踪增强
    ├── 迭代 #20  Phase 6: 前端思考时间线重构

六、技术选型对照表

领域选了放弃了为什么
后端框架Spring Boot 3.4 + Spring AI 1.1.4LangChain4j / LangChain (Python)Spring AI 原生支持 Function Calling + MCP Server,Java 生态成熟
向量数据库Milvus 2.3.4PgVector, Qdrant, PineconeSpring AI 原生支持,COSINE + 标量过滤联合查询,可扩展到亿级
全文检索Lucene 8.11 (SmartCN)Elasticsearch内嵌式零额外部署,BM25 + 中文原生分词,项目规模不需要分布式
重排序DashScope gte-rerank (API)本地 BGE-Reranker-v2-m3无 GPU 环境,API 调用简单免运维;后续可切本地部署
嵌入模型text-embedding-v3 (1024 维)OpenAI ada-002, BGE-M3阿里云原生 + DashScope 统一计费,中文效果好
LLMqwen-plus / qwen-turboGPT-4o, ClaudeDashScope 统一生态 + 成本可控(双模型策略)
文档解析MinerU 云端 APITabula+POI+Tess4J 拼凑 / 自部署 MinerU一个依赖解决 PDF/PPT/图片/网页,免 GPU,统一输出 Markdown
Agent 架构Supervisor-Worker(自建)LangChain Plan-and-ExecuteRAG 子任务同构,不需要 DAG 调度;自建轻量可控
Query 拆解Query DecompositionPlan-and-Execute学术共识:multi-hop QA 用 Decomposition,非通用 Plan-and-Execute
缓存Redis 7(答案缓存+用户记忆)Caffeine / Memcached同时承担两个角色减少组件数,支持 TTL + 跨实例共享
对象存储MinIO本地磁盘 / 阿里 OSSS3 兼容 + 私有化部署,原件持久化
可观测性Langfuse + OpenTelemetryPrometheus + GrafanaLangfuse 原生理解 LLM 概念(prompt/completion/token),Spring AI 内置 OTel 支持
前端Vue 3.5 + TypeScript + Element PlusReact / Ant Design类型安全 + 成熟 UI 组件库 + SSE 流式渲染支持好

七、核心技术深度(简历扩展用)

算法与公式

算法公式应用场景
RRF 加权融合score = weight / (k + rank), k=60向量+BM25 结果合并
BM25Σ[IDF × TF(k1+1) / (TF + k1(1-b+b×dl/avgdl))], k1=1.5, b=0.75关键词全文检索
MMR 多样性MMR = λ×relevance - (1-λ)×max_sim(d, selected), λ=0.7重排后多样性保证
COSINE 相似度Milvus HNSW 索引, ef=64向量近邻检索
SHA-256content_hash 增量索引文档更新 diff

并发与线程模型

组件并发模型要点
AgentToolContextThreadLocal + synchronizedList工具执行侧通道,finally 清理防泄漏
SSE 流式DelegatingSecurityContextExecutorService子线程继承 Spring Security 认证信息
PlanExecutorCompletableFuture + 拓扑排序同层步骤并行,跨层串行
Query Decomposition专用线程池(core=8, max=16, CallerRunsPolicy)IO 密集独立于 commonPool
ChatModel 热切换AtomicReference CAS旧引用被 SSE 流自然持有,GC 回收

降级策略体系

正常路径降级路径触发条件
LLM Function CallingQueryRouter 规则路由LLM 调用异常
Cross-Encoder API关键词覆盖度打分rerank API 超时/429
MinerU 云端解析PDFBox 文本提取 (PDF only)MinerU 不可用
向量检索跳过,只用 BM25embedding API 异常
BM25 MySQL FULLTEXT应用内分词+模糊匹配FULLTEXT 无结果
Self-Reflection LLM规则检查(长度/措辞)反思 LLM 调用异常
Redis 缓存跳过缓存正常执行Redis 连接异常