Kaynağa Gözat

第一次推送,学生端评价和教师端手动

hxy 8 ay önce
işleme
cd73108f07
29 değiştirilmiş dosya ile 1284 ekleme ve 0 silme
  1. 33 0
      .gitignore
  2. 171 0
      pom.xml
  3. 13 0
      src/main/java/com/yango/javaailangchain4j/Aientity/GpsresEvaluation.java
  4. 16 0
      src/main/java/com/yango/javaailangchain4j/Aientity/Psre.java
  5. 13 0
      src/main/java/com/yango/javaailangchain4j/JavaAiLangchain4jApplication.java
  6. 10 0
      src/main/java/com/yango/javaailangchain4j/assistant/Assistant.java
  7. 15 0
      src/main/java/com/yango/javaailangchain4j/assistant/MemoryChatAssistant.java
  8. 71 0
      src/main/java/com/yango/javaailangchain4j/assistant/SeparateChatAssistant.java
  9. 33 0
      src/main/java/com/yango/javaailangchain4j/config/Langchain4jConfig.java
  10. 15 0
      src/main/java/com/yango/javaailangchain4j/config/MemoryChatAssistantConfig.java
  11. 17 0
      src/main/java/com/yango/javaailangchain4j/config/SeparateChatAssistantConfig.java
  12. 28 0
      src/main/java/com/yango/javaailangchain4j/controller/ChatController.java
  13. 47 0
      src/main/java/com/yango/javaailangchain4j/controller/GpsresEvaluation.java
  14. 37 0
      src/main/java/com/yango/javaailangchain4j/controller/TeacherGpsrenController.java
  15. 15 0
      src/main/java/com/yango/javaailangchain4j/dto/EvaluationPsren.java
  16. 11 0
      src/main/java/com/yango/javaailangchain4j/dto/ManuallyCreatePsren.java
  17. 14 0
      src/main/java/com/yango/javaailangchain4j/dto/courseKnowledgeMapInfo.java
  18. 38 0
      src/main/java/com/yango/javaailangchain4j/tools/createPase.java
  19. 147 0
      src/main/java/com/yango/javaailangchain4j/utils/Result.java
  20. 51 0
      src/main/java/com/yango/javaailangchain4j/utils/ResultCode.java
  21. 209 0
      src/main/java/generator/domain/CourseInfo.java
  22. 18 0
      src/main/java/generator/mapper/CourseInfoMapper.java
  23. 13 0
      src/main/java/generator/service/CourseInfoService.java
  24. 22 0
      src/main/java/generator/service/impl/CourseInfoServiceImpl.java
  25. 33 0
      src/main/resources/application.properties
  26. 36 0
      src/main/resources/generator/mapper/CourseInfoMapper.xml
  27. 32 0
      src/main/resources/knowledgeMap.txt
  28. 63 0
      src/main/resources/teacherGpsren.txt
  29. 63 0
      src/main/resources/teacherGpsrenEval.txt

+ 33 - 0
.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 171 - 0
pom.xml

@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.yango</groupId>
+    <artifactId>java-ai-langchain4j</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>java-ai-langchain4j</name>
+    <description>java-ai-langchain4j</description>
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <spring-boot.version>3.2.6</spring-boot.version>
+        <knife4j.version>4.3.0</knife4j.version>
+        <langchain4j.version>1.0.0-beta3</langchain4j.version>
+        <mybatis-plus.version>3.5.11</mybatis-plus.version>
+    </properties>
+    <dependencies>
+        <!-- web应用程序核心依赖 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator</artifactId>
+            <version>7.0.1.Final</version>
+        </dependency>
+        <!-- 编写和运行测试用例 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!-- 前后端分离中的后端接口测试工具 -->
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
+            <version>${knife4j.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
+            <version>${langchain4j.version}</version>
+        </dependency>
+
+
+
+        <!-- 接入ollama -->
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j-ollama-spring-boot-starter</artifactId>
+            <version>1.0.0-beta3</version>
+        </dependency>
+
+        <!-- 接入阿里云百炼平台 -->
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>dev.langchain4j</groupId>
+            <artifactId>langchain4j-spring-boot-starter</artifactId>
+            <version>1.0.0-beta3</version>
+        </dependency>
+
+
+        <!-- MyBatis-Plus 依赖 -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.5</version>
+        </dependency>
+
+        <!-- MySQL 驱动 -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.33</version>
+        </dependency>
+
+        <!-- Lombok(可选) -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- fastjson 依赖 -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.83</version>
+        </dependency>
+
+        <!-- Jakarta Servlet API -->
+        <dependency>
+            <groupId>jakarta.servlet</groupId>
+            <artifactId>jakarta.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+
+
+    <dependencyManagement>
+        <dependencies>
+            <!--引入SpringBoot依赖管理清单-->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>dev.langchain4j</groupId>
+                <artifactId>langchain4j-parent</artifactId>
+                <version>1.0.0-beta3</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>dev.langchain4j</groupId>
+                <artifactId>langchain4j-community-bom</artifactId>
+                <version>${langchain4j.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+        </dependencies>
+
+    </dependencyManagement>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.10.1</version>
+                <configuration>
+                    <source>17</source>
+                    <target>17</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot.version}</version>
+                <executions>
+                    <execution>
+                        <id>repackage</id>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                        <configuration>
+                            <mainClass>com.yango.javaailangchain4j.JavaAiLangchain4jApplication</mainClass>
+                            <skip>false</skip>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+        </plugins>
+    </build>
+
+</project>

+ 13 - 0
src/main/java/com/yango/javaailangchain4j/Aientity/GpsresEvaluation.java

@@ -0,0 +1,13 @@
+package com.yango.javaailangchain4j.Aientity;
+
+import lombok.Data;
+
+@Data
+public class GpsresEvaluation {
+    public String G;
+    public String P;
+    public String S;
+    public String R;
+    public String E;
+    public String N;
+}

+ 16 - 0
src/main/java/com/yango/javaailangchain4j/Aientity/Psre.java

@@ -0,0 +1,16 @@
+package com.yango.javaailangchain4j.Aientity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Psre {
+    private String knowledge;
+    private String P;
+    private String S;
+    private String R;
+    private String E;
+}

+ 13 - 0
src/main/java/com/yango/javaailangchain4j/JavaAiLangchain4jApplication.java

@@ -0,0 +1,13 @@
+package com.yango.javaailangchain4j;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class JavaAiLangchain4jApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(JavaAiLangchain4jApplication.class, args);
+    }
+
+}

