百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

基于深度研究的生成式AI应用开发(深度研究什么意思)

ccwgpt 2025-05-11 14:32 3 浏览 0 评论

“到2025年,RAG就死了。它已经被解决、重复过无数次了。它已经不再是什么新东西了。”最近我听到一位机器学习工程师这样说。确实,在2025年与客户讨论生成式人工智能用例时,我发现标准的RAG通常无法处理他们需要回答的复杂且不明确的问题。他们也无法训练用户提出足够具体的问题,以便简单的检索能够识别正确的上下文。数据源的数量和类型过于复杂,标准化变得困难。

进入深度研究。深度研究是目前最具通用性和价值的生成式人工智能应用设计模式。每个AI工程师和领域领导者都应该理解深度研究及其如何定制以满足特定领域的知识任务。不是指Gemini、ChatGPT等提供的现成的深度研究人员,而是您自己的自定义实现,解决您的特定领域知识任务。

在这篇文章中,我们将讨论如何实施和推广深度研究的设计模式。最终目标是将其专门化为您的领域用例。完整的代码库可以在GitHub上找到。

1、用于回答GCP技术问题的深度研究人员

为了有一个可以工作的示例用例,我们的目标是自动化我的大部分客户服务工程师的工作。在与客户会面后,我经常花时间撰写技术跟进邮件,提供答案以及文档和示例代码等资源。根据复杂程度的不同,这是一项相当大的时间投入,尤其是每周多次这样做时。我们将构建一个深度研究系统来自动化这些技术跟进邮件。作为工作流框架,我们将使用Firebase Genkit。

2、概念概述

深度研究模式由三个步骤组成:

  1. 理解并分解用户的请求
  2. 并行研究与检索管道以收集信息
  3. 聚合研究结果

深度研究生成式人工智能应用程序设计模式概述

让我们开始构建!

3、分解用户请求

我们的起点是会议记录。在会议结束后,我们需要提取技术问题以进行后续跟进。我们应该以易于后续处理的格式提取这些问题。

这是一个简单的文本提示就可以轻松解决的任务,使用原始会议记录作为输入。每个要提取的任务都是一个普通的字符串形式的问题。例如,一个问题可能如下所示:“我如何使用Gemini 2.5和Genkit构建自己的深度研究助手?”由于我们希望助手适用于任何会议记录,因此要提取的任务数量应该是灵活的。因此,提取提示应该输出一个包含不确定数量字符串的数组。

Genkit在TypeScript中允许我们为可调用提示定义输入和输出类型。提取提示的输入是原始会议记录,即一个简单的字符串。我们定义提取提示(任务对象数组)的输出如下:

const TaskSchema = z.object({  
   description: z.string(),  
});
const TaskArraySchema = ai.defineSchema(  
   'TaskArraySchema',  
   z.array(TaskSchema)  
);

提取提示不应过度工程化,提取问题是相对简单的任务。提示应解释任务的上下文和规则。大型语言模型必须不能编造或遗漏任何在记录中存在的问题。此外,它应简要总结问题,同时尽可能保持事实性。为此,我们将温度设置在较低的一端。使用dotprompt,Genkit使定义提示与提示配置、输入和输出模式相结合变得容易(Firebase Genkit文档)。

---
config:
  temperature: 0.1
input:
  schema:
    transcript: string
output:
  schema: 
  TaskArraySchema
---

<< System Instructions >>
You are an AI assistant helping extract customer's technical questions from a conversation between a Google Cloud Customer Engineer (CE) and a customer.
Analyze the transcript and identify the core technical questions, needs, or pain points the customer expresses or implies. Focus on questions that highlight the customer's technical understanding and requirements regarding Google Cloud.

** Always include topics that the CE promised to send a follow up on.
** Always focus on the specific technical questions that can be answered based on the GCP documentation.
** Only focus on questions that have NOT YET been answered in the meeting.
** DO NOT include high level business and use case questions.

<< Output Formatting >>
Format the output as a JSON array of tasks, where each task has:

description: The customer's technical question, phrased as a concise question from the customer's perspective.

<< Meeting Transcript to analyze >>
    
{{transcript}}

<< End of Meeting Transcript to analyze >>
    
<< Tasks (JSON array) >>

为了协调提取步骤,我们定义了一个Genkit流程,定义了一个可调用的提示如下:

export const taskExtractionFlow = ai.defineFlow(  
    {  
        name: "taskExtractionFlow",  
        inputSchema: z.string(),  
        outputSchema: TaskArraySchema,  
    },  
    async (transcript) => {  

        const taskExtractionPrompt = ai.prompt('taskExtraction');  

        const { output } = await taskExtractionPrompt(  
            {  
                transcript: transcript,  
            },  
            {  
                model: gemini25ProPreview0325,  
                output: { schema: TaskArraySchema }  
            }  
        );  

        return output;  
    }  
);

