Skip to content

待优化清单

已识别的优化方向,按优先级排列。每完成一项,移到 04-优化迭代记录.md 并标记完成。

高优先级(快速见效,面试加分明显)

H10. 离线评测框架(Naive vs Hybrid vs Rerank vs Full 对照) ✅ 已完成(2026-05-04)

  • 详见 04-优化迭代记录.md #1009-评测体系建设.md
  • 后续工作
    • 数据集从 10 条扩到 50+ 条(按真实 KB 内容补 expectedDocNames)
    • 跑完一次完整评测后把数字回填到 #10 与 09-doc
    • 加 V0(无 RAG 直答 baseline)+ V5(V4 + Query Decomposition)两档对照

H1. VectorRetriever 向量化失败降级修复 ✅ 已完成(2026-04-27)

H2. Agent 各步骤耗时统计 ✅ 已完成(2026-04-27)

H3. RRF/BM25/TextChunker 核心算法单元测试

  • 问题:核心算法没有测试覆盖,边界情况(空输入、单条输入、超长输入)未验证
  • 方案:参数化测试验证 RRF 融合公式、BM25 评分、文本切分逻辑
  • 面试价值:展示测试驱动的工程素养

H4. Self-Reflection 置信度标记 ✅ 已完成(2026-04-27)

H5. Query Decomposition 多跳检索 ✅ 已完成(2026-04-28)

H6. Query-Aware Adaptive Retrieval ✅ 已完成(2026-04-28)

  • 查询感知自适应检索参数:Complexity × Specificity 二维画像 → 8 套参数预设 + RRF 加权融合
  • 详见 04-优化迭代记录.md #5

H7. 双执行路径合并 + Query Decomposition 接入主路径 ✅ 已完成(2026-04-28)

  • 删除 RagPipeline 旧路径与 ChatController + Med* 实体重复映射
  • Query Decomposition 升级为 DocMindAgent 主路径能力
  • 详见 04-优化迭代记录.md #6

H8. 链路成本/延迟 Tier 1 优化 ✅ 已完成(2026-04-28)

  • SelfReflection 高分短路 + 双模型策略(qwen-plus / qwen-turbo)+ 缓存阈值 3→2 + stream_complete SSE 事件
  • 预期单查询成本 -50%、p50 延迟 -25%
  • 详见 04-优化迭代记录.md #7

H9. 全格式统一通过 MinerU 入库 —— PDF / PPT / 图片 / 网页 → Markdown ✅ 已完成(2026-04-28)

  • PDFBox 行交错 + 丢图丢表 + 不支持 PPT / 图片 / 网页:接 MinerU 云端 API(一个外部依赖解决多模态文档入库)
  • 文件流程(PDF/PPT/图片)+ URL 流程(MinerU-HTML)共享轮询主循环,通过 stateExtractor 函数抽象屏蔽 batch / task 两类响应差异
  • 降级分级:PDF 失败降级 PDFBox;PPT / 图片 / URL fail-fast 不静默降级
  • 双层闸门:env 静态开关 + sys_ai_config 动态开关
  • 详见 04-优化迭代记录.md #8

中优先级(功能完善,体现系统性思考)

M1. 检索结果置信度评分 ✅ 已完成(2026-05-07,Phase 5 Step 13)

  • 实际方案落点比原计划更深入:参考 CRAG 论文(Yan et al. 2024)做了三档评估器(HIGH / AMBIGUOUS / LOW),灰区四种仲裁模式(cross_encoder 默认 / llm / heuristic / disabled)
  • 不是简单的"低于阈值就标记",而是分档触发不同后续动作:HIGH 直接生成,AMBIGUOUS 进入仲裁,LOW 让现有 fallback 接管
  • 详见 04-优化迭代记录.md #16

M2. Micrometer 指标监控 ✅ 已被 Langfuse 方案覆盖(Phase 6 增强)

  • Phase 6 升级为完整 OTel 集成:TracedOp 消除 span 样板代码 + RootNameFilteringSpanProcessor 白名单过滤 + ChatModelObservationFilter 自动采集 LLM 调用
  • 详见 04-优化迭代记录.md #19

M3. QueryRouter 意图识别增强 → 已被 Phase 2 SupervisorAgent 架构取代,Phase 5 进一步加上范畴判定层

  • 原方案:增强 QueryRouter 正则 or 改用 few-shot LLM 分类
  • Phase 2 演进:引入 QueryClassification(intent + complexity + specificity 三维分类)+ SupervisorAgent 多策略编排 + ObservationEvaluator 动态降级链,原 QueryRouter 的职责被拆解到更精细的组件中。详见 04-优化迭代记录.md #13
  • Phase 5 补强:在三维分类之上加最外层"范畴判定层",区分四种处理路径(元对话 / 闲聊 / 知识查询 / 任务执行 / 越界)。原五类 intent 都默认要查知识库,Phase 5 解决了"总结上面的对话"被错误送入检索的问题。详见 04-优化迭代记录.md #16

M5. Markdown-aware Chunker(MinerU 后续) ✅ 已完成(2026-04-30)

M4. ContextCompressor 去重粒度参数化

  • 问题:去重用固定的前 50 字比较,不够灵活
  • 方案:将去重阈值移到 sys_ai_config,支持运行时调整
  • 面试价值:展示参数化设计思维

低优先级(锦上添花)