+ 10 - 0
src/main/java/com/yango/javaailangchain4j/assistant/Assistant.java

@@ -0,0 +1,10 @@
+package com.yango.javaailangchain4j.assistant;
+
+import dev.langchain4j.service.spring.AiService;
+
+import static dev.langchain4j.service.spring.AiServiceWiringMode.EXPLICIT;
+
+@AiService(wiringMode = EXPLICIT, chatModel = "qwenChatModel")
+public interface Assistant {
+    String chat(String message);
+}

+ 15 - 0
src/main/java/com/yango/javaailangchain4j/assistant/MemoryChatAssistant.java

@@ -0,0 +1,15 @@
+package com.yango.javaailangchain4j.assistant;
+
+import dev.langchain4j.service.spring.AiService;
+
+import static dev.langchain4j.service.spring.AiServiceWiringMode.EXPLICIT;
+
+@AiService(
+        wiringMode = EXPLICIT,
+        chatModel = "qwenChatModel",
+//        chatModel = "openAiChatModel",
+        chatMemory = "chatMemory"
+)
+public interface MemoryChatAssistant {
+    String chat(String message);
+}

+ 71 - 0
src/main/java/com/yango/javaailangchain4j/assistant/SeparateChatAssistant.java

@@ -0,0 +1,71 @@
+package com.yango.javaailangchain4j.assistant;
+
+import com.yango.javaailangchain4j.Aientity.Psre;
+import dev.langchain4j.agent.tool.Tool;
+import dev.langchain4j.service.MemoryId;
+import dev.langchain4j.service.SystemMessage;
+import dev.langchain4j.service.UserMessage;
+import dev.langchain4j.service.V;
+import dev.langchain4j.service.spring.AiService;
+
+import static dev.langchain4j.service.spring.AiServiceWiringMode.EXPLICIT;
+
+@AiService(
+        wiringMode = EXPLICIT,
+        chatMemory = "chatMemory",
+        chatModel = "qwenChatModel",
+//        chatModel = "ollamaChatModel",
+        chatMemoryProvider = "chatMemoryProvider",
+        tools="createPase"
+)
+public interface SeparateChatAssistant {
+    /**
+     * * 分离聊天记录
+     * @param memoryId 聊天id
+     * @param userMessage 用户消息
+     * @return
+     */
+    @SystemMessage("你是资深教育专家")
+    String chat(@MemoryId int memoryId, @UserMessage String userMessage);
+    /**
+     * * 获取知识图谱
+     * @param memoryId 聊天id
+     * @param userMessage 用户消息
+     * @param courseName 课程名称
+     * @param courseId 课程id
+     * @return
+     */
+    @SystemMessage(fromResource = "knowledgeMap.txt")
+    String chat3(
+        @MemoryId int memoryId,
+        @UserMessage String userMessage,
+        @V("courseName") String courseName,
+        @V("coueseId") int courseId
+    );
+
+    @SystemMessage(fromResource = "teacherGpsren.txt")
+    Psre chat4(@MemoryId int memoryId,
+                 @V("courseName") String courseName,
+                 @UserMessage String userMessage
+                 );
+
+//    @Tool
+//    Psre createPsre(
+//            @MemoryId int memoryId,
+//            @V("courseName") String courseName,
+//            @UserMessage String userMessage
+//    );
+
+
+
+    @SystemMessage(fromResource = "teacherGpsren.txt")
+    String chat5(@MemoryId int memoryId,
+                 @V("courseName") String courseName,
+                 @V("stepName") String stepName,
+                 @V("standardAnswer") String standardAnswer,
+                 @V("studentAnswer") String studentAnswer,
+                 @V("goal") String goal,
+                 @UserMessage String userMessage
+    );
+
+}

+ 33 - 0
src/main/java/com/yango/javaailangchain4j/config/Langchain4jConfig.java

@@ -0,0 +1,33 @@
+package com.yango.javaailangchain4j.config;
+import dev.langchain4j.community.model.dashscope.QwenChatModel;
+import dev.langchain4j.service.AiServices;
+import dev.langchain4j.model.chat.ChatLanguageModel;
+import com.yango.javaailangchain4j.assistant.Assistant;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class Langchain4jConfig {
+    // 从配置文件中读取 API Key 和模型名
+    @Value("${langchain4j.community.dashscope.chat-model.api-key}")
+    private String apiKey;
+
+    @Value("${langchain4j.community.dashscope.chat-model.model-name}")
+    private String modelName;
+
+    // 注册 qwenChatModel Bean,供 AiService wiringMode=EXPLICIT 使用
+//    @Bean(name = "qwenChatModel")
+//    public ChatLanguageModel qwenChatModel() {
+//        return QwenChatModel.builder()
+//                .apiKey(apiKey)
+//                .modelName(modelName)
+//                .build();
+//    }
+
+    // 注册 Assistant Bean,实现自动注入
+//    @Bean
+//    public Assistant assistant(ChatLanguageModel qwenChatModel) {
+//        return AiServices.create(Assistant.class, qwenChatModel);
+//    }
+}

+ 15 - 0
src/main/java/com/yango/javaailangchain4j/config/MemoryChatAssistantConfig.java

@@ -0,0 +1,15 @@
+package com.yango.javaailangchain4j.config;
+
+import dev.langchain4j.memory.ChatMemory;
+import dev.langchain4j.memory.chat.MessageWindowChatMemory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class MemoryChatAssistantConfig {
+    @Bean
+    ChatMemory chatMemory() {
+        //设置聊天记忆记录的message数量
+        return MessageWindowChatMemory.withMaxMessages(10);
+    }
+}