就这样,我们已经完成了任务提取。我们完成了第一步,现在可以动态地为每次过去的会议提取要研究的问题。

4、并行任务研究

接下来,我们需要研究每个问题。研究步骤的复杂度随着所需知识库的大小和类型而大大不同。我们的应用程序处理围绕GCP架构决策和技术问题,当在GCP上构建应用程序时。我们通常提供最新的GCP文档信息和GCP GitHub存储库中的示例代码。

我们选择两个知识来源来提供适当的研究背景:

首先,假设我们拥有自定义构建的知识库,将有价值的GCP文档片段转换为文本嵌入并存储在Firestore中。这可以通过Firestore向量索引功能访问。

其次,我们包括Google可编程搜索引擎API,以模拟每个研究任务的Google搜索。可编程搜索引擎API允许我们利用Google索引的最新文档,并限制搜索引擎到给定的一组网站及其子页面。这使得可编程搜索引擎API成为获取实时信息的便捷来源,而无需重新构建我们的知识库(每当文档更新时)。

任务研究的输入是我们之前创建的研究任务数组。每个任务的研究结果应按以下方式分类:

const TaskResearchResponse = ai.defineSchema(  
   'TaskResearchResponse',  
   z.object({  
       answer: z.string(),  
       caveats: z.array(z.string()),  
       docReferences: z.array(z.object({  
           title: z.string(),  
           url: z.string(),  
           relevantContent: z.string().optional(),  
       })),  
   })  
);

这种严格类型化的研究报告允许我们在聚合步骤中传递重要的注意事项和相关文档引用。这种结构对于保持对哪个文档导致哪些见解的监督至关重要。它允许我们在后续电子邮件中提供文档链接和见解。

任务研究的核心是文档检索。Genkit允许通过许多预构建插件或自定义函数连接知识库。在这种情况下,我们定义了两个自定义检索器,一个用于在Firestore向量索引上运行相似性搜索,另一个用于通过可编程搜索引擎API运行搜索查询。

以下是我们的Firestore向量搜索Genkit检索器的定义。它使用向量搜索服务器端操作(ssa)。该ssa被定义为Firestore SDK的包装器(请参阅代码库中的代码)。然后将知识库中最近邻文档格式化为Genkit文档数组。

export async function createSimpleFirestoreVSRetriever(ai: Genkit) {  
    return ai.defineSimpleRetriever(  
        {  
            name: "simpleFirestoreVSRetriever",  
            configSchema: z.object({  
                limit: z.number().optional().default(5),  
            }).optional(),  
            // Specify how to get the main text content from the Document object  
            content: (doc: Document) => doc.text,  
            // Specify how to get metadata from the Document object  
            metadata: (doc: Document) => ({ ...doc.metadata }), // Include all metadata from the action  
        },  
        async (query, config) => {  
            const results = await vectorSearchAction(query.text, { limit: config?.limit });  

            const resultDocs: Document[] = results.map(doc => {  
                return Document.fromText(  
                    doc.content || '', {  
                    firestore_id: doc.documentId,  
                    chunkId: doc.chunkId  
                });  
            });  

            return resultDocs;  
        }  
    );  
}

自定义搜索检索器调用我们之前定义的可编程搜索引擎。搜索引擎API仅提供结果URL。因此,我们解析结果并通过提供的URL从顶部搜索结果中抓取内容。我们对原始HTML内容进行一些基本清理,并将其转换为Genkit文档以供进一步处理。您可以在仓库中找到完整代码(GitHub链接)。

接下来,我们使用Gemini 2.5填充研究问题响应模式来总结单个研究问题的答案。汇总提示是一般且简单的:

---  
config:  
  temperature: 0.1  
input:  
  schema:  
    task: string  
    format_instructions: string  
output:  
  schema:   
  TaskResearchResponse  
---  
使用提供的Google Cloud文档上下文研究以下技术任务。  

任务: {{task}}  

提供一个响应,满足以下条件:  
1. 清晰回答技术问题  
2. 在相关时包括具体的步骤或配置  
3. 注意重要的注意事项或最佳实践  
4. 引用特定部分的文档  

技术响应:

最后,我们将各个任务研究步骤合并到Genkit流程中。为了高效处理,我们将检索步骤包装成每个任务的Promise,并将研究聚合包装成异步映射。这样并行化了各个任务研究。

