169 lines
15 KiB
Python
169 lines
15 KiB
Python
import json
|
||
from openai import OpenAI
|
||
from datetime import datetime
|
||
import os
|
||
import sys
|
||
|
||
current_file_path = os.path.abspath(__file__)
|
||
current_file_floder = os.path.dirname(current_file_path)
|
||
Path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(current_file_path))))
|
||
print(Path)
|
||
MassageRobot_Dobot_Path = os.path.dirname(Path)
|
||
sys.path.append(MassageRobot_Dobot_Path)
|
||
|
||
from VortXDB.client import VTXClient
|
||
|
||
class TrajectoryRecommender:
|
||
def __init__(self):
|
||
self.vtxdb = VTXClient()
|
||
self.Ali_OpenAI_api_key = self.vtxdb.get("robot_config", "Language.LLM.Ali_OpenAI_api_key")
|
||
self.Ali_OpenAI_BaseUrl = self.vtxdb.get("robot_config", "Language.LLM.Ali_OpenAI_BaseUrl")
|
||
self.client = OpenAI(api_key=self.Ali_OpenAI_api_key, base_url=self.Ali_OpenAI_BaseUrl)
|
||
self.body_part_prompts = self.load_body_part_prompts(os.path.join(current_file_floder, "trajectory_config/body_part_prompts.txt"))
|
||
self.shoulder_limit_prompts = self.load_body_part_prompts(os.path.join(current_file_floder, "trajectory_config/shoulder_limit_prompts.txt"))
|
||
self.back_limit_prompts = self.load_body_part_prompts(os.path.join(current_file_floder, "trajectory_config/back_limit_prompts.txt"))
|
||
self.waist_limit_prompts = self.load_body_part_prompts(os.path.join(current_file_floder, "trajectory_config/waist_limit_prompts.txt"))
|
||
self.belly_limit_prompts = self.load_body_part_prompts(os.path.join(current_file_floder, "trajectory_config/belly_limit_prompts.txt"))
|
||
self.leg_limit_prompts = self.load_body_part_prompts(os.path.join(current_file_floder, "trajectory_config/leg_limit_prompts.txt"))
|
||
|
||
self.task_mapping = {
|
||
"finger": "指疗通络",
|
||
"shockwave": "点阵按摩",
|
||
"roller": "滚滚刺疗",
|
||
"thermotherapy": "深部热疗",
|
||
"stone": "温砭舒揉",
|
||
"ball": "全能滚珠"
|
||
}
|
||
|
||
self.body_mapping = {
|
||
"back": "背部",
|
||
"belly": "腹部",
|
||
"waist": "腰部",
|
||
"shoulder": "肩颈",
|
||
"leg": "腿部"
|
||
}
|
||
|
||
def load_body_part_prompts(self,file_path):
|
||
try:
|
||
with open(file_path, 'r', encoding='utf-8') as f:
|
||
prompts = f.read()
|
||
return prompts
|
||
except Exception as e:
|
||
print(f"读取提示词文件失败:{e}")
|
||
return "背部,点按"
|
||
|
||
def model_output(self, messages, model='qwen2.5-7b-instruct', stream=False, timeout=10):
|
||
try:
|
||
completion = self.client.chat.completions.create(
|
||
model=model,
|
||
messages=messages,
|
||
stream=stream,
|
||
timeout=timeout
|
||
)
|
||
return completion
|
||
except Exception as e:
|
||
print(f"调用大模型时出错:{e}")
|
||
return {"error": f"调用大模型时出错:{e}"}
|
||
|
||
def process_user_input(self, input):
|
||
messages = [
|
||
{'role': 'system', 'content': self.body_part_prompts},
|
||
{'role': 'user', 'content': f"用户输入:{input}"},
|
||
{'role': 'user', 'content': "请根据用户输入推断出用户想要按摩的部位及按摩头选择"}
|
||
]
|
||
|
||
try:
|
||
completion = self.model_output(messages, model='qwen2.5-7b-instruct', stream=False)
|
||
if hasattr(completion, "model_dump_json"):
|
||
response_json = json.loads(completion.model_dump_json())
|
||
content_str = response_json['choices'][0]['message']['content']
|
||
else:
|
||
# 如果不是 OpenAI 风格对象,而是普通 dict
|
||
content_str = completion['choices'][0]['message']['content']
|
||
|
||
# 提取 JSON 数据块
|
||
json_text = content_str.strip()
|
||
if json_text.startswith("```json"):
|
||
json_text = json_text[7:]
|
||
if json_text.endswith("```"):
|
||
json_text = json_text[:-3]
|
||
body_and_header = json.loads(json_text.strip())
|
||
return body_and_header
|
||
|
||
except Exception as e:
|
||
print(f"解析JSON格式部位失败:{e}")
|
||
return {'body_part': '背部', 'choose_task': '深部热疗'}
|
||
|
||
def trajectory_generate(self,input):
|
||
body_and_header = self.process_user_input(input)
|
||
plan_body_part = body_and_header.get('body_part')
|
||
plan_task = body_and_header.get('choose_task')
|
||
# print(body_part)
|
||
# print(task)
|
||
if plan_body_part == '肩颈':
|
||
body_and_header['body_part'] = 'shoulder'
|
||
body_part_prompts = self.shoulder_limit_prompts
|
||
elif plan_body_part == '背部':
|
||
body_and_header['body_part'] = 'back'
|
||
body_part_prompts = self.back_limit_prompts
|
||
elif plan_body_part == '腰部':
|
||
body_and_header['body_part'] = 'waist'
|
||
body_part_prompts = self.waist_limit_prompts
|
||
elif plan_body_part == '腹部':
|
||
body_and_header['body_part'] = 'belly'
|
||
body_part_prompts = self.belly_limit_prompts
|
||
elif plan_body_part == '腿部':
|
||
body_and_header['body_part'] = 'leg'
|
||
body_part_prompts = self.leg_limit_prompts
|
||
else:
|
||
print("获取到的部位有误")
|
||
return "获取部位有误"
|
||
|
||
messages=[
|
||
{'role': 'system', 'content': body_part_prompts},
|
||
{'role': 'user', 'content': f"用户输入:{input}"},
|
||
{'role': 'user', 'content': f"部位、按摩头:{body_and_header}"},
|
||
{'role': 'user', 'content': "请根据用户输入及提供的部位、按摩头,生成该部位的中医理疗按摩手法轨迹,按摩穴位以用户输入内容的为参考,适当增加或减少,不允许违反规则生成"}]
|
||
|
||
try:
|
||
completion = self.model_output(messages,model='qwen-plus', stream=False,timeout=60)
|
||
print(completion.model_dump_json())
|
||
response_json = json.loads(completion.model_dump_json())
|
||
content_str = response_json['choices'][0]['message']['content']
|
||
# print("content_str:",content_str)
|
||
json_data = content_str.strip().strip('```json').strip()
|
||
massage_plan = json.loads(json_data)
|
||
except Exception as e:
|
||
print("解析JSON格式轨迹失败")
|
||
return "解析JSON格式轨迹失败"
|
||
|
||
try:
|
||
plan_timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
|
||
plan_name = f"{self.task_mapping[massage_plan['choose_task']]}-{self.body_mapping[massage_plan['body_part']]}-{massage_plan['title']}{plan_timestamp}"
|
||
plan_selection = f"按摩头以及部位选择:{self.task_mapping[massage_plan['choose_task']]}-{self.body_mapping[massage_plan['body_part']]}"
|
||
print("plan_name:",plan_name)
|
||
print("plan_selection:",plan_selection)
|
||
massage_plan['can_delete'] = True
|
||
self.vtxdb.set("massage_plan", plan_name, massage_plan)
|
||
result = {
|
||
"plan_name": plan_name,
|
||
"body_part": massage_plan['body_part'],
|
||
"choose_task": massage_plan['choose_task'],
|
||
"title": massage_plan['title'],
|
||
"plan_timestamp": plan_timestamp
|
||
}
|
||
print(result)
|
||
return result
|
||
|
||
except Exception as e:
|
||
print(f"检查参数服务器key格式或者没写进参数服务器{e}")
|
||
return "按摩手法记录失败,请重新生成"
|
||
|
||
if __name__ == '__main__':
|
||
trajectoryrecommender=TrajectoryRecommender()
|
||
input = """ "summary": "### 健康分析\n\n- **温度分布趋势**:从热图可以看出,人体上半身的温度分布呈现出由上至下逐渐降低的趋势,即头部和面部温度最高,肩部和上臂次之,胸部温度最低。这种温度分布符合人体正常的生理特点。\n \n- **无明显异常**:在正常相机拍摄的图像中未发现明显病症,在热图中也没有显示出局部温度异常升高的现象,因此可以认为该个体的上半身温度分布处于正常状态。\n\n### 健康等级评估\n\n- **总体健康等级**:🔵 **优秀**\n\n### 潜在风险\n\n- **潜在风险**:无明显异常,无需特别关注。 \n - 风险等级:无\n\n### 调理建议\n\n尽管目前温度分布正常,仍需注意保持良好的生活习惯,预防可能出现的问题。\n\n#### 推荐按摩部位:肩颈\n\n#### 推荐穴位(左右各选5,共10个)\n- 左侧:肩中左俞、肩外左俞、秉风左、天宗左、曲垣左\n- 右侧:肩中右俞、肩外右俞、秉风右、天宗右、附分右\n\n#### 按摩手法建议\n- **手法**:按揉、点按,每穴位3-5秒,重复3轮,每日早晚各1次。\n- **时长**:每次5-10分钟。\n\n#### 其他调理方式\n- **可行方案**:\n - 热敷:温热毛巾敷肩部10分钟,有助于缓解肌肉紧张。\n - 泡脚:每天晚上泡脚15分钟,促进全身血液循环。\n - 饮食调理:适量摄入富含蛋白质的食物,避免辛辣刺激性食物。\n- **需要避免**:\n - 长时间保持一个姿势不动,尤其是长时间伏案工作。\n - 寒凉饮食,避免受寒。\n\n### 综合评估\n\n- **总体健康等级**:🔵 **优秀**\n- **主要关注点**:无明显异常,但需维持良好的生活习惯以预防潜在问题。\n\n### 建议配合理疗机器人执行个性化按摩方案\n\n- **定期按摩保健**(重点穴位:肩中、秉风、天宗、附分)\n- **合理作息**,保持充足睡眠,避免熬夜。\n- **适当运动**,如肩部拉伸、颈部转动等,改善血液循环。\n- **饮食调理**,避免寒凉食物,适当补充温热食材。\n\n通过以上调理措施,可以进一步巩固身体健康,预防未来可能出现的问题。"""
|
||
input1 = """"summary": "### 健康分析\n\n🔍 中医分析:\n- **背部和肩部区域**温度较高,可能提示气血运行旺盛或局部炎症、寒湿积聚。根据《黄帝内经》所述,背部和肩部区域属于膀胱经和手足太阳经,气血运行不畅可能导致局部热量聚集。此外,长期久坐不动、工作压力大、寒湿侵袭等因素也可能导致此现象。\n- **头部区域**温度较高,符合人体正常生理现象,但也可能与情绪紧张、压力过大有关,影响肝气疏泄。\n\n### 健康等级评估\n\n- **背部和肩部区域**:🌡️ **中等偏下** (🟠)\n- **头部区域**:🌡️ **良好** (🟡)\n\n### 潜在风险\n\n- **背部和肩部区域**:可能存在肌肉紧张、疲劳、甚至颈椎问题的风险。长期下去,可能会引起肩颈疼痛、肌肉僵硬等问题,属于中度风险(⚠️⚠️)。\n- **头部区域**:由于温度较高,可能存在轻度情绪紧张、压力过大的风险,属于轻度风险(⚠️)。\n\n### 调理建议\n\n#### 主要关注部位:背部\n\n🌿 **推荐穴位(左右各选5,共10个)**:\n- 左侧:风门左、大杼左、肺俞左、厥阴左俞、心俞左\n- 右侧:风门右、大杼右、肺俞右、厥阴右俞、心俞右\n\n**按摩手法建议**:采用按揉、点按的手法,每穴位3-5秒,重复3轮,建议每日早晚各1次,可配合理疗机器人红外热敷辅助。\n\n✅ **其他调理方式**:\n- 热敷:温热毛巾敷背部10分钟,有助于缓解肌肉紧张。\n- 避免久坐,建议每小时起身活动肩颈部位2-3分钟。\n- 情绪管理:避免过度紧张,建议进行适当的放松训练或冥想。\n\n### 综合调理方案\n\n📍 **推荐按摩部位:背部**\n🌿 **推荐穴位(左右各选5,共10个)**:\n- 左侧:风门左、大杼左、肺俞左、厥阴左俞、心俞左\n- 右侧:风门右、大杼右、肺俞右、厥阴右俞、心俞右\n\n**按摩手法建议**:走线拍打 + 穴位按揉结合,每穴3-5秒,重复3轮,建议每日1~2次,配合艾灸与热敷效果更佳。\n\n✅ **综合调理方案**\n- 定期按摩保健(重点穴位:风门、大杼、肺俞、厥阴俞、心俞)\n- 合理作息,减少熬夜,避免情绪焦虑\n- 每日泡脚(艾草+生姜),增强下肢血液循环\n- 饮食清淡,避免油腻、寒凉食物,适当饮用莲子心茶、小米粥\n\n📌 **建议配合理疗机器人执行个性化按摩方案** 🏥🤖\n\n通过上述调理方案,可以有效改善背部和肩部的气血运行,缓解肌肉紧张,预防相关健康问题的发生。"""
|
||
input2 = """ "summary": "### **健康分析**\n- **背部整体温度较高**:根据温度分布,背部整体温度较高,颜色以黄色和红色为主,这可能提示该区域气血运行较为旺盛或存在局部热邪积聚。\n- **肩胛骨区域温度较低**:肩胛骨附近的温度较低,颜色较浅,可能与该区域肌肉活动较少或血液循环相对较弱有关。\n- **腰部温度显著升高**:腰部区域温度明显较高,颜色偏红,可能提示该区域气血运行活跃或存在局部炎症。\n- **手臂和手部温度较高**:尤其是手部的高温点,可能与手部的血液循环或活动有关。\n\n### **健康等级评估**\n- **总体健康等级**:🟡 **中等**\n\n### **潜在风险**\n- **轻度风险**:\n - 背部及腰部温度较高可能引起局部不适或炎症,长期可能影响相关经络的功能。\n - 手部的高温点可能提示局部血液循环过盛或活动过度,需注意防止过度疲劳。\n\n### **调理建议**\n#### **主要按摩部位**:背部\n\n#### **推荐穴位(≥10个)**\n- **左侧**:肺俞左、厥阴左俞、心俞左、督俞左、魄户左、膏肓左、神堂左、譩譆左、膈关左、膈俞左\n- **右侧**:肺俞右、厥阴右俞、心俞右、督俞右、魄户右、膏肓右、神堂右、譩譆右、膈关右、膈俞右\n\n#### **按摩手法与时长**\n- **手法**:按揉、点按,每穴位3-5秒,重复3轮,每日早晚各1次。\n- **时长**:每次5-10分钟。\n\n#### **其他调理方式**\n- **可行方案**:\n - 泡脚:每天泡脚15分钟,使用温热水加入一些艾叶或生姜,有助于全身血液循环。\n - 热敷:使用热敷袋对肩胛骨区域进行热敷,每次15分钟,有助于改善局部血液循环。\n - 饮食调理:避免寒凉食物,多吃温热性食物,如姜汤、羊肉等。\n- **需要避免**:\n - 避免长时间保持一个姿势不动,每小时起身活动5-10分钟。\n - 减少剧烈运动或重体力劳动,以免加重局部负担。\n\n### **综合调理方案**\n- **定期按摩保健**:重点穴位包括肺俞、心俞、膏肓、膈俞等,每天早晚各一次。\n- **合理作息**:保证充足的睡眠,避免熬夜,减少精神压力。\n- **日常保养**:每天泡脚15分钟,使用温热水加入艾叶或生姜,有助于改善全身血液循环。\n- **饮食调理**:避免寒凉食物,多吃温热性食物,如姜汤、羊肉等。\n\n### **总结**\n通过上述综合调理方案,可以有效改善背部及腰部的气血运行,缓解局部不适,预防潜在风险。同时,注意日常生活中的保养措施,避免不良生活习惯,以维持良好的身体健康状态。"""
|
||
# body_and_header = trajectoryrecommender.process_user_input(input2)
|
||
# print(body_and_header)
|
||
trajectoryrecommender.trajectory_generate(input2) |