import gradio as gr from huggingface_hub import InferenceClient import os os.environ["HF_ENDPOINT"] = "https://hf-mirror.com" # 中国大陆加速 # 部署后查看 Logs 标签页的输出 import sys from importlib.util import find_spec def verify_environment(): # 检查 Python 版本 if sys.version_info < (3, 7): raise RuntimeError("需要 Python 3.7 或更高版本") # 检查关键依赖 for package in ["tenacity", "gradio"]: if not find_spec(package): raise ModuleNotFoundError(f"缺失关键依赖: {package}") # 检查环境变量 if "HF_TOKEN" not in os.environ: print("警告: 未设置HF_TOKEN环境变量,模型调用可能会失败") # 打印版本信息 try: from importlib.metadata import version print(f"Tenacity 版本: {version('tenacity')}") print(f"Gradio 版本: {version('gradio')}") except ImportError: from pkg_resources import get_distribution print(f"Tenacity 版本: {get_distribution('tenacity').version}") print(f"Gradio 版本: {get_distribution('gradio').version}") if __name__ == "__main__": verify_environment() # 使用 Hugging Face Inference API 调用云端模型(无需本地加载) import os from tenacity import retry, stop_after_attempt, wait_exponential # 安全地获取token,如果不存在则使用空字符串 hf_token = os.environ.get("HF_TOKEN", "") client = InferenceClient(token=hf_token) @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10)) def safe_model_call(prompt): try: print(f"尝试调用模型,使用token长度: {len(hf_token)}") print(f"使用的HF_ENDPOINT: {os.environ.get('HF_ENDPOINT', '默认')}") # 优先使用通用大模型,因为它们生成能力更强 try: # 首先尝试使用通用大模型 return client.text_generation( prompt=prompt, model="meta-llama/Llama-2-70b-chat-hf", # 强大的通用大模型 max_new_tokens=500, # 增加输出长度 temperature=0.7, # 适中的温度,平衡创造性和准确性 repetition_penalty=1.1, do_sample=True, top_p=0.9 ) except Exception as llama_error: print(f"Llama模型调用失败: {str(llama_error)}") # 尝试使用另一个通用大模型 try: return client.text_generation( prompt=prompt, model="Qwen/Qwen-72B-Chat", # 阿里的大模型,支持中文 max_new_tokens=500, temperature=0.7, repetition_penalty=1.1 ) except Exception as qwen_error: print(f"Qwen模型调用失败: {str(qwen_error)}") # 尝试使用医疗专业模型 try: return client.text_generation( prompt=prompt, model="epfl-llm/meditron-7b", # 医疗领域专用模型 max_new_tokens=300, temperature=0.3, repetition_penalty=1.2, do_sample=True, top_p=0.9 ) except Exception as meditron_error: print(f"Meditron模型调用失败: {str(meditron_error)}") # 最后尝试使用小模型 return client.text_generation( prompt=prompt, model="bigscience/bloomz-7b1", # 备选 max_new_tokens=300, temperature=0.5, repetition_penalty=1.2 ) except Exception as e: error_type = type(e).__name__ error_msg = str(e) print(f"模型调用失败: {error_type} - {error_msg}") # 检查是否是认证错误 if "401" in error_msg or "unauthorized" in error_msg.lower() or "authentication" in error_msg.lower(): print("可能是认证问题,请检查HF_TOKEN是否正确设置") # 检查是否是网络错误 elif "timeout" in error_msg.lower() or "connection" in error_msg.lower(): print("可能是网络连接问题") # 检查是否是模型不可用 elif "not found" in error_msg.lower() or "404" in error_msg: print("模型可能不存在或不可用") raise # 添加一个简单的本地备用模式 def local_fallback_response(query): """当API调用失败时提供基本的本地响应""" query = query.lower() # 处理烫伤情况 if any(keyword in query for keyword in ["烫伤", "烧伤", "烫到", "烫着"]): return """对于烫伤的紧急处理,请按以下步骤操作: **第一步:立即冷却** 1. 立即将烫伤部位置于冷自来水下冲洗10-15分钟 2. 水温应为凉水或微凉水,不要使用冰水或冰块(可能会加重组织损伤) 3. 如果无法将烫伤部位放在水下,可以用浸湿的冷毛巾敷在烫伤处 **第二步:评估烫伤程度** - 一度烫伤:皮肤发红,轻微肿胀,有疼痛感 - 二度烫伤:皮肤起水泡,明显红肿,疼痛明显 - 三度烫伤:皮肤呈白色、棕色或黑色,可能没有疼痛感(因为神经已损伤) **第三步:处理伤口** 1. 轻度烫伤(一度): - 冷却后,可以涂抹芦荟凝胶或专用烫伤药膏 - 用干净的纱布轻轻覆盖 2. 中度烫伤(二度): - 不要刺破水泡 - 用干净的纱布轻轻覆盖 - 不要使用棉花或有绒毛的材料 3. 严重烫伤(三度): - 立即就医,不要自行处理 **禁忌事项**: - 不要在烫伤处涂抹牙膏、酱油、油脂等民间偏方 - 不要刺破水泡 - 不要使用冰块直接接触烫伤处 - 不要在严重烫伤处涂抹任何药物,应立即就医 **何时就医**: - 任何三度烫伤 - 面积较大的二度烫伤(大于手掌大小) - 烫伤位于面部、手、脚、生殖器或关节处 - 烫伤后出现感染迹象(如红肿加剧、有脓液、发热) - 婴幼儿的任何烫伤 这些是基本的急救措施,如果情况严重,请立即就医。""" # 处理呛水/窒息情况 if any(keyword in query for keyword in ["呛水", "窒息", "噎住", "喉咙卡"]): return """对于呛水或窒息的紧急处理,请按以下步骤操作: **呛水处理**: 1. 如果孩子能够咳嗽、说话或呼吸: - 鼓励他们咳嗽,帮助排出呛入的水 - 不要拍打背部,让自然咳嗽将水排出 - 密切观察呼吸情况 2. 如果孩子无法咳嗽、说话或呼吸(窒息): - 对于1岁以上儿童:执行海姆立克急救法(腹部冲击法) a. 站在孩子身后,双臂环抱孩子腰部 b. 一只手握拳,拇指侧抵住孩子上腹部(肚脐上方,胸骨下方) c. 另一只手抓住拳头 d. 快速向内上方挤压5次 e. 重复直到异物排出或孩子失去意识 - 对于1岁以下婴儿: a. 将婴儿面朝下放在您的前臂上,头低于躯干 b. 用手掌根部在婴儿背部肩胛骨之间拍打5次 c. 如果异物未排出,将婴儿翻过来,面朝上放在您的前臂上 d. 用两根手指在胸骨中央(乳头连线下方)按压5次 e. 交替进行背部拍打和胸部按压,直到异物排出 3. 如果孩子失去意识: - 立即拨打急救电话 - 开始心肺复苏(CPR) **窒息处理**(食物或异物): - 步骤与上述呛水窒息处理相同 **注意事项**: - 任何严重呛水事件后,即使症状消失,也应就医检查 - 如果孩子在呛水后出现呼吸困难、持续咳嗽、发热或异常嗜睡,应立即就医 - 预防呛水:监督儿童游泳,教导安全饮食习惯,避免在进食时玩耍或奔跑 这些是基本的急救措施,如果情况严重,请立即就医或拨打急救电话。""" # 处理发烧情况 if any(keyword in query for keyword in ["发烧", "发热", "体温高"]): return """对于儿童发烧的处理,请按以下指导操作: **评估体温**: - 轻度发热:37.5°C-38°C - 中度发热:38.1°C-39°C - 高热:39.1°C以上 **家庭处理措施**: 1. **保持水分摄入**: - 鼓励孩子多喝水,防止脱水 - 可以提供稀释的果汁或电解质饮料 2. **物理降温**: - 穿着轻薄、透气的衣物 - 保持室温舒适,不要过热 - 可以用温水(不是冷水)擦拭额头、腋下、颈部和腹股沟 - 避免使用酒精擦拭 3. **药物降温**(在医生指导下): - 对于38.5°C以上的发热,可以考虑使用对乙酰氨基酚或布洛芬 - 严格按照年龄和体重给药 - 不要同时使用多种退热药 - 不要给18岁以下儿童使用阿司匹林(可能导致瑞氏综合征) **何时就医**: - 3个月以下婴儿:任何发热都应立即就医 - 3-6个月婴儿:体温超过38°C - 6个月-2岁儿童:体温超过39°C,或发热持续超过24小时 - 任何年龄: - 发热伴随剧烈头痛、颈部僵硬、皮疹、呼吸困难、持续呕吐或腹泻 - 孩子异常嗜睡、烦躁或对周围环境反应迟钝 - 发热持续超过3天 - 孩子看起来非常不适或您感到担忧 **注意事项**: - 发热本身是身体对抗感染的自然反应,不一定需要立即降温 - 观察孩子的整体状态比单纯看体温更重要 - 确保孩子充分休息 - 记录体温变化、用药情况和其他症状,以便向医生报告 这些是基本的家庭护理建议,如有疑虑,请咨询医生。""" # 处理擦伤、流血等急救情况 if any(keyword in query for keyword in ["擦伤", "擦破", "流血", "出血", "伤口", "摔倒", "摔伤"]): return """对于擦伤和轻微流血的紧急处理,请按以下步骤操作: **第一步:保持冷静** - 安抚小孩情绪,保持冷静 **第二步:清洁伤口** 1. 用清水或生理盐水轻轻冲洗伤口,去除污垢和异物 2. 如果没有流动水,可以使用干净的瓶装水 3. 用温和的肥皂和水清洗伤口周围的皮肤,但避免肥皂直接接触开放性伤口 **第三步:止血** 1. 用干净的纱布或干净的布轻轻按压伤口 2. 保持压力约5-10分钟,直到出血停止 3. 如果血液浸透了纱布,不要移除它,而是在上面再加一层 **第四步:消毒处理** 1. 使用医用酒精、碘伏或双氧水等消毒液轻轻擦拭伤口周围(不要直接涂在开放性伤口上) 2. 可以使用无刺激性的抗菌药膏涂抹在伤口上 **第五步:包扎保护** 1. 用干净的创可贴或纱布覆盖伤口 2. 如果是较大的伤口,使用绷带轻轻包扎,但不要太紧 **注意事项**: - 如果伤口较深、面积较大、异物无法清除,或者持续出血超过15分钟,应立即就医 - 观察伤口是否有感染迹象(如红肿、疼痛加剧、有脓液或发热),如有这些症状应及时就医 - 确认小孩的破伤风疫苗接种情况,如果超过5年未接种且伤口较深或被污染,应咨询医生是否需要接种破伤风疫苗 这些是基本的急救措施,如果情况严重,请立即就医。""" # 详细的失眠响应 if "失眠" in query or "睡不着" in query or "睡眠" in query: days_match = None if "三天" in query or "3天" in query: days_match = "三天" elif "两天" in query or "2天" in query: days_match = "两天" elif "一周" in query or "7天" in query: days_match = "一周" elif "长期" in query or "慢性" in query: days_match = "长期" response = f"""关于{'持续'+days_match+'的' if days_match else ''}失眠问题,我可以提供以下专业建议: **症状分析**: 失眠是指难以入睡、维持睡眠困难、早醒或睡眠质量差的情况。{'连续'+days_match+'的失眠可能会导致白天疲劳、注意力不集中、情绪波动等问题。' if days_match else '失眠会导致白天疲劳、注意力不集中、情绪波动等问题。'} **可能的原因**: 1. 心理因素:压力、焦虑、抑郁或其他情绪问题 2. 生活习惯:不规律的睡眠时间、白天小睡过多 3. 环境因素:噪音、光线、温度不适宜 4. 电子设备使用:睡前使用手机、电脑等发光设备 5. 饮食因素:睡前摄入咖啡因、酒精或大量食物 6. 身体不适:疼痛、呼吸问题或其他身体不适 **建议措施**: 1. **建立规律的睡眠时间表**: - 每天同一时间上床和起床,包括周末 - 避免白天长时间小睡,如需小睡,控制在30分钟以内 2. **优化睡眠环境**: - 保持卧室安静、黑暗和凉爽 - 使用舒适的床垫和枕头 - 考虑使用白噪音机器或耳塞来屏蔽干扰噪音 3. **改善睡前习惯**: - 睡前1-2小时避免使用电子设备 - 建立放松的睡前仪式,如温水浴、阅读、冥想或轻柔的伸展运动 - 避免睡前进行激烈运动或处理紧张事务 4. **注意饮食**: - 睡前4-6小时避免摄入咖啡因 - 睡前避免大量饮水,减少夜间起床 - 睡前避免大量或重口味食物 - 限制酒精摄入,虽然酒精可能帮助入睡,但会影响睡眠质量 5. **放松技巧**: - 尝试深呼吸练习:吸气4秒,屏息7秒,呼气8秒 - 渐进性肌肉放松:依次绷紧然后放松身体各部位肌肉 - 引导冥想或正念练习 **何时就医**: - {'由于失眠已持续'+days_match+',建议咨询医生,特别是如果它影响了您的日常生活和工作' if days_match else '如果失眠持续超过两周,或严重影响日常生活,应咨询医生'} - 如果失眠伴随其他症状,如呼吸暂停、剧烈打鼾、夜间出汗、心悸等 - 如果您怀疑失眠可能与其他健康问题或药物副作用有关 **预防建议**: - 保持规律的体育锻炼,但避免睡前3小时内进行 - 管理日间压力,可以通过冥想、瑜伽或其他放松技巧 - 限制白天的咖啡因摄入 - 保持健康的生活方式和饮食习惯 希望这些信息对您有所帮助。请记住,这只是一般性建议,不能替代专业医疗咨询。如果失眠问题持续或严重,建议咨询医生或睡眠专家。""" return response # 详细的头痛响应 if "头痛" in query: days_match = None if "三天" in query or "3天" in query: days_match = "三天" elif "两天" in query or "2天" in query: days_match = "两天" elif "一天" in query or "1天" in query: days_match = "一天" response = f"""关于{'持续'+days_match+'的' if days_match else ''}头痛问题,我可以提供以下建议: **可能的原因**: - 紧张性头痛:由压力、焦虑或肌肉紧张引起 - 偏头痛:常伴有对光、声音敏感,有时伴随恶心 - 脱水:体内水分不足可导致头痛 - 睡眠不足或睡眠质量差 - 眼睛疲劳:长时间用眼或需要更新眼镜处方 - 感染:如感冒、流感或鼻窦感染 **建议措施**: 1. 休息:在安静、黑暗的房间休息 2. 水分补充:确保充分饮水 3. 热/冷敷:在疼痛部位使用热敷或冷敷 4. 按摩:轻轻按摩太阳穴或颈部 5. 非处方止痛药:如对乙酰氨基酚或布洛芬(请按说明使用) 6. 减轻压力:尝试放松技巧如深呼吸或冥想 **注意事项**: - {'由于头痛已持续'+days_match+',建议咨询医生' if days_match else '如果头痛持续超过3天,应咨询医生'} - 如果头痛非常剧烈、突然发作或伴随其他症状(如发热、颈部僵硬、视力问题、意识混乱),请立即就医 - 定期头痛需要专业医生评估 希望这些信息对您有所帮助。请记住,这只是一般性建议,不能替代专业医疗咨询。""" return response # 其他关键词匹配 responses = { "发烧": """关于发热问题: **可能的原因**: - 感染(病毒、细菌) - 免疫反应 - 疫苗接种后反应 - 其他炎症反应 **建议措施**: 1. 休息:保持充分休息 2. 水分补充:多喝水防止脱水 3. 降温:使用退热药物(如对乙酰氨基酚) 4. 轻便衣物:穿着轻便,避免过热 **注意事项**: - 如果体温超过38.5°C,可以使用退烧药 - 高烧(39°C以上)或持续发热超过3天应就医 - 如果发热伴随严重症状(如呼吸困难、剧烈头痛、意识模糊),请立即就医 请记住,这只是一般性建议,不能替代专业医疗咨询。""", "咳嗽": """关于咳嗽问题: **可能的原因**: - 上呼吸道感染(感冒、流感) - 过敏 - 哮喘 - 胃酸反流 - 环境刺激物 **建议措施**: 1. 保持水分摄入:多喝温水 2. 使用蜂蜜柠檬水:可缓解喉咙刺激 3. 湿度:使用加湿器增加空气湿度 4. 非处方止咳药:根据咳嗽类型选择 **注意事项**: - 如果咳嗽持续超过2周,应咨询医生 - 如果咳嗽伴有血痰、呼吸困难、高热或胸痛,请立即就医 - 夜间咳嗽加重或影响睡眠也需要医疗关注 请记住,这只是一般性建议,不能替代专业医疗咨询。""", "疫苗": "疫苗接种后出现接种部位疼痛、轻微发热是正常反应,通常会在几天内消失。如出现严重过敏反应或高烧,应立即就医。", "感冒": "感冒通常会自行痊愈,建议多休息、多喝水、可使用非处方药缓解症状。如症状加重或持续一周以上,请咨询医生。", "腹痛": "腹痛可能由多种原因引起,如消化不良、胃肠炎等。建议注意饮食、避免辛辣刺激食物。如果疼痛剧烈或伴随其他症状,请咨询医生。", "过敏": "避免接触过敏原,可使用抗组胺药缓解症状。如果出现呼吸困难等严重症状,请立即就医。" } # 检查查询中是否包含关键词 for keyword, response in responses.items(): if keyword in query: return response # 默认回复 return """您好,我是AI医疗助手。我可以提供一些基本的健康建议,但不能替代专业医生的诊断。 为了给您提供更有针对性的建议,请尽量详细描述您的症状,包括: - 症状的具体表现 - 持续时间 - 是否有加重或缓解因素 - 是否尝试过任何缓解方法 对于任何严重或持续的健康问题,建议您咨询专业医生获取准确诊断和治疗方案。""" def medical_chat(user_input, history): # 检查是否是紧急情况,如果是,直接使用本地备用响应 emergency_keywords = ["摔倒", "摔伤", "流血", "出血", "擦伤", "擦破", "伤口", "烫伤", "烧伤", "烫到", "烫着", "呛水", "窒息", "噎住", "喉咙卡", "急救", "紧急", "立即", "马上"] if any(keyword in user_input.lower() for keyword in emergency_keywords): print(f"检测到紧急情况关键词,直接使用本地备用响应") return local_fallback_response(user_input) # 构建更详细的医学对话提示词,针对通用大模型进行优化 system_prompt = """你是一位经验丰富的医生,专注于提供准确、客观、专业且详细的医疗建议。 请根据患者描述的症状,提供科学的建议和可能的解决方案。 你的回答应该: 1. 基于医学事实和科学证据 2. 详细全面,包含充分的解释和建议 3. 使用通俗易懂的语言,避免过于专业的术语 4. 在必要时建议患者就医 5. 不做确定性的诊断,因为这需要面诊和检查 6. 不推荐具体的药品品牌 7. 不要说"给你开药",因为你不能开处方 8. 提供深入的分析和多方面的建议,而不是简单的答复 回答结构应包含: - 症状分析:解释患者描述的症状可能意味着什么 - 可能的原因:列出几种可能导致这些症状的常见原因 - 建议措施:提供3-5个具体的自我管理建议 - 何时就医:明确说明在什么情况下患者应该寻求专业医疗帮助 - 预防建议:如何预防类似问题再次发生 对于紧急情况(如外伤、烫伤、窒息等),请提供清晰的急救步骤和注意事项。 请记住,你的建议仅供参考,不能替代专业医生的面诊。每个回答都应该全面、详细、有条理,就像一位真正的医生会提供的那种深入建议。""" # 构建完整的提示词 prompt = f"{system_prompt}\n\n患者:{user_input}\n医生:" try: # 尝试调用云端模型 print(f"发送到模型的提示: {prompt}") # 检查是否有有效的token if not hf_token.strip(): print("HF_TOKEN未设置,使用本地备用模式") return local_fallback_response(user_input) response = safe_model_call(prompt) print(f"模型原始响应: {response}") # 检查响应是否为空 if not response: print("模型返回空响应,使用本地备用模式") return local_fallback_response(user_input) # 检查响应类型并适当处理 if isinstance(response, str): # 如果响应是字符串,直接处理 doctor_response = response else: # 如果响应是其他类型的对象,尝试获取文本内容 # 这取决于InferenceClient的返回类型 print(f"响应类型: {type(response)}") try: # 尝试不同的属性或方法来获取文本 if hasattr(response, 'generated_text'): doctor_response = response.generated_text elif hasattr(response, 'text'): doctor_response = response.text else: # 尝试将响应转换为字符串 doctor_response = str(response) except Exception as e: print(f"处理响应时出错: {str(e)},使用本地备用模式") return local_fallback_response(user_input) print(f"处理后的响应: {doctor_response}") # 增强响应质量检测 low_quality_indicators = [ "没药", "不知道", "开点", "开药", "处方药", "非处方药", "既然是", "那就", "我就给你", "吧", "呢", "哦", "呀", "简单", "随便", "试试看", "看看", "应该没事" ] # 检查响应质量 if len(doctor_response.strip()) < 100: # 增加最小长度要求 print(f"响应太短: '{doctor_response}',使用本地备用模式") return local_fallback_response(user_input) # 检查是否包含低质量指标 for indicator in low_quality_indicators: if indicator in doctor_response: print(f"响应包含低质量指标 '{indicator}': '{doctor_response}',使用本地备用模式") return local_fallback_response(user_input) # 检查是否包含足够的医疗建议内容 medical_advice_indicators = ["建议", "可以", "应该", "如果", "症状", "原因", "方法", "帮助", "改善"] has_medical_advice = any(indicator in doctor_response for indicator in medical_advice_indicators) if not has_medical_advice: print(f"响应缺乏医疗建议: '{doctor_response}',使用本地备用模式") return local_fallback_response(user_input) # 如果响应中没有"医生:",则直接返回整个响应 if "医生:" not in doctor_response: # 添加安全过滤 if "死亡" in doctor_response or "癌症" in doctor_response: return "⚠️ 请及时联系线下医疗机构进行专业诊断!" return doctor_response # 提取医生回复部分 doctor_response = doctor_response.split("医生:")[-1].strip() # 添加安全过滤 if "死亡" in doctor_response or "癌症" in doctor_response: return "⚠️ 请及时联系线下医疗机构进行专业诊断!" return doctor_response except Exception as e: print(f"调用模型时出错: {str(e)},使用本地备用模式") return local_fallback_response(user_input) # 构建 Gradio 界面 with gr.Blocks(theme=gr.themes.Soft(), css=""" /* 使用CSS选择器定位提交按钮并将其移到右侧 */ .gradio-container .submit-btn { position: absolute; right: 10px; bottom: 10px; } """) as demo: gr.Markdown("# 🏥 专业医疗咨询助手") gr.Markdown("### 本系统提供基于AI的医疗咨询服务,仅供参考,不能替代专业医生的诊断") with gr.Column(): gr.Markdown("### 请描述您的症状或健康问题") chat_interface = gr.ChatInterface( fn=medical_chat, examples=[ "咳嗽一周了,有什么缓解方法?", "经常失眠怎么调理?", "孩子有轻微发烧,需要去医院吗?" ], title="症状咨询", chatbot=gr.Chatbot(height=500) ) with gr.Accordion("医疗免责声明", open=True): gr.Markdown(""" ### 📋 医疗免责声明 1. 本系统提供的信息仅供参考,不构成医疗建议、诊断或治疗方案 2. 本系统不能替代专业医疗人员的面诊和专业判断 3. 如遇紧急情况,请立即前往医院就诊或拨打急救电话 4. 系统可能无法识别所有医疗紧急情况,请谨慎使用 5. 使用本系统即表示您理解并接受以上声明 """) with gr.Accordion("常见医疗问题", open=False): gr.Markdown(""" ### 常见医疗问题解答 **头痛** - 轻度头痛可以休息、按摩太阳穴或服用非处方止痛药 - 如果头痛剧烈、持续时间长或伴随其他症状,请咨询医生 **发热** - 轻度发热(38°C以下)可多喝水、休息并使用退烧药 - 高烧(38°C以上)或持续发热超过3天应就医 **咳嗽** - 保持水分摄入,可使用非处方止咳药 - 如果咳嗽持续超过2周或伴有血痰,请咨询医生 **疫苗接种后反应** - 接种部位疼痛、轻微发热是正常反应 - 如出现严重过敏反应或高烧,应立即就医 """) with gr.Accordion("使用说明", open=False): gr.Markdown(""" ### 💡 使用说明 1. 请简明扼要地描述您的症状或健康问题 2. 尽量提供症状的持续时间、严重程度等相关信息 3. 系统会根据您的描述提供一般性的健康建议 4. 如果系统无法提供有用的建议,请尝试重新描述您的问题 5. 对于复杂或严重的健康问题,请务必咨询专业医生 """) with gr.Accordion("系统状态", open=False): hf_token_status = "✅ 已设置" if "HF_TOKEN" in os.environ and os.environ.get("HF_TOKEN", "").strip() else "❌ 未设置" gr.Markdown(f"- HF_TOKEN: {hf_token_status}") gr.Markdown(f"- HF_ENDPOINT: {os.environ.get('HF_ENDPOINT', '默认')}") if hf_token_status == "❌ 未设置": gr.Markdown(""" ### ⚠️ 警告:未设置HF_TOKEN 请在Hugging Face Spaces的设置中添加HF_TOKEN环境变量。 1. 前往 [Hugging Face](https://huggingface.co/settings/tokens) 创建访问令牌 2. 在Spaces设置中添加环境变量HF_TOKEN,值为你的访问令牌 3. 重新部署应用 """) # 启动应用(Hugging Face Spaces 会自动处理) print("启动应用...") demo.launch(debug=True) # 启用调试模式以获取更多错误信息