qinghuan
返回三条项目主线

主项目候选 · 三选一 / 研究与编排方向

DeepResearch

做一个会查资料、可中断、能追溯来源的研究助手

如果你已能独立写 Spring Boot 接口,想重点准备 Agent 工作流、检索和评测,优先考虑这一条。范围限定为技术选型报告:先给研究计划,用户批准后查资料,最后交付带来源的结论。

中高核对 2026-09-29

先固定版本和学习范围

JDK 17 · Spring Boot 3.4.8 · Spring AI 1.0.0 · Spring AI Alibaba 1.0.0.4

打开本轮固定源码 · 项目仓库

提交 7f009adf56fadacdc78a02c4967aebe784918b11

仓库许可证标识:Apache-2.0(读取该 SHA 的 LICENSE)。本页介绍所读版本,未保证未来版本保持相同行为。

开始前要会

  • 能写 Spring Boot 接口与自动化测试
  • 理解异步任务、取消信号和数据库事务
  • 先理解“先找资料再回答”的检索增强流程
环境、模型费用和额外服务
  • JDK 17+、Maven(README 要求 3.6+)
  • 自备 DashScope 模型账户和额度;模型调用可能产生费用,不复用 README 免费额度宣传。
  • 默认配置还启用了 Tavily、SerpAPI、阿里云搜索等入口,不能只填一个模型 Key 就承诺完整功能能用;选择一个搜索服务并关闭不用的项。
  • Python 执行要 Docker Engine;默认 docker-host 是 Unix socket,Windows 要按本机 Docker 环境配置。
  • 按功能启用 Elasticsearch、Redis、Langfuse;默认 RAG/Redis/MCP 开关关闭,不能说全部已接通。

已经在源码中读到

一次任务大致怎样走

  1. 用户提问
  2. 拆解问题与研究计划
  3. 用户批准或修改
  4. 按步骤搜索 / 计算
  5. 整理报告与来源

工作流有真实分支

源码包含规划、人工反馈、并行研究和报告节点。搜索在研究节点内由服务调用;不能把每一步都说成模型自主决定。

有可比较的检索实现

混合检索和 RRF 已有源码。RRF 按搜索结果的名次合并分数,不等于用另一个模型重新判断相关性。

需要自己补齐或验证

这些能力不能直接写成“已实现”

  • 状态留在内存中;持久化任务、重复恢复和副作用防重需要自己补。
  • 当前流式路径保存的 Future 代表“建立订阅”这份工作,并非流本身。离线实验复现了“停止返回 true,但等待中的上游未收到取消”的时序;真实模型、工具与 HTTP 连接的取消传播仍待验证。
  • RRF 默认 k=60、阈值 0.1。两个来源都排第一时 2/61≈0.0328,需要检查阈值用途;单来源分支处理不同,且 RAG 默认关闭,不能推广为整个应用失效。
  • 原 pom 默认跳过测试;现有 GraphProcessExceptionHandlingTest 主要走旧 AsyncGenerator 重载,不能覆盖当前 Flux 路径。

建议改造 · 不是原仓库成绩

把原项目变成自己的项目

按顺序完成最小闭环,再增加难度。只把真正实现并测过的部分写进简历;如果声明支持恢复或并发,就补对应的故障实验。

01

让“停止”和“预算”真正生效

取消信号传到流订阅、模型和搜索;累计任务的调用次数、Token、搜索次数和总耗时。

怎样验收

  • 假模型持续要求工具调用时,在配置上限结束并说明原因。
  • 取消后不再发起新节点;记录未能立刻停止的在途请求和清理耗时。
02

用数据证明报告可信

自建 30–50 个技术问题与固定文档集,比较纯向量检索、混合检索和不同 RRF 参数;检查引用是否支持结论。

怎样验收

  • 相同题集、模型和预算做对照;报告检索命中率、引用可追溯率与失败样本。
  • 网页无结果、来源互相矛盾、搜索限流时,输出明确的不确定性和部分结果。
