dodo-agent

PPT生成失败策略与断点恢复

失败策略(FailedStrategy) 接下来我们来看 PPT生成流程中的失败策略(FailedStrategy)。在整个 PPT 生成智能体中,我们前面已经介绍过很多不同阶段,这些阶段本质上都是由 状态机 + 策略模式 来驱动执…

TL;DR

失败策略(FailedStrategy) 接下来我们来看 PPT生成流程中的失败策略(FailedStrategy)。在整个 PPT 生成智能体中,我们前面已经介绍过很多不同阶段,这些阶段本质上都是由 状态机 + 策略模式 来驱动执…

失败策略(FailedStrategy)

接下来我们来看 PPT生成流程中的失败策略(FailedStrategy)。在整个 PPT 生成智能体中,我们前面已经介绍过很多不同阶段,这些阶段本质上都是由 状态机 + 策略模式 来驱动执行的。系统会根据当前实例的状态,选择对应的策略进行处理。 但在真实的工程环境中,一个复杂的 AI 生成流程不能完全保证每一步都顺利完成。例如在实际运行过程中,可能会遇到很多问题: - 大模型返回结果格式异常 - 外部工具调用失败 - 文件生成异常 一旦这些问题发生,如果系统没有统一的失败处理机制,就很容易出现流程卡死、前端一直等待、或者直接抛出异常的情况。 因此在整个 PPT 生成系统中,我们设计了一个 统一的失败策略(FailedStrategy),专门用来处理所有异常情况。他的核心作用就是: 当 PPT 生成流程出现错误时,统一生成失败说明,并优雅地结束整个生成流程。 每个策略模式的donError都会有这样的一个状态机转向操作,将失败转向FailedStrategy,进行统一处理。

失败信息来源

当某个阶段执行失败时,系统会把错误信息记录到 AiPptInst 实例对象中:

String errorMsg = inst.getErrorMsg();

这个 errorMsg 可能来自很多不同的地方,例如: - 工具调用异常 - 大模型返回解析失败 - 网络请求错误 - 服务超时 这些错误信息会被统一保存到 AiPptInst 中,作为失败策略的输入。

构造失败说明

在获取到错误信息之后,不会直接把技术错误返回给用户,而是会先构造一段提示词,让大模型生成一段更加友好的失败说明。在构造提示词时,系统还会把 本轮的思考过程 一起传递给模型。这些思考过程会保存在 thinkingBuffer 中,例如可能如下所示: 系统会将这些信息组合成类似这样的内容:

## 上一轮遇到的问题:
信息不全请补充xxxx....

## 本轮遇到的问题
还缺少以下关键信息...

然后通过 Prompt 模板,让大模型生成一段自然语言的解释。这样用户看到的就不再是一段技术异常,而是一段更容易理解的说明。当然,在生成失败说明时,仍然会采用 流式输出的方式 返回结果。这样用户看到的效果仍然是 逐步生成的回复。前端的交互逻辑可以保持完全一致。无论是正常生成 PPT,还是生成失败,前端都只需要处理同一种流式数据结构。

保存失败结果

当失败说明生成完成后,系统还会把最终结果保存到当前会话中。保存的信息主要包括两部分: - 最终返回给用户的回答内容。 - 整个生成过程的思考记录。 例如系统可能会记录: 最终回答: “很抱歉,本次 PPT 生成过程中在生成第5页内容时出现异常,请稍后重试。” 思考过程: - 生成 PPT 大纲 - 生成第1页内容 - 生成第2页内容 - 调用图片生成服务 - 图片生成失败 这些信息会通过 sessionService 保存到会话记录中,方便后续查看或调试。

需求澄清如何暂停流程

在 PPT 生成智能体的整个流程中,需求澄清阶段其实是非常关键的一步。因为用户输入的往往只是一个非常简单的自然语言,例如: “帮我生成一份关于人工智能的PPT” 但对于系统来说,仅仅这一句话其实是远远不够的。因为在真正生成 PPT 之前,我们至少需要明确几个核心信息,例如: - PPT 的主题是什么 - 需要多少页 - 希望采用什么风格 - 面向的受众群体是谁 如果这些信息不完整,后续的生成效果往往会非常差。因此在系统设计中,我们专门设计了一个 需求澄清阶段,让大模型先对用户需求进行分析和补充。 这一阶段的核心目标是: 将用户的自然语言需求,转化为结构化、完整的 PPT 生成需求。 为此,我们会给大模型提供一段专门的提示词,用来指导它完成需求分析。

