瀏覽代碼

代码提交

SGTY 3 天之前
父節點
當前提交
89b8f42833
共有 2 個文件被更改,包括 179 次插入43 次删除
  1. 168 42
      src/knowledge/main.py
  2. 11 1
      src/knowledge/service/search_service.py

+ 168 - 42
src/knowledge/main.py

@@ -99,42 +99,79 @@ class DiseaseInfoRequest(BaseModel):
     type: Optional[str] = None
 
 
-@app.post("/symptom_diseases", response_model=StandardResponse, operation_id="根据症状获取相关疾病列表",
+@app.post("/symptom_diseases", response_model=StandardResponse, operation_id="getSymptomDiseases",
           summary="根据症状获取相关疾病列表",
           description="""根据输入的症状列表,查询可能相关的疾病列表。
-         该接口主要用于医疗知识图谱查询场景,例如:通过输入症状名称,
-         返回可能相关的疾病信息。
-         典型应用场景包括:
-         - 初步诊断:输入患者症状获取可能疾病
-         - 鉴别诊断:通过症状缩小疾病范围
-         - 健康教育:了解症状可能对应的疾病""",
-          response_description="""返回疾病名称的字符串列表,格式为:
-         ["疾病名称1", "疾病名称2", ...]""")
+
+该接口主要用于医疗知识查询场景,例如:
+- 通过输入症状名称查询相关疾病
+- 了解症状可能对应的疾病范围
+- 辅助临床诊断决策
+
+典型应用场景:
+1. 初步诊断:输入患者症状获取可能疾病
+2. 鉴别诊断:通过症状缩小疾病范围
+3. 健康教育:了解症状可能对应的疾病
+
+输入要求:
+- 症状名称应为标准医学术语
+
+输出格式:
+- 返回标准JSON响应
+- 包含疾病列表""",
+          response_description="""返回标准响应格式,包含疾病名称列表。
+
+成功响应示例:
+{
+    "success": true,
+    "data": ["流感", "肺炎"]
+}
+
+错误响应示例:
+{
+    "success": false,
+    "error": "Invalid symptom name"
+}""")
 async def get_symptom_diseases(
         symptoms: List[str] = Query(...,
-                  description="""症状名称列表,应为标准医学术语。
-                 该参数用于查询与输入症状相关的疾病列表。
-                 示例值:["头痛", "发热", "咳嗽"]""",
-                  examples=["头痛", "发热", "咳嗽"],
-                  min_length=1)
+                  alias="symptomNames",
+                  description="""症状名称列表。
+
+该参数用于查询与输入症状相关的疾病列表。
+建议使用标准医学术语。
+示例值:["头痛", "发热"]""",
+                  examples=[["头痛", "发热"]],
+                  min_length=1,
+                  max_length=10)
 ):
     """
     根据症状列表获取相关疾病
-    
+
     Args:
         symptoms: 症状名称列表,每个症状应为标准医学术语
-                示例: ["头痛", "发热", "咳嗽"]
-                
+                示例: ["头痛", "发热"] 
+
     Returns:
-        StandardResponse: 包含相关疾病列表的标准响应
-        
+        StandardResponse: 包含疾病列表的标准响应
+            - data字段包含症状数组和疾病数组,每个疾病可能有权重
+
     Raises:
-        HTTPException: 当查询过程中发生错误时抛出500异常
-        
-    Notes:
-        - 症状名称建议使用标准医学术语,避免口语化表达
-        - 多个症状同时查询时,返回的是这些症状共同相关的疾病
-        - 空列表将返回空结果
+        HTTPException: 当发生以下情况时抛出异常
+            - 症状名称无效(400)
+            - 内部服务错误(500)
+
+    Example:
+        >>> POST /symptom_diseases?symptomNames=头痛,发热
+        {
+            "success": true,
+            "data": {
+                "symptoms": ["头痛", "发热"],
+                "diseases": [
+                    {"name": "流感", "weight": 0.8},
+                    {"name": "肺炎", "weight": 0.6}
+                ]
+            }
+        }
     """
     try:
         #打印request
@@ -142,35 +179,124 @@ async def get_symptom_diseases(
         # 实现获取症状相关疾病的逻辑
         search = SearchBusiness()
         results = search.get_symptom_diseases(symptoms)
-        return StandardResponse(success=True, data=results)
+        # 直接返回疾病名称列表
+        disease_names = [disease["disease_name"] for disease in results] if results else []
+        return StandardResponse(success=True, data=disease_names)
     except Exception as e:
         logger.exception(f"获取症状相关疾病失败: {str(e)}")
         raise HTTPException(500, detail=StandardResponse.error(str(e)))
 
-@app.post("/disease_symptoms",
+@app.post("/getDiseaseSymptoms",
           response_model=StandardResponse,
-          operation_id="获取疾病相关症状",
-          summary="获取疾病相关症状",
-          description="根据疾病ID获取该疾病的所有症状及其严重程度权重",
-          response_description="""返回包含症状列表和症状严重程度权重的JSON结构,格式为:
-    {
-        "success": bool,
-        "data": {
-            {"symptoms": [], "severity_weights": {}}
-        }
-    }"""
+          operation_id="getDiseaseSymptoms",
+          summary="根据疾病名称获取相关症状",
+          description="""根据疾病名称获取该疾病的所有症状。
+
+该接口主要用于医疗知识查询场景,例如:
+- 通过输入疾病名称查询相关症状
+- 了解疾病的主要临床表现
+- 辅助临床诊断决策
+
+典型应用场景:
+1. 临床诊断辅助:通过疾病名称获取典型症状
+2. 患者教育:了解疾病可能出现的症状
+3. 医学知识问答系统:为AI提供结构化症状数据
+
+输入要求:
+- 仅支持标准医学术语名称
+- 不支持任何形式的编码(如ICD-10等)
+
+输出格式:
+- 返回标准JSON响应
+- 包含症状列表""",
+          response_description="""返回标准响应格式,包含症状列表。
+
+成功响应示例:
+{
+    "success": true,
+    "data": {
+        "disease": "胃癌",
+        "symptoms": [
+            "胃丢失蛋白",
+            "胃肠粘膜的通透性增高",
+            "手掌呈黑色",
+            "上腹痛",
+            "吞咽困难",
+            "疲劳",
+            "进食后饱胀",
+            "贫血",
+            "黑便",
+            "恶心"
+        ]
+    }
+}
+
+错误响应示例:
+{
+    "success": false,
+    "error": "Invalid disease name"
+}"""
           )
-async def get_disease_symptoms(
+async def getDiseaseSymptoms(
         disease_name: str = Query(...,
-                  description="疾病ID,应为标准医学术语ID。该参数用于查询该疾病的所有症状及其严重程度权重。",
-                  examples="艾滋病",
-                  min_length=1)
+                  alias="diseaseName",
+                  description="""疾病名称(仅支持标准医学术语名称,不支持编码)。
+
+该参数用于查询该疾病的所有症状及其严重程度权重。
+必须使用标准医学术语名称。
+示例值:"胃癌""",
+                  examples=["胃癌"],
+                  min_length=1,
+                  max_length=100)
 ):
