Browse Source

updata:inquiry

惊鸿戏梦 3 months ago
parent
commit
2e08369981

+ 1 - 1
newyouth-app/src/agent/agent-user-input/agent-user-input.component.html

@@ -12,7 +12,7 @@
 <ion-content class="ion-padding">
   @for(filed of filedsArray;track filed.name){
     <ion-item>
-      <ion-input labelPlacement="stacked" label="请输入:{{filed.name}}" [(ngModel)]="inputData['poem']" placeholder="{{filed.desc}}"></ion-input>
+      <ion-input labelPlacement="stacked" label="请输入:{{filed.name}}" [(ngModel)]="inputData[filed.name]" placeholder="{{filed.desc}}"></ion-input>
     </ion-item>
   }
 </ion-content>

+ 0 - 1
newyouth-app/src/agent/agent-user-input/agent-user-input.component.ts

@@ -18,7 +18,6 @@ export interface AgentUserInputFiled{
   standalone: true
 })
 export class AgentUserInputComponent  implements OnInit {
-  poem:string="";
   
   @Input()
   filedsArray:AgentUserInputFiled[]=[]

+ 44 - 0
newyouth-app/src/agent/agent.json.ts

@@ -0,0 +1,44 @@
+/**
+ * 
+ 结果是:
+ {
+     "keshi":"呼吸科",
+     "user":{
+         "name":""
+     }
+ }
+ */
+export function extactAndParseJsonFromString(inputString:string){
+    let startIndex = inputString.indexOf("{")
+    if(startIndex==-1) return {}
+
+    let count = 0;
+    let endIndex = startIndex;
+
+    // 遍历字符串,计算花括号实现数量平衡
+    for (let i = startIndex; i < inputString.length; i++) {
+        // console.log(i,inputString[i])
+        if(inputString[i]==="{"){
+            count++;
+        }else if(inputString[i]==="}"){
+            count--;
+        }
+        // 当花括号平衡,我们找到了完整的JSON
+        if(count === 0){
+            endIndex = i;
+            break;
+        }
+    }
+    // 若不平衡
+    if(count!=0) return {};
+
+    // 提取JSON字符串,并解析
+    const jsonString = inputString.slice(startIndex,endIndex+1);
+    console.log("jsonString",jsonString)
+    try{
+        return JSON.parse(jsonString);
+    }catch(error){
+        console.error("Failed to parse JSON",error);
+        return {}
+    }
+ }

+ 64 - 0
newyouth-app/src/agent/tasks/inquiry/1.inquiry-user-story.ts

@@ -0,0 +1,64 @@
+import { AgentTaskStep } from 'src/agent/agent.task';
+import { getUserInput } from 'src/agent/agent.input';
+import { ModalController } from '@ionic/angular/standalone';
+import { FmodeChatCompletion } from 'fmode-ng';
+import { extactAndParseJsonFromString } from 'src/agent/agent.json';
+
+export function TaskInqueryUserStory(options:{
+    modalCtrl:ModalController
+    shareData:any}
+    ):AgentTaskStep{
+        let task1 = new AgentTaskStep({title:"导诊:根据患者描述导诊对应科室",shareData:options.shareData})
+        task1.handle = ()=>{
+            return new Promise(async (resolve,reject)=>{
+                // 获取用户输入的诗词
+                let userInput = await getUserInput(options.modalCtrl,{filedsArray:[
+                    {name:"症状口述",type:"text",desc:"描述下感觉到的症状或不适。"}
+                ]});
+
+                if(!userInput?.['症状口述']){
+                    task1.error = "无症状口述,无法判断科室"
+                    resolve(false);
+                }
+
+                // 文本生成
+                let PromptTemplate = `您是一名专业的医护人员,在门诊大厅负责导诊服务,请您根据患者的症状口述,为其选择合适的科室进行挂号。
+                患者症状口述:${userInput['症状口述']}
+                结果以JSON格式表示:
+                症状名称为具体的症状,症状描述为用户的感受,持续时间若没有直接说,可以写近期即可。
+                {
+                    "keshi":"科室名称",
+                    "sympList":[
+                        {"title":"症状名称","desc":"症状描述","duration":"持续时间"}
+                    ]
+                }
+                `
+                let completion = new FmodeChatCompletion([
+                    {role:"system",content:""},
+                    {role:"user",content:PromptTemplate}
+                    ])
+                    completion.sendCompletion().subscribe((message:any)=>{
+                        if(task1.progress < 0.5){
+                            task1.progress += 0.1
+                        }
+                        if(task1.progress >= 0.5 && task1.progress <= 0.9){
+                            task1.progress += 0.01
+                        }
+                        if(task1.progress >= 0.9){
+                            task1.progress += 0.001
+                        }
+                        // 打印消息体
+                        console.log(message.content)
+                        // 赋值消息内容给组件内属性
+                        if(message.complete){ // 判断message为完成状态,则设置isComplete为完成
+                            options.shareData.userStory = extactAndParseJsonFromString(message.content)
+                            options.shareData.userStory['症状口述'] = userInput['症状口述']
+                            task1.progress = 1
+                            resolve(true)
+                        }
+                })
+            })
+
+        }
+        return task1
+}

+ 79 - 0
newyouth-app/src/agent/tasks/inquiry/2.inquiry-doctor-question.ts

@@ -0,0 +1,79 @@
+import { AgentTaskStep } from 'src/agent/agent.task';
+import { getUserInput } from 'src/agent/agent.input';
+import { ModalController } from '@ionic/angular/standalone';
+import { FmodeChatCompletion } from 'fmode-ng';
+import { extactAndParseJsonFromString } from 'src/agent/agent.json';
+
+export function TaskInqueryDoctorQuestion(options:{
+    modalCtrl:ModalController
+    shareData:any}
+    ):AgentTaskStep{
+        /**
+         shareData.userStory // 已经拥有的用户描述数据
+         {
+                  "keshi": "神经内科",
+                  "sympList": [
+                      {
+                          "title": "偏头痛",
+                          "desc": "持续了2天的偏头疼",
+                          "duration": "2天"
+                      },
+                      {
+                          "title": "发冷",
+                          "desc": "感觉发冷,已经有一天",
+                          "duration": "1天"
+                      }
+                  ]
+              }
+         */
+        let task1 = new AgentTaskStep({title:"问诊:医生根据患者情况,主动询问",shareData:options.shareData})
+        task1.handle = ()=>{
+            return new Promise(async (resolve,reject)=>{
+                // 获取用户输入
+                // let userInput = await getUserInput(options.modalCtrl,{fieldsArray:[
+                //     {name:"症状口述",type:"text",desc:"描述下感觉到的症状或不适。"}
+                // ]});
+
+                // if(!userInput?.['症状口述']){
+                //     task1.error = "无症状口述,无法判断科室"
+                //     resolve(false);
+                // }
+
+                // 文本生成
+                let PromptTemplate = `您是一名专业的${options.shareData.userStory.keshi}主任医生,患者简单描述了一下他的情况,请您思考下还有哪些需要询问。
+                症状口述:${options.shareData.userStory['症状口述']}
+                结果以JSON格式表示:
+                {
+                    "questionList":[
+                        {"title":"问题标题","desc":"问题描述"}
+                    ]
+                }
+                `
+                let completion = new FmodeChatCompletion([
+                    {role:"system",content:""},
+                    {role:"user",content:PromptTemplate}
+                    ])
+                    completion.sendCompletion().subscribe((message:any)=>{
+                        if(task1.progress < 0.5){
+                            task1.progress += 0.1
+                        }
+                        if(task1.progress >= 0.5 && task1.progress <= 0.9){
+                            task1.progress += 0.01
+                        }
+                        if(task1.progress >= 0.7){
+                            task1.progress += 0.001
+                        }
+                        // 打印消息体
+                        console.log(message.content)
+                        // 赋值消息内容给组件内属性
+                        if(message.complete){ // 判断message为完成状态,则设置isComplete为完成
+                            options.shareData.userStory.questionList = extactAndParseJsonFromString(message.content).questionList || []
+                            task1.progress = 1
+                            resolve(true)
+                        }
+                })
+            })
+
+        }
+        return task1
+}

+ 141 - 0
newyouth-app/src/agent/tasks/inquiry/3.inquiry-user-answer.ts

@@ -0,0 +1,141 @@
+import { AgentTaskStep } from 'src/agent/agent.task';
+import { getUserInput } from 'src/agent/agent.input';
+import { ModalController } from '@ionic/angular/standalone';
+import { FmodeChatCompletion } from 'fmode-ng';
+import { extactAndParseJsonFromString } from 'src/agent/agent.json';
+
+export function TaskInqueryUserAnswer(options:{
+    modalCtrl:ModalController
+    shareData:any}
+    ):AgentTaskStep{
+        /**
+         shareData.userStory // 已经拥有的医生主动询问
+         {
+            "questionList": [
+                {
+                    "title": "头痛的性质",
+                    "desc": "请问您的偏头痛是怎样的感觉?是刺痛、跳动还是压迫感?"
+                },
+            ]
+        }
+         */
+        let task1 = new AgentTaskStep({title:"诊断:患者回答具体内容后,医生给出诊断结果",shareData:options.shareData})
+        task1.handle = ()=>{
+            return new Promise(async (resolve,reject)=>{
+                // 获取用户输入的问题清单
+                let questionList = options.shareData.userStory.questionList.map((item:any)=>{return {name:item.title,desc:item.desc,type:"text"}})
+                
+                let userInputResult = await getUserInput(options.modalCtrl,{filedsArray:questionList});
+                console.log(userInputResult)
+                questionList.forEach((question:any)=>{
+                    question.answer = userInputResult[question.name]
+                })
+            
+                // 文本生成
+                let qaContent = options.shareData.userStory.questionList.map((item:any)=>`医生问:${item.title},${item.desc}\n患者答:${item.answer||"没回答"}`).join("\n")
+                let PromptTemplate = `您是一名专业的${options.shareData.userStory.keshi}主任医生,根据具体的询问,给出初步诊断。
+                症状口述:${options.shareData.userStory['症状口述']}
+                具体询问:${qaContent}
+                结果以JSON格式表示:
+                症状名称为具体的症状,症状描述为用户的感受,持续时间若没有直接说,可以写近期即可。
+                {
+                    "title":"病例标题",
+                    "desc":"病情概括",
+                    "content":"给出完整的治疗方案和建议"
+                }
+                `
+                let completion = new FmodeChatCompletion([
+                    {role:"system",content:""},
+                    {role:"user",content:PromptTemplate}
+                    ])
+                    completion.sendCompletion().subscribe((message:any)=>{
+                        if(task1.progress < 0.5){
+                            task1.progress += 0.1
+                        }
+                        if(task1.progress >= 0.5 && task1.progress <= 0.9){
+                            task1.progress += 0.01
+                        }
+                        if(task1.progress >= 0.9){
+                            task1.progress += 0.001
+                        }
+                        // 打印消息体
+                        console.log(message.content)
+                        // 赋值消息内容给组件内属性
+                        if(message.complete){ // 判断message为完成状态,则设置isComplete为完成
+                            options.shareData.diagResult = extactAndParseJsonFromString(message.content)
+                            task1.progress = 1
+                            resolve(true)
+                        }
+                })
+            })
+
+        }
+        return task1
+}
+
+
+const TestShareData = {
+userStory : {
+  "keshi": "神经内科",
+  "sympList": [
+      {
+          "title": "偏头疼",
+          "desc": "已经持续了2天了",
+          "duration": "2天"
+      },
+      {
+          "title": "发冷",
+          "desc": "感觉已经有一天",
+          "duration": "1天"
+      }
+  ],
+  "症状口述": "偏头疼已经持续了2天了,发冷感觉已经有一天。",
+  "questionList": [
+      {
+          "title": "头痛的性质",
+          "desc": "请描述您的头痛是搏动性、压迫性还是其他类型?",
+          "answer":"压迫性头疼"
+      },
+      {
+          "title": "头痛的部位",
+          "desc": "您的头痛主要集中在头部的哪个区域?",
+          "answer":"左侧头疼"
+      },
+      {
+          "title": "伴随症状",
+          "desc": "除了头痛和发冷,您还有其他的症状吗?例如恶心、呕吐、视力模糊或对光敏感等?",
+          "answer":"有点恶心但是没有呕吐"
+      },
+      {
+          "title": "发冷的性质",
+          "desc": "您感到发冷时是否伴随有发热、出汗或其他症状?",
+          "answer":"没有"
+      },
+      {
+          "title": "既往病史",
+          "desc": "您是否有偏头痛或其他头痛的病史?",
+          "answer":"没有"
+      },
+      {
+          "title": "生活习惯",
+          "desc": "您最近的生活习惯是否有变化?例如睡眠不足、压力增大或饮食不规律?",
+          "answer":"经常熬夜,学习压力大"
+      },
+      {
+          "title": "药物使用",
+          "desc": "您是否有服用任何药物来缓解头痛或其他症状?",
+          "answer":"没有"
+      },
+      {
+          "title": "家族病史",
+          "desc": "您的家族中是否有人有类似的头痛或神经系统疾病史?",
+          "answer":"没有"
+      },
+      {
+          "title": "过敏史",
+          "desc": "您是否有药物或其他物质的过敏史?",
+          "answer":"没有"
+      }
+  ]
+}
+}

+ 3 - 3
newyouth-app/src/agent/tasks/poem/poem-desc.ts

@@ -16,9 +16,9 @@ export function TaskPoemPictureDesc(options:{
               ]});
               console.log("已获取用户输入:",userInput)
               if(userInput){
-                  console.log("已获取诗文内容:",userInput.poem)
+                  console.log("已获取诗文内容:",userInput['诗文内容'])
               }
