1、(1)星火文档问答主要解决的是–当需要AI解读时,文字数目较多,可把文字输入文档,对文档进行问答操作。
(2)百度千帆适用于文字较少(一次最多1000,但最好控制在两百以内,不然太慢了)。
2、下面是官网,官网提供的Java demo,缺少依赖,不能使用,而且编写的chat方法和普通的方法略有不同,没法编写返回值(因为问答还没读完就跳出方法了,这个你们测试方法的时候就会发现。各种bug,和大学生写的代码一样)(狠狠的吐槽)星火文档问答官网
3、方法提示:(异步获取数据,想怎么写随意,我简单提供一个比较low的方法)
(1)上传文件upload方法,需要时间,内部使用回调方法确保上传完成后再chat。
(2)在ChatDocUtil的chat方法中,status=2中把buffer存入redis,下次调直接从redis获取就可以。
(3)在主方法中,fori,sleep,break 循环获取redis的值。
(4)问答读取的时候可能会携带文档名称,我这边用的txt文件,就在问的时候给他说了–返回结果不要出现字母txt,或者可以replace替换一下。
(5)若需要解读多个文档,建议分开调方法,避免时间太长。
//主方法
abs = resultKey.getString("abs");
String abs_result = "摘要:\n"+abs.replaceAll("\\&[a-zA-Z]{1,10};", "") //去除类似< > 的字串
.replaceAll("<[a-zA-Z]+[1-9]?[^><]*>", "") //去除开始标签及没有结束标签的标签
.replaceAll("</[a-zA-Z]+[1-9]?>", ""); //去除结束标签
createFolderAndFile("D:\\ContentAi", "D:\\ContentAi\\" + "abs" + publicNum + ".txt", abs_result);
absAI = AI_API("D:\\ContentAi\\" + "abs" + publicNum + ".txt", publicNum, "abs");
// 设置定时任务来删除文件
Timer timer = new Timer();
timer.schedule(new DeleteFolderTask("D:\\ContentAi"), 1000 * 60 * 60 * 24);
//创建本地文件
private static void createFolderAndFile(String folderPath, String filePath, String content) {
File folder = new File(folderPath);
if (!folder.exists()) {
folder.mkdirs(); // 创建文件夹
}
File file = new File(filePath);
if (!file.exists()) {
try {
file.createNewFile();
FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//定期删除文件
private static class DeleteFolderTask extends TimerTask {
private Path folderPath;
public DeleteFolderTask(String folderPath) {
this.folderPath = Paths.get(folderPath);
}
@Override
public void run() {
try {
Files.walk(folderPath)
.sorted(java.util.Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
System.out.println("文件夹及其内容已成功删除。");
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String AI_API(String path,String question,String publicNum,String flag) throws Exception {
//flag、publicNum是存redis的key标识,随便写
// 1、上传
UploadResp uploadResp = chatDocUtil.upload(path, uploadUrl, appId, secret);
System.out.println("请求sid=" + uploadResp.getSid());
System.out.println("文件id=" + uploadResp.getData().getFileId());
Object redis_AI = redisUtil.get("AIContent"+flag+publicNum);
for (int i = 0; i <50 ; i++) {
if (redis_AI != null){
System.out.println("//"+redis_AI);
break;
}else {
Thread.sleep(1000);
redis_AI = redisUtil.get("AIContent"+flag+publicNum);
}
}
return redis_AI.toString();
}
//官网给的demo,加了些代码
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import okhttp3.*;
import org.jh.controller.system.CallbackController;
import org.jh.controller.xfyun.dto.UploadResp;
import org.jh.controller.xfyun.dto.chat.ChatMessage;
import org.jh.controller.xfyun.dto.chat.ChatRequest;
import org.jh.util.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* Test
*
* @author ydwang16
* @version 2023/09/06 11:45
**/
@Service
public class ChatDocUtil {
@Autowired
private RedisUtil redisUtil;
private static Logger logger = LoggerFactory.getLogger(CallbackController.class);
public UploadResp upload(String filePath, String url, String appId, String secret,String question,String publicNum,String flag) throws Exception {
File file = new File(filePath);
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.connectTimeout(20, TimeUnit.SECONDS)
.build();
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("file", file.getName(),
RequestBody.create(MediaType.parse("multipart/form-data"), file));
builder.addFormDataPart("fileType", "wiki");
builder.addFormDataPart("callbackUrl", "这里填写回调方法的地址(用线上的地址+路径)");
RequestBody body = builder.build();
long ts = System.currentTimeMillis() / 1000;
Request request = new Request.Builder()
.url(url)
.post(body)
.addHeader("appId", appId)
.addHeader("timestamp", String.valueOf(ts))
.addHeader("signature", ApiAuthUtil.getSignature(appId, secret, ts))
.build();
try {
okhttp3.Response response = okHttpClient.newCall(request).execute();
if (Objects.equals(response.code(), 200)) {
String respBody = response.body().string();
UploadResp respBody_json = JSONUtil.toBean(respBody, UploadResp.class);
redisUtil.set(respBody_json.getData().getFileId(),"AIContent"+flag+publicNum);
redisUtil.expire(respBody_json.getData().getFileId(), 60 * 60 * 24);//结果存放缓存24小时
logger.info("--------set----------------set----------------set----------------set----------------set--------");
return respBody_json;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return null;
}
public void chat(String chatUrl, String fileId, String question, String appId, String secret,String flag) {
ChatMessage message = new ChatMessage();
message.setRole("user");
message.setContent(question);
// 请求内容
ChatRequest request = ChatRequest.builder()
.fileIds(Collections.singletonList(fileId))
.topN(3)
.messages(Collections.singletonList(message))
.build();
// 构造url鉴权
long ts = System.currentTimeMillis() / 1000;
String signature = ApiAuthUtil.getSignature(appId, secret, ts);
String requestUrl = chatUrl + "?" + "appId=" + appId + "×tamp=" + ts + "&signature=" + signature;
// ws
Request wsRequest = (new Request.Builder()).url(requestUrl).build();
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().build();
StringBuffer buffer = new StringBuffer();
WebSocket webSocket = okHttpClient.newWebSocket(wsRequest, new WebSocketListener() {
@Override
public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
super.onClosed(webSocket, code, reason);
webSocket.close(1002, "websocket finish");
okHttpClient.connectionPool().evictAll();
}
@Override
public void onFailure(@NotNull WebSocket webSocket, @NotNull Throwable t, @Nullable Response response) {
super.onFailure(webSocket, t, response);
webSocket.close(1001, "websocket finish");
okHttpClient.connectionPool().evictAll();
}
@Override
public void onMessage(@NotNull WebSocket webSocket, @NotNull String text) {
System.out.println(text);
JSONObject jsonObject = JSONUtil.parseObj(text);
String content = jsonObject.getStr("content");
if (StrUtil.isNotEmpty(content)) {
buffer.append(content);
}
if (Objects.equals(jsonObject.getInt("status"), 2)) {
System.out.println("回答内容:" + buffer);
redisUtil.set(flag,buffer);
redisUtil.expire(flag, 60 * 60 * 24);//结果存放缓存24小时
System.out.println(buffer);
webSocket.close(1000, "websocket finish");
okHttpClient.connectionPool().evictAll();
// System.exit(0);
}
}
});
webSocket.send(JSONUtil.toJsonStr(request));
}
}
//回调函数
import com.alibaba.fastjson.JSON;
import org.jh.controller.base.BaseController;
import org.jh.controller.xfyun.util.ChatDocUtil;
import org.jh.entity.PageData;
import org.jh.util.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/callback")
public class CallbackController extends BaseController {
private static Logger logger = LoggerFactory.getLogger(CallbackController.class);
//官网账号等数据
private static final String chatUrl = "";
private static final String appId = "";
private static final String secret = "";
@Autowired
private RedisUtil redisUtil;
@Autowired
private ChatDocUtil chatDocUtil;
@RequestMapping(value="/portal/fileState")
@ResponseBody
public String fileState() {
PageData pdd = new PageData();
pdd = this.getPageData();
logger.info("--------fileAgain--------"+ JSON.toJSONString(pdd));
if (pdd.getString("fileStatus").equals("vectored")){
String fileId = pdd.getString("fileId");
String redis_public = redisUtil.get(fileId).toString();
logger.info("--------get----------------get----------------get----------------get----------------get--------");
chatDocUtil.chat(chatUrl, fileId, "解读一下内容且返回结果不要出现字母txt", appId, secret,redis_public);
}
return null;
}
}
4、传入文字一个一个的蹦出来(AI的样式)
// <p id="ABS_AI_AN"> <p/>
// this.addABS("ABS_AI_AN",this.content);
addABS:function(divid, content) {
let i = 0;
let interval;
if (i > content.length) {
clearInterval(interval);
} else {
interval = setInterval(() => {
i++;
let str = content.substr(0, i);
if (i > content.length) {
$('#' + divid).html(str);
clearInterval(interval);
} else {
$('#' + divid).html(str + "_");
}
}, 100);
}
},