03

进阶:让任务能在重启后继续

用数据库保存任务、节点结果、恢复版本和工具调用标识;恢复前检查哪些动作已经完成。

怎样验收

  • 在人工批准前停机,再启动后可继续同一任务。
  • 工具已完成、结果尚未保存时故障;本地业务通过事务与幂等记录防重,外部动作依据服务方幂等协议或对账结果恢复,无法确认则进入待核对。

按这个顺序读源码

每读一步,画一条调用关系,写下输入、状态变化和失败出口。无需先把整个仓库读完。

  1. 第 1 步 · 先固定构建版本pom.xmlpom.xml
  2. 第 2 步 · 从请求找到图与恢复入口ChatController.javasrc/main/java/com/alibaba/cloud/ai/example/deepresearch/controller/ChatController.java
  3. 第 3 步 · 画清哪些分支是程序决定的DeepResearchConfiguration.javasrc/main/java/com/alibaba/cloud/ai/example/deepresearch/config/DeepResearchConfiguration.java
  4. 第 4 步 · 追踪流、异常和取消GraphProcess.javasrc/main/java/com/alibaba/cloud/ai/example/deepresearch/controller/graph/GraphProcess.java
  5. 第 5 步 · 用两份短列表手算融合分数RrfFusionStrategy.javasrc/main/java/com/alibaba/cloud/ai/example/deepresearch/rag/strategy/RrfFusionStrategy.java
  6. 第 6 步 · 区分旧测试与当前接口路径GraphProcessExceptionHandlingTest.javasrc/test/java/com/alibaba/cloud/ai/example/deepresearch/controller/graph/GraphProcessExceptionHandlingTest.java

准备好回答这些追问

先用自己的实现和实验回答,再对照源码。只背术语,很难解释异常情况。

  1. 同一次请求中,哪些是固定工作流,哪些决定由模型做?为什么不用一个超长 Prompt?
  2. MemorySaver 与会话历史、任务持久化有什么区别?进程在工具成功但 checkpoint 未写入时崩溃怎么办?
  3. 用户点击停止,为什么只 cancel Future 可能停不掉 Flux 下游?如何证明钱不再花?
  4. 研究节点有失败时,报告应该等待、重试、跳过还是交付部分结果?
  5. RRF 与向量相似度、神经重排分别解决什么?为什么不能直接共用一个 0.1 阈值?
  6. 怎样说明混合检索确实有收益,而非模块越多越好?

本轮实际验证范围

  • 已固定提交并审阅源码;在独占副本中仅将 pom 的 skipTests 从 true 改为 false,使用 JDK 17.0.20.1 编译与定向执行测试,原克隆未改。
  • GraphProcessExceptionHandlingTest 的 Surefire 报告:4 个测试、0 失败、0 错误、0 跳过。命令直接调用 compiler 与 surefire 目标,避开绑定的格式修改步骤。
  • 这 4 个测试调用旧 AsyncGenerator 重载,不证明当前 Flux 接口的取消与恢复正确。未启动完整应用、未调用模型或搜索服务。
  • 原 RRF 类与 Spring AI 1.0.0 依赖在 JDK 21.0.12 下按 Java 17 目标编译运行,10 个固定断言通过。双来源样例在 k=60、threshold=0.1 时返回空列表;阈值 0 仅作实验对照,未验证 Spring 配置绑定或真实检索质量。
  • 对当前 GraphProcess 的 Flux 重载做了一个离线取消实验:订阅已建立、负责建立订阅的 Future 已结束、上游仍等待时,stopGraph 返回 true,但未取消上游,之后仍能收到完成信号。9 个检查描述同一个实验时序,不是 9 个端到端任务;无模型、HTTP 或真实研究节点。

源码链接是阅读证据;改造建议是待完成任务。二者都不等于完整系统运行证明。