-              if(!userInput?.poem){
+              if(!userInput?.['诗文内容']){
                   task1.error = "缺少诗文内容,请重新开始"
                   resolve(false);
               }
@@ -26,7 +26,7 @@ export function TaskPoemPictureDesc(options:{
                   // 文本生成
               let PromptTemplate = `您是一名专业的美术画家,请您根据古诗文的内容,将其描述的画面、场景、人物、物品等用最简短的语言表达,直接写出画面,并且以中国的古风意境为主
               诗文如下:
-              ${userInput.poem}
+              ${userInput['诗文内容']}
               `
               let completion = new FmodeChatCompletion([
                   {role:"system",content:""},

+ 7 - 7
newyouth-app/src/app/tab3/tab3.page.html

@@ -9,7 +9,7 @@
 <ion-content [fullscreen]="true">
   <ion-button (click)="doPoemTask()">执行诗文意境绘制任务集</ion-button>
   <ion-button (click)="doInqueryTask()">执行问诊任务集</ion-button>
-  <!-- <ion-button (click)="testJSON()">测试JSON</ion-button> -->
+  <ion-button (click)="testJSON()">测试JSON</ion-button>
 
    <ul>
     @for(step of taskList;track step.title;){
@@ -45,10 +45,10 @@
     }
 
 
-<!-- 问诊报告生成结果 -->
-<!-- @if(shareData.diagResult){
-  <h1>{{shareData.diagResult.title}}</h1>
-  <h2>{{shareData.diagResult.desc}}</h2>
-  <p>{{shareData.diagResult.content}}</p>
-} -->
+    <!-- 问诊报告生成结果 -->
+    @if(shareData.diagResult){
+      <h1>{{shareData.diagResult.title}}</h1>
+      <h2>{{shareData.diagResult.desc}}</h2>
+      <p>{{shareData.diagResult.content}}</p>
+    }
 </ion-content>

+ 63 - 31
newyouth-app/src/app/tab3/tab3.page.ts

@@ -11,6 +11,10 @@ import { share } from 'rxjs';
 import { DalleOptions, FmodeChatCompletion, ImagineWork } from 'fmode-ng';
 import { getUserInput } from 'src/agent/agent.input';
 import { DecimalPipe } from '@angular/common';
+import { TaskInqueryUserStory } from 'src/agent/tasks/inquiry/1.inquiry-user-story';
+import { TaskInqueryDoctorQuestion } from 'src/agent/tasks/inquiry/2.inquiry-doctor-question';
+import { TaskInqueryUserAnswer } from 'src/agent/tasks/inquiry/3.inquiry-user-answer';
+import { extactAndParseJsonFromString } from 'src/agent/agent.json';
 
 addIcons({radioButtonOffOutline,reloadOutline,checkmarkCircleOutline,closeCircleOutline})
 @Component({
@@ -102,41 +106,69 @@ export class Tab3Page {
     startTask(PoemTaskList)
   }
 
+
+  testJSON(){
+    let string = `
+          ''''json
+              {
+                  "keshi": "神经内科",
+                  "sympList": [
+                      {
+                          "title": "偏头痛",
+                          "desc": "持续了2天的偏头疼",
+                          "duration": "2天"
+                      },
+                      {
+                          "title": "发冷",
+                          "desc": "感觉发冷,已经有一天",
+                          "duration": "1天"
+                      }
+                  ]
+              }
+              ''''
+      `
+      console.log(extactAndParseJsonFromString(string))
+  }
   // 任务集:医疗问诊任务集 完成一次完整的门诊服务
   doInqueryTask(){
-    let task1 = new AgentTaskStep({title:"导诊",shareData:this.shareData});
-    task1.handle=async()=>{
-      await this.wait(1000)
-      console.log("导诊:执行过程")
-      task1.progress=1
-    }
-    let task2 = new AgentTaskStep({title:"问诊",shareData:this.shareData});
-    task2.handle=async()=>{
-      await this.wait(1000)
-      console.log("问诊:执行过程")
-      task2.progress=1
-    }
-    let task3 = new AgentTaskStep({title:"初诊",shareData:this.shareData});
-    task3.handle=async()=>{
-      await this.wait(1000)
-      console.log("初诊:执行过程")
-      task3.progress=1
-    }
-    let task4 = new AgentTaskStep({title:"检验",shareData:this.shareData});
-    task4.handle=async()=>{
-      await this.wait(1000)
-      console.log("检验:执行过程")
-      task4.progress=1
-    }
-    let task5 = new AgentTaskStep({title:"处方",shareData:this.shareData});
-    task5.handle=async()=>{
-      await this.wait(1000)
-      console.log("处方:执行过程")
-      task5.progress=1
-    }
+    // let task1 = new AgentTaskStep({title:"导诊",shareData:this.shareData});
+    // task1.handle=async()=>{
+    //   await this.wait(1000)
+    //   console.log("导诊:执行过程")
+    //   task1.progress=1
+    // }
+    // let task2 = new AgentTaskStep({title:"问诊",shareData:this.shareData});
+    // task2.handle=async()=>{
+    //   await this.wait(1000)
+    //   console.log("问诊:执行过程")
+    //   task2.progress=1
+    // }
+    // let task3 = new AgentTaskStep({title:"初诊",shareData:this.shareData});
+    // task3.handle=async()=>{
+    //   await this.wait(1000)
+    //   console.log("初诊:执行过程")
+    //   task3.progress=1
+    // }
+    // let task4 = new AgentTaskStep({title:"检验",shareData:this.shareData});
+    // task4.handle=async()=>{
+    //   await this.wait(1000)
+    //   console.log("检验:执行过程")
+    //   task4.progress=1
+    // }
+    // let task5 = new AgentTaskStep({title:"处方",shareData:this.shareData});
+    // task5.handle=async()=>{
+    //   await this.wait(1000)
+    //   console.log("处方:执行过程")
+    //   task5.progress=1
+    // }
+    let task1 = TaskInqueryUserStory({shareData:this.shareData,modalCtrl:this.modalCtrl});
+    let task2 = TaskInqueryDoctorQuestion({shareData:this.shareData,modalCtrl:this.modalCtrl});
+    let task3 = TaskInqueryUserAnswer({shareData:this.shareData,modalCtrl:this.modalCtrl});
+    
+    
     // 定义任务集
     let InquireServiceTaskList = [
-      task1,task2,task3,task4,task5
+      task1,task2,task3
     ]
     // 传递给显示组件
     this.taskList = InquireServiceTaskList