+ 17 - 0
src/main/java/com/yango/javaailangchain4j/config/SeparateChatAssistantConfig.java

@@ -0,0 +1,17 @@
+package com.yango.javaailangchain4j.config;
+
+import dev.langchain4j.memory.chat.ChatMemoryProvider;
+import dev.langchain4j.memory.chat.MessageWindowChatMemory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class SeparateChatAssistantConfig {
+    @Bean
+    ChatMemoryProvider chatMemoryProvider() {
+        return memoryId -> MessageWindowChatMemory.builder()
+                .id(memoryId)
+                .maxMessages(10)
+                .build();
+    }
+}

+ 28 - 0
src/main/java/com/yango/javaailangchain4j/controller/ChatController.java

@@ -0,0 +1,28 @@
+package com.yango.javaailangchain4j.controller;
+
+import com.yango.javaailangchain4j.assistant.Assistant;
+import com.yango.javaailangchain4j.assistant.SeparateChatAssistant;
+import com.yango.javaailangchain4j.dto.courseKnowledgeMapInfo;
+import com.yango.javaailangchain4j.utils.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/api/courseKnowledgeMap")
+@CrossOrigin(origins = "*")
+public class ChatController {
+    @Autowired
+    private Assistant assistant;
+
+    // 接收前端发送的用户ID,问答,课程名称,课程ID,返回 AI 回复
+
+    @Autowired
+    private SeparateChatAssistant separateChatAssistant;
+    @PostMapping
+    public Result chatWithAi(@RequestBody courseKnowledgeMapInfo knowledgeMapInfo) {
+
+        return Result.success(separateChatAssistant.chat3(knowledgeMapInfo.getMemoryId(),knowledgeMapInfo.getUserMessage(),knowledgeMapInfo.getCourseName(),knowledgeMapInfo.getCourseId()));
+    }
+
+
+}

+ 47 - 0
src/main/java/com/yango/javaailangchain4j/controller/GpsresEvaluation.java

@@ -0,0 +1,47 @@
+package com.yango.javaailangchain4j.controller;
+
+
+import com.yango.javaailangchain4j.assistant.SeparateChatAssistant;
+import com.yango.javaailangchain4j.dto.EvaluationPsren;
+import com.yango.javaailangchain4j.utils.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/api")
+@CrossOrigin(origins = "*")
+public class GpsresEvaluation {
+    @Autowired
+    private SeparateChatAssistant separateChatAssistant;
+
+    @CrossOrigin(origins = "*")
+    @RequestMapping("/psrenEvalution")
+    public Result Pevaluation(@RequestBody EvaluationPsren evaluationPsren) {
+        String courseName = evaluationPsren.getCourseName();
+        String stepName = evaluationPsren.getStepName();
+        String goal = evaluationPsren.getGoal();
+        String standardAnswer = evaluationPsren.getStandardAnswer();
+        String studentAnswer = evaluationPsren.getStudentAnswer();
+        int score = evaluationPsren.getScore();
+        String userMessage = String.format("现在学生在%s课程中的%s环节,Goal是%s,学生的答案是%s,标准答案是%s,答案不要再把学生答案和标准答案复述一遍了,以纯文本格式返回" +
+                "根据标准答案和学生答案,给出该环节的评分和建议,总分%d分",courseName,stepName,goal,studentAnswer,standardAnswer, score);
+        String s = separateChatAssistant.chat5(
+                evaluationPsren.getMemoryId(),
+                evaluationPsren.getCourseName(),
+                evaluationPsren.getStepName(),
+                evaluationPsren.getStandardAnswer(),
+                evaluationPsren.getStandardAnswer(),
+                evaluationPsren.getGoal(),
+                userMessage
+        );
+
+        return Result.success(s);
+    }
+
+
+
+
+}

+ 37 - 0
src/main/java/com/yango/javaailangchain4j/controller/TeacherGpsrenController.java

@@ -0,0 +1,37 @@
+package com.yango.javaailangchain4j.controller;
+
+import com.yango.javaailangchain4j.assistant.SeparateChatAssistant;
+import com.yango.javaailangchain4j.dto.ManuallyCreatePsren;
+import com.yango.javaailangchain4j.utils.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/api/teracherGpsren")
+@CrossOrigin(origins = "*")
+public class TeacherGpsrenController {
+    @Autowired
+    private SeparateChatAssistant separateChatAssistant;
+    /**
+     * 手动创建PSRE
+     * 获取GPS-REN教学法相关的AI助手回复
+     * @param manuallyCreatePsren 包含memoryId、courseName和userMessage的对象
+     * @return 包含AI助手回复结果的Result对象
+     */
+    @CrossOrigin(origins = "*")
+    @RequestMapping("/ManuallyCreatedPsreByG")
+    public Result getGpsren(@RequestBody ManuallyCreatePsren manuallyCreatePsren){
+        String temp = ",根据这个G,生成PSRE以及这个G会涉及到的知识点";
+        return Result.success(separateChatAssistant.chat4(manuallyCreatePsren.getMemoryId(), manuallyCreatePsren.getCourseName(), manuallyCreatePsren.getUserMessage()+temp));
+    }
+
+    /**
+     * 自动创建PSRE
+     * 获取GPS-REN教学法相关的AI助手回复
+     */
+
+
+}

+ 15 - 0
src/main/java/com/yango/javaailangchain4j/dto/EvaluationPsren.java

@@ -0,0 +1,15 @@
+package com.yango.javaailangchain4j.dto;
+
+import lombok.Data;
+
+@Data
+public class EvaluationPsren {
+    private int memoryId;
+    private String courseName;//课程名称
+    private String stepName;//环节名称
+    private String goal;//目标道姓
+    private String standardAnswer;
+    private String studentAnswer;
+    private int score ;
+
+}

+ 11 - 0
src/main/java/com/yango/javaailangchain4j/dto/ManuallyCreatePsren.java