export const taskReseachFlow = ai.defineFlow(  
    {  
        name: "taskReseachFlow",  
        inputSchema: TaskArraySchema,  
        outputSchema: TaskResearchResponseArray,  
    },  
    async (tasks) => {  

        console.log("Running Task Research Flow on transcript...");  

        // 1. 并行检索每个任务的相关文档  
        const retrievalPromises = tasks.map(task => {  
            return ai.retrieve({  
                retriever: 'simpleFirestoreVSRetriever',  
                query: task.description, // 使用任务描述作为查询  
                options: { limit: 10 }  
            });  
        });  

        const taskDocsArray = await Promise.all(retrievalPromises);  

        // 2. 并行任务研究生成  
        const taskResearchPrompt = ai.prompt('taskResearch');  
        const generationPromises = tasks.map(async (task, index) => {  
            const docs = taskDocsArray[index];  
            const { output } = await taskResearchPrompt(  
                {  
                    question: task.description  
                },  
                {  
                    docs: docs,  
                    output: { schema: TaskResearchResponse }  
                }  
            );  

            return output;  
        });  
        const researchResults = await Promise.all(generationPromises);  

        return researchResults;  
    }  
);

我们的流程返回一个研究结果对象数组。标准化的格式使结果最容易在下一个工作流步骤中处理。

5、研究结果的聚合

我们已经取得了很大的进展!我们成功地提取了要研究的任务,并建立了一个高效的管道,可以并行高效地处理任意数量的研究任务,利用多个知识库,包括公共和私有知识库。剩下的就是聚合一份关于我们发现的报告,以一种对我们和我们的用户有用的形式呈现。我们的工作示例是撰写技术跟进邮件的挑战。使用个体研究报告的集合,让我们制定一个文本提示,使用这些报告撰写一封简洁的电子邮件草稿,提供答案和文档资源。

研究报告聚合提示将因用例而异。迄今为止我们使用的提示中,这个提示应该是最详细的,因为我们需要定义期望的输出格式、语气等。由于我们主要调整的是写作风格,多镜头提示方法在这里也很有意义。通过清晰且多样的例子,模型更容易遵循你的风格指导。

为了生成我们的技术跟进邮件,让我们使用以下提示:

---
config:
  temperature: 1
input:
  schema:
    tasks: string
    research: string
output: 
  schema:
    email: string
---
Generate a professional follow-up email to the customer based on the technical research results.
    
Original Task:
{{tasks}}
    
Research Findings:
{{research}}
    
Requirements for the email:
1. Start with a brief meeting reference and summary
2. Address each technical question briefly and consicely, most bullet points should not be longer than one sentence
3. Link to specific documentation sections whenever possible, but only as it makes sense in the context
5. Maintain a professional but friendly tone
6. End with next steps or an offer for further clarification

Here is an example of the conciseness level of the email.
In your email please match the level of details provided in the example.
<< BEGINNING OF EXAMPLE EMAIL >>
See example in the full codebase
<< END OF EXAMPLE EMAIL >>
    
Generated Email:

我们最终应该将电子邮件生成提示包装到相应的流程中(代码在仓库中)。

这就完成了深度研究管道。

此深度研究工作流的完整代码可在GitHub上找到。克隆仓库,探索实现细节,并根据您的研究密集型任务进行调整。

6、结束语

深度研究设计模式是生成式人工智能应用架构中最实用的一种。深度研究是标准RAG系统的下一代进化。我相信在未来1到2年内,许多日常知识工作者的任务将通过深度研究应用程序加速或自动化。这个项目的最初想法是为了自动化我工作中的一大块内容。这已经做得非常好了。

任何深度研究人员的实际实用性将在很大程度上取决于您可以提供访问的知识库的相关性。如果需要进一步调整结果,检索质量和任务研究报告的整理是额外的性能杠杆。最后,最终报告生成必须针对每个用例进行定制。所需输出格式将因知识任务而异。最终报告的整理至关重要,特别是在将深度研究人员暴露给终端用户时。即使您可以生成最佳和最相关的个体任务研究结果,但如果最终报告不符合用户的需求,整个深度研究人员将是无用的。

当然,我们生活在一个LLM代理的时代。我们讨论的实现遵循LLM工作流,而不是依赖代理做出决策。在大多数情况下,这将是足够的。我们可以考虑为最复杂的任务实现一个代理循环。例如,任务研究可以迭代每个任务研究报告,直到研究足够彻底。然而,代理能力往往会使架构复杂化,而使用工作流(甚至更好)可以达到相同的效果。因此,我们将代理实现留作下一篇文章的主题。

您对深度研究模式有何经验?您是否能够对其进行定制?您打算用它自动化日常工作中的哪些任务?


原文链接:基于深度研究的GenAI应用开发 - 汇智网

相关推荐

定时任务工具,《此刻我要...》软件体验

