mirror of
https://gitee.com/270580156/weiyu.git
synced 2026-05-16 20:27:50 +00:00
update
This commit is contained in:
@@ -29,6 +29,10 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
/**
|
||||
* https://spring.io/blog/2025/09/16/spring-ai-mcp-intro-blog
|
||||
* McpServer Management Controller - Content mcpServer management and categorization APIs
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/mcp/server")
|
||||
@AllArgsConstructor
|
||||
|
||||
@@ -13,77 +13,77 @@
|
||||
*/
|
||||
package com.bytedesk.ai.workflow.alibaba;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
// import java.util.HashMap;
|
||||
// import java.util.Map;
|
||||
|
||||
import com.alibaba.cloud.ai.graph.CompileConfig;
|
||||
import com.alibaba.cloud.ai.graph.CompiledGraph;
|
||||
import com.alibaba.cloud.ai.graph.exception.GraphStateException;
|
||||
import com.alibaba.cloud.ai.graph.OverAllState;
|
||||
import com.alibaba.cloud.ai.graph.StateGraph;
|
||||
import com.alibaba.cloud.ai.graph.action.EdgeAction;
|
||||
import com.alibaba.cloud.ai.graph.observation.GraphObservationLifecycleListener;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
// import com.alibaba.cloud.ai.graph.CompileConfig;
|
||||
// import com.alibaba.cloud.ai.graph.CompiledGraph;
|
||||
// import com.alibaba.cloud.ai.graph.exception.GraphStateException;
|
||||
// import com.alibaba.cloud.ai.graph.OverAllState;
|
||||
// import com.alibaba.cloud.ai.graph.StateGraph;
|
||||
// import com.alibaba.cloud.ai.graph.action.EdgeAction;
|
||||
// import com.alibaba.cloud.ai.graph.observation.GraphObservationLifecycleListener;
|
||||
// import io.micrometer.observation.ObservationRegistry;
|
||||
// import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
// import org.springframework.beans.factory.ObjectProvider;
|
||||
// import org.springframework.beans.factory.annotation.Qualifier;
|
||||
// import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
// import org.springframework.web.bind.annotation.GetMapping;
|
||||
// import org.springframework.web.bind.annotation.RequestMapping;
|
||||
// import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/customer")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.workflow.graph", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class CustomerServiceController {
|
||||
// @Slf4j
|
||||
// @RestController
|
||||
// @RequestMapping("/customer")
|
||||
// @ConditionalOnProperty(prefix = "spring.ai.workflow.graph", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
// public class CustomerServiceController {
|
||||
|
||||
private CompiledGraph compiledGraph;
|
||||
// private CompiledGraph compiledGraph;
|
||||
|
||||
public CustomerServiceController(@Qualifier("workflowGraph") StateGraph stateGraph,
|
||||
ObjectProvider<ObservationRegistry> observationRegistry) throws GraphStateException {
|
||||
this.compiledGraph = stateGraph.compile(CompileConfig.builder()
|
||||
.withLifecycleListener(new GraphObservationLifecycleListener(
|
||||
observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)))
|
||||
.build());
|
||||
}
|
||||
// public CustomerServiceController(@Qualifier("workflowGraph") StateGraph stateGraph,
|
||||
// ObjectProvider<ObservationRegistry> observationRegistry) throws GraphStateException {
|
||||
// this.compiledGraph = stateGraph.compile(CompileConfig.builder()
|
||||
// .withLifecycleListener(new GraphObservationLifecycleListener(
|
||||
// observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP)))
|
||||
// .build());
|
||||
// }
|
||||
|
||||
// http://localhost:9003/customer/chat?query=我收到的产品有快递破损,需要退换货?
|
||||
// http://localhost:9003/customer/chat?query=我的产品不能正常工作了,要怎么去做维修?
|
||||
// http://localhost:9003/customer/chat?query=商品收到了,非常好,下次还会买。
|
||||
@GetMapping("/chat")
|
||||
public String simpleChat(String query) throws Exception {
|
||||
return compiledGraph.invoke(Map.of("input", query)).get().value("solution").get().toString();
|
||||
}
|
||||
// // http://localhost:9003/customer/chat?query=我收到的产品有快递破损,需要退换货?
|
||||
// // http://localhost:9003/customer/chat?query=我的产品不能正常工作了,要怎么去做维修?
|
||||
// // http://localhost:9003/customer/chat?query=商品收到了,非常好,下次还会买。
|
||||
// @GetMapping("/chat")
|
||||
// public String simpleChat(String query) throws Exception {
|
||||
// return compiledGraph.invoke(Map.of("input", query)).get().value("solution").get().toString();
|
||||
// }
|
||||
|
||||
public static class FeedbackQuestionDispatcher implements EdgeAction {
|
||||
@Override
|
||||
public String apply(OverAllState state) throws Exception {
|
||||
String classifierOutput = (String) state.value("classifier_output").orElse("");
|
||||
log.info("classifierOutput: {}", classifierOutput);
|
||||
if (classifierOutput.contains("positive")) {
|
||||
return "positive";
|
||||
}
|
||||
return "negative";
|
||||
}
|
||||
}
|
||||
// public static class FeedbackQuestionDispatcher implements EdgeAction {
|
||||
// @Override
|
||||
// public String apply(OverAllState state) throws Exception {
|
||||
// String classifierOutput = (String) state.value("classifier_output").orElse("");
|
||||
// log.info("classifierOutput: {}", classifierOutput);
|
||||
// if (classifierOutput.contains("positive")) {
|
||||
// return "positive";
|
||||
// }
|
||||
// return "negative";
|
||||
// }
|
||||
// }
|
||||
|
||||
public static class SpecificQuestionDispatcher implements EdgeAction {
|
||||
@Override
|
||||
public String apply(OverAllState state) throws Exception {
|
||||
String classifierOutput = (String) state.value("classifier_output").orElse("");
|
||||
log.info("classifierOutput: {}", classifierOutput);
|
||||
Map<String, String> classifierMap = new HashMap<>();
|
||||
classifierMap.put("after-sale", "after-sale");
|
||||
classifierMap.put("quality", "quality");
|
||||
classifierMap.put("transportation", "transportation");
|
||||
for (Map.Entry<String, String> entry : classifierMap.entrySet()) {
|
||||
if (classifierOutput.contains(entry.getKey())) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return "others";
|
||||
}
|
||||
}
|
||||
}
|
||||
// public static class SpecificQuestionDispatcher implements EdgeAction {
|
||||
// @Override
|
||||
// public String apply(OverAllState state) throws Exception {
|
||||
// String classifierOutput = (String) state.value("classifier_output").orElse("");
|
||||
// log.info("classifierOutput: {}", classifierOutput);
|
||||
// Map<String, String> classifierMap = new HashMap<>();
|
||||
// classifierMap.put("after-sale", "after-sale");
|
||||
// classifierMap.put("quality", "quality");
|
||||
// classifierMap.put("transportation", "transportation");
|
||||
// for (Map.Entry<String, String> entry : classifierMap.entrySet()) {
|
||||
// if (classifierOutput.contains(entry.getKey())) {
|
||||
// return entry.getValue();
|
||||
// }
|
||||
// }
|
||||
// return "others";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -13,88 +13,88 @@
|
||||
*/
|
||||
package com.bytedesk.ai.workflow.alibaba;
|
||||
|
||||
import com.alibaba.cloud.ai.graph.GraphRepresentation;
|
||||
import com.alibaba.cloud.ai.graph.KeyStrategy;
|
||||
import com.alibaba.cloud.ai.graph.StateGraph;
|
||||
import com.alibaba.cloud.ai.graph.exception.GraphStateException;
|
||||
import com.alibaba.cloud.ai.graph.node.QuestionClassifierNode;
|
||||
import com.alibaba.cloud.ai.graph.state.strategy.ReplaceStrategy;
|
||||
// import com.alibaba.cloud.ai.graph.GraphRepresentation;
|
||||
// import com.alibaba.cloud.ai.graph.KeyStrategy;
|
||||
// import com.alibaba.cloud.ai.graph.StateGraph;
|
||||
// import com.alibaba.cloud.ai.graph.exception.GraphStateException;
|
||||
// import com.alibaba.cloud.ai.graph.node.QuestionClassifierNode;
|
||||
// import com.alibaba.cloud.ai.graph.state.strategy.ReplaceStrategy;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
// import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.ai.chat.client.ChatClient;
|
||||
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
|
||||
import org.springframework.ai.chat.model.ChatModel;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
// import org.springframework.ai.chat.client.ChatClient;
|
||||
// import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
|
||||
// import org.springframework.ai.chat.model.ChatModel;
|
||||
// import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
// import org.springframework.context.annotation.Bean;
|
||||
// import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
// import java.util.HashMap;
|
||||
// import java.util.List;
|
||||
// import java.util.Map;
|
||||
|
||||
import static com.alibaba.cloud.ai.graph.StateGraph.END;
|
||||
import static com.alibaba.cloud.ai.graph.StateGraph.START;
|
||||
import static com.alibaba.cloud.ai.graph.action.AsyncEdgeAction.edge_async;
|
||||
import static com.alibaba.cloud.ai.graph.action.AsyncNodeAction.node_async;
|
||||
// import static com.alibaba.cloud.ai.graph.StateGraph.END;
|
||||
// import static com.alibaba.cloud.ai.graph.StateGraph.START;
|
||||
// import static com.alibaba.cloud.ai.graph.action.AsyncEdgeAction.edge_async;
|
||||
// import static com.alibaba.cloud.ai.graph.action.AsyncNodeAction.node_async;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "spring.ai.workflow.graph", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class WorkflowAutoConfiguration {
|
||||
// /**
|
||||
// *
|
||||
// */
|
||||
// @Slf4j
|
||||
// @Configuration
|
||||
// @ConditionalOnProperty(prefix = "spring.ai.workflow.graph", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
// public class WorkflowAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public StateGraph workflowGraph(ChatModel chatModel) throws GraphStateException {
|
||||
// @Bean
|
||||
// public StateGraph workflowGraph(ChatModel chatModel) throws GraphStateException {
|
||||
|
||||
ChatClient chatClient = ChatClient.builder(chatModel).defaultAdvisors(new SimpleLoggerAdvisor()).build();
|
||||
// ChatClient chatClient = ChatClient.builder(chatModel).defaultAdvisors(new SimpleLoggerAdvisor()).build();
|
||||
|
||||
QuestionClassifierNode feedbackClassifier = QuestionClassifierNode.builder()
|
||||
.chatClient(chatClient)
|
||||
.inputTextKey("input")
|
||||
.outputKey("classifier_output")
|
||||
.categories(List.of("positive feedback", "negative feedback"))
|
||||
.classificationInstructions(
|
||||
List.of("Try to understand the user's feeling when he/she is giving the feedback."))
|
||||
.build();
|
||||
// QuestionClassifierNode feedbackClassifier = QuestionClassifierNode.builder()
|
||||
// .chatClient(chatClient)
|
||||
// .inputTextKey("input")
|
||||
// .outputKey("classifier_output")
|
||||
// .categories(List.of("positive feedback", "negative feedback"))
|
||||
// .classificationInstructions(
|
||||
// List.of("Try to understand the user's feeling when he/she is giving the feedback."))
|
||||
// .build();
|
||||
|
||||
QuestionClassifierNode specificQuestionClassifier = QuestionClassifierNode.builder()
|
||||
.chatClient(chatClient)
|
||||
.inputTextKey("input")
|
||||
.outputKey("classifier_output")
|
||||
.categories(List.of("after-sale service", "transportation", "product quality", "others"))
|
||||
.classificationInstructions(List
|
||||
.of("What kind of service or help the customer is trying to get from us? Classify the question based on your understanding."))
|
||||
.build();
|
||||
// QuestionClassifierNode specificQuestionClassifier = QuestionClassifierNode.builder()
|
||||
// .chatClient(chatClient)
|
||||
// .inputTextKey("input")
|
||||
// .outputKey("classifier_output")
|
||||
// .categories(List.of("after-sale service", "transportation", "product quality", "others"))
|
||||
// .classificationInstructions(List
|
||||
// .of("What kind of service or help the customer is trying to get from us? Classify the question based on your understanding."))
|
||||
// .build();
|
||||
|
||||
StateGraph stateGraph = new StateGraph("Consumer Service Workflow Demo", () -> {
|
||||
Map<String, KeyStrategy> strategies = new HashMap<>();
|
||||
strategies.put("input", new ReplaceStrategy());
|
||||
strategies.put("classifier_output", new ReplaceStrategy());
|
||||
strategies.put("solution", new ReplaceStrategy());
|
||||
return strategies;
|
||||
}).addNode("feedback_classifier", node_async(feedbackClassifier))
|
||||
.addNode("specific_question_classifier", node_async(specificQuestionClassifier))
|
||||
.addNode("recorder", node_async(new RecordingNode()))
|
||||
// StateGraph stateGraph = new StateGraph("Consumer Service Workflow Demo", () -> {
|
||||
// Map<String, KeyStrategy> strategies = new HashMap<>();
|
||||
// strategies.put("input", new ReplaceStrategy());
|
||||
// strategies.put("classifier_output", new ReplaceStrategy());
|
||||
// strategies.put("solution", new ReplaceStrategy());
|
||||
// return strategies;
|
||||
// }).addNode("feedback_classifier", node_async(feedbackClassifier))
|
||||
// .addNode("specific_question_classifier", node_async(specificQuestionClassifier))
|
||||
// .addNode("recorder", node_async(new RecordingNode()))
|
||||
|
||||
.addEdge(START, "feedback_classifier")
|
||||
.addConditionalEdges("feedback_classifier",
|
||||
edge_async(new CustomerServiceController.FeedbackQuestionDispatcher()),
|
||||
Map.of("positive", "recorder", "negative", "specific_question_classifier"))
|
||||
.addConditionalEdges("specific_question_classifier",
|
||||
edge_async(new CustomerServiceController.SpecificQuestionDispatcher()),
|
||||
Map.of("after-sale", "recorder", "transportation", "recorder", "quality", "recorder", "others",
|
||||
"recorder"))
|
||||
.addEdge("recorder", END);
|
||||
// .addEdge(START, "feedback_classifier")
|
||||
// .addConditionalEdges("feedback_classifier",
|
||||
// edge_async(new CustomerServiceController.FeedbackQuestionDispatcher()),
|
||||
// Map.of("positive", "recorder", "negative", "specific_question_classifier"))
|
||||
// .addConditionalEdges("specific_question_classifier",
|
||||
// edge_async(new CustomerServiceController.SpecificQuestionDispatcher()),
|
||||
// Map.of("after-sale", "recorder", "transportation", "recorder", "quality", "recorder", "others",
|
||||
// "recorder"))
|
||||
// .addEdge("recorder", END);
|
||||
|
||||
GraphRepresentation graphRepresentation = stateGraph.getGraph(GraphRepresentation.Type.PLANTUML,
|
||||
"workflow graph");
|
||||
// GraphRepresentation graphRepresentation = stateGraph.getGraph(GraphRepresentation.Type.PLANTUML,
|
||||
// "workflow graph");
|
||||
|
||||
log.info("workflow graph: {}", graphRepresentation.content());
|
||||
// log.info("workflow graph: {}", graphRepresentation.content());
|
||||
|
||||
return stateGraph;
|
||||
}
|
||||
// return stateGraph;
|
||||
// }
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user