+    """
+    根据疾病名称获取相关症状
+
+    Args:
+        disease_name: 疾病名称(仅支持标准医学术语名称,不支持编码)
+
+    Returns:
+        StandardResponse: 包含症状列表的标准响应
+            - data字段包含症状数组,每个症状可能有严重程度权重
+
+    Raises:
+        HTTPException: 当发生以下情况时抛出异常
+            - 疾病名称无效(400)
+            - 内部服务错误(500)
+
+    Example:
+        >>> POST /getDiseaseSymptoms?diseaseName=胃癌
+        {
+            "success": true,
+            "data": {
+                "disease": "胃癌",
+                "symptoms": [
+                "胃丢失蛋白",
+                "胃肠粘膜的通透性增高",
+                "手掌呈黑色",
+                "上腹痛",
+                "吞咽困难",
+                "疲劳",
+                "进食后饱胀",
+                "贫血",
+                "黑便",
+                "恶心"
+                ]
+            }
+        }
+    """
     try:
-        # 实现获取疾病症状的逻辑
+        # 验证疾病名称有效性
+        if not disease_name or len(disease_name.strip()) == 0:
+            raise ValueError("疾病名称不能为空")
+            
+        # 调用业务逻辑获取症状
         search = SearchBusiness()
         results = search.get_disease_symptoms(disease_name)
         return StandardResponse(success=True, data=results)
+    except ValueError as e:
+        logger.warning(f"无效的疾病名称: {disease_name}")
+        raise HTTPException(400, detail=StandardResponse.error(str(e)))
     except Exception as e:
         logger.error(f"获取疾病症状失败: {str(e)}")
         raise HTTPException(500, detail=StandardResponse.error(str(e)))

+ 11 - 1
src/knowledge/service/search_service.py

@@ -202,7 +202,10 @@ class SearchBusiness:
         try:
             # 1. 根据疾病名称查询疾病列表
             diseases = self.search_nodes(name=disease_name, type="疾病")
-            logger.info(f"Get diseases by name: {disease_name}, result: {diseases}")
+            #日志打印diseases的name,id和score
+            for disease in diseases:
+                logger.info(f"Get disease name: {disease.get('public_kg_nodes_name')}, id: {disease.get('public_kg_nodes_id')}, score: {disease.get('score')}")
+
             if not diseases:
                 return []
 
@@ -222,6 +225,13 @@ class SearchBusiness:
 
                 # 2. 根据疾病ID查找症状关系
                 edges = self.search_edges(name="相关症状", src_id=disease["public_kg_nodes_id"])
+                # 增加对'疾病相关症状'关系的查询
+                disease_symptom_edges = self.search_edges(name="疾病相关症状", src_id=disease["public_kg_nodes_id"])
+                
+                # 合并两种关系的查询结果
+                if disease_symptom_edges:
+                    edges.extend(disease_symptom_edges)
+                
                 logger.info(f"Get symptoms by disease id: {disease['public_kg_nodes_id']}, result: {edges}")
                 if not edges:
                     continue