创新实训二 使用通义千问API实现多轮对话
2.1 通义千问API调研
我们的程序之前的Serviceapi.java中实现了调用api实现单次对话,但这显然无法满足我们的需求。
首先,我阅读了阿里云的如何使用通义千问API实现模型多轮对话:如何使用通义千问API_模型服务灵积(DashScope)-阿里云帮助中心 (aliyun.com)。想要通过其示例程序实现多轮对话。其示例程序如下。
// Copyright (c) Alibaba, Inc. and its affiliates.
import java.util.ArrayList;
import java.util.List;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.JsonUtils;
public class Main {
public static GenerationParam createGenerationParam(List<Message> messages) {
return GenerationParam.builder()
.model("qwen-turbo")
.messages(messages)
.resultFormat(GenerationParam.ResultFormat.MESSAGE)
.topP(0.8)
.build();
}
public static GenerationResult callGenerationWithMessages(GenerationParam param) throws ApiException, NoApiKeyException, InputRequiredException {
Generation gen = new Generation();
return gen.call(param);
}
public static void main(String[] args) {
try {
List<Message> messages = new ArrayList<>();
messages.add(createMessage(Role.SYSTEM, "You are a helpful assistant."));
messages.add(createMessage(Role.USER, "如何做西红柿炖牛腩?"));
GenerationParam param = createGenerationParam(messages);
GenerationResult result = callGenerationWithMessages(param);
printResult(result);
// 添加assistant返回的消息到列表
messages.add(result.getOutput().getChoices().get(0).getMessage());
// 添加新的用户消息
messages.add(createMessage(Role.USER, "不放糖可以吗?"));
result = callGenerationWithMessages(param);
printResult(result);
printResultAsJson(result);
} catch (ApiException | NoApiKeyException | InputRequiredException e) {
e.printStackTrace();
}
System.exit(0);
}
private static Message createMessage(Role role, String content) {
return Message.builder().role(role.getValue()).content(content).build();
}
private static void printResult(GenerationResult result) {
System.out.println(result);
}
private static void printResultAsJson(GenerationResult result) {
System.out.println(JsonUtils.toJson(result));
}
}
在这段代码中,createGenerationParam(List<Message> messages)
方法用于创建并返回一个 GenerationParam
对象。这个对象包含了生成对话所需的参数,比如模型、消息列表、结果格式等。
callGenerationWithMessages(GenerationParam param)
方法用于调用生成对话的功能,并返回一个 GenerationResult
对象,其中包含生成的结果。
createMessage(Role role, String content)
方法用于创建一个包含特定角色和内容的消息对象(Message
)。
可以看出,实现多轮对话的核心在于创造一个Message List,把每一次我方的对话和Qwen的答句存储到这个List中。把List赋给param,然后反复使用param生成答句。
2.2 使用通义千问实现多轮对话
对一个用户在一次使用中生成多轮对话,我完成了一个简陋实现以替换我们原本的Apiservice.java。通过设置一个count,解决直接进行调用会出现的“不要让同一角色对话反复出现两次”的报错。
package com.SmartMed_Connect.service;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.aigc.generation.GenerationOutput;
import com.alibaba.dashscope.aigc.generation.models.QwenParam;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.MessageManager;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.utils.Constants;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class ApiService {
int count = 0;
public static GenerationParam createGenerationParam(List<Message> messages) {
return GenerationParam.builder()
.model("qwen-turbo")
.messages(messages)
.resultFormat(GenerationParam.ResultFormat.MESSAGE)
.topP(0.8)
.build();
}
public static GenerationResult callGenerationWithMessages(GenerationParam param) throws ApiException, NoApiKeyException, InputRequiredException {
Generation gen = new Generation();
return gen.call(param);
}
@Value("${ai-key}")
private String apiKey;
List<Message> messages = new ArrayList<>();
public String query(String queryMessage) {
Constants.apiKey = apiKey;
try {
if (count == 0) {
messages.add(createMessage(Role.SYSTEM, "你是一名智能医生,请结合上下文,回答病人的问题,不许回答其他问题。"));
}
messages.add(createMessage(Role.USER, queryMessage));
GenerationParam param = createGenerationParam(messages);
GenerationResult result = callGenerationWithMessages(param);
messages.add(result.getOutput().getChoices().get(0).getMessage());
GenerationOutput output = result.getOutput();
Message message = output.getChoices().get(0).getMessage();
count++;
return message.getContent();
/*
Generation gen = new Generation();
MessageManager msgManager = new MessageManager(10);
Message systemMsg = Message.builder().role(Role.SYSTEM.getValue()).content("你是智能医生,你只回答与医疗相关的问题,不要回答其他问题!").build();
Message userMsg = Message.builder().role(Role.USER.getValue()).content(queryMessage).build();
msgManager.add(systemMsg);
msgManager.add(userMsg);
QwenParam param = QwenParam.builder().model(Generation.Models.QWEN_TURBO).messages(msgManager.get()).resultFormat(QwenParam.ResultFormat.MESSAGE).build();
GenerationResult result = gen.call(param);
GenerationOutput output = result.getOutput();
Message message = output.getChoices().get(0).getMessage();
return message.getContent();
*/
} catch (Exception e) {
return "发生错误,请稍后再试。";
}
}
private static Message createMessage(Role role, String content) {
return Message.builder().role(role.getValue()).content(content).build();
}
}
加粗样式