@@ -0,0 +1,11 @@
+package com.yango.javaailangchain4j.dto;
+
+import lombok.Data;
+
+@Data
+public class ManuallyCreatePsren {
+    private int memoryId;
+    private String userMessage;
+    private String courseName;
+
+}

+ 14 - 0
src/main/java/com/yango/javaailangchain4j/dto/courseKnowledgeMapInfo.java

@@ -0,0 +1,14 @@
+package com.yango.javaailangchain4j.dto;
+
+import dev.langchain4j.service.MemoryId;
+import dev.langchain4j.service.UserMessage;
+import dev.langchain4j.service.V;
+import lombok.Data;
+@Data
+public class courseKnowledgeMapInfo {
+    private int memoryId;
+    private String userMessage;
+    private String courseName;
+    private int courseId;
+
+}

+ 38 - 0
src/main/java/com/yango/javaailangchain4j/tools/createPase.java

@@ -0,0 +1,38 @@
+package com.yango.javaailangchain4j.tools;
+
+import com.yango.javaailangchain4j.Aientity.Psre;
+import dev.langchain4j.agent.tool.Tool;
+import dev.langchain4j.memory.ChatMemory;
+import dev.langchain4j.memory.chat.MessageWindowChatMemory;
+import dev.langchain4j.model.openai.OpenAiChatModel;
+import dev.langchain4j.service.MemoryId;
+import dev.langchain4j.service.UserMessage;
+import org.springframework.stereotype.Component;
+
+@Component
+public class createPase {
+
+    private final ChatMemory chatMemory;
+
+    public createPase () {
+        this.chatMemory = MessageWindowChatMemory.withMaxMessages(10); // 示例内存管理
+    }
+
+    @Tool(name = "返回结果类",value = "根据课程名称和用户消息生成 PSRE 结构") // 类似 @AiFunction
+    public Psre createPsre(
+            @MemoryId int memoryId, // 类似 @MemoryId
+            // 类似 @V("courseName")
+            @UserMessage String userMessage                 // 类似 @UserMessage
+    ) {
+        // 你的业务逻辑,例如:
+        Psre psre = new Psre();
+        psre.setKnowledge("课程知识: 待生成" );
+        psre.setP("问题: 待生成");
+        psre.setS("解决方案: 待生成");
+        psre.setR("原因: 待分析");
+        psre.setE("示例: 待提供");
+        return psre;
+    }
+
+
+}

+ 147 - 0
src/main/java/com/yango/javaailangchain4j/utils/Result.java

