feat(agent): add executor evidence v2 contract
This commit is contained in:
@@ -444,8 +444,12 @@ public class ChatService {
|
||||
}
|
||||
|
||||
if ("PASS".equals(finalDecision.verdict())) {
|
||||
answer = extractUserFacingAnswer(answer)
|
||||
.orElse(answer == null || answer.isBlank() ? "抱歉,多 Agent 分析未能生成有效结论。" : answer);
|
||||
String executorAnswer = answer;
|
||||
answer = extractUserFacingAnswer(executorAnswer)
|
||||
.or(() -> renderStructuredExecutorAnswer(executorAnswer))
|
||||
.orElse(executorAnswer == null || executorAnswer.isBlank()
|
||||
? "抱歉,多 Agent 分析未能生成有效结论。"
|
||||
: executorAnswer);
|
||||
persistVerifierEvaluation(session, finalDecision, round);
|
||||
break;
|
||||
}
|
||||
@@ -816,6 +820,98 @@ public class ChatService {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Optional<String> renderStructuredExecutorAnswer(String executorAnswer) {
|
||||
if (executorAnswer == null || executorAnswer.isBlank()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
JsonNode root = objectMapper.readTree(sanitizeJsonPayload(executorAnswer));
|
||||
if (!"executor_evidence_v2".equals(root.path("answer_version").asText(""))) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
StringBuilder output = new StringBuilder();
|
||||
appendTextArraySection(output, "已确认信息", root.path("claims"), "claim_text", "暂无可稳定确认的信息");
|
||||
appendHypothesesSection(output, root.path("hypotheses"));
|
||||
appendStringArraySection(output, "当前缺口", root.path("missing_info"), "当前缺少足够的直接证据支撑完整结论");
|
||||
appendRecommendedActionsSection(output, root.path("recommended_actions"));
|
||||
String rendered = output.toString().trim();
|
||||
return rendered.isBlank() ? Optional.empty() : Optional.of(rendered);
|
||||
} catch (Exception e) {
|
||||
logger.debug("Failed to render executor_evidence_v2 answer", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private void appendTextArraySection(StringBuilder output, String title, JsonNode items,
|
||||
String fieldName, String emptyText) {
|
||||
output.append(title).append(":");
|
||||
if (!items.isArray() || items.isEmpty()) {
|
||||
output.append("\n- ").append(emptyText);
|
||||
return;
|
||||
}
|
||||
for (JsonNode item : items) {
|
||||
String text = item.path(fieldName).asText("");
|
||||
if (!text.isBlank()) {
|
||||
output.append("\n- ").append(text);
|
||||
}
|
||||
}
|
||||
if (output.charAt(output.length() - 1) == ':') {
|
||||
output.append("\n- ").append(emptyText);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendHypothesesSection(StringBuilder output, JsonNode hypotheses) {
|
||||
if (!hypotheses.isArray() || hypotheses.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
output.append("\n\n可能方向:");
|
||||
for (JsonNode hypothesis : hypotheses) {
|
||||
String text = hypothesis.path("hypothesis_text").asText("");
|
||||
if (text.isBlank()) {
|
||||
continue;
|
||||
}
|
||||
String basis = hypothesis.path("basis").asText("");
|
||||
output.append("\n- ").append(text);
|
||||
if (!basis.isBlank()) {
|
||||
output.append("(").append(basis).append(")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void appendStringArraySection(StringBuilder output, String title, JsonNode items, String emptyText) {
|
||||
output.append("\n\n").append(title).append(":");
|
||||
if (!items.isArray() || items.isEmpty()) {
|
||||
output.append("\n- ").append(emptyText);
|
||||
return;
|
||||
}
|
||||
for (JsonNode item : items) {
|
||||
String text = item.asText("");
|
||||
if (!text.isBlank()) {
|
||||
output.append("\n- ").append(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void appendRecommendedActionsSection(StringBuilder output, JsonNode actions) {
|
||||
output.append("\n\n建议下一步:");
|
||||
if (!actions.isArray() || actions.isEmpty()) {
|
||||
output.append("\n- 围绕上述证据缺口补充只读查询,再由人工复核最终结论");
|
||||
return;
|
||||
}
|
||||
for (JsonNode action : actions) {
|
||||
String text = action.path("action_text").asText("");
|
||||
if (text.isBlank()) {
|
||||
continue;
|
||||
}
|
||||
String reason = action.path("reason").asText("");
|
||||
output.append("\n- ").append(text);
|
||||
if (!reason.isBlank()) {
|
||||
output.append(":").append(reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String buildDegradedOutput(VerifierDecision decision) {
|
||||
StringBuilder output = new StringBuilder(DEGRADED_PREFIX);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user