L1. MCP 工具调用统计竞态修复

  • 问题:查询+更新之间有竞态窗口
  • 方案:数据库 INSERT ON DUPLICATE KEY UPDATE

L2. MemoryTool 并发写入保护

  • 问题:无乐观锁,并发写入丢失更新
  • 方案:Redis WATCH/MULTI 或版本号

L3. 超长 Query 截断处理

  • 问题:用户输入 10000 字没有限制
  • 方案:入口处截断到 500 字,日志记录原始长度

L4. 文档提取编码检测

  • 问题:固定 UTF-8,旧 PDF 可能是 GBK
  • 方案:使用 ICU4J 或 juniversalchardet 自动检测编码

链路成本/延迟优化 Tier 2-3(迭代 #7 后续)

Tier 1(短路 + 双模型 + 缓存阈值)已落地。下面是延伸方向,按 ROI 排。详见 04-优化迭代记录.md #7 末尾的 Tier 2-3 列表。

T2-1. 拆解路径 Reranker 批量化(中 ROI)

  • 问题:3 子问题各调 1 次 rerank,3× 网络往返
  • 方案:合并候选集 → 1 次 rerank(query 用 originalQuery)→ SubQueryMerger 用合并分数
  • 预期:拆解路径 rerank API 调用 -67%

T2-2. Prompt 模板瘦身(中 ROI)

  • 问题:主回答 input ~4000 tokens 里模板 + 元信息占 ~1000+
  • 方案:审 src/main/resources/prompts/,删冗余前言、用更紧凑的 YAML 风格
  • 预期:主回答 input -15%

T2-3. 历史上下文摘要(中 ROI)

  • 问题buildConversationHistory 取近 6 条原始拼接,长会话膨胀
  • 方案:超过 N 条时把更早内容用小模型摘要为 1 段
  • 预期:长会话主回答 input -20-40%

T2-4. WebSearch 提前并行启动(低 ROI)

  • 问题:Tavily 1-3s 阻塞主流程
  • 方案:QueryProfiler 标 timeAware=true 时 Decomp 阶段就异步启动,最后 join

T2-5. Reranker 候选数自适应下调(低 ROI)

  • 问题:当前固定 25-40 候选,简单查询过度
  • 方案QueryProfiler.RetrievalParamsrerankCandidates 字段

T2-6. DashScope Context Cache(Prompt Cache)接入(中-高 ROI)

概念区分:语义答案缓存 vs Prompt Cache

项目当前已有的 SemanticCacheService 不是 Prompt Cache,二者是不同层的优化,可叠加使用。

维度语义答案缓存(已有)Prompt Cache(待接入)
缓存对象完整 RAG 答案 + sourcesLLM 输入侧的稳定前缀(系统提示、工具 schema)
命中条件query embedding cosine ≥ 0.92 且 KB 版本一致输入前缀逐字节相同(provider 侧 KV cache)
节省的成本整次 RAG 调用(embedding + 检索 + rerank + LLM)仅 LLM 输入 token 计费 + 首 token 延迟
失效粒度KB 任一变更全失效前缀任意 token 变更即失效
实现层应用层 RedisLLM Provider(DashScope Context Cache)
适用场景高频重复问题每次都跑的 agent 循环(工具描述、系统模板)

关键洞察:当前命中率 ~45% 的语义缓存解决的是"重复问题",但剩下 55% 不命中的请求每次都把 ~1000+ token 的稳定前缀(工具 schema + 系统模板)原样发给 LLM,这部分才是 Prompt Cache 的目标

改造方案

  • 问题:每次 agent 循环都把工具 schema(~600 token)+ 系统模板(~400 token)+ 反思模板(~300 token)原样发给 qwen,前缀稳定却未复用
  • 方案
    1. 调用 DashScope /services/aigc/text-generation/generation 时按 context-cache 文档加 cache: { enable: true } 参数(具体字段以 DashScope 当时文档为准)
    2. PromptAssembler 把 prompt 重组为 [稳定前缀] + [动态 chunks] + [用户问题] 三段式,前缀放在最前
    3. 工具调用路径(ChatClient + ToolCallbackProvider)确认 Spring AI 是否透传 cache 参数;不行则降级到自建 OkHttp 客户端走原生 API
    4. AiConfigHoldercache.prompt_cache_enabled 开关,便于 A/B
  • 预期
    • 主回答 input token 计费 -25~40%(前缀命中 50% 折扣,按 DashScope 现价)
    • TTFT 延迟 -15~30%(命中前缀不重新跑 attention)
    • 工具选择 / 反思的小模型路径收益更高(前缀占比更大)
  • 风险
    • DashScope Context Cache 有最小前缀长度门槛(通常 ≥256 token),短模板可能不命中
    • 前缀里任何动态字段(时间戳、用户 ID、随机 nonce)都会破坏命中,需审一遍模板
  • 面试 talking point

    "项目里语义缓存解决的是'同一个问题不要再跑一遍',但 agent 每次循环里工具 schema 和系统模板都是稳定的,那部分输入 token 还是每次都付钱。所以下一步是接 DashScope 的 Context Cache,把 prompt 重排成'稳定前缀 + 动态 chunks + 用户问题'三段,让 LLM provider 在 KV cache 层复用稳定前缀——和应用层语义缓存是叠加关系,一个省整次调用、一个省每次的输入 token。"