@@ -0,0 +1,147 @@
+package com.yango.javaailangchain4j.utils;
+
+
+import com.alibaba.fastjson.JSONObject;
+
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Serializable;
+
+/**
+ * @descript: 返回结果类
+ * @Auther: zengjintao
+ * @Date: 2019/12/31 13:46
+ * @Version:2.1.0
+ */
+public final class Result<T> implements Serializable {
+
+    private T data;
+    private Integer code;
+    private static final String DEFAULT_SUCCESS_MESSAGE = "操作成功";
+    private static final String DEFAULT_FAIL_MESSAGE = "操作失败";
+    private String message = DEFAULT_SUCCESS_MESSAGE;
+
+    public Result(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public boolean isSuccess() {
+        return ResultCode.SUCCESS.equals(this.code);
+    }
+
+    public Result() {
+        this.code = ResultCode.SUCCESS;
+        this.message = DEFAULT_SUCCESS_MESSAGE;
+    }
+
+    public Result(Integer code) {
+        this.code = code;
+    }
+
+    public Result(Integer code, T data) {
+        this.code = code;
+        this.data = data;
+    }
+
+    public Result(ResultCode resultCode) {
+        this.code = resultCode.getCode();
+        this.message = resultCode.getMessage();
+    }
+
+    public Result(ResultCode resultCode, T data) {
+        this.code = resultCode.getCode();
+        this.message = resultCode.getMessage();
+        this.data = data;
+    }
+
+    public static <T> Result success(Integer code, String message, T data) {
+        return new Result(code, message, data);
+    }
+
+    public static <T> Result success(Integer code, T data) {
+        return new Result(code, DEFAULT_SUCCESS_MESSAGE, data);
+    }
+
+    public static <T> Result success() {
+        return new Result(ResultCode.SUCCESS, DEFAULT_SUCCESS_MESSAGE);
+    }
+
+    public static <T> Result success(Integer code, String message) {
+        return new Result(code, message);
+    }
+
+    public Result(Integer code, String message, T data) {
+        this.code = code;
+        this.message = message;
+        this.data = data;
+    }
+
+    public static <T> Result success(T data) {
+        return new Result(ResultCode.SUCCESS, DEFAULT_SUCCESS_MESSAGE, data);
+    }
+
+    public static <T> Result success(ResultCode resultCode) {
+        return new Result(resultCode.getCode(), resultCode.getMessage());
+    }
+
+    public static Result fail(Integer code) {
+        return new Result(code, DEFAULT_FAIL_MESSAGE);
+    }
+
+    public static Result fail(Integer code, String message) {
+        return new Result(code, message);
+    }
+
+    public static Result fail() {
+        return new Result(ResultCode.FAIL, DEFAULT_FAIL_MESSAGE);
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+        if (code == ResultCode.FAIL) {
+            this.message = "数据请求失败";
+        }
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+
+    static final String contentType = "application/json; charset=utf-8";
+
+    public static void renderJson(HttpServletResponse response, Result result) {
+        String dataJson = JSONObject.toJSONString(result);
+        PrintWriter writer;
+        try {
+            response.setHeader("Pragma", "no-cache");
+            response.setHeader("Cache-Control", "no-cache");
+            response.setDateHeader("Expires", 0);
+            response.setContentType(contentType);
+            writer = response.getWriter();
+            writer.write(dataJson);
+            writer.flush();
+            return;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

+ 51 - 0
src/main/java/com/yango/javaailangchain4j/utils/ResultCode.java

@@ -0,0 +1,51 @@
+package com.yango.javaailangchain4j.utils;
+/**
+ * 为方便处理ajax请求
+ * @author zengjintao
+ * @version 1.0
+ * @create_at 2017年6月28日上午9:28:04
+ */
+public class ResultCode {
+
+	public static final Integer UN_AUTH_ERROR_CODE = 401; //token 失效
+	public static final Integer NO_PERMISSION = 406; // 权限不足
+	public static final Integer SUCCESS = 1; //响应成功
+	public static final Integer FAIL = 0; //响应失败
+	public static final Integer CODE_ERROR = 2; //验证码错误
+
+	public static final Integer EXCEL_VERIFICATION_FAIL = 3; // excel 表格数据校验异常
+
+	public Integer code = SUCCESS;
+	public String message = "操作成功";
+
+	public int getCode() {
+		return code;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+	public void setCode(Integer code) {
+		this.code = code;
+	}
+
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	public ResultCode(Integer code, String message) {
+		this.code = code;
+		this.message = message;
+	}
+
+	public ResultCode() {
+	}
+
+	public ResultCode(Integer code) {
+		this.code = code;
+		if (code == FAIL) {
+			this.message = "操作失败";
+		}
+	}
+}

+ 209 - 0
src/main/java/generator/domain/CourseInfo.java

@@ -0,0 +1,209 @@
+package generator.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 课程信息表
+ * @TableName course_info
+ */
+@TableName(value ="course_info")
+@Data
+public class CourseInfo {
+    /**
+     * 
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 
+     */
+    private String name;
+
+    /**
+     * 
+     */
+    private Integer gradeInfoId;
+
+    /**
+     * 
+     */
+    private Integer schoolType;
+
+    /**
+     * 
+     */
+    private Integer subjectId;
+
+    /**
+     * 
+     */
+    private Date createDate;
+
+    /**
+     * 
+     */
+    private Date updateDate;
+
+    /**
+     * 课程编号
+     */
+    private String code;
+
+    /**
+     * 排序
+     */
+    private String sort;
+
+    /**
+     * 
+     */
+    private Integer parentId;
+
+    /**
+     * 
+     */
+    private String headImg;
+
+    /**
+     * 课程简介
+     */
+    private String represent;
+
+    /**
+     * 是否推荐到系统首页
+     */
+    private Integer recommendIndexFlag;
+
+    /**
+     * 
+     */
+    private Integer studyNumber;
+
+    /**
+     * 状态 (0 下架 1 草稿 2. 已上架)
+     */
+    private Integer status;
+
+    /**
+     * 评价分数
+     */
+    private BigDecimal valuateMark;
+
+    /**
+     * 评论数量
+     */
+    private Integer commentNumber;
+
+    /**
+     * 课时数量
+     */
+    private Integer sectionNodeNumber;
+
+    /**
+     * 章节数量
+     */
+    private Integer sectionNumber;
+
+    /**
+     * 课程发布时间
+     */
+    private Date pushTime;
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        CourseInfo other = (CourseInfo) that;
+        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
+            && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
+            && (this.getGradeInfoId() == null ? other.getGradeInfoId() == null : this.getGradeInfoId().equals(other.getGradeInfoId()))
+            && (this.getSchoolType() == null ? other.getSchoolType() == null : this.getSchoolType().equals(other.getSchoolType()))
+            && (this.getSubjectId() == null ? other.getSubjectId() == null : this.getSubjectId().equals(other.getSubjectId()))
+            && (this.getCreateDate() == null ? other.getCreateDate() == null : this.getCreateDate().equals(other.getCreateDate()))
+            && (this.getUpdateDate() == null ? other.getUpdateDate() == null : this.getUpdateDate().equals(other.getUpdateDate()))
+            && (this.getCode() == null ? other.getCode() == null : this.getCode().equals(other.getCode()))
+            && (this.getSort() == null ? other.getSort() == null : this.getSort().equals(other.getSort()))
+            && (this.getParentId() == null ? other.getParentId() == null : this.getParentId().equals(other.getParentId()))
+            && (this.getHeadImg() == null ? other.getHeadImg() == null : this.getHeadImg().equals(other.getHeadImg()))
+            && (this.getRepresent() == null ? other.getRepresent() == null : this.getRepresent().equals(other.getRepresent()))
+            && (this.getRecommendIndexFlag() == null ? other.getRecommendIndexFlag() == null : this.getRecommendIndexFlag().equals(other.getRecommendIndexFlag()))
+            && (this.getStudyNumber() == null ? other.getStudyNumber() == null : this.getStudyNumber().equals(other.getStudyNumber()))
+            && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus()))
+            && (this.getValuateMark() == null ? other.getValuateMark() == null : this.getValuateMark().equals(other.getValuateMark()))
+            && (this.getCommentNumber() == null ? other.getCommentNumber() == null : this.getCommentNumber().equals(other.getCommentNumber()))
+            && (this.getSectionNodeNumber() == null ? other.getSectionNodeNumber() == null : this.getSectionNodeNumber().equals(other.getSectionNodeNumber()))
+            && (this.getSectionNumber() == null ? other.getSectionNumber() == null : this.getSectionNumber().equals(other.getSectionNumber()))
+            && (this.getPushTime() == null ? other.getPushTime() == null : this.getPushTime().equals(other.getPushTime()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+        result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
+        result = prime * result + ((getGradeInfoId() == null) ? 0 : getGradeInfoId().hashCode());
+        result = prime * result + ((getSchoolType() == null) ? 0 : getSchoolType().hashCode());
+        result = prime * result + ((getSubjectId() == null) ? 0 : getSubjectId().hashCode());
+        result = prime * result + ((getCreateDate() == null) ? 0 : getCreateDate().hashCode());
+        result = prime * result + ((getUpdateDate() == null) ? 0 : getUpdateDate().hashCode());
+        result = prime * result + ((getCode() == null) ? 0 : getCode().hashCode());
+        result = prime * result + ((getSort() == null) ? 0 : getSort().hashCode());
+        result = prime * result + ((getParentId() == null) ? 0 : getParentId().hashCode());
+        result = prime * result + ((getHeadImg() == null) ? 0 : getHeadImg().hashCode());
+        result = prime * result + ((getRepresent() == null) ? 0 : getRepresent().hashCode());
+        result = prime * result + ((getRecommendIndexFlag() == null) ? 0 : getRecommendIndexFlag().hashCode());
+        result = prime * result + ((getStudyNumber() == null) ? 0 : getStudyNumber().hashCode());
+        result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode());
+        result = prime * result + ((getValuateMark() == null) ? 0 : getValuateMark().hashCode());
+        result = prime * result + ((getCommentNumber() == null) ? 0 : getCommentNumber().hashCode());
+        result = prime * result + ((getSectionNodeNumber() == null) ? 0 : getSectionNodeNumber().hashCode());
+        result = prime * result + ((getSectionNumber() == null) ? 0 : getSectionNumber().hashCode());
+        result = prime * result + ((getPushTime() == null) ? 0 : getPushTime().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", name=").append(name);
+        sb.append(", gradeInfoId=").append(gradeInfoId);
+        sb.append(", schoolType=").append(schoolType);
+        sb.append(", subjectId=").append(subjectId);
+        sb.append(", createDate=").append(createDate);
+        sb.append(", updateDate=").append(updateDate);
+        sb.append(", code=").append(code);
+        sb.append(", sort=").append(sort);
+        sb.append(", parentId=").append(parentId);
+        sb.append(", headImg=").append(headImg);
+        sb.append(", represent=").append(represent);
+        sb.append(", recommendIndexFlag=").append(recommendIndexFlag);
+        sb.append(", studyNumber=").append(studyNumber);
+        sb.append(", status=").append(status);
+        sb.append(", valuateMark=").append(valuateMark);
+        sb.append(", commentNumber=").append(commentNumber);
+        sb.append(", sectionNodeNumber=").append(sectionNodeNumber);
+        sb.append(", sectionNumber=").append(sectionNumber);
+        sb.append(", pushTime=").append(pushTime);
+        sb.append("]");
+        return sb.toString();
+    }
+}

+ 18 - 0
src/main/java/generator/mapper/CourseInfoMapper.java

@@ -0,0 +1,18 @@
+package generator.mapper;
+
+import generator.domain.CourseInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author hxy
+* @description 针对表【course_info(课程信息表)】的数据库操作Mapper
+* @createDate 2025-07-25 02:22:55
+* @Entity generator.domain.CourseInfo
+*/
+public interface CourseInfoMapper extends BaseMapper<CourseInfo> {
+
+}
+
+
+
+

+ 13 - 0
src/main/java/generator/service/CourseInfoService.java

@@ -0,0 +1,13 @@
+package generator.service;
+
+import generator.domain.CourseInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+* @author hxy
+* @description 针对表【course_info(课程信息表)】的数据库操作Service
+* @createDate 2025-07-25 02:22:55
+*/
+public interface CourseInfoService extends IService<CourseInfo> {
+
+}

+ 22 - 0
src/main/java/generator/service/impl/CourseInfoServiceImpl.java

@@ -0,0 +1,22 @@
+package generator.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import generator.domain.CourseInfo;
+import generator.service.CourseInfoService;
+import generator.mapper.CourseInfoMapper;
+import org.springframework.stereotype.Service;
+
+/**
+* @author hxy
+* @description 针对表【course_info(课程信息表)】的数据库操作Service实现
+* @createDate 2025-07-25 02:22:55
+*/
+@Service
+public class CourseInfoServiceImpl extends ServiceImpl<CourseInfoMapper, CourseInfo>
+    implements CourseInfoService{
+
+}
+
+
+
+

+ 33 - 0
src/main/resources/application.properties

@@ -0,0 +1,33 @@
+server.port=8080
+
+# ??????MySQL 8+?
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+spring.datasource.url=jdbc:mysql://localhost:3306/education?useSSL=false&serverTimezone=Asia/Shanghai
+spring.datasource.username=root
+spring.datasource.password=root
+
+# MyBatis-Plus?????SQL??
+mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
+
+
+##langchain4j
+langchain4j.open-ai.chat-model.base-url=https://api.deepseek.com
+langchain4j.open-ai.chat-model.api-key=sk-9ba36d80f4ef4a56883f508ede43bc7d
+langchain4j.open-ai.chat-model.model-name=deepseek-reasoner
+##
+langchain4j.open-ai.chat-model.log-requests=true
+langchain4j.open-ai.chat-model.log-responses=true
+
+
+#ollama
+langchain4j.ollama.chat-model.base-url=http://localhost:11434
+langchain4j.ollama.chat-model.model-name=deepseek-r1:1.5b
+langchain4j.ollama.chat-model.temperature=0.8
+langchain4j.ollama.chat-model.timeout=PT60S
+
+##????????debug??
+#logging.level.root=debug
+
+langchain4j.community.dashscope.chat-model.api-key=sk-c8af7be399424a0c8085216f73508180
+langchain4j.community.dashscope.chat-model.model-name=qwen-max
+

+ 36 - 0
src/main/resources/generator/mapper/CourseInfoMapper.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="generator.mapper.CourseInfoMapper">
+
+    <resultMap id="BaseResultMap" type="generator.domain.CourseInfo">
+            <id property="id" column="id" />
+            <result property="name" column="name" />
+            <result property="gradeInfoId" column="grade_info_id" />
+            <result property="schoolType" column="school_type" />
+            <result property="subjectId" column="subject_id" />
+            <result property="createDate" column="create_date" />
+            <result property="updateDate" column="update_date" />
+            <result property="code" column="code" />
+            <result property="sort" column="sort" />
+            <result property="parentId" column="parent_id" />
+            <result property="headImg" column="head_img" />
+            <result property="represent" column="represent" />
+            <result property="recommendIndexFlag" column="recommend_index_flag" />
+            <result property="studyNumber" column="study_number" />
+            <result property="status" column="status" />
+            <result property="valuateMark" column="valuate_mark" />
+            <result property="commentNumber" column="comment_number" />
+            <result property="sectionNodeNumber" column="section_node_number" />
+            <result property="sectionNumber" column="section_number" />
+            <result property="pushTime" column="push_time" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,name,grade_info_id,school_type,subject_id,create_date,
+        update_date,code,sort,parent_id,head_img,
+        represent,recommend_index_flag,study_number,status,valuate_mark,
+        comment_number,section_node_number,section_number,push_time
+    </sql>
+</mapper>

+ 32 - 0
src/main/resources/knowledgeMap.txt

@@ -0,0 +1,32 @@
+你是教学知识系统构建专家,帮我为课程{{courseName}}自动生成完整的知识体系结构树,并将其结构转化为 SQL 插入语句,插入到知识点表 `ext_knowledge_point` 中。
+
+## 要求:
+1. 自动构建课程知识点结构,分为 3~4 级:
+   - 一级为模块(如:线性结构、算法基础)
+   - 二级为子主题(如:数组、链表、排序)
+   - 三级为概念或实现(如:快速排序、链表反转)
+   - 四级为更深一层(如:二叉搜索树、哈希冲突处理)
+
+2. SQL 插入语句包括:
+   - 一条 `INSERT INTO ext_knowledge_point (...) VALUES (...), (...), ...;`
+   - 所有知识点 id 从 `10001` 开始,递增,格式为 `{course_id}{四位顺序号}`,如 course_id=1 → 10001,10002,...
+   - 每个知识点应包含:
+     - `id`
+     - `course_id = {{coueseId}}`
+     - `point_name`
+     - `point_code`(自增长整型数字)
+     - `description`(自动补充一句话)
+     - `level`(0~3)
+     - `parent_id`(引用上级 ID,根节点为NULL)
+     - `sequence`(同级知识点排序)
+     - `resource_url`(如 `/stack`,小写英文,驼峰或短横线连接)
+     - `created_at`(创建时间)
+     - `updated_at`(更新时间)
+
+
+3. 输出格式整洁清晰,带层级注释(如 `-- Level 1: 子节点`)
+
+4. 所有语句为标准 MySQL 插入语法
+
+5. 结果只输出可一次性执行完成的sql语句
+

+ 63 - 0
src/main/resources/teacherGpsren.txt

@@ -0,0 +1,63 @@
+你是一个教育专家,现在我们课题组弄了一个名为GPS-REN的AI教学法
+其中G表示Goal-Oriented,目标导向,以具体问题驱动学习过程。
+P表示Problem Definition问题定义用专业语言精确完备地描述问题从而向A获取更优结果。
+S表示Systematic Breakdown系统拆解系统性拆解问题复杂问题分解为简单问题逐步向A获取高质量结果。
+R表示Result Integration结果整合运用AI工具获取结果,并整合。
+E表示Evaluation结果评估设计评估方案评估结果质量。
+N表示New Knowledge总结新知识总结新知识实现学习闭环。
+现在我给你一个完整的示例:
+G目标导向:求二维迷宫从起点到终点的最短路径
+P问题描述:编写一个Python程序,用于解决二维迷宫中寻找最短路径的问题。该迷宫用*的矩阵来表示,矩阵中的每一个元素代表迷宫中的一个格子,其中值为1的格子表示障碍物,不能通行;值为0的格子是可以自由通行的空格;值为2的格子代表起点;值为3的格子代表终点。程序的目标是找出从起点到终点的最短路径。输入要求:程序首先会接受一个正整数,它代表了迷宫矩阵的维度大小,接着,程序会依次接收n行数据,每行数据n个用空格隔开的整数,这些整数共同构成了迷宫矩阵。输出要求:如果存在从起点到终点的最短路径,程序需要将该路径上的所有格子标记为*,并输出这个标记后的迷官矩阵;如果不存在这样的路径,则输出false。
+S系统拆解:将起点放入队列从队列中取出一个点查找相邻的点将以访问的点标为4.
+R结果整合:from collections import deque
+
+      def find_path(maze, start, end):
+          directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]  # 上下左右
+          queue = deque()
+          queue.append((start[0], start[1], 0))
+          maze[start[0]][start[1]] = 1  # 标记访问
+
+          while queue:
+              x, y, steps = queue.popleft()
+
+              if x == end[0] and y == end[1]:
+                  return steps
+
+              for dx, dy in directions:
+                  nx, ny = x + dx, y + dy
+                  if 0 <= nx < len(maze) and 0 <= ny < len(maze[0]) and maze[nx][ny] == 0:
+                      queue.append((nx, ny, steps + 1))
+                      maze[nx][ny] = 1
+
+          return -1
+
+      if __name__ == "__main__":
+          maze = [
+              [0, 1, 0, 0, 0],
+              [0, 1, 0, 1, 0],
+              [0, 0, 0, 0, 0],
+              [0, 1, 1, 1, 0],
+              [0, 0, 0, 1, 0]
+          ]
+          start = (0, 0)
+          end = (4, 4)
+          steps = find_path(maze, start, end)
+          print(f"最短路径: {steps}" if steps != -1 else "无路径")
+E结果评估:1.正确性验证,测试用例示例:// 测试1:普通迷宫maze1 = [
+                                    [0, 0, 0],
+                                    [0, 1, 0],
+                                    [0, 0, 0]
+                                ]
+                                assert find_path(maze1, (0, 0), (2, 2)) == 4
+                   // 测试2:无解迷宫:maze2 = [
+                                   [0, 1],
+                                   [1, 0]
+                               ]
+                               assert find_path(maze2, (0, 0), (1, 1)) == -1
+                   // 测试3:起点即终点
+                   assert find_path(maze1, (0, 0), (0, 0)) == 0
+                   print("All tests passed!")
+                   2. 健壮性问题:
+                   当迷宫不是矩形时(如[[0], [0,1]]),原代码len(maze[0])会始终以第一行为基准,可能导致后续行访问时越界。
+
+N总结新知识:起点和终点定位(1)变量初始化:startX、startY、endX和endY分别用于存储起点和终点的坐标,初始值设为-1表示尚未找到。(2)遍历迷宫:使用嵌套的fo循环遍历整个迷官,当遇到值为2的格子时,记录其坐标作为起点;当遇到值为3的格子时,记录其坐标作为终点。(3)检查起点和终点是否存在:如果starXi或endX仍为-1,说明迷宫中缺少起点或终点,程序输出false并终止。 BFS搜索相关数据结构和初始化(1)visited数组:二维布尔数组visited,用于标记迷宫中每个格子是否已经被访问过,初始值都为false。(2)prev数组:三位整数数组prev用于记录每个格子的前驱节点, prev[x]yIO]和orev[x]yI1]分别表示格子(x,y)的前驱节点的x和y坐标。(3)Queue队列:Queue是java中的一个接口,LinkedLists实现了该接口,用于实现BFS算法的队列。将起点加入队列,并将其标记为已访问。(4)found标志:布尔变量found用于标记是否找到了终点,初始值为false

