Spaces:
Running
Running
Sontranwakumo
commited on
Commit
·
68b63d6
1
Parent(s):
e57a125
feat: update data
Browse files- app/api/routes.py +18 -10
- app/core/type.py +5 -1
- app/models/gemini_caller.py +4 -0
- app/models/knowledge_graph.py +30 -22
- app/services/predict.py +122 -1
- app/utils/constant.py +710 -0
- app/utils/prompt.py +49 -0
app/api/routes.py
CHANGED
@@ -30,15 +30,8 @@ async def analyze(
|
|
30 |
filename=image.filename,
|
31 |
headers=image.headers
|
32 |
)
|
33 |
-
image_copy2 = UploadFile(
|
34 |
-
file=io.BytesIO(image_content),
|
35 |
-
filename=image.filename,
|
36 |
-
headers=image.headers
|
37 |
-
)
|
38 |
-
|
39 |
predicted_label_task = asyncio.create_task(predict_service.predict_image(image_copy1))
|
40 |
-
|
41 |
-
predicted_label, nodes = await asyncio.gather(predicted_label_task, nodes_task)
|
42 |
|
43 |
filtered_labels = [label for label in predicted_label if label.confidence > 0.05]
|
44 |
if not filtered_labels and predicted_label:
|
@@ -47,8 +40,8 @@ async def analyze(
|
|
47 |
return {
|
48 |
"crop_id": filtered_labels[0].crop_id if filtered_labels else None,
|
49 |
"predicted_labels": filtered_labels,
|
50 |
-
"nodes": nodes,
|
51 |
-
"final_labels": filtered_labels
|
52 |
}
|
53 |
|
54 |
|
@@ -58,3 +51,18 @@ async def query_kg(
|
|
58 |
predict_service: PredictService = Depends(get_predict_service),
|
59 |
):
|
60 |
return await predict_service.retrieve_kg(request)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
filename=image.filename,
|
31 |
headers=image.headers
|
32 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
predicted_label_task = asyncio.create_task(predict_service.predict_image(image_copy1))
|
34 |
+
predicted_label = await predicted_label_task
|
|
|
35 |
|
36 |
filtered_labels = [label for label in predicted_label if label.confidence > 0.05]
|
37 |
if not filtered_labels and predicted_label:
|
|
|
40 |
return {
|
41 |
"crop_id": filtered_labels[0].crop_id if filtered_labels else None,
|
42 |
"predicted_labels": filtered_labels,
|
43 |
+
# "nodes": nodes,
|
44 |
+
# "final_labels": filtered_labels
|
45 |
}
|
46 |
|
47 |
|
|
|
51 |
predict_service: PredictService = Depends(get_predict_service),
|
52 |
):
|
53 |
return await predict_service.retrieve_kg(request)
|
54 |
+
|
55 |
+
|
56 |
+
@router.post("/kg-query-text")
|
57 |
+
async def query_kg_text(
|
58 |
+
request: KGQueryRequest,
|
59 |
+
predict_service: PredictService = Depends(get_predict_service),
|
60 |
+
):
|
61 |
+
return await predict_service.retrieve_kg_text(request)
|
62 |
+
|
63 |
+
|
64 |
+
# @router.post("/get-all-nodes")
|
65 |
+
# async def get_all_nodes(
|
66 |
+
# predict_service: PredictService = Depends(get_predict_service),
|
67 |
+
# ):
|
68 |
+
# return await predict_service.get_all_nodes()
|
app/core/type.py
CHANGED
@@ -10,7 +10,9 @@ class Node(BaseModel):
|
|
10 |
score: Optional[float] = None
|
11 |
|
12 |
@staticmethod
|
13 |
-
def map_json_to_node(json_data
|
|
|
|
|
14 |
node_data = {
|
15 |
"name": json_data.pop("name") if "name" in json_data else json_data["id"],
|
16 |
"id": json_data.pop("id"),
|
@@ -29,6 +31,8 @@ class Node(BaseModel):
|
|
29 |
score=score
|
30 |
)
|
31 |
|
|
|
|
|
32 |
class Relationship(BaseModel):
|
33 |
source: str
|
34 |
target: str
|
|
|
10 |
score: Optional[float] = None
|
11 |
|
12 |
@staticmethod
|
13 |
+
def map_json_to_node(json_data, label: str = None) -> 'Node':
|
14 |
+
if json_data is None:
|
15 |
+
return None
|
16 |
node_data = {
|
17 |
"name": json_data.pop("name") if "name" in json_data else json_data["id"],
|
18 |
"id": json_data.pop("id"),
|
|
|
31 |
score=score
|
32 |
)
|
33 |
|
34 |
+
def __str__(self):
|
35 |
+
return f"id={self.id}, name={self.name}, label={self.label}, properties={self.properties})"
|
36 |
class Relationship(BaseModel):
|
37 |
source: str
|
38 |
target: str
|
app/models/gemini_caller.py
CHANGED
@@ -41,5 +41,9 @@ class GeminiGenerator:
|
|
41 |
|
42 |
return response
|
43 |
|
|
|
|
|
|
|
|
|
44 |
if __name__ == "__main__":
|
45 |
generator = GeminiGenerator()
|
|
|
41 |
|
42 |
return response
|
43 |
|
44 |
+
async def generate_async(self, prompt="Hello, world!", system_prompt=None, image=None):
|
45 |
+
response = await self.generate(prompt, system_prompt, image)
|
46 |
+
return response
|
47 |
+
|
48 |
if __name__ == "__main__":
|
49 |
generator = GeminiGenerator()
|
app/models/knowledge_graph.py
CHANGED
@@ -6,13 +6,22 @@ from concurrent.futures import ThreadPoolExecutor
|
|
6 |
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
7 |
from core.type import Node
|
8 |
from neo4j import GraphDatabase
|
9 |
-
from utils.constant import NEO4J_LABELS, NEO4J_RELATIONS
|
10 |
|
11 |
NEO4J_URI = os.getenv("NEO4J_URI", "neo4j://localhost:7687")
|
12 |
NEO4J_USER = os.getenv("NEO4J_USER", "neo4j")
|
13 |
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD", "password")
|
14 |
NEO4J_DATABASE = os.getenv("NEO4J_DATABASE", "neo4j")
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
class Neo4jConnection:
|
17 |
def __init__(self):
|
18 |
"""Khởi tạo kết nối tới Neo4j"""
|
@@ -66,30 +75,30 @@ class KnowledgeGraphUtils:
|
|
66 |
WHERE ef.id IN {envFactors}
|
67 |
OPTIONAL MATCH (ef2:EnvironmentalFactor)-[:FAVORS]-(cause:Cause)-[:CAUSES|AFFECTS]-(d)
|
68 |
WHERE ef2.id IN {envFactors}
|
69 |
-
WITH d, COLLECT(DISTINCT ef.id) AS direct_env, COLLECT(DISTINCT ef2.id) AS indirect_env
|
70 |
WHERE SIZE(direct_env) > 0 OR SIZE(indirect_env) > 0
|
71 |
-
RETURN DISTINCT d, direct_env, indirect_env
|
72 |
"""
|
73 |
kg = Neo4jConnection()
|
74 |
result = kg.execute_query(query)
|
|
|
75 |
print(result)
|
76 |
final_result = []
|
|
|
77 |
for record in result:
|
78 |
record_dict = dict(record)
|
79 |
disease = Node.map_json_to_node(dict(record_dict["d"]), "Disease")
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
if param.id == env_id:
|
86 |
-
score = max(score, param.score)
|
87 |
-
disease.score = score
|
88 |
final_result.append({
|
89 |
"disease": disease,
|
90 |
-
"
|
|
|
|
|
91 |
})
|
92 |
-
final_result.sort(key=lambda x: x["disease"].score, reverse=True)
|
93 |
kg.close()
|
94 |
return final_result
|
95 |
|
@@ -120,21 +129,20 @@ class KnowledgeGraphUtils:
|
|
120 |
disease = Node.map_json_to_node(dict(record_dict["d"]), "Disease")
|
121 |
print(disease)
|
122 |
symptom_ids = list(record_dict["direct_symptom"]) + list(record_dict["indirect_symptom"])
|
123 |
-
score = 0
|
124 |
-
for symptom_id in symptom_ids:
|
125 |
-
for param in params:
|
126 |
-
if param.id == symptom_id:
|
127 |
-
if (param.score == None):
|
128 |
-
param.score = 0.9
|
129 |
-
score = max(score, param.score)
|
130 |
-
disease.score = score
|
131 |
final_result.append({
|
132 |
"disease": disease,
|
133 |
"symptom_ids": symptom_ids
|
134 |
})
|
135 |
-
final_result.sort(key=lambda x: x["disease"].score, reverse=True)
|
136 |
kg.close()
|
|
|
137 |
return final_result
|
138 |
|
139 |
loop = asyncio.get_event_loop()
|
140 |
return await loop.run_in_executor(self.executor, _get_disease_from_symptoms)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
7 |
from core.type import Node
|
8 |
from neo4j import GraphDatabase
|
9 |
+
from utils.constant import EXTRACTED_NODES, NEO4J_LABELS, NEO4J_RELATIONS
|
10 |
|
11 |
NEO4J_URI = os.getenv("NEO4J_URI", "neo4j://localhost:7687")
|
12 |
NEO4J_USER = os.getenv("NEO4J_USER", "neo4j")
|
13 |
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD", "password")
|
14 |
NEO4J_DATABASE = os.getenv("NEO4J_DATABASE", "neo4j")
|
15 |
|
16 |
+
extracted_nodes = [
|
17 |
+
Node(
|
18 |
+
id=node['id'],
|
19 |
+
label=node['label'],
|
20 |
+
name=node['name'],
|
21 |
+
properties={'description': node['description']},
|
22 |
+
score=None
|
23 |
+
) for node in EXTRACTED_NODES
|
24 |
+
]
|
25 |
class Neo4jConnection:
|
26 |
def __init__(self):
|
27 |
"""Khởi tạo kết nối tới Neo4j"""
|
|
|
75 |
WHERE ef.id IN {envFactors}
|
76 |
OPTIONAL MATCH (ef2:EnvironmentalFactor)-[:FAVORS]-(cause:Cause)-[:CAUSES|AFFECTS]-(d)
|
77 |
WHERE ef2.id IN {envFactors}
|
78 |
+
WITH d, COLLECT(DISTINCT ef.id) AS direct_env, COLLECT(DISTINCT ef2.id) AS indirect_env, cause
|
79 |
WHERE SIZE(direct_env) > 0 OR SIZE(indirect_env) > 0
|
80 |
+
RETURN DISTINCT d, direct_env, indirect_env, cause
|
81 |
"""
|
82 |
kg = Neo4jConnection()
|
83 |
result = kg.execute_query(query)
|
84 |
+
|
85 |
print(result)
|
86 |
final_result = []
|
87 |
+
comments = []
|
88 |
for record in result:
|
89 |
record_dict = dict(record)
|
90 |
disease = Node.map_json_to_node(dict(record_dict["d"]), "Disease")
|
91 |
+
cause_data = record_dict["cause"]
|
92 |
+
cause = Node.map_json_to_node(dict(cause_data) if cause_data is not None else None, "Cause")
|
93 |
+
direct_env = record_dict["direct_env"]
|
94 |
+
indirect_env = record_dict["indirect_env"]
|
95 |
+
|
|
|
|
|
|
|
96 |
final_result.append({
|
97 |
"disease": disease,
|
98 |
+
"cause": cause,
|
99 |
+
"direct_env": [next((node for node in extracted_nodes if node.id == id), None) for id in direct_env],
|
100 |
+
"indirect_env": [next((node for node in extracted_nodes if node.id == id), None) for id in indirect_env]
|
101 |
})
|
|
|
102 |
kg.close()
|
103 |
return final_result
|
104 |
|
|
|
129 |
disease = Node.map_json_to_node(dict(record_dict["d"]), "Disease")
|
130 |
print(disease)
|
131 |
symptom_ids = list(record_dict["direct_symptom"]) + list(record_dict["indirect_symptom"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
final_result.append({
|
133 |
"disease": disease,
|
134 |
"symptom_ids": symptom_ids
|
135 |
})
|
|
|
136 |
kg.close()
|
137 |
+
print(final_result)
|
138 |
return final_result
|
139 |
|
140 |
loop = asyncio.get_event_loop()
|
141 |
return await loop.run_in_executor(self.executor, _get_disease_from_symptoms)
|
142 |
+
|
143 |
+
async def get_all_nodes(self):
|
144 |
+
kg = Neo4jConnection()
|
145 |
+
query = "MATCH (n:Symptom) RETURN n"
|
146 |
+
result = kg.execute_query(query)
|
147 |
+
kg.close()
|
148 |
+
return result
|
app/services/predict.py
CHANGED
@@ -12,9 +12,58 @@ from app.core.type import Node
|
|
12 |
from app.models.crop_clip import EfficientNetModule
|
13 |
from app.models.gemini_caller import GeminiGenerator
|
14 |
from app.models.knowledge_graph import KnowledgeGraphUtils
|
|
|
15 |
from app.utils.data_mapping import VECTOR_EMBEDDINGS_DB_PATH, DataMapping
|
16 |
from app.utils.extract_entity import clean_text, extract_entities
|
17 |
-
from app.utils.prompt import EXTRACT_NODES_FROM_IMAGE_PROMPT
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
class PredictService:
|
20 |
def __init__(self, models):
|
@@ -210,5 +259,77 @@ class PredictService:
|
|
210 |
cursor.close() # Đóng connection sau khi dùng xong
|
211 |
conn.close()
|
212 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
def get_predict_service(models = Depends(get_all_models)):
|
214 |
return PredictService(models)
|
|
|
12 |
from app.models.crop_clip import EfficientNetModule
|
13 |
from app.models.gemini_caller import GeminiGenerator
|
14 |
from app.models.knowledge_graph import KnowledgeGraphUtils
|
15 |
+
from app.utils.constant import EXTRACTED_NODES
|
16 |
from app.utils.data_mapping import VECTOR_EMBEDDINGS_DB_PATH, DataMapping
|
17 |
from app.utils.extract_entity import clean_text, extract_entities
|
18 |
+
from app.utils.prompt import EXTRACT_NODES_FROM_IMAGE_PROMPT, EXTRACT_NODES_FROM_TEXT_PROMPT, GET_STATEMENT_FROM_DISEASE_KG, GET_STATEMENT_FROM_ENV_FACTORS_KG
|
19 |
+
|
20 |
+
class CustomJSONEncoder(json.JSONEncoder):
|
21 |
+
def default(self, obj):
|
22 |
+
if hasattr(obj, 'model_dump'): # Pydantic v2 BaseModel
|
23 |
+
return obj.model_dump()
|
24 |
+
elif hasattr(obj, 'dict'): # Pydantic v1 BaseModel
|
25 |
+
return obj.dict()
|
26 |
+
elif isinstance(obj, (list, tuple)):
|
27 |
+
return [self.default(item) if hasattr(item, 'model_dump') or hasattr(item, 'dict') else item for item in obj]
|
28 |
+
return super().default(obj)
|
29 |
+
|
30 |
+
def convert_to_json_serializable(obj):
|
31 |
+
"""Convert objects containing Node instances to JSON serializable format"""
|
32 |
+
try:
|
33 |
+
if hasattr(obj, 'model_dump'): # Pydantic v2 BaseModel
|
34 |
+
return obj.model_dump()
|
35 |
+
elif hasattr(obj, 'dict'): # Pydantic v1 BaseModel
|
36 |
+
return obj.dict()
|
37 |
+
elif isinstance(obj, list):
|
38 |
+
return [convert_to_json_serializable(item) for item in obj]
|
39 |
+
elif isinstance(obj, dict):
|
40 |
+
return {key: convert_to_json_serializable(value) for key, value in obj.items()}
|
41 |
+
elif isinstance(obj, tuple):
|
42 |
+
return [convert_to_json_serializable(item) for item in obj]
|
43 |
+
elif obj is None:
|
44 |
+
return None
|
45 |
+
else:
|
46 |
+
# Try to convert basic types
|
47 |
+
try:
|
48 |
+
json.dumps(obj) # Test if it's JSON serializable
|
49 |
+
return obj
|
50 |
+
except (TypeError, ValueError):
|
51 |
+
# If it's not serializable, convert to string as fallback
|
52 |
+
print(f"Warning: Converting non-serializable object {type(obj)} to string: {obj}")
|
53 |
+
return str(obj)
|
54 |
+
except Exception as e:
|
55 |
+
print(f"Error in convert_to_json_serializable for object {type(obj)}: {e}")
|
56 |
+
return str(obj)
|
57 |
+
|
58 |
+
extracted_nodes = [
|
59 |
+
Node(
|
60 |
+
id=node['id'],
|
61 |
+
label=node['label'],
|
62 |
+
name=node['name'],
|
63 |
+
properties={'description': node['description']},
|
64 |
+
score=None
|
65 |
+
) for node in EXTRACTED_NODES
|
66 |
+
]
|
67 |
|
68 |
class PredictService:
|
69 |
def __init__(self, models):
|
|
|
259 |
cursor.close() # Đóng connection sau khi dùng xong
|
260 |
conn.close()
|
261 |
|
262 |
+
|
263 |
+
async def retrieve_kg_text(self, request: KGQueryRequest):
|
264 |
+
try:
|
265 |
+
nodes = await self.get_nodes_from_text(request.additional_info)
|
266 |
+
kg: KnowledgeGraphUtils = self.models["knowledge_graph"]
|
267 |
+
env_task = asyncio.create_task(
|
268 |
+
kg.get_disease_from_env_factors(request.crop_id, nodes)
|
269 |
+
)
|
270 |
+
symptom_task = asyncio.create_task(
|
271 |
+
kg.get_disease_from_symptoms(request.crop_id, nodes)
|
272 |
+
)
|
273 |
+
|
274 |
+
env_results, symptom_results = await asyncio.gather(env_task, symptom_task)
|
275 |
+
|
276 |
+
best_label = request.context.predicted_labels[0].label
|
277 |
+
best_env_result = next((result for result in env_results if result["disease"].id == best_label), None)
|
278 |
+
best_env_result_str = str(best_env_result)
|
279 |
+
best_symptom_result = next((result for result in symptom_results if result["disease"].id == best_label), None)
|
280 |
+
best_symptom_result_str = str(best_symptom_result)
|
281 |
+
prompt1 = None
|
282 |
+
prompt2 = None
|
283 |
+
|
284 |
+
result1 = None
|
285 |
+
result2 = None
|
286 |
+
|
287 |
+
if best_env_result:
|
288 |
+
prompt1 = Template(GET_STATEMENT_FROM_ENV_FACTORS_KG).substitute(context=best_env_result_str)
|
289 |
+
if best_symptom_result:
|
290 |
+
prompt2 = Template(GET_STATEMENT_FROM_DISEASE_KG).substitute(context=best_symptom_result_str)
|
291 |
+
gemini = GeminiGenerator()
|
292 |
+
print(prompt1)
|
293 |
+
if prompt1:
|
294 |
+
result1 = gemini.generate(prompt1)
|
295 |
+
if prompt2:
|
296 |
+
result2 = gemini.generate(prompt2)
|
297 |
+
|
298 |
+
return {
|
299 |
+
"env_results": env_results,
|
300 |
+
"symptom_results": symptom_results,
|
301 |
+
"env_statement": result1.text if result1 else None,
|
302 |
+
"symptom_statement": result2.text if result2 else None
|
303 |
+
}
|
304 |
+
except Exception as e:
|
305 |
+
print(e)
|
306 |
+
raise e
|
307 |
+
|
308 |
+
async def get_nodes_from_text(self, text: str):
|
309 |
+
try:
|
310 |
+
|
311 |
+
|
312 |
+
gemini = GeminiGenerator()
|
313 |
+
node_list = [f" + id:{node.id}, name:{node.name}, description:{node.properties.get('description', '')}" for node in extracted_nodes]
|
314 |
+
prompt = Template(EXTRACT_NODES_FROM_TEXT_PROMPT).substitute(text=text, node_list=node_list)
|
315 |
+
ids = gemini.generate(prompt)
|
316 |
+
print(ids)
|
317 |
+
|
318 |
+
ids = (json.loads(clean_text(ids.text)))["ids"]
|
319 |
+
print(ids)
|
320 |
+
nodes = [next((node for node in extracted_nodes if node.id == id), None) for id in ids]
|
321 |
+
return nodes
|
322 |
+
except Exception as e:
|
323 |
+
print(e)
|
324 |
+
|
325 |
+
# async def get_all_nodes(self):
|
326 |
+
# try:
|
327 |
+
# kg: KnowledgeGraphUtils = self.models["knowledge_graph"]
|
328 |
+
# list_nodes = await kg.get_all_nodes()
|
329 |
+
# return [dict(node[0], **{"label": "Symptom"}) for node in list_nodes]
|
330 |
+
# except Exception as e:
|
331 |
+
# print(e)
|
332 |
+
# return []
|
333 |
+
|
334 |
def get_predict_service(models = Depends(get_all_models)):
|
335 |
return PredictService(models)
|
app/utils/constant.py
CHANGED
@@ -1,2 +1,712 @@
|
|
1 |
NEO4J_LABELS =['Disease', 'Symptom', 'Treatment', 'Cause', 'Effect', 'Prevention', 'EnvironmentalFactor', 'Stage', 'Crop', 'CropType', 'PlantPart', 'SoilType', 'DiagnosisMethod']
|
2 |
NEO4J_RELATIONS = ['CAUSES', 'HAS_SYMPTOM', 'PRODUCES', 'FAVORS', 'IS_TREATED_BY', 'PREVENTS', 'OCCURS_AT', 'BELONGS_TO', 'CONTAINS', 'LOCATED_ON', 'AFFECTS', 'IS_APPLIED_TO']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
NEO4J_LABELS =['Disease', 'Symptom', 'Treatment', 'Cause', 'Effect', 'Prevention', 'EnvironmentalFactor', 'Stage', 'Crop', 'CropType', 'PlantPart', 'SoilType', 'DiagnosisMethod']
|
2 |
NEO4J_RELATIONS = ['CAUSES', 'HAS_SYMPTOM', 'PRODUCES', 'FAVORS', 'IS_TREATED_BY', 'PREVENTS', 'OCCURS_AT', 'BELONGS_TO', 'CONTAINS', 'LOCATED_ON', 'AFFECTS', 'IS_APPLIED_TO']
|
3 |
+
EXTRACTED_NODES = [
|
4 |
+
{
|
5 |
+
"name": "nhiệt độ mát",
|
6 |
+
"description": "Không có mô tả cụ thể",
|
7 |
+
"id": "nhietDoMat",
|
8 |
+
"label": "EnvironmentalFactor"
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"name": "mưa thường xuyên",
|
12 |
+
"description": "Không có mô tả cụ thể",
|
13 |
+
"id": "muaThuongXuyen",
|
14 |
+
"label": "EnvironmentalFactor"
|
15 |
+
},
|
16 |
+
{
|
17 |
+
"name": "độ ẩm không khí cao",
|
18 |
+
"description": "Không có mô tả cụ thể",
|
19 |
+
"id": "doAmKhongKhiCao",
|
20 |
+
"label": "EnvironmentalFactor"
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"name": "Lá chịu ẩm",
|
24 |
+
"description": "Lá chịu ẩm trong thời gian dài",
|
25 |
+
"id": "laChiuAm",
|
26 |
+
"label": "EnvironmentalFactor"
|
27 |
+
},
|
28 |
+
{
|
29 |
+
"name": "nhiệt độ 24-28°C",
|
30 |
+
"description": "Không có mô tả cụ thể",
|
31 |
+
"id": "nhietDo24_28",
|
32 |
+
"label": "EnvironmentalFactor"
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"name": "ẩm độ không khí trên 80%",
|
36 |
+
"description": "Không có mô tả cụ thể",
|
37 |
+
"id": "amDoKhongKhi80",
|
38 |
+
"label": "EnvironmentalFactor"
|
39 |
+
},
|
40 |
+
{
|
41 |
+
"name": "trời âm u",
|
42 |
+
"description": "Không có mô tả cụ thể",
|
43 |
+
"id": "troiAmU",
|
44 |
+
"label": "EnvironmentalFactor"
|
45 |
+
},
|
46 |
+
{
|
47 |
+
"name": "mưa phùn",
|
48 |
+
"description": "Không có mô tả cụ thể",
|
49 |
+
"id": "muaPhun",
|
50 |
+
"label": "EnvironmentalFactor"
|
51 |
+
},
|
52 |
+
{
|
53 |
+
"name": "ruộng có khuynh hướng chịu sương",
|
54 |
+
"description": "Không có mô tả cụ thể",
|
55 |
+
"id": "ruongCoSuong",
|
56 |
+
"label": "EnvironmentalFactor"
|
57 |
+
},
|
58 |
+
{
|
59 |
+
"name": "Lá bị ẩm ướt kéo dài",
|
60 |
+
"description": "Lá bị ẩm ướt kéo dài.",
|
61 |
+
"id": "laBiAmUotKeoDai",
|
62 |
+
"label": "EnvironmentalFactor"
|
63 |
+
},
|
64 |
+
{
|
65 |
+
"name": "Nhiệt độ cao",
|
66 |
+
"description": "Nhiệt độ cao (16-36°C).",
|
67 |
+
"id": "nhietDoCao",
|
68 |
+
"label": "EnvironmentalFactor"
|
69 |
+
},
|
70 |
+
{
|
71 |
+
"name": "Mùa khô",
|
72 |
+
"description": "Điều kiện khô hạn.",
|
73 |
+
"id": "muaKho",
|
74 |
+
"label": "EnvironmentalFactor"
|
75 |
+
},
|
76 |
+
{
|
77 |
+
"name": "Mùa mưa",
|
78 |
+
"description": "Bệnh phát triển trong mùa mưa",
|
79 |
+
"id": "muaMua",
|
80 |
+
"label": "EnvironmentalFactor"
|
81 |
+
},
|
82 |
+
{
|
83 |
+
"name": "Nhiệt độ không khí cao",
|
84 |
+
"description": "Nhiệt độ không khí cao trên 30 độ C",
|
85 |
+
"id": "nhietDoKhongKhiCao",
|
86 |
+
"label": "EnvironmentalFactor"
|
87 |
+
},
|
88 |
+
{
|
89 |
+
"name": "Nhiệt độ",
|
90 |
+
"description": "Nhiệt độ 10-36oC",
|
91 |
+
"id": "nhietDo",
|
92 |
+
"label": "EnvironmentalFactor"
|
93 |
+
},
|
94 |
+
{
|
95 |
+
"name": "Thời tiết ẩm ướt",
|
96 |
+
"description": "Thời tiết ẩm ướt, ẩm ướt trên lá",
|
97 |
+
"id": "thoiTietAmUot",
|
98 |
+
"label": "EnvironmentalFactor"
|
99 |
+
},
|
100 |
+
{
|
101 |
+
"name": "Nhiệt độ",
|
102 |
+
"description": "Nhiệt độ từ 22 đến 30°C",
|
103 |
+
"id": "nhietDo22Den30",
|
104 |
+
"label": "EnvironmentalFactor"
|
105 |
+
},
|
106 |
+
{
|
107 |
+
"name": "nhiệt độ 25-28oC",
|
108 |
+
"description": "Điều kiện nhiệt độ 25-28oC",
|
109 |
+
"id": "nhietDoThuanLoi",
|
110 |
+
"label": "EnvironmentalFactor"
|
111 |
+
},
|
112 |
+
{
|
113 |
+
"name": "Độ ẩm tương đối cao",
|
114 |
+
"description": "Không có mô tả cụ thể",
|
115 |
+
"id": "doAmTuongDoiCao",
|
116 |
+
"label": "EnvironmentalFactor"
|
117 |
+
},
|
118 |
+
{
|
119 |
+
"name": "Mưa lớn",
|
120 |
+
"description": "Không có mô tả cụ thể",
|
121 |
+
"id": "muaLon",
|
122 |
+
"label": "EnvironmentalFactor"
|
123 |
+
},
|
124 |
+
{
|
125 |
+
"name": "Ẩm ướt kéo dài",
|
126 |
+
"description": "Không có mô tả cụ thể",
|
127 |
+
"id": "amUotKeoDai",
|
128 |
+
"label": "EnvironmentalFactor"
|
129 |
+
},
|
130 |
+
{
|
131 |
+
"name": "Tưới nước bằng cách phun từ trên cao",
|
132 |
+
"description": "Không có mô tả cụ thể",
|
133 |
+
"id": "tuoiNuocBangCachPhunTuTrenCao",
|
134 |
+
"label": "EnvironmentalFactor"
|
135 |
+
},
|
136 |
+
{
|
137 |
+
"name": "Tưới trong thời tiết nóng",
|
138 |
+
"description": "Không có mô tả cụ thể",
|
139 |
+
"id": "tuoiTrongThoiTietNong",
|
140 |
+
"label": "EnvironmentalFactor"
|
141 |
+
},
|
142 |
+
{
|
143 |
+
"name": "Độ ẩm thấp",
|
144 |
+
"description": "Độ ẩm thấp là điều kiện môi trường thuận lợi cho bệnh phát triển.",
|
145 |
+
"id": "doAmThap",
|
146 |
+
"label": "EnvironmentalFactor"
|
147 |
+
},
|
148 |
+
{
|
149 |
+
"name": "Đất thiếu dinh dưỡng",
|
150 |
+
"description": "Đất thiếu dinh dưỡng làm cây yếu, dễ nhiễm bệnh.",
|
151 |
+
"id": "datThieuDinhDuong",
|
152 |
+
"label": "EnvironmentalFactor"
|
153 |
+
},
|
154 |
+
{
|
155 |
+
"name": "đất ẩm",
|
156 |
+
"description": "Đất ẩm",
|
157 |
+
"id": "datAm",
|
158 |
+
"label": "EnvironmentalFactor"
|
159 |
+
},
|
160 |
+
{
|
161 |
+
"name": "ấm và ẩm ướt",
|
162 |
+
"description": "Điều kiện ấm áp và ẩm ướt",
|
163 |
+
"id": "amUot",
|
164 |
+
"label": "EnvironmentalFactor"
|
165 |
+
},
|
166 |
+
{
|
167 |
+
"name": "Bào tử nấm trong không khí",
|
168 |
+
"description": "Bào tử nấm trong không khí, đặc biệt trong mùa mưa hoặc môi trường ẩm ướt.",
|
169 |
+
"id": "baoTuNamTrongKhongKhi",
|
170 |
+
"label": "EnvironmentalFactor"
|
171 |
+
},
|
172 |
+
{
|
173 |
+
"name": "Tàn dư thực vật bị nhiễm bệnh",
|
174 |
+
"description": "Tàn dư thực vật bị nhiễm bệnh còn sót lại trên đồng ruộng.",
|
175 |
+
"id": "tanDuThucVatNhiemBenh",
|
176 |
+
"label": "EnvironmentalFactor"
|
177 |
+
},
|
178 |
+
{
|
179 |
+
"name": "Nước tưới hoặc mưa bắn",
|
180 |
+
"description": "Nước tưới hoặc mưa bắn làm lây lan bào tử từ lá bệnh sang lá khỏe.",
|
181 |
+
"id": "nuocTuoiMuaBan",
|
182 |
+
"label": "EnvironmentalFactor"
|
183 |
+
},
|
184 |
+
{
|
185 |
+
"name": "Điều kiện nhiệt độ từ 25-30°C và độ ẩm cao",
|
186 |
+
"description": "Điều kiện nhiệt độ từ 25-30°C và độ ẩm cao tạo điều kiện thuận lợi cho nấm phát triển.",
|
187 |
+
"id": "nhietDoDoAmCao",
|
188 |
+
"label": "EnvironmentalFactor"
|
189 |
+
},
|
190 |
+
{
|
191 |
+
"name": "thời tiết xấu (mưa gió thường xuyên)",
|
192 |
+
"description": "",
|
193 |
+
"id": "thoiTietXauMuaGio",
|
194 |
+
"label": "EnvironmentalFactor"
|
195 |
+
},
|
196 |
+
{
|
197 |
+
"name": "độ ẩm cao",
|
198 |
+
"description": "độ ẩm cao (trên 70%)",
|
199 |
+
"id": "doAmCao",
|
200 |
+
"label": "EnvironmentalFactor"
|
201 |
+
},
|
202 |
+
{
|
203 |
+
"name": "nhiệt độ ấm",
|
204 |
+
"description": "nhiệt độ ấm (25°C đến 34°C)",
|
205 |
+
"id": "nhietDoAm",
|
206 |
+
"label": "EnvironmentalFactor"
|
207 |
+
},
|
208 |
+
{
|
209 |
+
"name": "đốm có dạng hình bầu dục",
|
210 |
+
"description": "Các đốm có dạng hình bầu dục hay dạng hình thoi, vàng úa ngả xanh nhợt",
|
211 |
+
"id": "domHinhBauDuc",
|
212 |
+
"label": "Symptom"
|
213 |
+
},
|
214 |
+
{
|
215 |
+
"name": "Vết bệnh điển hình trên lá có dạng hình thoi",
|
216 |
+
"description": "Vết bệnh điển hình trên lá có dạng hình thoi",
|
217 |
+
"id": "vetBenhHinhThoi",
|
218 |
+
"label": "Symptom"
|
219 |
+
},
|
220 |
+
{
|
221 |
+
"name": "mầu xanh đậm",
|
222 |
+
"description": "Đường viền vết bệnh ban đầu mầu xanh đậm, sau chuyển mầu nâu đỏ",
|
223 |
+
"id": "vienXanhDam",
|
224 |
+
"label": "Symptom"
|
225 |
+
},
|
226 |
+
{
|
227 |
+
"name": "mô chết",
|
228 |
+
"description": "Đường viền bên ngoài các đốm tổn thương ấy là phần mô chết",
|
229 |
+
"id": "moChet",
|
230 |
+
"label": "Symptom"
|
231 |
+
},
|
232 |
+
{
|
233 |
+
"name": "bị hoại tử",
|
234 |
+
"description": "Phần giữa vết bệnh thường có màu trắng hoặc nâu do bị hoại tử",
|
235 |
+
"id": "hoaiTu",
|
236 |
+
"label": "Symptom"
|
237 |
+
},
|
238 |
+
{
|
239 |
+
"name": "lá khô héo",
|
240 |
+
"description": "Khi các đốm tổn thương ấy phát triển, lá khô héo dần",
|
241 |
+
"id": "laKhoHeo",
|
242 |
+
"label": "Symptom"
|
243 |
+
},
|
244 |
+
{
|
245 |
+
"name": "thối cổ lá",
|
246 |
+
"description": "Hiện tượng thối cổ lá có thể xuất hiện và phần lá phía trên điểm nối sẽ chết",
|
247 |
+
"id": "thoiCoLa",
|
248 |
+
"label": "Symptom"
|
249 |
+
},
|
250 |
+
{
|
251 |
+
"name": "đốt thân hóa nâu",
|
252 |
+
"description": "Các đốt thân cũng có thể bị ảnh hưởng. Điều đó dẫn đến triệu chứng các đốt thân hóa nâu và gãy thân",
|
253 |
+
"id": "dotThanHoaNau",
|
254 |
+
"label": "Symptom"
|
255 |
+
},
|
256 |
+
{
|
257 |
+
"name": "gãy thân",
|
258 |
+
"description": "Các đốt thân cũng có thể bị ảnh hưởng. Điều đó dẫn đến triệu chứng các đốt thân hóa nâu và gãy thân",
|
259 |
+
"id": "gayThan",
|
260 |
+
"label": "Symptom"
|
261 |
+
},
|
262 |
+
{
|
263 |
+
"name": "Đốm tròn hay bầu dục màu nâu",
|
264 |
+
"description": "Đốm tròn hay bầu dục màu nâu với một quầng màu vàng xuất hiện trong giai đoạn lúa đẻ nhánh.",
|
265 |
+
"id": "domTronBauDucMauNau",
|
266 |
+
"label": "Symptom"
|
267 |
+
},
|
268 |
+
{
|
269 |
+
"name": "Điểm giữa màu xám",
|
270 |
+
"description": "Điểm giữa của đốm chuyển sang màu xám khi đốm lớn dần.",
|
271 |
+
"id": "diemGiuaMauXam",
|
272 |
+
"label": "Symptom"
|
273 |
+
},
|
274 |
+
{
|
275 |
+
"name": "Mép màu nâu đỏ",
|
276 |
+
"description": "Mép của đốm chuyển sang màu nâu hơi đỏ khi đốm lớn dần.",
|
277 |
+
"id": "mepMauNauDo",
|
278 |
+
"label": "Symptom"
|
279 |
+
},
|
280 |
+
{
|
281 |
+
"name": "Bạc màu thân",
|
282 |
+
"description": "Bạc màu thân cũng là một triệu chứng đặc trưng.",
|
283 |
+
"id": "bacMauThan",
|
284 |
+
"label": "Symptom"
|
285 |
+
},
|
286 |
+
{
|
287 |
+
"name": "Tổn thương màu vàng đến nâu",
|
288 |
+
"description": "Các tổn thương có màu vàng đến nâu và có kích cỡ như đầu kim trên các giống có sức đề kháng.",
|
289 |
+
"id": "tonThuongMauVangNau",
|
290 |
+
"label": "Symptom"
|
291 |
+
},
|
292 |
+
{
|
293 |
+
"name": "Đầy hạt không trọn vẹn",
|
294 |
+
"description": "Bông nhiễm bệnh dẫn đến tình trạng giai đoạn đầy hạt không trọn vẹn hoặc bị phá vỡ.",
|
295 |
+
"id": "dayHatKhongTronVen",
|
296 |
+
"label": "Symptom"
|
297 |
+
},
|
298 |
+
{
|
299 |
+
"name": "Chấm nhỏ màu vàng",
|
300 |
+
"description": "Những chấm nhỏ màu vàng trên phiến lá.",
|
301 |
+
"id": "chamNhoMauVang",
|
302 |
+
"label": "Symptom"
|
303 |
+
},
|
304 |
+
{
|
305 |
+
"name": "Lá đốm",
|
306 |
+
"description": "Lá có đốm.",
|
307 |
+
"id": "laDom",
|
308 |
+
"label": "Symptom"
|
309 |
+
},
|
310 |
+
{
|
311 |
+
"name": "Phát triển kém",
|
312 |
+
"description": "Cây phát triển kém.",
|
313 |
+
"id": "phatTrienKem",
|
314 |
+
"label": "Symptom"
|
315 |
+
},
|
316 |
+
{
|
317 |
+
"name": "Rụng lá",
|
318 |
+
"description": "Lá bị rụng.",
|
319 |
+
"id": "laRung",
|
320 |
+
"label": "Symptom"
|
321 |
+
},
|
322 |
+
{
|
323 |
+
"name": "Lá ngọn khô",
|
324 |
+
"description": "Lá ngọn bị khô.",
|
325 |
+
"id": "laNgonKho",
|
326 |
+
"label": "Symptom"
|
327 |
+
},
|
328 |
+
{
|
329 |
+
"name": "đốt thân trơ",
|
330 |
+
"description": "Đốt thân ngọn còn trơ lại như tim đèn.",
|
331 |
+
"id": "dotThanTro",
|
332 |
+
"label": "Symptom"
|
333 |
+
},
|
334 |
+
{
|
335 |
+
"name": "Đốm nhỏ hình tròn",
|
336 |
+
"description": "Các thương tổn có hình dạng bắt đầu như những đốm nhỏ hình tròn, màu vàng hơi ngả xanh",
|
337 |
+
"id": "domNhoHinhTron",
|
338 |
+
"label": "Symptom"
|
339 |
+
},
|
340 |
+
{
|
341 |
+
"name": "Mảng góc cạnh",
|
342 |
+
"description": "Khi lan rộng, các đốm ấy bị giới hạn bởi các gân lá chính và phát triển thành các mảng góc cạnh",
|
343 |
+
"id": "mangGocCanh",
|
344 |
+
"label": "Symptom"
|
345 |
+
},
|
346 |
+
{
|
347 |
+
"name": "Đốm màu vàng nâu",
|
348 |
+
"description": "Ở mặt trên, các đốm chuyển sang màu vàng nâu hay vàng nâu nhạt, có kích thước không đồng đều, có rìa màu nâu sẫm, hơi gồ lên",
|
349 |
+
"id": "domMauVangNau",
|
350 |
+
"label": "Symptom"
|
351 |
+
},
|
352 |
+
{
|
353 |
+
"name": "Đường hoại tử màu đen",
|
354 |
+
"description": "Đôi khi, các gân lá nhỏ xen ngang các mảng đốm trông như những đường hoại tử màu đen",
|
355 |
+
"id": "duongHoaiTuMauDen",
|
356 |
+
"label": "Symptom"
|
357 |
+
},
|
358 |
+
{
|
359 |
+
"name": "Vùng trung tâm khô",
|
360 |
+
"description": "Theo thời gian, vùng trung tâm của các đốm khô đi",
|
361 |
+
"id": "vungTrungTamKho",
|
362 |
+
"label": "Symptom"
|
363 |
+
},
|
364 |
+
{
|
365 |
+
"name": "Quầng vàng",
|
366 |
+
"description": "Trong các trường hợp cây bị nhiễm nặng, các đốm lá được bao quanh bởi một quầng vàng do nhiễm độc tố của các sợi nấm đang tiến triển tạo ra",
|
367 |
+
"id": "quangVang",
|
368 |
+
"label": "Symptom"
|
369 |
+
},
|
370 |
+
{
|
371 |
+
"name": "Rụng lá sớm",
|
372 |
+
"description": "Các thương tổn này có thể kết tụ lại và phủ toàn bộ lá, gây ra hiện tượng rụng lá sớm",
|
373 |
+
"id": "rungLaSom",
|
374 |
+
"label": "Symptom"
|
375 |
+
},
|
376 |
+
{
|
377 |
+
"name": "Đốm màu xám",
|
378 |
+
"description": "Ở mặt dưới lá, các đốm có màu xám và kém nổi bật hơn",
|
379 |
+
"id": "domMauXam",
|
380 |
+
"label": "Symptom"
|
381 |
+
},
|
382 |
+
{
|
383 |
+
"name": "Vết bệnh hình tròn",
|
384 |
+
"description": "vết bệnh hình tròn hoặc méo mó, từ 1-10mm. Lúc đầu có màu xanh tái, sau chuyển màu vàng,giữa màu xám,xung quanh viền nâu sẫm",
|
385 |
+
"id": "vetBenhHinhTron",
|
386 |
+
"label": "Symptom"
|
387 |
+
},
|
388 |
+
{
|
389 |
+
"name": "Ổ nấm màu đen",
|
390 |
+
"description": "Ở giữa vết bệnh đã già mọc lên những ổ nấm màu đen, đôi khi xếp thành các vòng đồng tâm",
|
391 |
+
"id": "oNamMauDen",
|
392 |
+
"label": "Symptom"
|
393 |
+
},
|
394 |
+
{
|
395 |
+
"name": "Lá biến vàng",
|
396 |
+
"description": "Lá bị bệnh nặng biến vàng",
|
397 |
+
"id": "laBienVang",
|
398 |
+
"label": "Symptom"
|
399 |
+
},
|
400 |
+
{
|
401 |
+
"name": "Khảm vàng Loang Lổ",
|
402 |
+
"description": "Xuất hiện khảm vàng loang lổ trên lá cây.",
|
403 |
+
"id": "khamVangLoangLo",
|
404 |
+
"label": "Symptom"
|
405 |
+
},
|
406 |
+
{
|
407 |
+
"name": "Lá xoăn, quăn, nhăn nheo",
|
408 |
+
"description": "Lá sắn xoăn, quăn, nhăn nheo.",
|
409 |
+
"id": "laXoanQuan",
|
410 |
+
"label": "Symptom"
|
411 |
+
},
|
412 |
+
{
|
413 |
+
"name": "Vết bệnh hình bầu dục",
|
414 |
+
"description": "Vết bệnh có hình bầu dục, hai mép của vết bệnh có khuynh hướng chạy dọc (song song) theo phiến lá và kết thúc bằng nơi tiếp xúc hai cạnh. Vết bệnh có màu vàng nhạt ở giữa, xung quanh là màu nâu đỏ. Các vết bệnh thường bị giới hạn bởi gân lá",
|
415 |
+
"id": "vetBenhHinhBauDuc",
|
416 |
+
"label": "Symptom"
|
417 |
+
},
|
418 |
+
{
|
419 |
+
"name": "Lá bị khô",
|
420 |
+
"description": "Các vết bệnh liên kết lại với nhau làm cho lá bị khô",
|
421 |
+
"id": "laBiKho",
|
422 |
+
"label": "Symptom"
|
423 |
+
},
|
424 |
+
{
|
425 |
+
"name": "Màu mốc xám",
|
426 |
+
"description": "Trên bắp ngô khi nhiễm bệnh thì có màu mốc xám",
|
427 |
+
"id": "bapBiMocXam",
|
428 |
+
"label": "Symptom"
|
429 |
+
},
|
430 |
+
{
|
431 |
+
"name": "Bắp thối nhũn",
|
432 |
+
"description": "Khi nhiễm nặng thì nấm bệnh làm cho bắp thối nhũn",
|
433 |
+
"id": "bapThoiNhun",
|
434 |
+
"label": "Symptom"
|
435 |
+
},
|
436 |
+
{
|
437 |
+
"name": "Vết bệnh cháy nâu",
|
438 |
+
"description": "Vết bệnh cháy nâu, hình kim cương đến thon dài, có viền màu nâu xuất hiện đầu tiên trên lá thấp và sau đó từ từ di chuyển lên tán lá non.",
|
439 |
+
"id": "vetBenhChayNau",
|
440 |
+
"label": "Symptom"
|
441 |
+
},
|
442 |
+
{
|
443 |
+
"name": "Bạc màu",
|
444 |
+
"description": "Hiện tượng bạc màu hoàn toàn phần lớn phiến lá.",
|
445 |
+
"id": "laBacMau",
|
446 |
+
"label": "Symptom"
|
447 |
+
},
|
448 |
+
{
|
449 |
+
"name": "Lớp phủ màu xám",
|
450 |
+
"description": "Xuất hiện lớp phủ màu xám",
|
451 |
+
"id": "lopPhuMauXam",
|
452 |
+
"label": "Symptom"
|
453 |
+
},
|
454 |
+
{
|
455 |
+
"name": "Biến dạng",
|
456 |
+
"description": "Biến dạng",
|
457 |
+
"id": "bienDang",
|
458 |
+
"label": "Symptom"
|
459 |
+
},
|
460 |
+
{
|
461 |
+
"name": "Cây khô héo",
|
462 |
+
"description": "Tình trạng cây khô héo",
|
463 |
+
"id": "cayKhoHeo",
|
464 |
+
"label": "Symptom"
|
465 |
+
},
|
466 |
+
{
|
467 |
+
"name": "Thân cây bị gãy",
|
468 |
+
"description": "Thân cây bị gãy",
|
469 |
+
"id": "thanCayBiGay",
|
470 |
+
"label": "Symptom"
|
471 |
+
},
|
472 |
+
{
|
473 |
+
"name": "Héo tàn cây",
|
474 |
+
"description": "Héo tàn cây",
|
475 |
+
"id": "heoTanCay",
|
476 |
+
"label": "Symptom"
|
477 |
+
},
|
478 |
+
{
|
479 |
+
"name": "Vết sẹo trên lá",
|
480 |
+
"description": "Loại bỏ các mô lá xuống lớp biểu bì dưới, để lại những vết sẹo hoặc vệt trắng mỏng, dài",
|
481 |
+
"id": "vetSeoTrenLa",
|
482 |
+
"label": "Symptom"
|
483 |
+
},
|
484 |
+
{
|
485 |
+
"name": "vết bệnh mầu vàng trong",
|
486 |
+
"description": "Những chấm nhỏ mầu vàng trong trên phiến lá.",
|
487 |
+
"id": "vetBenhVang",
|
488 |
+
"label": "Symptom"
|
489 |
+
},
|
490 |
+
{
|
491 |
+
"name": "vệt bệnh to",
|
492 |
+
"description": "Các vết bệnh phát triển, liên kết với nhau thành những vệt bệnh to.",
|
493 |
+
"id": "vetBenhTo",
|
494 |
+
"label": "Symptom"
|
495 |
+
},
|
496 |
+
{
|
497 |
+
"name": "lá ngô khô",
|
498 |
+
"description": "Trong trường hợp bệnh nặng có thể làm lá ngô khô đi và cuộn lại.",
|
499 |
+
"id": "laNgoKho",
|
500 |
+
"label": "Symptom"
|
501 |
+
},
|
502 |
+
{
|
503 |
+
"name": "u nhỏ",
|
504 |
+
"description": "Trên những vết bệnh này xuất hiện những u nhỏ (giống như mụn cóc), bên trong chứa đầy chất bột màu rỉ sắt.",
|
505 |
+
"id": "munCoc",
|
506 |
+
"label": "Symptom"
|
507 |
+
},
|
508 |
+
{
|
509 |
+
"name": "vết bệnh màu đen",
|
510 |
+
"description": "Cuối giai đoạn sinh trưởng, vết bệnh chuyển thành màu đen.",
|
511 |
+
"id": "vetBenhDen",
|
512 |
+
"label": "Symptom"
|
513 |
+
},
|
514 |
+
{
|
515 |
+
"name": "Đốm tròn nhỏ, úa vàng",
|
516 |
+
"description": "Các đốm tròn nhỏ, úa vàng được tìm thấy ở gốc lá non",
|
517 |
+
"id": "domTronNhoUaVang",
|
518 |
+
"label": "Symptom"
|
519 |
+
},
|
520 |
+
{
|
521 |
+
"name": "Vệt mỏng, màu trắng ngả vàng",
|
522 |
+
"description": "Các vệt mỏng, màu trắng ngả vàng song song với gân lá",
|
523 |
+
"id": "vetManhMauTrangNgaVang",
|
524 |
+
"label": "Symptom"
|
525 |
+
},
|
526 |
+
{
|
527 |
+
"name": "Còi cọc",
|
528 |
+
"description": "Cây bị còi cọc",
|
529 |
+
"id": "cayCoiCoc",
|
530 |
+
"label": "Symptom"
|
531 |
+
},
|
532 |
+
{
|
533 |
+
"name": "Hoa và lõi ngô phát triển không hoàn chỉnh",
|
534 |
+
"description": "Hoa và lõi ngô phát triển không hoàn chỉnh",
|
535 |
+
"id": "hoaVaLoiNgoPhatTrienKhongHoanChinh",
|
536 |
+
"label": "Symptom"
|
537 |
+
},
|
538 |
+
{
|
539 |
+
"name": "Khả năng làm đầy hạt bị suy giảm",
|
540 |
+
"description": "Khả năng làm đầy hạt bị suy giảm",
|
541 |
+
"id": "khaNangLamDayHatSuyGiam",
|
542 |
+
"label": "Symptom"
|
543 |
+
},
|
544 |
+
{
|
545 |
+
"name": "Vết sọc hẹp dài ngắn khác nhau",
|
546 |
+
"description": "Các vết sọc hẹp dài ngắn khác nhau, có màu nâu cam hoặc nâu vàng cháy, phát triển trên lá",
|
547 |
+
"id": "vetSocHepDaiNganKhacNhau",
|
548 |
+
"label": "Symptom"
|
549 |
+
},
|
550 |
+
{
|
551 |
+
"name": "Trong mờ",
|
552 |
+
"description": "Các vết sọc trong mờ và có rìa lượn sóng và màu vàng nhạt",
|
553 |
+
"id": "vetSocTrongMo",
|
554 |
+
"label": "Symptom"
|
555 |
+
},
|
556 |
+
{
|
557 |
+
"name": "Chất nhờn rỉ ra",
|
558 |
+
"description": "Chất nhờn rỉ ra từ các phần lá bị nhiễm",
|
559 |
+
"id": "chatNhonRiRa",
|
560 |
+
"label": "Symptom"
|
561 |
+
},
|
562 |
+
{
|
563 |
+
"name": "Lá cà chua bị xoăn",
|
564 |
+
"description": "Lá cà chua bị xoăn, cuộn lại, thường hướng lên trên hoặc xuống dưới.",
|
565 |
+
"id": "laCaChuaBiXoan",
|
566 |
+
"label": "Symptom"
|
567 |
+
},
|
568 |
+
{
|
569 |
+
"name": "Lá bị biến dạng, nhỏ lại",
|
570 |
+
"description": "Lá bị biến dạng, nhỏ lại, có màu vàng hoặc xanh nhạt.",
|
571 |
+
"id": "laBienDangNhoLai",
|
572 |
+
"label": "Symptom"
|
573 |
+
},
|
574 |
+
{
|
575 |
+
"name": "Quả nhỏ, méo mó",
|
576 |
+
"description": "Quả nhỏ, méo mó hoặc không hình thành quả.",
|
577 |
+
"id": "quaNhoMeoMo",
|
578 |
+
"label": "Symptom"
|
579 |
+
},
|
580 |
+
{
|
581 |
+
"name": "lá vàng úa",
|
582 |
+
"description": "Lá vàng úa ở phần dưới của cây, bắt đầu từ các lá già và lan dần lên trên.",
|
583 |
+
"id": "laVangUa",
|
584 |
+
"label": "Symptom"
|
585 |
+
},
|
586 |
+
{
|
587 |
+
"name": "héo rũ",
|
588 |
+
"description": "Các lá có thể héo rũ, đặc biệt vào ban ngày khi nhiệt độ cao, nhưng có thể phục hồi tạm thời vào ban đêm.",
|
589 |
+
"id": "heoRu",
|
590 |
+
"label": "Symptom"
|
591 |
+
},
|
592 |
+
{
|
593 |
+
"name": "đốm tròn hoặc hình chữ V",
|
594 |
+
"description": "Các đốm tròn hoặc hình chữ V màu vàng xuất hiện trên lá, sau đó chuyển sang màu nâu và khô.",
|
595 |
+
"id": "domTronHinhChuV",
|
596 |
+
"label": "Symptom"
|
597 |
+
},
|
598 |
+
{
|
599 |
+
"name": "đổi màu bên trong",
|
600 |
+
"description": "Thân cây có thể bị đổi màu bên trong, với các mô mạch gỗ chuyển màu nâu hoặc đen khi cắt ngang.",
|
601 |
+
"id": "thanCayDoiMau",
|
602 |
+
"label": "Symptom"
|
603 |
+
},
|
604 |
+
{
|
605 |
+
"name": "đốm tròn, màu nâu",
|
606 |
+
"description": "Các đốm tròn, màu nâu hoặc đen, có kích thước từ 1-5 mm trên lá",
|
607 |
+
"id": "domTronMauNau",
|
608 |
+
"label": "Symptom"
|
609 |
+
},
|
610 |
+
{
|
611 |
+
"name": "viền vàng",
|
612 |
+
"description": "Các đốm này thường có viền vàng xung quanh",
|
613 |
+
"id": "vienVang",
|
614 |
+
"label": "Symptom"
|
615 |
+
},
|
616 |
+
{
|
617 |
+
"name": "lá vàng",
|
618 |
+
"description": "Hiện tượng lá vàng",
|
619 |
+
"id": "laVang",
|
620 |
+
"label": "Symptom"
|
621 |
+
},
|
622 |
+
{
|
623 |
+
"name": "rụng sớm",
|
624 |
+
"description": "Hiện tượng rụng sớm",
|
625 |
+
"id": "rungSom",
|
626 |
+
"label": "Symptom"
|
627 |
+
},
|
628 |
+
{
|
629 |
+
"name": "hoại tử mô lá",
|
630 |
+
"description": "Dẫn đến hoại tử mô lá",
|
631 |
+
"id": "hoaiTuMoLa",
|
632 |
+
"label": "Symptom"
|
633 |
+
},
|
634 |
+
{
|
635 |
+
"name": "đốm nâu hoặc đen trên lá",
|
636 |
+
"description": "Xuất hiện các đốm nâu hoặc đen trên lá, thường có vòng đồng tâm giống \"mắt bò\".",
|
637 |
+
"id": "domNauDenTrenLa",
|
638 |
+
"label": "Symptom"
|
639 |
+
},
|
640 |
+
{
|
641 |
+
"name": "lá bị khô, cháy và rụng",
|
642 |
+
"description": "Các đốm bệnh lan rộng, khiến lá bị khô, cháy và rụng sớm.",
|
643 |
+
"id": "laBiKhoChayRung",
|
644 |
+
"label": "Symptom"
|
645 |
+
},
|
646 |
+
{
|
647 |
+
"name": "vết nâu đen",
|
648 |
+
"description": "Thân và cuống lá có thể bị ảnh hưởng, xuất hiện các vết nâu đen.",
|
649 |
+
"id": "vetNauDenTrenThanCuongLa",
|
650 |
+
"label": "Symptom"
|
651 |
+
},
|
652 |
+
{
|
653 |
+
"name": "đốm đen, thối nhũn",
|
654 |
+
"description": "Quả cà chua có thể bị đốm đen, thối nhũn, đặc biệt khi bệnh nặng.",
|
655 |
+
"id": "domDenThoiNhunTrenQua",
|
656 |
+
"label": "Symptom"
|
657 |
+
},
|
658 |
+
{
|
659 |
+
"name": "Cây sinh trưởng kém",
|
660 |
+
"description": "Cây sinh trưởng kém",
|
661 |
+
"id": "caySinhTruongKem",
|
662 |
+
"label": "Symptom"
|
663 |
+
},
|
664 |
+
{
|
665 |
+
"name": "lá nhiễm bệnh chuyển sang màu vàng",
|
666 |
+
"description": "Lúc đầu các lá nhiễm bệnh chuyển sang màu vàng đến màu rơm, sau đó héo úa và chết đi.",
|
667 |
+
"id": "laNhiemBenhChuyenVang",
|
668 |
+
"label": "Symptom"
|
669 |
+
},
|
670 |
+
{
|
671 |
+
"name": "lá héo úa",
|
672 |
+
"description": "Lúc đầu các lá nhiễm bệnh chuyển sang màu vàng đến màu rơm, sau đó héo úa và chết đi.",
|
673 |
+
"id": "laHeoUa",
|
674 |
+
"label": "Symptom"
|
675 |
+
},
|
676 |
+
{
|
677 |
+
"name": "dải màu xanh nhạt và sũng nước",
|
678 |
+
"description": "Các dải màu xanh nhạt và sũng nước xuất hiện trước tiên trên lá.",
|
679 |
+
"id": "daiMauXanhNhatSungNuoc",
|
680 |
+
"label": "Symptom"
|
681 |
+
},
|
682 |
+
{
|
683 |
+
"name": "vết bệnh xuất hiện từ mép lá hoặc chóp lá",
|
684 |
+
"description": "Vết bệnh thường xuất hiện từ mép lá hoặc chóp lá sau đó lan dần xuống phía dưới và phía bên trong phiến lá.",
|
685 |
+
"id": "vetBenhXuatHienTuMepLaChopLa",
|
686 |
+
"label": "Symptom"
|
687 |
+
},
|
688 |
+
{
|
689 |
+
"name": "thương tổn màu vàng",
|
690 |
+
"description": "Khi các dải này xuất hiện, chúng hình thành các thương tổn màu vàng lớn hơn với các mép không đồng đều.",
|
691 |
+
"id": "thuongTonMauVang",
|
692 |
+
"label": "Symptom"
|
693 |
+
},
|
694 |
+
{
|
695 |
+
"name": "lá úa vàng",
|
696 |
+
"description": "Lá úa vàng, héo đi rồi chết.",
|
697 |
+
"id": "laUaVang",
|
698 |
+
"label": "Symptom"
|
699 |
+
},
|
700 |
+
{
|
701 |
+
"name": "giọt dịch vi khuẩn, khi mới xuất hiện màu trắng sữa",
|
702 |
+
"description": "Trên bề mặt lá và dọc theo ría vết bệnh , có thể quan sát thấy các giọt dịch vi khuẩn, khi mới xuất hiện màu trắng sữa do vi khuẩn rỉ và nhỏ ra từ các lá",
|
703 |
+
"id": "giotDichViKhuanMauTrangSua",
|
704 |
+
"label": "Symptom"
|
705 |
+
},
|
706 |
+
{
|
707 |
+
"name": "giọt dịch khô có màu vàng",
|
708 |
+
"description": "khi giọt dịch khô có màu vàng đến vàng đậm, lâu ngày có thể chuyển nâu",
|
709 |
+
"id": "giotDichKhoMauVang",
|
710 |
+
"label": "Symptom"
|
711 |
+
}
|
712 |
+
]
|
app/utils/prompt.py
CHANGED
@@ -103,3 +103,52 @@ Trả về danh sách ids của các thực thể Symptom được chọn, dư
|
|
103 |
}
|
104 |
```
|
105 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
}
|
104 |
```
|
105 |
"""
|
106 |
+
|
107 |
+
GET_STATEMENT_FROM_DISEASE_KG = """
|
108 |
+
Dựa trên thông tin từ Knowledge Graph:
|
109 |
+
$context
|
110 |
+
|
111 |
+
Hãy trả lời theo mẫu sau:
|
112 |
+
|
113 |
+
Câu trả lời nên ngắn gọn, mạch lạc và giống như cách con người nói chuyện.
|
114 |
+
"""
|
115 |
+
|
116 |
+
GET_STATEMENT_FROM_ENV_FACTORS_KG = """
|
117 |
+
Dựa trên thông tin từ Dữ liệu sau:
|
118 |
+
|
119 |
+
$context
|
120 |
+
|
121 |
+
Trong đó:
|
122 |
+
- indirect_env: Yếu tố môi trường gián tiếp ảnh hưởng đến bệnh, thông qua nguyên nhân cause
|
123 |
+
- direct_env: Yếu tố môi trường trực tiếp ảnh hưởng đến bệnh
|
124 |
+
|
125 |
+
Hãy trả lời theo mẫu sau:
|
126 |
+
(indirect_env) ... kích thích nguyên nhân gây bệnh ... tăng trưởng, một trong những tác nhân gây bệnh ... (trong trường hợp có cause)
|
127 |
+
(direct_env) ... tác động đến bệnh ... (trong trường hợp không có cause)
|
128 |
+
|
129 |
+
Câu trả lời nên ngắn gọn, mạch lạc và giống như cách con người nói chuyện.
|
130 |
+
"""
|
131 |
+
|
132 |
+
|
133 |
+
EXTRACT_NODES_FROM_TEXT_PROMPT = """
|
134 |
+
Từ văn bản mô tả được cung cấp, hãy chọn các thực thể có trong danh sách Thực thể (Node) được liệt kê ở bên dưới mô tả gần nhất nhất và tối đa 10 thực thể.
|
135 |
+
Nếu không có thực thể nào trong danh sách thoả mãn, hãy trả về danh sách rỗng.
|
136 |
+
|
137 |
+
Văn bản đầu vào:
|
138 |
+
$text
|
139 |
+
|
140 |
+
Danh sách thực thể:
|
141 |
+
$node_list
|
142 |
+
|
143 |
+
Trả về danh sách ids của các thực thể được chọn, dưới dạng JSON:
|
144 |
+
```json
|
145 |
+
{
|
146 |
+
"ids": [
|
147 |
+
"domNauDenTrenLa",
|
148 |
+
"laHeo",
|
149 |
+
"domNau",
|
150 |
+
...
|
151 |
+
]
|
152 |
+
}
|
153 |
+
```
|
154 |
+
"""
|