index.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <template>
  2. <div class="pblCourse" v-loading="loading">
  3. <div class="pc_left">
  4. <div class="pc_l_top">
  5. <procedureArea :phase="phase" />
  6. </div>
  7. <div class="pc_l_bottom">
  8. <doWorkArea :phase="phase" @changePhase="changePhase" @choiceAnswer="choiceAnswer" @submitTask="submitTask" :task="taskList[phase.atPhase]" @getTaskList="getTaskList"/>
  9. </div>
  10. </div>
  11. <div class="pc_right">
  12. <chatArea />
  13. </div>
  14. <selectTopicDialog ref="selectTopicDialogRef" @success="selectTopicSuccess"/>
  15. </div>
  16. </template>
  17. <script>
  18. import chatArea from './component/chatArea'
  19. import doWorkArea from './component/doWorkArea'
  20. import procedureArea from './component/procedureArea'
  21. import { v4 as uuidv4 } from "uuid";
  22. import selectTopicDialog from './component/selectTopicDialog'
  23. export default {
  24. components: {
  25. chatArea,
  26. doWorkArea,
  27. procedureArea,
  28. selectTopicDialog,
  29. },
  30. data() {
  31. return {
  32. loading: false,
  33. phase:{
  34. doPhase:0,
  35. atPhase:0,
  36. },
  37. selectTopic:"",
  38. taskList:[]
  39. };
  40. },
  41. methods: {
  42. changePhase(type,newValue){
  43. this.phase[type] = newValue;
  44. },
  45. getTaskList(phase = 0){
  46. return new Promise((resolve,reject)=>{
  47. if(this.loading)return this.$message.info("请稍等")
  48. this.loading = true;
  49. const _uuid = uuidv4()
  50. const _msg = `
  51. NOTICE
  52. Role: 作为学生的学习指导Agent,你熟悉熟悉PBL(基于问题的学习)和5EX教学模型,能够根据学生的学情数据(当前的学习任务设计、学习表现数据、作业数据等)生成自适应的学习任务和对应的5道考核题目。
  53. Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
  54. ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
  55. Instruction: Based on the context, follow "Format example", write content.
  56. # Context
  57. ## 语气
  58. 你的语气应该是亲切地,有趣的,循循善诱的一个老师
  59. ## 工具能力
  60. 1. 5E教学模型应用:
  61. 你需要熟悉并应用5E教学模型(即引入、探索、解释、扩展和评估)于学习任务的设计中,确保学习过程的有效性和吸引力。5E教学模型是一种以学生为中心的教学方法,旨在通过五个阶段(Engage, Explore, Explain, Elaborate, Evaluate)来促进学生的学习和理解。
  62. Engage(引入):在这个阶段,教师通过引人入胜的活动或问题来激发学生的兴趣和好奇心,帮助他们建立与新知识的联系。
  63. Explore(探索):学生通过动手实验或调查活动来探索新概念,培养他们的探究能力和批判性思维。
  64. Explain(解释):学生在这个阶段分享他们的发现,教师提供进一步的解释和指导,帮助学生理解新概念。
  65. Elaborate(拓展):学生通过应用新知识来解决更复杂的问题,进一步深化他们的理解。
  66. Evaluate(评估):教师和学生共同评估学习效果,反思学习过程,确定需要改进的地方。
  67. 2. 学生表现与选择的感知:
  68. 通过与学生互动,实时感知学生的学习表现和选择,理解他们的学习需求和难点。
  69. 3. 自适应任务生成:
  70. 基于学生的反馈和选择,自动生成个性化的学习任务,任务难度和类型随学生的表现和需求而变化。
  71. ## 工作流程
  72. 1. 判断学生当前处在5E模型中哪一个学习阶段。如果未提供学情数据,或无法判断学生当前处在5E教学模型中的哪一个解释,则默认处在第一个阶段(引入)阶段。请随机选择一个适合小学五年级学生的科学学习主题,并生成相应的符合引入阶段的学习任务。
  73. 2. 结合学生当前的学情数据,生成紧随其后的下一个阶段的学习任务,但是仅仅生成紧随其后的下一个阶段的学习任务。你需要沿着这个顺序判断:引入阶段→探索阶段→解释阶段→拓展阶段→评估阶段。比如,当你判断学情数据中,学生目前已经完成了引入阶段的学习,那么你需要提供探索阶段的学习任务。
  74. 3. 生成上一步中学习任务对应的5道考核选择题
  75. ## 限制
  76. 1. 请仅仅生成某一个阶段对应的学习任务。不要同时给出多个阶段、多个学习任务。
  77. 2. 请严格按照以下格式要求输出内容,请仅仅告知相应的5E阶段名称和对应的任务描述,不需要包含学情数据等与【任务】无关的内容。
  78. 3. 生成相应的考核题目,仅限单选题
  79. 4. 任务描述的格式以markdown方式输出
  80. ## 学情数据
  81. 选题:${this.selectTopic}
  82. ${this.phase.doPhase==0?'':`这是你生成适应性学习任务时,需要参考的前置学情数据${JSON.stringify(this.taskList[this.phase.doPhase-1])}(当前的学习任务设计、学习表现数据、作业数据等)。`}
  83. # Format example
  84. {
  85. "name": "任务名字",
  86. "detail": "任务描述(要求markdown的格式)",
  87. "target":"任务目标",
  88. "steps":"任务步骤",
  89. "tips":"任务提示",
  90. "answerArray":[
  91. {
  92. "title": "标题",
  93. "type": "单选题",
  94. "option": ["选项1","选项2","选项3","选项4"],
  95. "answer": "答案(最好是index)"
  96. },
  97. {
  98. "title": "标题",
  99. "type": "单选题",
  100. "option": ["选项1","选项2","选项3","选项4"],
  101. "answer": "答案(最好是index)"
  102. }
  103. ]
  104. }
  105. Instruction: Based on the context, follow "Format example", write content.
  106. `
  107. console.log(_msg)
  108. // ${
  109. // this.phase.doPhase==0?'':`
  110. // ## 学情数据
  111. // 这是你生成适应性学习任务时,需要参考的前置学情数据${JSON.stringify(this.taskList[this.phase.doPhase])}(当前的学习任务设计、学习表现数据、作业数据等)。`
  112. // }
  113. let params = {
  114. model: "gpt-3.5-turbo",
  115. temperature: 0,
  116. max_tokens: 4096,
  117. top_p: 1,
  118. frequency_penalty: 0,
  119. presence_penalty: 0,
  120. messages: [{role:"user",content:_msg}],
  121. uid: _uuid,
  122. mind_map_question: "",
  123. stream:false
  124. }
  125. this.ajax
  126. .post("https://gpt4.cocorobo.cn/chat", params)
  127. .then((res) => {
  128. let _data = res.data.FunctionResponse.choices[0];
  129. let content = _data.message.content;
  130. console.log(content)
  131. content = content.replaceAll('```json','').replaceAll('```','')
  132. // console.log(content)
  133. const _result = JSON.parse(content);
  134. _result.detail = _result.detail?_result.detail:"",
  135. _result.steps = _result.steps?_result.steps:"",
  136. _result.target = _result.target?_result.target:"",
  137. _result.tips =_result.tips?_result.tips:""
  138. this.taskList[phase] = _result;
  139. // this.phase.doPhase = phase;
  140. this.phase.atPhase = phase;
  141. console.log(this.taskList)
  142. this.loading = false;
  143. resolve();
  144. })
  145. .catch((e) => {
  146. this.loading = false;
  147. this.$message.error("获取任务失败")
  148. if(this.phase.doPhase!=0){
  149. this.phase.doPhase--;
  150. }
  151. resolve();
  152. console.log(e);
  153. });
  154. })
  155. },
  156. choiceAnswer(_data){
  157. this.taskList[this.phase.atPhase].answerArray[_data[0]].userAnswer = _data[1];
  158. this.$forceUpdate()
  159. },
  160. submitTask(){
  161. this.loading = true;
  162. let sum = 0;
  163. this.taskList[this.phase.atPhase].answerArray.forEach(i=>{
  164. if('userAnswer' in i){
  165. sum++;
  166. }
  167. })
  168. if(sum<this.taskList[this.phase.atPhase].answerArray.length){
  169. this.loading = false;
  170. return this.$message.error("当前阶段还未完成")
  171. }else if((this.phase.doPhase>this.phase.atPhase)){
  172. this.loading = false;
  173. return this.$message.error("该阶段已经提交过了")
  174. }else{
  175. this.loading = false;
  176. this.phase.doPhase++;
  177. if(this.phase.doPhase==5){
  178. return this.$message.error('所有阶段已经完成');
  179. }
  180. this.getTaskList(this.phase.doPhase)
  181. }
  182. },
  183. selectTopicSuccess(_form){
  184. if(_form.title){
  185. this.phase = {
  186. doPhase:0,
  187. atPhase:0,
  188. }
  189. this.selectTopic = _form.title;
  190. this.getTaskList()
  191. this.$refs.selectTopicDialogRef.close();
  192. }
  193. }
  194. },
  195. mounted() {
  196. this.selectTopic = "";
  197. this.$refs.selectTopicDialogRef.open();
  198. // this.getTaskList()
  199. },
  200. };
  201. </script>
  202. <style scoped>
  203. .pblCourse {
  204. min-width: 1500px;
  205. /* min-height: 800px; */
  206. width: 100%;
  207. height: 100vh;
  208. display: flex;
  209. background-color: #f0f2f5;
  210. box-sizing: border-box;
  211. padding: 20px;
  212. }
  213. .pc_left {
  214. width: calc(100% - 500px - 20px);
  215. margin-right: 20px;
  216. box-sizing: border-box;
  217. }
  218. .pc_l_top {
  219. width: 100%;
  220. height: 150px;
  221. box-sizing: border-box;
  222. }
  223. .pc_l_bottom {
  224. width: 100%;
  225. height: calc(100% - 150px - 15px);
  226. box-sizing: border-box;
  227. margin-top: 15px;
  228. }
  229. .pc_right {
  230. width: 500px;
  231. height: 100%;
  232. box-sizing: border-box;
  233. }
  234. </style>