/**


public
        ## 角色
        你是专业的PPT需求澄清助手。名字叫做:豆豆,英文名叫dodo,你的责任是根据上下文及历史会话,帮助用户澄清他们的需求,确保所有必要信息都被收集。

        ## 任务
        分析用户需求,判断信息是否足够生成PPT:
        至少包含:


        ## 输出要求

在这个提示词中,有一个非常关键的设计:特殊标记。我们要求大模型在不同情况下输出不同的标记: - 如果信息不足,必须输出 【暂停生成PPT】 - 如果信息完整,必须输出 【开始生成PPT】 这样做的目的其实非常简单:让系统能够通过这些标记来判断流程是否应该继续执行。 因为在实际工程中,大模型返回的是自然语言文本,如果没有一个明确的结构标记,程序是很难准确判断模型意图的。例如模型可能会说:“信息已经足够,可以开始生成 PPT。”或者:“好的,我现在帮你生成 PPT。” 这些表达方式看起来意思差不多,但程序很难稳定识别。而通过强制约定 固定标记,系统就可以非常可靠地进行流程控制。 在实际实现中,我们会在流式输出结束时,对模型返回的完整文本进行一次判断。核心逻辑如下:

/**


public


}

这个方法的整体逻辑其实非常清晰,可以分为三个判断步骤。 第一步是 优先判断明确标记。 如果返回内容中包含:【开始生成PPT】,说明需求已经完整,系统可以继续执行后续流程。但是如果返回内容包含:【暂停生成PPT】。说明信息仍然不足,系统需要停止当前流程,并等待用户补充信息。 第二步是 兜底判断。 在实际运行中,大模型偶尔可能会忘记输出标记。因此我们增加了一层简单的兜底逻辑。如果返回内容中包含一些明显的提问词,例如:请问、请提供、请问需要,这类话术,那基本可以判断模型仍然在向用户询问信息,此时流程也应该暂停。最后,如果既没有发现暂停标记,也没有发现提问关键词,系统就会默认认为信息已经完整,可以继续执行。 通过这种方式,我们就可以实现完整的需求澄清的效果了。

用户中断会话如何断点恢复

PPT流程正在执行中,就被用户点击终止会话中断了,这种场景其实非常常见,那我们的流程如何恢复,如何从断点恢复执行呢? 其中用户中断这边的逻辑我们是和智能对话助手那边的逻辑是保持一致的,都是统一用的taskManager来进行控制,那么我们这边需要做的就是将每个策略的任务都注册成Disposable,并一起交给taskManager进行统一管理。 那当用户先终止了流程,然后在同一会话窗口中要求继续生成,我们的流程应该如何恢复呢? 让我们把注意力再转回到意图识别那部分PptIntentRecognizer。

存在错误信息

首先系统会判断任务是否存在错误信息。

if

}

如果 errorMsg 不为空,说明上一次执行过程中出现了异常。例如: - 调用工具失败 - 大模型返回异常 - 外部服务超时 - 需求澄清要求补齐信息 在这种情况下,如果用户再次发送消息,系统默认认为用户是希望 重新尝试之前的任务,因此直接返回 true,继续执行流程。

用户明确要求继续

接下来系统会检查用户输入的内容,看看用户是否明确表达了“继续执行”的意图。

String

如果用户输入中包含这些关键词,例如: - “继续生成” - “刚才那个 PPT 继续” - “retry” 系统就会认为用户希望恢复任务,因此返回 true。

任务处于中间状态

如果前面两个条件都没有触发,系统还会根据 任务状态 来进行判断。

if

这里的意思是:如果当前任务状态 既不是初始化状态,也不是成功状态,说明任务其实还没有真正完成。 例如可能处于这些状态: - 生成大纲中 - 生成页面中 - 生成图片中 如果此时用户又发送了一条消息,但并没有明确要求重新生成,那么系统会默认认为用户是希望 继续之前的任务。

用户明确要求重新生成

当然,还有一种情况是用户希望重新开始。例如用户输入: “重新生成一个 PPT。” 或者 “新建一个。” 因此系统还会检查是否包含一些 新建任务的关键词:

String

如果检测到这些关键词,系统就会判断用户希望 创建一个新的任务,因此返回 false,不再恢复之前的流程。

判断意图为恢复流程

当判断用户意图是恢复流程的时候,PPTBuilderAgent会进入到RESUME_PPT分支。 首先,系统会根据当前会话 ID,查询这个会话中最近的一次 PPT 实例。

AiPptInst

如果系统没有查到任何实例,说明这个会话之前并没有创建过 PPT 任务。这时候系统会直接返回提示信息: “当前会话中没有 PPT 实例,无法继续,请先创建一个 PPT。” 随后结束本次流程。如果成功获取到实例,系统接下来会读取当前任务的状态。

PptInstStatus

这个状态就是之前流程中断时所停留的位置。接下来系统会做一个特殊判断:如果当前状态已经是 SUCCESS。

if

这说明 PPT 实际上已经生成完成了。如果用户此时又说“继续生成”,系统就不会再执行生成流程,而是给出一个提示: “当前 PPT 已经成功生成,如果需要修改,请说明具体修改需求。” 这样做的原因很简单:生成流程已经结束,不存在继续执行的断点。 如果当前状态并不是 SUCCESS,那么说明任务实际上还没有完成。这时候系统就可以执行 断点恢复逻辑。 首先系统会向前端输出一段思考信息,让用户知道系统正在恢复流程。 例如:

正在从状态 RENDER 继续执行PPT生成

然后系统会直接调用状态机继续执行。

PptStateStrategyFactory

这里有一个非常重要的设计:系统并不会重新创建任务,也不会从头开始执行,而是直接从当前状态继续推进状态机。因为 AiPptInst 中已经记录了当前状态,状态机会根据这个状态找到对应的策略,然后继续执行后续流程。整个恢复流程可以理解为下面这样:

用户输入:继续生成
        ↓
意图识别判断为 ResumeIntent
        ↓
查询当前会话的 PPT 实例
        ↓
获取实例当前状态
        ↓
如果状态是 SUCCESS → 提示用户修改
        ↓
否则从当前状态继续执行状态机

通过这种方式,系统就实现了一种 非常自然的断点恢复机制。

版本提示

模型、框架与接口会持续变化。涉及版本号、参数与生产配置时,请在实践前对照对应官方文档。

LLMentor系统化学习大模型应用工程

内容来自个人课程知识库备份,并经过结构化整理。技术版本持续演进,生产使用前请结合官方文档验证。