本篇为spring-ai-alibaba学习系列第三十一篇

前面介绍 rewrite_multi_query 节点最后会根据用户上传文件标识 user_upload_file 决定下一节点

现在来看一下第二个分支,当 user_upload_file 为 false 时,转入 background_investigator 节点

该节点主要是负责将每一个优化查询进行分类,并选择合适的搜索平台进行搜索,之后调用大模型结合搜索结果对优化查询进行解答

提示词

上述三步都用到了大模型,其提示词如下

问题分类提示词

# 问题分类Agent你是一个智能问题分类器,负责将用户问题分配给最合适的专业Agent。你需要准确分析问题的主题和意图,然后选择最适合处理该问题的专业Agent。## Agent类型说明### 1. academic_research (学术研究Agent)
**适用场景**:
- 学术论文查找和分析
- 科研项目调研
- 技术文献综述
- 研究方法指导
- 学术写作支持
- 期刊会议信息
- 研究趋势分析**关键词识别**:论文、期刊、研究、学术、科研、技术、算法、学者、引用、文献、会议、学科、理论、实验、分析、方法、模型、框架、综述、调研### 2. lifestyle_travel (生活&旅游Agent)
**适用场景**:
- 旅游攻略和行程规划
- 美食推荐和餐厅信息
- 住宿和交通指南
- 购物和娱乐建议
- 生活服务信息
- 城市生活指南
- 当地文化体验**关键词识别**:旅游、旅行、攻略、美食、餐厅、酒店、景点、购物、生活、娱乐、休闲、度假、出行、路线、推荐、体验、民宿、特产、文化、风俗### 3. encyclopedia (百科Agent)
**适用场景**:
- 概念定义和解释
- 历史事件和文化知识
- 科普知识和原理说明
- 基础知识普及
- 名词术语解释
- 百科全书式问答
- 知识点关联分析**关键词识别**:什么是、定义、概念、历史、由来、起源、介绍、解释、含义、意思、百科、知识、科普、基础、原理、背景### 4. data_analysis (数据分析Agent)
**适用场景**:
- 统计数据分析
- 市场研究和调研
- 趋势分析和预测
- 行业报告解读
- 经济指标分析
- 数据可视化需求
- 量化研究支持**关键词识别**:数据、统计、分析、趋势、指标、报告、图表、比较、增长、下降、占比、排名、调查、市场、行业、经济、财务## 分类规则### 优先级判断
1. **学术性质优先**:如果问题涉及学术研究、论文、科研等,优先选择 `academic_research`
2. **数据分析优先**:如果问题明确要求数据分析、统计、趋势分析等,优先选择 `data_analysis`
3. **生活实用优先**:如果问题涉及旅游、美食、生活服务等实用信息,选择 `lifestyle_travel`
4. **知识普及默认**:如果问题是询问基础概念、定义、历史等,选择 `encyclopedia`### 特殊情况处理
- **跨领域问题**:选择最主要的需求领域对应的Agent
- **模糊问题**:根据问题的核心意图选择最合适的Agent
- **多重需求**:选择用户最主要关心的方面对应的Agent## 输出要求**严格按照以下格式输出,只返回Agent类型代码,不要任何解释或额外信息:**```
academic_research
```或```
lifestyle_travel
```或```
encyclopedia
```或```
data_analysis
```## 分类示例**学术研究类**:
- "帮我找一些关于机器学习的最新论文"
- "深度学习在医学影像中的应用研究现状如何?"
- "如何写一篇关于区块链技术的综述论文?"**生活旅游类**:
- "北京三日游攻略推荐"
- "上海有什么好吃的本帮菜餐厅?"
- "去日本旅游需要准备什么?"**百科知识类**:
- "什么是量子计算?"
- "法国大革命的背景和影响是什么?"
- "太阳系的形成过程是怎样的?"**数据分析类**:
- "中国GDP增长趋势分析"
- "电商行业市场规模统计数据"
- "房价走势预测分析"现在开始进行问题分类,只返回对应的Agent类型代码。 

搜索平台选择提示词

# 搜索平台智能选择器你是一个专业的搜索平台选择专家,负责根据用户问题的类型和内容,智能选择最合适的搜索平台。## 可用的搜索平台### 传统搜索引擎
- **TAVILY**: 通用网络搜索,适合大多数常规问题
- **ALIYUN_AI_SEARCH**: 阿里云AI搜索,适合中文内容和商业信息
- **BAIDU_SEARCH**: 百度搜索,适合中文本土化内容
- **SERPAPI**: Google搜索API,适合需要高质量英文搜索结果### 专业工具调用平台
- **OPENALEX**: 学术论文和研究文献搜索,适合学术研究
- **GOOGLE_SCHOLAR**: 谷歌学术搜索,适合论文、引用、学者信息
- **WIKIPEDIA**: 维基百科搜索,适合百科知识和基础概念
- **OPENTRIPMAP**: 旅游景点和地理位置信息,适合旅游规划
- **TRIPADVISOR**: 酒店、餐厅、景点评价,适合旅游决策
- **WORLDBANK_DATA**: 世界银行数据,适合经济和发展数据分析## 选择原则1. **学术研究类问题**:优先选择 OPENALEX 或 GOOGLE_SCHOLAR
2. **百科知识类问题**:优先选择 WIKIPEDIA
3. **旅游生活类问题**:根据具体需求选择 OPENTRIPMAP 或 TRIPADVISOR
4. **数据分析类问题**:优先选择 WORLDBANK_DATA
5. **通用问题**:根据语言和地域选择合适的传统搜索引擎## 输出格式请严格按照以下格式输出,只返回平台名称,不要添加任何其他内容:```
PLATFORM_NAME
```例如:
- 如果选择学术搜索:`OPENALEX`
- 如果选择维基百科:`WIKIPEDIA`
- 如果选择通用搜索:`TAVILY`## 注意事项- 仔细分析问题的领域和具体需求
- 优先选择最专业、最相关的平台
- 如果问题模糊或跨领域,选择覆盖面更广的平台
- 考虑问题的语言特点(中文/英文)

问题回答提示词

以下是对 [background.md](file://D:\code\spring-ai-alibaba\spring-ai-alibaba-deepresearch\src\main\resources\prompts\background.md) 文档的中文翻译:---CURRENT_TIME: {{ CURRENT_TIME }}你是一个由 `supervisor` 代理管理的 `researcher` 代理。你致力于使用搜索工具进行深入调查,并通过系统地使用可用工具(包括内置工具和动态加载的工具)提供全面的解决方案。## 步骤1. **理解问题**:忘记你之前的知识,仔细阅读问题陈述以确定所需的关键信息。
2. **综合信息**:- 结合从所有使用的工具(搜索结果、抓取内容和动态加载的工具输出)中收集到的信息。- 确保响应清晰、简洁并直接解决问题。- 跟踪并标注所有信息来源及其相应的 URL 以便正确引用。- 在有帮助的情况下,包含相关图片。## 输出格式- 以结构化的 markdown 格式提供响应。
- 包含以下部分:- **问题陈述**:重新表述问题以确保清晰。- **研究发现**:按主题而不是按使用的工具组织你的发现。对于每个主要发现:- 总结关键信息- 跟踪信息来源,但不要在文本中包含内联引用- 如有可用,包含相关图片- **结论**:基于收集到的信息提供对问题的综合回应。- **参考文献**:在文档末尾以链接参考格式列出所有使用的来源及其完整 URL。确保每个参考文献之间有一个空行以提高可读性。使用以下格式:```markdown- [来源标题](https://example.com/page1)- [来源标题](https://example.com/page2)```- 始终以 **{{ locale }}** 语言输出。
- 不要在文本中包含内联引用。相反,请跟踪所有来源并在末尾的参考文献部分使用链接参考格式列出它们。## 注意事项- 始终验证收集到的信息的相关性和可信度。
- 如果没有提供 URL,则仅关注搜索结果。
- 永远不要进行任何数学计算或文件操作。
- 不要尝试与页面交互。抓取工具只能用于抓取内容。
- 不要执行任何数学计算。
- 不要尝试进行任何文件操作。
- 只有当无法仅从搜索结果获得必要信息时才调用 `crawl_tool`。
- 始终为所有信息包含来源归属。这对最终报告的引用至关重要。
- 在呈现来自多个来源的信息时,清楚地标示每条信息来自哪个来源。
- 使用 `![图片描述](image_url)` 在单独的部分包含图片。
- 所包含的图片应**仅**来自从搜索结果或抓取内容中收集到的信息。**永远不要**包含不是来自搜索结果或抓取内容的图片。
- 始终使用 **{{ locale }}** 语言进行输出。

使用方法

首先需要添加所需的配置

# 是否开启智能agent,若不开启,则使用传统单一搜索引擎,默认开启
spring.ai.alibaba.deepresearch.smart-agents.enabled=# 智能agent搜索平台配置,对不同问题类型,配置不同搜索平台,若不配置,则交由大模型自主选择
# 例如,百科类问题,交由维基百科平台
spring.ai.alibaba.deepresearch.smart-agents.searchPlatformMapping.search-platform-mapping.{问题类型}.primary=# 可用的搜索引擎(列表)
spring.ai.alibaba.deepresearch.search-list=# 爬虫配置,爬取搜索引擎返回的链接
spring.ai.alibaba.toolcalling.jinacrawler.enabled=
spring.ai.alibaba.toolcalling.jinacrawler.api-key=

另外,需要将配置中用到的搜索组件注册为工具,以下是一个yaml格式的样例配置

spring:ai:alibaba:toolcalling:baidu:search:enabled: truetavilysearch:api-key: ${TAVILY_API_KEY}enabled: truejinacrawler:enabled: falseapi-key: ${JINA_API_KEY}serpapi:api-key: ${SERPAPI_KEY}enabled: truealiyunaisearch:api-key: ${ALIYUN_AI_SEARCH_API_KEY}base-url: ${ALIYUN_AI_SEARCH_BASE_URL}enabled: true# 学术研究工具调用配置openalex:enabled: false# 旅游生活工具调用配置opentripmap:enabled: falseapi-key: ${OPENTRIPMAP_API_KEY}# 百科知识工具调用配置wikipedia:enabled: false# 数据分析工具调用配置worldbankdata:enabled: falsegooglescholar:enabled: falsedeepresearch:# 定义项目可以使用的搜索引擎search-list:- tavily- aliyun- baidu- serpapismart-agents:enabled: falsesearch-platform-mapping:academic_research:primary: openalexlifestyle_travel:primary: opentripmapencyclopedia:primary: wikipediadata_analysis:primary: worldbankdatageneral_research:primary: tavily

最后,在对话的入参中需加入以下字段

enable_deepresearch:是否开启深度研究,决定后续节点

search_engine:搜索引擎,不填则默认为tavily

节点产出

background_investigation_results:大模型结合各搜索平台搜索结果生成的回答

site_information:各平台检索结果(1.0.0.3版本仅保存了最后一个平台的检索结果)

源码跟踪

跟踪:在 DeepResearchConfiguration 中,background_investigator 节点是一个 BackgroundInvestigationNode 类型的节点,创建时需要传入9个参数,分别是 jinaCrawlerService, infoCheckService, searchFilterService, questionClassifierService, searchPlatformSelectionService, smartAgentProperties, backgroundAgent, sessionContextService, toolCallingSearchService

其中,jinaCrawlerService、searchFilterService、toolCallingSearchService 用来构建 searchInfoService;smartAgentProperties、questionClassifierService、searchPlatformSelectionService 用来构建 smartAgentSelectionHelper

研究:先看一下 BackgroundInvestigationNode 的 apply 方法的整体逻辑

1)首先获取重写与扩展后的优化查询列表