+ 63 - 0
src/main/resources/teacherGpsrenEval.txt

@@ -0,0 +1,63 @@
+你是一个教育评审专家,现在我们课题组弄了一个名为GPS-REN的AI教学法
+其中G表示Goal-Oriented,目标导向,以具体问题驱动学习过程。
+P表示Problem Definition问题定义用专业语言精确完备地描述问题从而向A获取更优结果。
+S表示Systematic Breakdown系统拆解系统性拆解问题复杂问题分解为简单问题逐步向A获取高质量结果。
+R表示Result Integration结果整合运用AI工具获取结果,并整合。
+E表示Evaluation结果评估设计评估方案评估结果质量。
+N表示New Knowledge总结新知识总结新知识实现学习闭环。
+现在我给你一个完整的示例:
+G目标导向:求二维迷宫从起点到终点的最短路径
+P问题描述:编写一个Python程序,用于解决二维迷宫中寻找最短路径的问题。该迷宫用*的矩阵来表示,矩阵中的每一个元素代表迷宫中的一个格子,其中值为1的格子表示障碍物,不能通行;值为0的格子是可以自由通行的空格;值为2的格子代表起点;值为3的格子代表终点。程序的目标是找出从起点到终点的最短路径。输入要求:程序首先会接受一个正整数,它代表了迷宫矩阵的维度大小,接着,程序会依次接收n行数据,每行数据n个用空格隔开的整数,这些整数共同构成了迷宫矩阵。输出要求:如果存在从起点到终点的最短路径,程序需要将该路径上的所有格子标记为*,并输出这个标记后的迷官矩阵;如果不存在这样的路径,则输出false。
+S系统拆解:将起点放入队列从队列中取出一个点查找相邻的点将以访问的点标为4.
+R结果整合:from collections import deque
+
+      def find_path(maze, start, end):
+          directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]  # 上下左右
+          queue = deque()
+          queue.append((start[0], start[1], 0))
+          maze[start[0]][start[1]] = 1  # 标记访问
+
+          while queue:
+              x, y, steps = queue.popleft()
+
+              if x == end[0] and y == end[1]:
+                  return steps
+
+              for dx, dy in directions:
+                  nx, ny = x + dx, y + dy
+                  if 0 <= nx < len(maze) and 0 <= ny < len(maze[0]) and maze[nx][ny] == 0:
+                      queue.append((nx, ny, steps + 1))
+                      maze[nx][ny] = 1
+
+          return -1
+
+      if __name__ == "__main__":
+          maze = [
+              [0, 1, 0, 0, 0],
+              [0, 1, 0, 1, 0],
+              [0, 0, 0, 0, 0],
+              [0, 1, 1, 1, 0],
+              [0, 0, 0, 1, 0]
+          ]
+          start = (0, 0)
+          end = (4, 4)
+          steps = find_path(maze, start, end)
+          print(f"最短路径: {steps}" if steps != -1 else "无路径")
+E结果评估:1.正确性验证,测试用例示例:// 测试1:普通迷宫maze1 = [
+                                    [0, 0, 0],
+                                    [0, 1, 0],
+                                    [0, 0, 0]
+                                ]
+                                assert find_path(maze1, (0, 0), (2, 2)) == 4
+                   // 测试2:无解迷宫:maze2 = [
+                                   [0, 1],
+                                   [1, 0]
+                               ]
+                               assert find_path(maze2, (0, 0), (1, 1)) == -1
+                   // 测试3:起点即终点
+                   assert find_path(maze1, (0, 0), (0, 0)) == 0
+                   print("All tests passed!")
+                   2. 健壮性问题:
+                   当迷宫不是矩形时(如[[0], [0,1]]),原代码len(maze[0])会始终以第一行为基准,可能导致后续行访问时越界。
+
+N总结新知识:起点和终点定位(1)变量初始化:startX、startY、endX和endY分别用于存储起点和终点的坐标,初始值设为-1表示尚未找到。(2)遍历迷宫:使用嵌套的fo循环遍历整个迷官,当遇到值为2的格子时,记录其坐标作为起点;当遇到值为3的格子时,记录其坐标作为终点。(3)检查起点和终点是否存在:如果starXi或endX仍为-1,说明迷宫中缺少起点或终点,程序输出false并终止。 BFS搜索相关数据结构和初始化(1)visited数组:二维布尔数组visited,用于标记迷宫中每个格子是否已经被访问过,初始值都为false。(2)prev数组:三位整数数组prev用于记录每个格子的前驱节点, prev[x]yIO]和orev[x]yI1]分别表示格子(x,y)的前驱节点的x和y坐标。(3)Queue队列:Queue是java中的一个接口,LinkedLists实现了该接口,用于实现BFS算法的队列。将起点加入队列,并将其标记为已访问。(4)found标志:布尔变量found用于标记是否找到了终点,初始值为false