use supervisor agent for complex chat
This commit is contained in:
@@ -397,11 +397,25 @@ public class ChatService {
|
||||
.subAgents(List.of(planner, executor, verifier))
|
||||
.build();
|
||||
|
||||
String plannerPlan = callAgent(planner, buildPlannerInput(question, retryContext), config);
|
||||
answer = callAgent(executor, buildExecutorInput(question, plannerPlan, retryContext), config);
|
||||
String supervisorInput = buildSupervisorInput(question, retryContext);
|
||||
Optional<OverAllState> stateOptional = supervisor.invoke(supervisorInput, config);
|
||||
if (stateOptional.isEmpty()) {
|
||||
finalDecision = buildVerifierFallbackDecision(round, "supervisor 未返回有效状态");
|
||||
answer = buildLowConfidenceOutput(answer, finalDecision);
|
||||
persistVerifierEvaluation(session, finalDecision, round);
|
||||
break;
|
||||
}
|
||||
|
||||
String plannerPlan = extractStateText(stateOptional, "planner_plan");
|
||||
answer = extractStateText(stateOptional, "executor_feedback");
|
||||
VerifierContextHolder.setExecutorFinalAnswer(answer);
|
||||
String verifierOutput = callAgent(verifier, "VERIFY", config);
|
||||
String verifierOutput = extractStateText(stateOptional, "verifier_output");
|
||||
finalDecision = parseVerifierDecision(verifierOutput, round);
|
||||
logger.debug("Supervisor round {} finished: plannerPlanLength={}, answerLength={}, verifierOutputLength={}",
|
||||
round,
|
||||
plannerPlan != null ? plannerPlan.length() : 0,
|
||||
answer != null ? answer.length() : 0,
|
||||
verifierOutput != null ? verifierOutput.length() : 0);
|
||||
|
||||
if (finalDecision == null) {
|
||||
finalDecision = buildVerifierFallbackDecision(round, "verifier_output 缺失或无法解析");
|
||||
@@ -530,10 +544,6 @@ public class ChatService {
|
||||
.build();
|
||||
}
|
||||
|
||||
private String callAgent(ReactAgent agent, String input, RunnableConfig config) throws GraphRunnerException {
|
||||
return agent.call(input, config).getText();
|
||||
}
|
||||
|
||||
private String resolveSessionId(String requestedSessionId) {
|
||||
if (requestedSessionId != null && !requestedSessionId.isBlank()) {
|
||||
return requestedSessionId;
|
||||
@@ -558,21 +568,14 @@ public class ChatService {
|
||||
return session;
|
||||
}
|
||||
|
||||
private String buildPlannerInput(String question, String retryContext) {
|
||||
if (retryContext == null || retryContext.isBlank()) {
|
||||
return question;
|
||||
}
|
||||
return question + "\n\n--- 补充约束 ---\n" + retryContext;
|
||||
}
|
||||
|
||||
private String buildExecutorInput(String question, String plannerPlan, String retryContext) {
|
||||
StringBuilder input = new StringBuilder(question);
|
||||
if (plannerPlan != null && !plannerPlan.isBlank()) {
|
||||
input.append("\n\n--- planner_plan ---\n").append(plannerPlan);
|
||||
}
|
||||
private String buildSupervisorInput(String question, String retryContext) {
|
||||
StringBuilder input = new StringBuilder();
|
||||
input.append("请按 supervisor 系统提示完成本轮 Planner -> Executor -> Verifier 编排。\n\n");
|
||||
input.append("--- 用户问题 ---\n").append(question);
|
||||
if (retryContext != null && !retryContext.isBlank()) {
|
||||
input.append("\n\n--- retry_context ---\n").append(retryContext);
|
||||
}
|
||||
input.append("\n\n完成 verifier 后立即 FINISH,不要额外生成最终答案。");
|
||||
return input.toString();
|
||||
}
|
||||
|
||||
@@ -674,55 +677,20 @@ public class ChatService {
|
||||
""".formatted(round);
|
||||
}
|
||||
|
||||
private String buildRoundInput(String question, String retryContext) {
|
||||
if (retryContext == null || retryContext.isBlank()) {
|
||||
return question;
|
||||
}
|
||||
return question + "\n\n--- 补充约束 ---\n" + retryContext;
|
||||
}
|
||||
|
||||
private String extractExecutorAnswer(Optional<OverAllState> stateOptional) {
|
||||
private String extractStateText(Optional<OverAllState> stateOptional, String key) {
|
||||
if (stateOptional.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return stateOptional.get().value("executor_feedback")
|
||||
.filter(AssistantMessage.class::isInstance)
|
||||
.map(AssistantMessage.class::cast)
|
||||
.map(AssistantMessage::getText)
|
||||
return stateOptional.get().value(key)
|
||||
.map(value -> {
|
||||
if (value instanceof AssistantMessage assistantMessage) {
|
||||
return assistantMessage.getText();
|
||||
}
|
||||
return String.valueOf(value);
|
||||
})
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private VerifierDecision parseVerifierDecision(Optional<OverAllState> stateOptional, int round) {
|
||||
if (stateOptional.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Optional<AssistantMessage> verifierOutput = stateOptional.get().value("verifier_output")
|
||||
.filter(AssistantMessage.class::isInstance)
|
||||
.map(AssistantMessage.class::cast);
|
||||
|
||||
if (verifierOutput.isEmpty() || verifierOutput.get().getText() == null || verifierOutput.get().getText().isBlank()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
JsonNode root = objectMapper.readTree(verifierOutput.get().getText());
|
||||
List<Map<String, Object>> factsChecked = parseFactsChecked(root.path("facts_checked"));
|
||||
|
||||
return new VerifierDecision(
|
||||
root.path("verdict").asText("LOW_CONFID"),
|
||||
root.path("groundedness_score").asDouble(0.0),
|
||||
root.path("critical_fact_count").asInt(0),
|
||||
factsChecked,
|
||||
root.path("rationale").asText(""),
|
||||
round
|
||||
);
|
||||
} catch (Exception e) {
|
||||
logger.error("解析 verifier_output 失败: {}", verifierOutput.get().getText(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void persistVerifierEvaluation(DiagnosisSession session, VerifierDecision decision, int round) {
|
||||
if (decision == null) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user