2)针对每一个优化查询,首先使用 smartAgentSelectionHelper 自动选择查询方式,然后使用 searchInfoService 执行搜索,将搜索结果放入 site_information 中

ps:1.0.0.3 版本中,只会将最后一个查询的结果放入 site_information,之前请求的搜索结果会被覆盖

3)针对每一对优化查询及其搜索结果,构造一条UserMessage,然后根据 session_id,使用sessionContextService,获取最近的报告,然后使用 backgroundAgent 一起发送给大模型

4)将第三步中的所有返回结果,一起放入 background_investigation_results 中

5)判断 enable_deepresearch 标识,为 true 则进入 planner 节点,否则进入 reporter 节点

跟踪:使用 smartAgentSelectionHelper 的 intelligentSearchSelection 方法,可以根据用户查询返回合适的搜索方法

1)使用 questionClassifierService 对用户问题进行分类,分为学术研究、生活旅游、百科、数据分析和通用研究五个类别

2)根据问题类别选择合适的平台,选择时优先考虑配置文件中对每一类问题配置的搜索平台,若未配置,则交由大模型进行选择,若大模型选择失败,则使用每一类问题默认的搜索平台

跟踪:使用 searchInfoService 的 searchInfo 方法,执行搜索,获取搜索结果

跟踪:backgroundAgent,预设了一个提示词模板的 ChatClient,主要通过搜集的结果来回答每一个优化后的问题

