mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-21 07:43:40 +00:00
新增千问3重排序模型,并附带新增sql文件
This commit is contained in:
46
docs/script/sql/update/updat-0420.sql
Normal file
46
docs/script/sql/update/updat-0420.sql
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
Navicat Premium Dump SQL
|
||||||
|
|
||||||
|
Source Server : localhost-mysql
|
||||||
|
Source Server Type : MySQL
|
||||||
|
Source Server Version : 80045 (8.0.45)
|
||||||
|
Source Host : localhost:3306
|
||||||
|
Source Schema : ruoyi-ai
|
||||||
|
|
||||||
|
Target Server Type : MySQL
|
||||||
|
Target Server Version : 80045 (8.0.45)
|
||||||
|
File Encoding : 65001
|
||||||
|
|
||||||
|
Date: 20/04/2026 15:30:00
|
||||||
|
*/
|
||||||
|
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- 新增:重排序模型(chat_model)
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO `chat_model`
|
||||||
|
(id, category, model_name, provider_code, model_describe, model_dimension, model_show, api_host, api_key, create_dept, create_by, create_time, update_by, update_time, remark, tenant_id)
|
||||||
|
VALUES(2045071617578237953, 'rerank', 'rerank', 'zhipu', '智谱重排序', NULL, 'Y', 'https://open.bigmodel.cn', 'e9xx', 103, 1, '2026-04-17 17:27:24', 1, '2026-04-20 15:21:48', '智谱重排序', 0);
|
||||||
|
|
||||||
|
INSERT INTO `chat_model`
|
||||||
|
(id, category, model_name, provider_code, model_describe, model_dimension, model_show, api_host, api_key, create_dept, create_by, create_time, update_by, update_time, remark, tenant_id)
|
||||||
|
VALUES(2046119803482902530, 'rerank', 'qwen3-rerank', 'qianwen', '千问3重排序', NULL, NULL, 'https://dashscope.aliyuncs.com', 'sk-xx', 103, 1, '2026-04-20 14:52:31', 1, '2026-04-20 15:03:13', '千问3文本重排序', 0);
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- 新增:字典类型 - 重排序模型分类
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO `sys_dict_data`
|
||||||
|
(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark)
|
||||||
|
VALUES(2045070879435259905, '000000', 4, '重排序', 'rerank', 'chat_model_category', NULL, '#000000', 'N', 103, 1, '2026-04-17 17:24:28', 1, '2026-04-19 01:02:20', '重排序模型');
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- 修改表:knowledge_info 增加重排序相关字段
|
||||||
|
-- ----------------------------
|
||||||
|
ALTER TABLE `knowledge_info` ADD COLUMN `enable_rerank` tinyint DEFAULT 0 NULL COMMENT '是否启用重排序(0否 1是)';
|
||||||
|
ALTER TABLE `knowledge_info` ADD COLUMN `rerank_score_threshold` double NULL COMMENT '重排序相关性分数阈值';
|
||||||
|
ALTER TABLE `knowledge_info` ADD COLUMN `rerank_top_n` int NULL COMMENT '重排序后返回的文档数量';
|
||||||
|
ALTER TABLE `knowledge_info` ADD COLUMN `rerank_model` varchar(100) NULL COMMENT '重排序模型名称';
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package org.ruoyi.domain.dto.request;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里百炼重排序请求DTO(OpenAI兼容格式)
|
||||||
|
*
|
||||||
|
* @author yang
|
||||||
|
* @date 2026-04-20
|
||||||
|
*/
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
public record AliBaiLianRerankRequest(
|
||||||
|
String model,
|
||||||
|
List<String> documents,
|
||||||
|
String query,
|
||||||
|
@JsonProperty("top_n")
|
||||||
|
Integer topN,
|
||||||
|
String instruct,
|
||||||
|
@JsonProperty("return_documents")
|
||||||
|
Boolean returnDocuments
|
||||||
|
) {
|
||||||
|
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建文本重排序请求
|
||||||
|
*/
|
||||||
|
public static AliBaiLianRerankRequest create(String modelName, String query,
|
||||||
|
List<String> documents, Integer topN,
|
||||||
|
Boolean returnDocuments) {
|
||||||
|
return new AliBaiLianRerankRequest(
|
||||||
|
modelName,
|
||||||
|
documents,
|
||||||
|
query,
|
||||||
|
topN != null ? topN : documents.size(),
|
||||||
|
null,
|
||||||
|
returnDocuments != null ? returnDocuments : true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为JSON字符串
|
||||||
|
*/
|
||||||
|
public String toJson() {
|
||||||
|
try {
|
||||||
|
return OBJECT_MAPPER.writeValueAsString(this);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new IllegalArgumentException("序列化阿里百炼重排序请求失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package org.ruoyi.domain.dto.response;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import org.ruoyi.domain.bo.rerank.RerankResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里百炼重排序响应DTO(OpenAI兼容格式)
|
||||||
|
*
|
||||||
|
* @author yang
|
||||||
|
* @date 2026-04-20
|
||||||
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public record AliBaiLianRerankResponse(
|
||||||
|
String id,
|
||||||
|
String object,
|
||||||
|
List<ResultItem> results,
|
||||||
|
UsageInfo usage
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* 单个重排序结果项
|
||||||
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public record ResultItem(
|
||||||
|
Integer index,
|
||||||
|
@JsonProperty("relevance_score")
|
||||||
|
Double relevanceScore,
|
||||||
|
Object document
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* 获取文档文本内容
|
||||||
|
*/
|
||||||
|
public String getDocumentText() {
|
||||||
|
if (document == null) return null;
|
||||||
|
if (document instanceof String) return (String) document;
|
||||||
|
if (document instanceof Map) {
|
||||||
|
Object text = ((Map<?, ?>) document).get("text");
|
||||||
|
return text != null ? text.toString() : null;
|
||||||
|
}
|
||||||
|
return document.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token使用信息
|
||||||
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public record UsageInfo(
|
||||||
|
@JsonProperty("total_tokens")
|
||||||
|
Integer totalTokens,
|
||||||
|
@JsonProperty("prompt_tokens")
|
||||||
|
Integer promptTokens
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为通用RerankResult
|
||||||
|
*/
|
||||||
|
public RerankResult toRerankResult(int totalDocs, long durationMs) {
|
||||||
|
if (results == null || results.isEmpty()) {
|
||||||
|
return RerankResult.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<RerankResult.RerankDocument> documents = results.stream()
|
||||||
|
.map(item -> RerankResult.RerankDocument.builder()
|
||||||
|
.index(item.index())
|
||||||
|
.relevanceScore(item.relevanceScore())
|
||||||
|
.document(item.getDocumentText())
|
||||||
|
.build())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return RerankResult.builder()
|
||||||
|
.documents(documents)
|
||||||
|
.totalDocuments(totalDocs)
|
||||||
|
.durationMs(durationMs)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.ruoyi.domain.dto.response;
|
package org.ruoyi.domain.dto.response;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.ruoyi.domain.bo.rerank.RerankResult;
|
import org.ruoyi.domain.bo.rerank.RerankResult;
|
||||||
|
|
||||||
@@ -12,6 +13,7 @@ import java.util.stream.Collectors;
|
|||||||
* @author yang
|
* @author yang
|
||||||
* @date 2026-04-19
|
* @date 2026-04-19
|
||||||
*/
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public record ZhipuRerankResponse(
|
public record ZhipuRerankResponse(
|
||||||
String model,
|
String model,
|
||||||
String object,
|
String object,
|
||||||
@@ -31,6 +33,7 @@ public record ZhipuRerankResponse(
|
|||||||
/**
|
/**
|
||||||
* Token使用信息
|
* Token使用信息
|
||||||
*/
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public record UsageInfo(
|
public record UsageInfo(
|
||||||
@JsonProperty("total_tokens")
|
@JsonProperty("total_tokens")
|
||||||
Integer totalTokens,
|
Integer totalTokens,
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package org.ruoyi.service.rerank.impl;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import okhttp3.*;
|
||||||
|
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
|
||||||
|
import org.ruoyi.domain.bo.rerank.RerankRequest;
|
||||||
|
import org.ruoyi.domain.bo.rerank.RerankResult;
|
||||||
|
import org.ruoyi.domain.dto.request.AliBaiLianRerankRequest;
|
||||||
|
import org.ruoyi.domain.dto.response.AliBaiLianRerankResponse;
|
||||||
|
import org.ruoyi.service.rerank.RerankModelService;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里百炼重排序模型实现
|
||||||
|
* 参考设计模式:AliBaiLianMultiEmbeddingProvider
|
||||||
|
*
|
||||||
|
* @author yang
|
||||||
|
* @date 2026-04-20
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component("qianwenRerank")
|
||||||
|
public class AliBaiLianRerankModelService implements RerankModelService {
|
||||||
|
|
||||||
|
private final OkHttpClient okHttpClient;
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
private ChatModelVo chatModelVo;
|
||||||
|
|
||||||
|
public AliBaiLianRerankModelService() {
|
||||||
|
this.okHttpClient = new OkHttpClient.Builder()
|
||||||
|
.connectTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.readTimeout(60, TimeUnit.SECONDS)
|
||||||
|
.writeTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(ChatModelVo config) {
|
||||||
|
this.chatModelVo = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RerankResult rerank(RerankRequest rerankRequest) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构建请求
|
||||||
|
AliBaiLianRerankRequest request = buildRequest(rerankRequest);
|
||||||
|
AliBaiLianRerankResponse response = executeRequest(request);
|
||||||
|
|
||||||
|
return response.toRerankResult(
|
||||||
|
rerankRequest.getDocuments().size(),
|
||||||
|
System.currentTimeMillis() - startTime
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("阿里百炼重排序失败: {}", e.getMessage(), e);
|
||||||
|
throw new RuntimeException("重排序服务调用失败: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建请求对象
|
||||||
|
*/
|
||||||
|
private AliBaiLianRerankRequest buildRequest(RerankRequest rerankRequest) {
|
||||||
|
return AliBaiLianRerankRequest.create(
|
||||||
|
chatModelVo.getModelName(),
|
||||||
|
rerankRequest.getQuery(),
|
||||||
|
rerankRequest.getDocuments(),
|
||||||
|
rerankRequest.getTopN(),
|
||||||
|
rerankRequest.getReturnDocuments()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行HTTP请求并解析响应
|
||||||
|
*/
|
||||||
|
private AliBaiLianRerankResponse executeRequest(AliBaiLianRerankRequest request) throws IOException {
|
||||||
|
String jsonBody = request.toJson();
|
||||||
|
RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json"));
|
||||||
|
|
||||||
|
// 阿里百炼重排序 OpenAI兼容端点
|
||||||
|
String url = chatModelVo.getApiHost() + "/compatible-api/v1/reranks";
|
||||||
|
Request httpRequest = new Request.Builder()
|
||||||
|
.url(url)
|
||||||
|
.addHeader("Authorization", "Bearer " + chatModelVo.getApiKey())
|
||||||
|
.addHeader("Content-Type", "application/json")
|
||||||
|
.post(body)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response response = okHttpClient.newCall(httpRequest).execute()) {
|
||||||
|
if (!response.isSuccessful()) {
|
||||||
|
String err = response.body() != null ? response.body().string() : "无错误信息";
|
||||||
|
throw new IllegalArgumentException("阿里百炼API调用失败: " + response.code() + " - " + err);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResponseBody responseBody = response.body();
|
||||||
|
if (responseBody == null) {
|
||||||
|
throw new IllegalArgumentException("响应体为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseResponse(responseBody.string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析响应
|
||||||
|
*/
|
||||||
|
private AliBaiLianRerankResponse parseResponse(String responseBody) throws IOException {
|
||||||
|
return objectMapper.readValue(responseBody, AliBaiLianRerankResponse.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
package org.ruoyi.service.rerank.impl;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import dev.langchain4j.http.client.*;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
|
|
||||||
import org.ruoyi.domain.bo.rerank.RerankRequest;
|
|
||||||
import org.ruoyi.domain.bo.rerank.RerankResult;
|
|
||||||
import org.ruoyi.service.rerank.RerankModelService;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Jina AI 重排序模型实现
|
|
||||||
* 参考设计模式:OpenAiEmbeddingProvider
|
|
||||||
* 使用 Jina 官方重排序API
|
|
||||||
*
|
|
||||||
* @author yang
|
|
||||||
* @date 2026-04-19
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Component("jina")
|
|
||||||
public class JinaRerankModelService implements RerankModelService {
|
|
||||||
|
|
||||||
protected ChatModelVo chatModelVo;
|
|
||||||
protected HttpClient httpClient;
|
|
||||||
protected final ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void configure(ChatModelVo config) {
|
|
||||||
this.chatModelVo = config;
|
|
||||||
HttpClientBuilder httpClientBuilder = HttpClientBuilderLoader.loadHttpClientBuilder();
|
|
||||||
this.httpClient = httpClientBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RerankResult rerank(RerankRequest rerankRequest) {
|
|
||||||
long startTime = System.currentTimeMillis();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 构建Jina重排序请求体
|
|
||||||
Map<String, Object> requestBody = new HashMap<>();
|
|
||||||
requestBody.put("model", chatModelVo.getModelName());
|
|
||||||
requestBody.put("query", rerankRequest.getQuery());
|
|
||||||
requestBody.put("documents", rerankRequest.getDocuments());
|
|
||||||
requestBody.put("top_n", rerankRequest.getTopN() != null ?
|
|
||||||
rerankRequest.getTopN() : rerankRequest.getDocuments().size());
|
|
||||||
requestBody.put("return_documents", rerankRequest.getReturnDocuments());
|
|
||||||
|
|
||||||
// 构建HTTP请求
|
|
||||||
HttpRequest httpRequest = HttpRequest.builder()
|
|
||||||
.url(chatModelVo.getApiHost())
|
|
||||||
.method(HttpMethod.POST)
|
|
||||||
.addHeader("Content-Type", "application/json")
|
|
||||||
.addHeader("Authorization", "Bearer " + chatModelVo.getApiKey())
|
|
||||||
.body(objectMapper.writeValueAsString(requestBody))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// 发送请求
|
|
||||||
SuccessfulHttpResponse httpResponse = httpClient.execute(httpRequest);
|
|
||||||
|
|
||||||
// 解析响应
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Map<String, Object> response = objectMapper.readValue(httpResponse.body(), Map.class);
|
|
||||||
return parseResponse(response, rerankRequest.getDocuments().size(),
|
|
||||||
System.currentTimeMillis() - startTime);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Jina重排序失败: {}", e.getMessage(), e);
|
|
||||||
throw new RuntimeException("重排序服务调用失败: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解析Jina API响应
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private RerankResult parseResponse(Map<String, Object> response, int totalDocs, long durationMs) {
|
|
||||||
List<Map<String, Object>> results = (List<Map<String, Object>>) response.get("results");
|
|
||||||
if (results == null || results.isEmpty()) {
|
|
||||||
return RerankResult.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<RerankResult.RerankDocument> documents = new ArrayList<>();
|
|
||||||
for (Map<String, Object> result : results) {
|
|
||||||
Integer index = (Integer) result.get("index");
|
|
||||||
Double score = ((Number) result.get("relevance_score")).doubleValue();
|
|
||||||
String document = (String) result.get("document");
|
|
||||||
|
|
||||||
documents.add(RerankResult.RerankDocument.builder()
|
|
||||||
.index(index)
|
|
||||||
.relevanceScore(score)
|
|
||||||
.document(document)
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
return RerankResult.builder()
|
|
||||||
.documents(documents)
|
|
||||||
.totalDocuments(totalDocs)
|
|
||||||
.durationMs(durationMs)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -90,14 +90,15 @@ public class ZhiPuRerankModelService implements RerankModelService {
|
|||||||
// 生成智谱认证Token
|
// 生成智谱认证Token
|
||||||
String token = generateToken(chatModelVo.getApiKey());
|
String token = generateToken(chatModelVo.getApiKey());
|
||||||
|
|
||||||
String url = chatModelVo.getApiHost() + "/" + chatModelVo.getModelName();
|
// 智谱重排序固定端点路径
|
||||||
|
String url = chatModelVo.getApiHost() + "/api/paas/v4/rerank";
|
||||||
Request httpRequest = new Request.Builder()
|
Request httpRequest = new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.addHeader("Authorization", token)
|
.addHeader("Authorization", token)
|
||||||
.post(body)
|
.post(body)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
try (okhttp3.Response response = okHttpClient.newCall(httpRequest).execute()) {
|
try (Response response = okHttpClient.newCall(httpRequest).execute()) {
|
||||||
if (!response.isSuccessful()) {
|
if (!response.isSuccessful()) {
|
||||||
String err = response.body() != null ? response.body().string() : "无错误信息";
|
String err = response.body() != null ? response.body().string() : "无错误信息";
|
||||||
throw new IllegalArgumentException("智谱API调用失败: " + response.code() + " - " + err);
|
throw new IllegalArgumentException("智谱API调用失败: " + response.code() + " - " + err);
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package org.ruoyi.service.rerank.impl;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
|
||||||
|
import org.ruoyi.domain.bo.rerank.RerankRequest;
|
||||||
|
import org.ruoyi.domain.bo.rerank.RerankResult;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里百炼重排序模型测试类
|
||||||
|
* 运行前请设置环境变量 DASHSCOPE_API_KEY 或直接修改 apiKey
|
||||||
|
*/
|
||||||
|
class AliBaiLianRerankModelServiceTest {
|
||||||
|
|
||||||
|
private AliBaiLianRerankModelService service;
|
||||||
|
|
||||||
|
// 请替换为你的 API Key
|
||||||
|
private static final String API_KEY = System.getenv("DASHSCOPE_API_KEY");
|
||||||
|
private static final String API_HOST = "https://dashscope.aliyuncs.com";
|
||||||
|
private static final String MODEL_NAME = "qwen3-rerank";
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
service = new AliBaiLianRerankModelService();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConfigure() {
|
||||||
|
ChatModelVo config = createConfig();
|
||||||
|
service.configure(config);
|
||||||
|
assertNotNull(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRerank() {
|
||||||
|
// 跳过测试如果没有配置 API Key
|
||||||
|
if (API_KEY == null || API_KEY.isEmpty()) {
|
||||||
|
System.out.println("跳过测试: 未设置环境变量 DASHSCOPE_API_KEY");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatModelVo config = createConfig();
|
||||||
|
service.configure(config);
|
||||||
|
|
||||||
|
List<String> documents = Arrays.asList(
|
||||||
|
"文本排序模型广泛用于搜索引擎和推荐系统中,它们根据文本相关性对候选文本进行排序",
|
||||||
|
"量子计算是计算科学的一个前沿领域",
|
||||||
|
"预训练语言模型的发展给文本排序模型带来了新的进展"
|
||||||
|
);
|
||||||
|
|
||||||
|
RerankRequest request = RerankRequest.builder()
|
||||||
|
.query("什么是文本排序模型")
|
||||||
|
.documents(documents)
|
||||||
|
.topN(2)
|
||||||
|
.returnDocuments(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
RerankResult result = service.rerank(request);
|
||||||
|
|
||||||
|
System.out.println("=== 重排序结果 ===");
|
||||||
|
System.out.println("总文档数: " + result.getTotalDocuments());
|
||||||
|
System.out.println("耗时: " + result.getDurationMs() + "ms");
|
||||||
|
|
||||||
|
result.getDocuments().forEach(doc -> {
|
||||||
|
System.out.println("索引: " + doc.getIndex() +
|
||||||
|
", 相关性分数: " + doc.getRelevanceScore() +
|
||||||
|
", 文档: " + doc.getDocument());
|
||||||
|
});
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNotNull(result.getDocuments());
|
||||||
|
assertFalse(result.getDocuments().isEmpty());
|
||||||
|
assertEquals(2, result.getDocuments().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRerankWithFullDocuments() {
|
||||||
|
if (API_KEY == null || API_KEY.isEmpty()) {
|
||||||
|
System.out.println("跳过测试: 未设置环境变量 DASHSCOPE_API_KEY");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatModelVo config = createConfig();
|
||||||
|
service.configure(config);
|
||||||
|
|
||||||
|
List<String> documents = Arrays.asList(
|
||||||
|
"Java是一种广泛使用的编程语言",
|
||||||
|
"Python是人工智能领域最流行的语言",
|
||||||
|
"Go语言由Google开发,适合并发编程"
|
||||||
|
);
|
||||||
|
|
||||||
|
RerankRequest request = RerankRequest.builder()
|
||||||
|
.query("哪种语言适合AI开发")
|
||||||
|
.documents(documents)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
RerankResult result = service.rerank(request);
|
||||||
|
|
||||||
|
System.out.println("=== 重排序结果2 ===");
|
||||||
|
result.getDocuments().forEach(doc -> {
|
||||||
|
System.out.println("索引: " + doc.getIndex() +
|
||||||
|
", 分数: " + doc.getRelevanceScore() +
|
||||||
|
", 文档: " + doc.getDocument());
|
||||||
|
});
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(3, result.getDocuments().size());
|
||||||
|
|
||||||
|
// Python相关文档应该排在前面
|
||||||
|
assertEquals(1, result.getDocuments().get(0).getIndex());
|
||||||
|
assertTrue(result.getDocuments().get(0).getRelevanceScore() > 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChatModelVo createConfig() {
|
||||||
|
ChatModelVo config = new ChatModelVo();
|
||||||
|
config.setApiHost(API_HOST);
|
||||||
|
config.setApiKey(API_KEY != null ? API_KEY : "test-api-key");
|
||||||
|
config.setModelName(MODEL_NAME);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package org.ruoyi.service.rerank.impl;
|
||||||
|
|
||||||
|
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
|
||||||
|
import org.ruoyi.domain.bo.rerank.RerankRequest;
|
||||||
|
import org.ruoyi.domain.bo.rerank.RerankResult;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里百炼重排序模型测试 - Main方法直接运行
|
||||||
|
* 运行前请设置 API_KEY
|
||||||
|
*/
|
||||||
|
public class AliBaiLianRerankTestMain {
|
||||||
|
|
||||||
|
// 请替换为你的 API Key
|
||||||
|
private static final String API_KEY = "sk-your-api-key-here";
|
||||||
|
private static final String API_HOST = "https://dashscope.aliyuncs.com";
|
||||||
|
private static final String MODEL_NAME = "qwen3-rerank";
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
AliBaiLianRerankModelService service = new AliBaiLianRerankModelService();
|
||||||
|
|
||||||
|
// 配置
|
||||||
|
ChatModelVo config = new ChatModelVo();
|
||||||
|
config.setApiHost(API_HOST);
|
||||||
|
config.setApiKey(API_KEY);
|
||||||
|
config.setModelName(MODEL_NAME);
|
||||||
|
service.configure(config);
|
||||||
|
|
||||||
|
// 测试数据
|
||||||
|
List<String> documents = Arrays.asList(
|
||||||
|
"文本排序模型广泛用于搜索引擎和推荐系统中,它们根据文本相关性对候选文本进行排序",
|
||||||
|
"量子计算是计算科学的一个前沿领域",
|
||||||
|
"预训练语言模型的发展给文本排序模型带来了新的进展"
|
||||||
|
);
|
||||||
|
|
||||||
|
RerankRequest request = RerankRequest.builder()
|
||||||
|
.query("什么是文本排序模型")
|
||||||
|
.documents(documents)
|
||||||
|
.topN(2)
|
||||||
|
.returnDocuments(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
System.out.println("=== 开始测试阿里百炼重排序 ===");
|
||||||
|
System.out.println("API Host: " + API_HOST);
|
||||||
|
System.out.println("Model: " + MODEL_NAME);
|
||||||
|
System.out.println("Query: 什么是文本排序模型");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
try {
|
||||||
|
RerankResult result = service.rerank(request);
|
||||||
|
|
||||||
|
System.out.println("=== 重排序结果 ===");
|
||||||
|
System.out.println("总文档数: " + result.getTotalDocuments());
|
||||||
|
System.out.println("耗时: " + result.getDurationMs() + "ms");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
result.getDocuments().forEach(doc -> {
|
||||||
|
System.out.println("索引: " + doc.getIndex());
|
||||||
|
System.out.println("相关性分数: " + doc.getRelevanceScore());
|
||||||
|
System.out.println("文档: " + doc.getDocument());
|
||||||
|
System.out.println("---");
|
||||||
|
});
|
||||||
|
|
||||||
|
System.out.println("=== 测试成功 ===");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("=== 测试失败 ===");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user