fix: 修复推理模型连接验证截断

- 响应达到输出上限时使用 512 Token 单次重试

- 为自部署 vLLM/SGLang 传递关闭思考参数

- 补充截断重试与请求参数回归测试
This commit is contained in:
2026-07-28 12:20:12 +08:00
parent a22ca24906
commit 1630d6194a
2 changed files with 175 additions and 9 deletions

View File

@@ -61,6 +61,43 @@ public class AgentScopeChatModelConnectivityVerifierTest {
Assert.assertEquals(MsgRole.USER, factory.getMessageBatches().get(0).get(1).getRole());
}
/**
* 验证能力探测达到输出上限时使用更大预算重试一次。
*/
@Test
public void shouldRetryProbeWithLargerBudgetWhenResponseIsLengthLimited() {
RecordingModelFactory factory = new RecordingModelFactory(
Flux.just(lengthLimitedResponse()),
Flux.just(toolResponse(TEST_NONCE, null)));
ChatModelVerificationResult result = verifier(factory).verify(model(false));
Assert.assertEquals(ModelVerificationStatus.PASSED, result.getStatus());
Assert.assertEquals(Boolean.TRUE, result.getSupportTool());
Assert.assertEquals(List.of(1, 1), factory.getToolCounts());
Assert.assertEquals(List.of(128, 512), factory.getFactoryMaxTokens());
Assert.assertEquals(List.of(128, 512), factory.getRequestMaxTokens());
}
/**
* 验证自部署 vLLM/SGLang 入口通过聊天模板参数关闭思考。
*/
@Test
public void shouldDisableThinkingThroughChatTemplateKwargsForSelfHostedEndpoint() {
RecordingModelFactory factory = new RecordingModelFactory(
Flux.just(toolResponse(TEST_NONCE, null)));
ChatModelVerificationResult result = verifier(factory).verify(
model(false, "self-hosted"));
Assert.assertEquals(ModelVerificationStatus.PASSED, result.getStatus());
Map<String, Object> bodyParams = factory.getFactoryAdditionalBodyParams().get(0);
Assert.assertEquals(Boolean.FALSE, bodyParams.get("enable_thinking"));
Assert.assertEquals(
Map.of("enable_thinking", false),
bodyParams.get("chat_template_kwargs"));
}
/**
* 验证模型返回普通文本时连接通过但工具能力保持关闭。
*/
@@ -143,6 +180,17 @@ public class AgentScopeChatModelConnectivityVerifierTest {
* @return 测试模型
*/
private Model model(boolean supportImage) {
return model(supportImage, "gpustack");
}
/**
* 创建携带指定供应商类型的待验证模型。
*
* @param supportImage 是否支持图片
* @param providerType 供应商类型
* @return 测试模型
*/
private Model model(boolean supportImage, String providerType) {
Model model = new Model();
model.setId(BigInteger.TEN);
model.setModelName("test-model");
@@ -151,7 +199,7 @@ public class AgentScopeChatModelConnectivityVerifierTest {
model.setApiKey("test-key");
model.setSupportImage(supportImage);
ModelProvider provider = new ModelProvider();
provider.setProviderType("gpustack");
provider.setProviderType(providerType);
model.setModelProvider(provider);
return model;
}
@@ -182,6 +230,18 @@ public class AgentScopeChatModelConnectivityVerifierTest {
.build();
}
/**
* 创建达到输出上限的响应。
*
* @return 输出被截断的 AgentScope 响应
*/
private ChatResponse lengthLimitedResponse() {
return ChatResponse.builder()
.content(List.of(TextBlock.builder().text("incomplete").build()))
.finishReason("length")
.build();
}
/**
* 创建探测工具调用响应。
*
@@ -212,8 +272,14 @@ public class AgentScopeChatModelConnectivityVerifierTest {
private final List<Flux<ChatResponse>> responses;
/** 模型工厂收到的流式参数。 */
private final List<Boolean> factoryStreams = new ArrayList<>();
/** 模型工厂收到的最大输出 Token 数。 */
private final List<Integer> factoryMaxTokens = new ArrayList<>();
/** 模型工厂收到的额外请求体参数。 */
private final List<Map<String, Object>> factoryAdditionalBodyParams = new ArrayList<>();
/** 模型请求收到的流式参数。 */
private final List<Boolean> requestStreams = new ArrayList<>();
/** 模型请求收到的最大输出 Token 数。 */
private final List<Integer> requestMaxTokens = new ArrayList<>();
/** 模型请求收到的消息批次。 */
private final List<List<Msg>> messageBatches = new ArrayList<>();
/** 每次请求携带的工具数量。 */
@@ -244,6 +310,9 @@ public class AgentScopeChatModelConnectivityVerifierTest {
AgentGenerationOptions generationOptions) {
int requestIndex = factoryStreams.size();
factoryStreams.add(Boolean.TRUE.equals(generationOptions.getStream()));
factoryMaxTokens.add(generationOptions.getMaxTokens());
factoryAdditionalBodyParams.add(Map.copyOf(
generationOptions.getAdditionalBodyParams()));
Flux<ChatResponse> response = responses.get(requestIndex);
return new io.agentscope.core.model.Model() {
/**
@@ -260,6 +329,7 @@ public class AgentScopeChatModelConnectivityVerifierTest {
List<ToolSchema> tools,
GenerateOptions options) {
requestStreams.add(Boolean.TRUE.equals(options.getStream()));
requestMaxTokens.add(options.getMaxTokens());
messageBatches.add(List.copyOf(inputMessages));
toolCounts.add(tools.size());
toolChoices.add(options.getToolChoice());
@@ -287,6 +357,24 @@ public class AgentScopeChatModelConnectivityVerifierTest {
return factoryStreams;
}
/**
* 获取模型工厂收到的最大输出 Token 数。
*
* @return 最大输出 Token 数列表
*/
private List<Integer> getFactoryMaxTokens() {
return factoryMaxTokens;
}
/**
* 获取模型工厂收到的额外请求体参数。
*
* @return 额外请求体参数列表
*/
private List<Map<String, Object>> getFactoryAdditionalBodyParams() {
return factoryAdditionalBodyParams;
}
/**
* 获取请求流式参数。
*
@@ -296,6 +384,15 @@ public class AgentScopeChatModelConnectivityVerifierTest {
return requestStreams;
}
/**
* 获取模型请求收到的最大输出 Token 数。
*
* @return 最大输出 Token 数列表
*/
private List<Integer> getRequestMaxTokens() {
return requestMaxTokens;
}
/**
* 获取每次请求的验证消息批次。
*