附BackgroundInvestigationNode 的 apply 方法的代码

    public Map<String, Object> apply(OverAllState state) throws Exception {logger.info("background investigation node is running.");Map<String, Object> resultMap = new HashMap<>();List<List<Map<String, String>>> resultsList = new ArrayList<>();List<String> queries = StateUtil.getOptimizeQueries(state);assert queries != null && !queries.isEmpty();for (String query : queries) {// 使用统一的智能搜索选择方法SmartAgentUtil.SearchSelectionResult searchSelection = smartAgentSelectionHelper.intelligentSearchSelection(state, query);List<Map<String, String>> results;// 使用支持工具调用的搜索方法results = searchInfoService.searchInfo(StateUtil.isSearchFilter(state), searchSelection.getSearchEnum(),query, searchSelection.getSearchPlatform());resultMap.put("site_information", results);resultsList.add(results);}List<String> backgroundResults = new ArrayList<>();assert resultsList.size() != queries.size();for (int i = 0; i < resultsList.size(); i++) {List<Map<String, String>> searchResults = resultsList.get(i);String query = queries.get(i);Message messages = new UserMessage("搜索问题:" + query + "\n" + "以下是搜索结果:\n\n" + searchResults.stream().map(r -> {return String.format("标题: %s\n权重: %s\n内容: %s\n", r.get("title"), r.get("weight"),r.get("content"));}).collect(Collectors.joining("\n\n")));String sessionId = state.value("session_id", String.class).orElse("__default__");List<SessionHistory> reports = sessionContextService.getRecentReports(sessionId);Message lastReportMessage;if (reports != null && !reports.isEmpty()) {lastReportMessage = new AssistantMessage("这是用户前几次使用DeepResearch的报告:\r\n"+ reports.stream().map(SessionHistory::toString).collect(Collectors.joining("\r\n\r\n")));}else {lastReportMessage = new AssistantMessage("这是用户的第一次询问,因此没有上下文。");}String content = backgroundAgent.prompt().messages(lastReportMessage, messages).call().content();backgroundResults.add(content);logger.info("背景调查报告生成已完成: {}", backgroundResults.size());}resultMap.put("background_investigation_results", backgroundResults);String nextStep = "planner";if (!StateUtil.isDeepresearch(state)) {nextStep = "reporter";}resultMap.put("background_investigation_next_node", nextStep);return resultMap;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/95298.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/95298.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/95298.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ESP32S3:开发环境搭建、VSCODE 单步调试、Systemview 分析任务运行情况

目标: 实现点灯工程&#xff0c;并且可以基于 vscode 进行单步调试与 systemview 来分析任务运行情况。 环境搭建 如需在 ESP32-S3 上使用 ESP-IDF&#xff0c;请安装以下软件&#xff1a; 设置 工具链&#xff0c;用于编译 ESP32-S3 代码&#xff1b;编译构建工具 —— CMa…

linux系统学习(6.软件包管理)

目录 一、概述 1.分类 2.命名方式 3.一个软件包的组成 1. 软件包的基本定义 2. 一个软件包通常包含的部分 ① 程序文件 ② 库文件 ③ 配置文件 ④ 数据文件 / 资源文件 ⑤ 文档 / 帮助信息 ⑥ 服务脚本 / 单元文件&#xff08;如果是服务型软件&#xff09; ⑦ 包的…

数据结构青铜到王者第八话---队列(Queue)

目录 一、队列(Queue) 1、概念 2、队列的使用 3、队列模拟实现 4、循环队列 4.1数组下标循环的小技巧&#xff08;1&#xff09;下标最后再往后(offset 小于 array.length): index (index offset) % array.length 4.2如何区分空与满 4.3设计循环队列 二、双端队列 (Deq…

Windows系统之不使用第三方软件查看电脑详细配置信息

MENU使用系统信息工具&#xff08;最详细&#xff09;使用命令行查看命令提示符PowerShell&#xff08;信息更丰富&#xff09;使用DirectX诊断工具&#xff08;查看显卡和声音设备&#xff09;查看设备管理器&#xff08;查看硬件驱动&#xff09;一条命令合集&#xff08;Pow…

K8s学习笔记(一)——

一、k8s是什么一个分布式原来是主要用来管理容器的呀&#xff08;专业点叫“容器编排”&#xff09;&#xff0c;什么是管理&#xff1f;其实就是增删改查等等&#xff0c;简单来理解&#xff0c;k8s就是实现容器增删改查的呗。是开源的&#xff0c;在Linux系统下。就跟创建的s…

Zynq开发实践(FPGA之平台免费IP)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】和c语言平台提供posix api一样&#xff0c;一般fpga厂家也会提供各种各样免费的ip给客户使用。这样&#xff0c;客户就不需要自己去写每一个ip了&am…

nginx 配置文件初识全局块、events、http、server、location 的层级关系

Nginx 配置其实只有两类指令&#xff1a; 放在“某个块”里的块级指令&#xff1b;直接写在顶层的全局指令。 把全部配置想象成一个树形结构&#xff0c;根节点叫 main&#xff0c;往下依次分叉即可。下面用 1 张 ASCII 树 1 张极简示例&#xff0c;30 秒就能看懂层级关系。 层…

OCR大模型最新研究

最新OCR大模型介绍1.GPT-4o 2024.5.14 3.MinerU 2024.7.4 3.GOT-OCR 2024.9.3 4.InternVL3-78B 2025.4.11 开源 通用多模态大模型&#xff0c;OCR是它们的能力之一 因其训练数据的偏向&#xff0c;在文档理解、数学公式识别、图表分析等任务上通常是开源模型中的SOTA&a…

php电子签名

原理使用一对公钥和私钥&#xff0c;用私钥对数据进行签名&#xff0c;用公钥对签名数据进行加密&#xff0c;形成电子签名。电子签名认证&#xff0c;用私钥解密数据&#xff0c;用公钥验证签名。若加密容过长&#xff0c;则将加密内容按照固定长度分块&#xff0c;对每块进行…

鸿蒙Harmony-从零开始构建类似于安卓GreenDao的ORM数据库(三)

目录 一,插入单条数据 二,批量插入数据 三,根据条件删除数据 四,传入对象删除数据 五,删除整张表的数据 六,根据条件更新数据 前面两个章节数据库的创建以及数据库表的创建都已经完成了,下面我们再来看看数据库的增删改查如何构建。 一,插入单条数据 我们先来看一下官…

年度优质会议推荐:【西安石油大学主办|IEEE出版|往届均EI】第七届智能控制、测量与信号处理国际学术会议 (ICMSP 2025)

第七届智能控制、测量与信号处理国际学术会议 (ICMSP 2025) 2025 7th International Conference on Intelligent Control, Measurement and Signal Processing (ICMSP 2025) 2025年11月28-30日 中国北京 主办单位&#xff1a;西安石油大学 会议详情&#xff1a;请点击 亮…

isp 图像处理--DPC坏点矫正

一&#xff0c;Bayer pattern简要介绍我们平时所看到的彩色图像每个像素有三个分量组成&#xff0c;分别为红绿蓝。而目前广泛用到的成像传感器为CMOS传感器&#xff0c;其输出的数据格式为每个像素点只有一个颜色分量&#xff0c;一般称为Bayer Pattern数据&#xff0c;格式如…

Redis常见数据类型及应用场景

好的&#xff0c;我们来详细讲解 Redis 的数据结构及其应用场景。Redis 的强大之处不仅仅在于它支持简单的键值对&#xff0c;更在于它提供了丰富的数据结构&#xff0c;每种结构都针对特定类型的应用场景进行了优化。 核心数据结构与应用场景 Redis 主要支持以下五种核心数据结…

【后端数据库】MySQL 索引生效/失效规则 + 核心原理

SQL 优化的核心 —— 什么时候能“走索引”&#xff0c;什么时候会“失效”。整理一个索引生效/失效规则 核心原理的全景图&#xff0c;帮助彻底理解。&#x1f511; MySQL 索引使用的核心原理MySQL 使用 BTree 索引&#xff08;最常见&#xff09;&#xff0c;特点是&#xf…

基于 YOLOv11n 的无人机航拍小目标检测算法学习

基于 YOLOv11n 的无人机航拍小目标检测算法问题&#xff1a;无人机航拍图像中小目标检测面临尺度变化大导致的检测精度较低和推理速度较慢等 解决&#xff1a;在 C3k2 模块中引入可变形卷积&#xff08;DCN&#xff09;&#xff0c;增强模型在复杂背景下对 多尺度目标的特征提取…

第06章:map():数据变形金刚,想变什么变什么

文章目录map()基础&#xff1a;一对一的数据转换map()的工作原理方法引用让代码更简洁对象转换&#xff1a;实际业务应用用户信息转换示例特殊类型的map()&#xff1a;mapToInt、mapToLong、mapToDouble链式map()&#xff1a;多重转换map()与filter()组合&#xff1a;数据处理管…

197-200CSS3响应式布局,BFC

CSS3响应式布局-媒体查询举例<title>01.媒体查询_媒体类型</title><style>h1 {width: 600px;height: 400px;background-image: linear-gradient(60deg,red,yellow,green);font-size: 40px;color: white;text-shadow: 0 0 20px black;text-align: center;line…

[Android] UI进阶笔记:从 Toolbar 到可折叠标题栏的完整实战

学习 Android 开发的过程中&#xff0c;UI 控件往往是最直观也最容易踩坑的部分。本文整理了我在学习《第一行代码》后的实践笔记&#xff0c;涵盖 Toolbar、自定义标题栏、菜单、Snackbar、CoordinatorLayout、可折叠标题栏、SwipeRefreshLayout 下拉刷新、FloatingActionButt…

计算机网络---http(超文本传输协议)

1. HTTP的定义与核心属性 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是万维网&#xff08;WWW&#xff09;的核心通信协议&#xff0c;定义了客户端&#xff08;如浏览器、APP&#xff09;与服务器之间如何传输“超文本”&#xff08…

【qml-7】qml与c++交互(自动补全提示)

背景&#xff1a; 【qml-5】qml与c交互&#xff08;类型单例&#xff09; 之前记录过qml与c交互的方式&#xff0c;目前为止我使用的是“类型单例”方式。这些名字是我自己起的&#xff0c;只为说明问题&#xff0c;严谨的还是以手册为准。 “类型单例”方式时提到过自动补全…