Skip to content
oldmanpushcart edited this page Dec 28, 2024 · 1 revision

多模态对话生成

内容简介

QWEN在进行多模态对话生成时,主要分为文本模型和多模态模型两大类模型 API,这两类模型交互格式有比较大的差异,无形中给使用者增加了理解成本和使用难度。

为了降低使用难度 Dashscope4j 对文本和多模态的模型的调用方式进行了封装,允许调用者用相同的 API 完成多种模态的对话。

功能特点

  1. 统一文本和多模态模型的请求与应答 API 格式
  2. 封装函数调用与插件调用,具备一次对话多段函数调用能力
  3. 封装本地文件上传预处理动作,允许用本地文件完成多模态模型对话

内容大纲

  • 文本对话:QWEN
    • 函数调用
    • 插件调用
  • 图片识别:QWEN-VL
  • 音频识别:QWEN-AUDIO
  • 长文本对话:QWEN-LONG

详细内容

核心类介绍

整个对话过程Request和Response的请求应答过程,在其中关键的类和对应解释如下

  • ChatRequest: 对话请求
    • messages[]: 对话消息
      • contents[]: 消息内容
  • ChatResponse:对话应答
    • message:应答消息

其中,Content是屏蔽文本和多模态内容的关键类,不同的内容类型有不同的Content.Type来决定其代表的是视、图、音、文等众多类型中的那一类。根据模型的不同在序列化过程中会进行自动转换以应对不同模型之间的差异。

文本对话

对话的请求有 异步流式 两种模式

  • 异步模式:返回 CompletionStage,拿到返回值则表明对话已经成功结束。

      // 创建请求
      final ChatRequest request = ChatRequest.newBuilder()
          .model(ChatModel.QWEN_TURBO)
          .addMessage(Message.ofUser("你好呀!"))
          .build();
    
      // 对话应答
      client.chat().async(request)
          .thenAccept(System.out::println)
          .toCompletableFuture()
          .join();
  • 流式模式:返回 CompletionStage<Flowable>,拿到返回值则表明HTTP连接已经建立,正在接收SSE的事件,对应的事件会被转换为 ChatResponse 对象,并通过 Flowable 对外透出。

      final ChatRequest request = ChatRequest.newBuilder()
          .model(ChatModel.QWEN_TURBO)
          .addMessage(Message.ofUser("你好呀!"))
          .build();
    
      client.chat().flow(request)
          .thenAccept(flow -> flow.blockingSubscribe(response -> {
              System.out.println(response.output().best().message().text());
          }))
          .toCompletableFuture()
          .join();

    流式模式下可以通过设置 option(ChatOptions.ENABLE_INCREMENTAL_OUTPUT, true) 来开启增量输出,默认值为 false

函数调用

函数调用是智能体的杀手锏功能,也是和大模型和外部系统沟通的主要手段之一,堪称大模型的四肢。

在大模型的函数调用是通过两阶段 API 调用接力完成。

  • 第一阶段:用户对话LLM,LLM分析需要调用哪个函数,并根据对话内容组织函数入参,并返回给用户要发起函数调用,并声明了期望调用的函数名、参数列表。

  • 第二阶段:用户发起函数调用,LLM根据函数调用的参数调用函数,并返回函数的输出。

如果自己去写这两个阶段的拼接将会十分的繁琐,而且这只是一次函数调用。在部分场景下会在本次对话中持续多次不同的函数接力调用。这个时候 Dashscope4j 就为你提供了良好的封装,你可以像下面这样调用:

首先我们先声明一个函数类,并实现 ChatFunction 接口

@ChatFnName("echo")
@ChatFnDescription("当用户输入echo:,回显后边的文字")
public class EchoFunction implements ChatFunction<EchoFunction.Echo, EchoFunction.Echo> {

    @Override
    public CompletionStage<Echo> call(Echo echo) {
        return CompletableFuture.completedFuture(echo);
    }

    public static class Echo {

        @JsonProperty
        @JsonPropertyDescription("需要回显的文字")
        private String words;

    }

}

然后在与LLM对话时,将函数注册到对应 ChatRequest 中即可。

// 创建请求
final ChatRequest request = ChatRequest.newBuilder()
    .model(ChatModel.QWEN_TURBO)
    .addMessage(Message.ofUser("echo: HELLO!"))
    .addFunction(new EchoFunction()) // 注册函数
    .build();

// 对话应答
client.chat().async(request)
    .thenAccept(System.out::println)
    .toCompletableFuture()
    .join();

插件调用

图片识别

音频识别

长文本对话

Clone this wiki locally