之前果核给大家介绍过一款小众但实用的软件——小说规则下载器,可以把网页里的小说章节按照规则下载到本地,非常适合喜欢阅读小说的朋友。有意思的是,软件作者当时看到果核写的体验内容后,给反推荐到他的帖子里去...

前端定时任务的神库:Node-cron,让你的项目更高效!

在前端开发中,定时任务是一个常见的需求。无论是定时刷新数据、轮询接口,还是发送提醒,都需要一个可靠且灵活的定时任务解决方案。今天,我要向大家介绍一个强大的工具——Node-cron,它不仅能解决定时任...

Shutter Pro!一款多功能定时执行任务工具

这是一款可以在电脑上定时执行多种任务的小工具,使用它可以根据时间,电量等来设定一些定时任务,像定时打开程序、打开文件,定时关机重启,以及定时弹窗提醒等都可以轻松做到。这是个即开即用的小工具,无需安装,...

深度解析 Redis 缓存击穿及解决方案

在当今互联网大厂的后端开发体系中,Redis缓存占据着极为关键的地位。其凭借高性能、丰富的数据类型以及原子性操作等显著优势,助力众多高并发系统从容应对海量用户的访问冲击,已然成为后端开发从业者不可或...

从零搭建体育比分网站完整步骤(比较好的体育比分软件)

搭建一个体育比分网站是一个涉及前端、后端、数据源、部署和维护的完整项目。以下是从零开始搭建的详细流程:一、明确项目需求1.功能需求:实时比分展示(如足球、篮球、网球等)支持多个联赛和赛事历史数据查询比...

告别复杂命令行:GoCron 图形界面让定时任务触手可及

如果你是运维人员或者经常接触一些定时任务的配置,那么你一定希望有一款图形界面来帮助你方便的轻松配置定时任务,而GoCron就是这样一款软件,让你的配置可视化。什么是GoCron从名字你就可以大概猜到,...

Java任务管理框架核心技术解析与分布式高并发实战指南

在当今数字化时代,Java任务管理框架在众多应用场景中发挥着关键作用。随着业务规模的不断扩大,面对分布式高并发的复杂环境,掌握其核心技术并进行实战显得尤为重要。Java任务管理框架的核心技术涵盖多个方...

链表和结构体实现:MCU软件定时器(链表在单片机中的应用)

在一般的嵌入式产品设计中,介于成本、功耗等,所选型的MCU基本都是资源受限的,而里面的定时器的数量更是有限。在我们软件设计中往往有多种定时需求,例如脉冲输出、按键检测、LCD切屏延时等等,我们不可能...

SpringBoot定时任务(springboot定时任务每小时执行一次)

前言在我们开发中,经常碰到在某个时间点去执行某些操作,而我们不能人为的干预执行,这个时候就需要我们使用定时任务去完成该任务,下面我们来介绍下载springBoot中定时任务实现的方式。定时任务实现方式...

定时任务新玩法!systemd timer 完整实战详解

原文链接:「链接」Hello,大家好啊!今天给大家带来一篇使用systemdtimer实现定时任务调度的详细实战文章。相比传统的crontab,systemdtimer更加现代化、结构清晰...

Celery与Django:打造高效DevOps的定时任务与异步处理神器

本文详细介绍了Celery这一强大的异步任务队列系统,以及如何在Django框架中应用它来实现定时任务和异步处理,从而提高运维开发(DevOps)的效率和应用性能。下面我们先认识一下Cele...

订单超时自动取消的7种方案,我用这种!

前言在电商、外卖、票务等系统中,订单超时未支付自动取消是一个常见的需求。这个功能乍一看很简单,甚至很多初学者会觉得:"不就是加个定时器么?"但真到了实际工作中,细节的复杂程度往往会超...

裸机下多任务框架设计与实现(gd32裸机配置lwip 网络ping不通)

在嵌入式系统中,特别是在没有操作系统支持的裸机环境下,实现多任务执行是一个常见的挑战。本文将详细介绍一种基于定时器的多任务框架设计,通过全局时钟和状态机机制,实现任务的非阻塞调度,确保任务执行中不会出...

亿级高性能通知系统构建,小白也能拿来即用

作者介绍赵培龙,采货侠JAVA开发工程师分享概要一、服务划分二、系统设计1、首次消息发送2、重试消息发送三、稳定性的保障1、流量突增2、问题服务的资源隔离3、第三方服务的保护4、中间件的容错5、完善...

运维实战:深度拆解Systemd定时任务原理,90%的人不知道的玩法

运维实战:深度拆解Systemd定时任务原理,90%的人不知道的高效玩法一、Systemd定时任务的核心原理Systemd定时任务是Linux系统中替代传统cron的现代化解决方案,通过...

取消回复欢迎 发表评论: