一、系统概述
本系统是一套基于SKILL技能架构、聚焦糖尿病 + 高血压双慢病管理的全栈智能体,整合了专业医学大模型(AntAngelMed)、前后端实时交互、模块化技能体系,专为慢病患者、社区医护人员、家庭健康管理者设计,提供精准、专业、可落地的慢病咨询与管理服务。
系统核心优势的在于“技能化拆分、模块化扩展”,将慢病管理的核心能力(如血糖评估、血压解读、饮食指导、用药提醒等)拆分为标准化SKILL技能单元,每个技能独立开发、独立迭代、可动态加载,既保证了医学建议的专业性,又兼顾了系统的可扩展性和可维护性,彻底解决传统慢病咨询“响应慢、不精准、功能零散”的痛点。
同时,系统采用标准的AntAngelMed医学模型调用格式,确保所有医学建议均符合临床规范,避免非专业误导;前端设计简洁直观,适配不同年龄段用户(尤其是中老年慢病患者),操作便捷,无需专业技术基础即可轻松使用;后端基于 FastAPI+WebSocket 实现实时对话,无延迟交互,让用户获得一对一专属慢病顾问的体验。
早前我们通过普通调用的方式也实现慢病管理的基础智能体,可以结合对比看看基于SKILL做了哪些特性应用变更:
《大模型应用:基于安诊儿AntAngelMed模型+FastAPI构建慢病管理AI助手.86》
二、核心功能
- 实时慢病咨询:针对糖尿病、高血压相关问题,提供 7x24 小时实时响应,涵盖血糖、血压解读、症状分析、风险预警等。
- 个性化指导:根据用户提问,结合医学模型生成个性化饮食、运动、用药建议,适配不同患者的身体状况,如糖尿病合并高血压、老年患者、肥胖患者等。
- 技能化交互:基于 SKILL 架构,自动匹配用户需求与对应技能,确保建议精准、聚焦,避免无关信息干扰。
- 可扩展能力:支持动态新增 SKILL 技能,如体检报告解读、并发症预防、慢病随访提醒等,无需修改核心代码,快速适配业务升级。
- 简洁可视化:前端界面清晰易懂,对话记录可追溯,方便用户反复查看医学建议,也便于医护人员了解患者咨询情况。
功能适配的应用场景:
- 个人慢病管理:糖尿病、高血压患者日常咨询,如血糖或血压异常解读、饮食运动疑问、用药困惑等。
- 社区医疗服务:社区医护人员辅助工具,快速响应居民慢病咨询,减轻工作负担。
- 家庭健康监护:家属为老人咨询慢病护理知识,获取专业、可操作的护理建议。
- 慢病科普教育:用户主动了解糖尿病、高血压的预防、护理、并发症控制等知识。
三、项目架构
1. 整体架构
分层清晰,贴合 SKILL 体系:
- 前端层:静态网页(HTML+CSS+JS),提供实时对话界面,支持键盘输入、点击发送,适配PC端、移动端,交互流畅。
- 通信层:WebSocket 长连接,实现前端与后端的全双工实时通信,确保对话无延迟、无刷新,提升用户体验。
- 后端层:FastAPI 框架,负责请求处理、技能调度、模型调用,同时提供静态资源挂载,简化部署流程。
- SKILL 核心层:包含 SkillRegistry技能注册中心和各类慢病 SKILL 技能,是系统的能力核心,负责技能加载、匹配、执行。
- 模型调用层:基于 OpenAI SDK,严格按照标准格式调用 AntAngelMed 医学模型,确保医学建议的专业性和准确性。
- 配置层:.env 环境变量配置,统一管理模型地址、API 密钥等敏感信息,便于部署和维护。
2. 核心技术栈说明
- FastAPI:后端框架,轻量、高效,负责处理前端请求、调度技能、调用模型,支持WebSocket实时通信
- WebSocket:实时通信,实现前端与后端的双向实时对话,避免页面刷新,提升交互体验
- OpenAI SDK:模型调用,按照指定格式调用AntAngelMed医学模型,获取专业医学建议
- SKILL架构:能力管理,将慢病管理能力拆分为标准化技能,实现模块化开发、动态扩展
- YAML:技能配置,用于编写SKILL.md,定义技能的触发条件、输入输出规范,实现机器可读、人类可懂
- PyYAML:辅助工具,用于技能元数据解析,提升系统可维护性
3. 完整目录结构
chronic_agent/ # 项目根目录
├── main.py # 后端核心入口
├── skill_registry.py # SKILL注册中心
├── skills/ # 慢病管理SKILL技能包
│ ├── diabetes_assess/ # 糖尿病评估技能
│ │ ├── SKILL.md # 技能元数据文件
│ │ └── impl.py # 技能执行逻辑
│ ├── hypertension_assess/ # 高血压评估技能
│ │ ├── SKILL.md
│ │ └── impl.py
│ ├── diet_guide/ # 饮食指导技能
│ │ ├── SKILL.md
│ │ └── impl.py
│ └── risk_warning/ # 风险预警技能
│ ├── SKILL.md
│ └── impl.py
├── static/ # 前端静态资源目录
│ └── index.html # 前端实时对话页面
├── .env # 环境变量配置文件
└── requirements.txt # 项目依赖清单
四、项目文件详细
1. 所需依赖和插件 requirements.txt
fastapi # 后端框架,用于搭建API服务和WebSocket通信
uvicorn[standard] # 服务器,用于启动FastAPI服务,支持实时通信
websockets # 支持WebSocket协议,实现前后端实时对话
python-dotenv # 读取.env环境变量,管理敏感配置(如API密钥)
pydantic # 数据校验,确保技能输入输出格式规范
requests # 用于备用模型调用,如需扩展其他API
matplotlib # 用于技能可视化、数据统计,如慢病咨询量统计
pyyaml # 解析SKILL.md中的YAML格式元数据,加载技能信息
watchdog # 用于技能文件变更自动重载,提升开发效率
openai>=1.0 # OpenAI SDK,调用AntAngelMed医学模型,须安装对应版本
2. 配置文件 .env
# 医学模型配置 OPENAI_BASE_URL=https://api.tbox.cn/api/llm/v1/ # 模型基础地址,可按实际支持调整 OPENAI_API_KEY=your-token-here # 替换为模型调用的实际API密钥 MODEL_NAME=AntAngelMed # 模型名称,固定为AntAngelMed
说明:配置时,只需将your-token-here替换为实际API密钥,其他参数无需修改,确保模型调用正常。
3. 技能注册中心 skill_registry.py
import os import yaml import importlib from typing import Dict, Any class SkillRegistry: """ SKILL技能注册中心(核心组件) 作用:扫描skills目录下的所有技能,加载技能元数据,提供技能匹配、实例化功能 特点:自动加载、动态管理,新增技能无需修改核心代码,直接放入skills目录即可 """ def __init__(self, skill_dir="skills"): self.skill_dir = skill_dir # 技能存放目录(默认skills) self.skills: Dict[str, Any] = {} # 存储所有加载的技能(key:技能名称,value:技能元数据) self.load_all_skills() # 初始化时加载所有技能 def load_all_skills(self): """加载skills目录下的所有SKILL技能,自动解析SKILL.md元数据""" self.skills.clear() # 清空技能列表,避免重复加载 # 遍历skills目录下的所有文件夹(每个文件夹对应一个技能) for name in os.listdir(self.skill_dir): path = os.path.join(self.skill_dir, name) if os.path.isdir(path): # 只处理文件夹(排除文件) self.load_skill(path) # 加载单个技能 # 打印加载结果,便于开发调试 print(f"✅ 慢病管理技能加载完成:共加载 {len(self.skills)} 个技能") print(f"📋 已加载技能:{[name for name in self.skills.keys()]}") def load_skill(self, path): """加载单个技能,解析SKILL.md中的元数据""" # 找到技能的SKILL.md文件(核心配置文件,必须存在) md_path = os.path.join(path, "SKILL.md") if not os.path.exists(md_path): print(f"⚠️ 跳过无效技能:{os.path.basename(path)}(缺少SKILL.md文件)") return # 读取并解析SKILL.md中的YAML元数据(机器可解析部分) with open(md_path, 'r', encoding='utf-8') as f: content = f.read() # SKILL.md采用YAML+Markdown混合格式,提取YAML部分(---之间的内容) if '---' in content: yaml_content = content.split('---')[1] skill_meta = yaml.safe_load(yaml_content) # 记录技能的模块路径,用于后续实例化 skill_meta['module'] = f"skills.{os.path.basename(path)}.impl" # 将技能元数据存入技能列表 self.skills[skill_meta['name']] = skill_meta print(f"✅ 加载技能:{skill_meta['name']}({skill_meta['description']})") def match(self, query): """ 根据用户查询内容,匹配最适合的SKILL技能 匹配规则:根据技能的trigger.keywords(触发关键词),匹配用户查询中的关键词 返回:匹配到的技能列表(按匹配度排序,第一个为最优匹配) """ matched_skills = [] # 将用户查询转为小写,避免大小写影响匹配 user_query = query.lower() # 遍历所有已加载的技能,匹配关键词 for skill in self.skills.values(): # 检查用户查询是否包含当前技能的触发关键词 for keyword in skill['trigger']['keywords']: if keyword.lower() in user_query: matched_skills.append(skill) break # 匹配到一个关键词即可,无需重复匹配 return matched_skills def get_instance(self, skill_name): """ 根据技能名称,获取技能实例(用于执行技能逻辑) 原理:通过importlib导入技能的impl.py模块,调用get_skill()方法获取实例 """ if skill_name not in self.skills: raise ValueError(f"❌ 技能不存在:{skill_name}(请检查技能名称或是否已加载)") # 获取技能的模块路径(如:skills.diabetes_assess.impl) skill_module = self.skills[skill_name]['module'] # 导入技能模块 mod = importlib.import_module(skill_module) # 返回技能实例(每个技能的impl.py都必须实现get_skill()方法) return mod.get_skill()
4. 智能体调度引擎 main.py
from fastapi import FastAPI, WebSocket, WebSocketDisconnect from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse from openai import OpenAI import os import asyncio from dotenv import load_dotenv from skill_registry import SkillRegistry # 加载.env环境变量(优先加载敏感配置,避免硬编码) load_dotenv() # 初始化FastAPI应用(后端服务核心) app = FastAPI( title="糖尿病&高血压慢病管理SKILL智能体", description="基于SKILL架构、AntAngelMed医学模型的全栈慢病管理系统,提供实时咨询、个性化指导服务", version="1.0.0" ) # 挂载前端静态资源(让后端能够访问static目录下的index.html) app.mount("/static", StaticFiles(directory="static"), name="static") # 初始化SKILL技能注册中心(加载所有慢病管理技能) registry = SkillRegistry() # 初始化医学模型客户端(严格按照你提供的调用格式配置) model_client = OpenAI( base_url=os.getenv("OPENAI_BASE_URL"), # 从.env读取模型基础地址 api_key=os.getenv("OPENAI_API_KEY") # 从.env读取API密钥 ) class ConnectionManager: """ WebSocket连接管理类 作用:管理所有前端连接,实现消息发送、连接建立/断开等功能 确保多用户同时访问时,对话不冲突、不串线 """ def __init__(self): self.active_connections = [] # 存储当前活跃的WebSocket连接 async def connect(self, websocket: WebSocket): """建立WebSocket连接,接收前端请求""" await websocket.accept() # 接受前端连接 self.active_connections.append(websocket) # 将连接加入活跃列表 print(f"🔗 新用户连接:当前在线人数 {len(self.active_connections)}") def disconnect(self, websocket: WebSocket): """断开WebSocket连接,清理资源""" self.active_connections.remove(websocket) # 从活跃列表中移除连接 print(f"🔌 用户断开连接:当前在线人数 {len(self.active_connections)}") async def send_message(self, message: str, websocket: WebSocket): """向指定前端连接发送消息(实时对话核心)""" await websocket.send_text(message) # 发送文本消息 # 实例化连接管理器 conn_manager = ConnectionManager() def call_medical_model(prompt: str) -> str: """ 调用AntAngelMed医学模型,获取专业医学建议 参数:prompt - 经过格式化的用户查询(结合技能需求,优化提问方式) 返回:模型返回的医学建议(字符串),异常时返回友好提示 """ try: # 严格按照你提供的格式调用模型 response = model_client.chat.completions.create( model=os.getenv("MODEL_NAME"), # 模型名称(AntAngelMed) messages=[{"role": "user", "content": prompt}] # 消息格式(仅用户角色) ) # 提取模型返回的内容(取第一个结果) return response.choices[0].message.content except Exception as e: # 捕获模型调用异常,返回友好提示(避免用户看到技术错误) return f"⚠️ 医学咨询暂时无法响应,请稍后再试(错误信息:{str(e)[:50]})" def execute_skill_flow(user_query: str) -> str: """ 技能执行流程(核心逻辑) 步骤:1. 匹配用户查询对应的SKILL技能 → 2. 执行技能逻辑 → 3. 返回结果 若未匹配到技能,直接调用医学模型进行通用咨询 """ # 1. 匹配技能(根据用户查询中的关键词,找到最适合的技能) matched_skills = registry.match(user_query) # 2. 执行技能(若匹配到技能,优先执行技能逻辑;否则直接调用模型) if not matched_skills: # 未匹配到技能,直接调用医学模型,进行通用慢病咨询 print(f"🔍 未匹配到具体技能,直接调用医学模型处理:{user_query}") return call_medical_model(f"请作为专业的糖尿病、高血压慢病管理助手,简洁、专业、可执行地回答用户问题:{user_query}") else: # 匹配到技能,优先执行最优技能(第一个匹配到的技能) best_skill = matched_skills[0] print(f"🔍 匹配到技能:{best_skill['name']},执行技能逻辑") # 获取技能实例,执行技能 skill_instance = registry.get_instance(best_skill['name']) # 调用技能的execute方法,传入用户查询数据 skill_result = skill_instance.execute({"query": user_query}) # 统一处理字典格式,只返回建议文本 if isinstance(skill_result, dict): return skill_result.get("result", "暂无建议") return str(skill_result) # return skill_result # 前端页面访问路由(用户访问根路径时,返回前端对话页面) .get("/") def home_page(): """返回前端实时对话页面,用户交互入口""" return FileResponse("static/index.html") # WebSocket实时对话路由(核心交互接口) .websocket("/ws") async def websocket_endpoint(websocket: WebSocket): """ WebSocket实时对话处理逻辑 作用:接收前端用户输入,执行技能/模型调用,返回实时响应 """ # 建立WebSocket连接 await conn_manager.connect(websocket) try: # 循环监听前端消息(持续接收用户输入) while True: # 接收前端发送的用户查询(文本消息) user_message = await websocket.receive_text() # 向用户发送“用户输入”提示(便于用户区分自己和AI的消息) await conn_manager.send_message(f"👤 你:{user_message}", websocket) # 向用户发送“AI思考中”提示(提升用户体验,避免用户以为系统无响应) await conn_manager.send_message(f"⚕️ 慢病助手:正在为你分析...", websocket) # 执行技能/模型调用(使用asyncio.to_thread,避免阻塞WebSocket连接) response_result = await asyncio.to_thread(execute_skill_flow, user_message) # 向用户发送AI的响应结果(格式化显示,清晰易懂) await conn_manager.send_message(f"✅ 慢病助手:{response_result}", websocket) except WebSocketDisconnect: # 捕获用户断开连接异常,清理连接资源 conn_manager.disconnect(websocket) except Exception as e: # 捕获其他异常,向用户发送友好提示 await conn_manager.send_message(f"❌ 系统异常:{str(e)[:50]},请稍后再试", websocket) conn_manager.disconnect(websocket) # 启动服务(直接运行main.py即可启动,无需额外配置) if __name__ == "__main__": import uvicorn print("🚀 慢病管理智能体服务启动中...") print("📌 访问地址:http://127.0.0.1:8000") print("💡 提示:请确保.env文件中的API密钥配置正确,否则无法调用医学模型") # 启动uvicorn服务器,监听0.0.0.0:8000(可通过IP访问,支持局域网共享) uvicorn.run(app, host="0.0.0.0", port=8000)
5. 前端页面 static/index.html
<html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>糖尿病 & 高血压 慢病管理智能体</title> <style> /* 全局样式:简洁、清晰,适配中老年用户,避免复杂设计 */ *{margin:0;padding:0;box-sizing:border-box;font-family:"Microsoft YaHei", Arial, sans-serif} body{background:#f7f9fc;/* 浅灰色背景,保护视力 */} .container{max-width:900px;margin:30px auto;display:flex;flex-direction:column;height:90vh;/* 占满屏幕高度,提升体验 */} /* 标题样式:突出主题,颜色温和 */ .title{text-align:center;color:#009688;font-size:22px;font-weight:bold;margin-bottom:15px;} .subtitle{text-align:center;color:#666;font-size:14px;margin-bottom:10px;} /* 对话区域:白色背景,阴影效果,提升层次感 */ .chat-box{flex:1;background:white;border-radius:12px;padding:20px;overflow-y:auto;box-shadow:0 2px 10px rgba(0,0,0,0.05);} /* 输入区域:固定在底部,操作便捷 */ .input-area{display:flex;margin-top:15px;} #message-input{flex:1;padding:16px;border:1px solid #ddd;border-radius:8px;font-size:15px;outline:none;} #message-input:focus{border-color:#009688;/* 输入框聚焦时变色,提示用户 */} .send-btn{padding:16px 24px;background:#009688;color:white;border:none;border-radius:8px;margin-left:10px;cursor:pointer;} .send-btn:hover{background:#00796b;/* 按钮 hover 效果,提升交互感 */} /* 消息样式:区分用户和AI,清晰易懂 */ .message-item{margin:12px 0;padding:14px 16px;border-radius:8px;max-width:82%;word-wrap:break-word;/* 自动换行,避免长文本溢出 */} .user-message{background:#e3f2fd;align-self:flex-end;margin-left:auto;/* 用户消息靠右显示 */} .ai-message{background:#f1f8e9;align-self:flex-start;/* AI消息靠左显示 */} .loading-message{color:#666;font-size:14px;padding:4px;text-align:center;/* 加载提示样式 */} </style> </head> <body> <div class="container"> <!-- 标题区域:清晰说明系统用途,让用户快速了解 --> <div class="title">糖尿病 & 高血压 慢病管理智能体</div> <div class="subtitle">专业医学咨询 · 个性化指导 · 实时响应 | 基于AntAngelMed医学模型</div> <!-- 对话区域:显示用户和AI的对话记录 --> <div class="chat-box" id="chatBox"></div> <!-- 输入区域:用户输入问题,发送请求 --> <div class="input-area"> <input id="message-input" placeholder="请输入你的问题(例:空腹血糖7.0严重吗?高血压吃什么好?)"> <button class="send-btn" onclick="sendMessage()">发送</button> </div> </div> <script> // 获取DOM元素(对话区域、输入框) const chatBox = document.getElementById('chatBox'); const messageInput = document.getElementById('message-input'); // 建立WebSocket连接(自动连接后端,无需用户操作) const ws = new WebSocket(`ws://${location.host}/ws`); // 发送消息函数(用户点击发送按钮或按回车键触发) function sendMessage() { // 获取用户输入的内容,去除前后空格 const message = messageInput.value.trim(); // 若输入为空,提示用户,不发送请求 if (!message) { alert("请输入你的问题,例如:空腹血糖7.0严重吗?"); return; } // 清空输入框,方便用户输入下一个问题 messageInput.value = ''; // 发送消息到后端(通过WebSocket) ws.send(message); } // 监听WebSocket消息(接收后端返回的响应) ws.onmessage = function(event) { // 创建消息元素,根据消息类型设置样式 const messageDiv = document.createElement('div'); if (event.data.includes('👤 你:')) { // 用户消息样式 messageDiv.className = 'message-item user-message'; } else if (event.data.includes('✅ 慢病助手:')) { // AI响应消息样式 messageDiv.className = 'message-item ai-message'; } else { // 加载提示样式 messageDiv.className = 'loading-message'; } // 设置消息内容 messageDiv.innerText = event.data; // 将消息添加到对话区域 chatBox.appendChild(messageDiv); // 自动滚动到最新消息(避免用户手动滚动) chatBox.scrollTop = chatBox.scrollHeight; }; // 监听回车键(用户按回车键也能发送消息,提升操作便捷性) messageInput.addEventListener('keypress', function(event) { if (event.key === 'Enter') { sendMessage(); } }); // 监听WebSocket连接状态(提示用户连接状态) ws.onopen = function() { const welcomeDiv = document.createElement('div'); welcomeDiv.className = 'loading-message'; welcomeDiv.innerText = '✅ 已连接慢病助手,可随时提问(支持血糖、血压、饮食、用药等问题)'; chatBox.appendChild(welcomeDiv); }; // 监听WebSocket断开连接(提示用户重新连接) ws.onclose = function() { const closeDiv = document.createElement('div'); closeDiv.className = 'loading-message'; closeDiv.innerText = '🔌 连接已断开,请刷新页面重新连接'; chatBox.appendChild(closeDiv); }; </script> </body> </html>
五、完整 SKILL 技能包
1. 技能1:糖尿病评估
1.1 skills/diabetes_assess/SKILL.md
--- # 技能基础信息(机器可解析,系统识别核心) name: diabetes_assess # 技能唯一标识(英文下划线,不可重复) description: 糖尿病相关全场景咨询,包括血糖解读、糖尿病风险评估、症状分析、饮食运动建议、用药指导,聚焦糖尿病患者日常管理需求,提供专业、可执行的医学建议。 version: 1.0.0 # 技能版本(便于升级、回滚,后续迭代可修改) author: 慢病管理开发团队 # 技能开发者(便于维护、追溯) category: chronic_diabetes # 技能分类(糖尿病慢病类) priority: 8 # 优先级(1-10,数字越高,匹配时越优先,糖尿病咨询优先级高于通用咨询) # 触发规则(核心:系统根据这些规则,判断何时调用该技能) trigger: keywords: ["血糖", "糖尿病", "高血糖", "低血糖", "空腹血糖", "餐后血糖", "糖耐量", "糖化血红蛋白", "降糖", "吃糖", "糖尿病饮食", "糖尿病运动", "糖尿病用药", "糖尿病并发症", "糖尿病症状"] # 触发关键词,用户输入包含这些词,优先匹配该技能 intent: ["糖尿病咨询", "血糖解读", "糖尿病风险评估", "糖尿病饮食建议", "糖尿病用药指导"] # 用户意图,大模型可直接识别匹配 context: ["慢病管理", "日常护理", "血糖监测", "糖尿病预防"] # 场景上下文,避免无关场景误触发 confidence: 0.75 # 触发置信度阈值(高于0.75才触发,避免误匹配) # 输入规范(明确技能接收的输入格式,确保执行逻辑正常) input_schema: type: object properties: query: type: string description: 用户关于糖尿病的咨询问题,如“空腹血糖7.0mmol/L严重吗?”“糖尿病患者能吃米饭吗?” required: ["query"] # 必传参数(必须有用户查询,否则技能无法执行) # 输出规范(统一技能输出格式,便于后端解析、前端显示) output_schema: type: object properties: result: type: string description: 针对用户糖尿病咨询的专业医学建议,简洁、可执行,符合AntAngelMed模型输出规范,避免专业术语过于晦涩,适配普通用户理解。 success: type: boolean description: 技能执行是否成功(true=成功,false=失败) message: type: string description: 执行状态提示(成功时为“技能执行成功”,失败时为具体失败原因) # 示例案例(给大模型提供小样本学习,提升技能执行准确性;给开发者提供测试用例) examples: - input: {"query": "空腹血糖7.0mmol/L严重吗?我是糖尿病患者,平时需要注意什么?"} output: {"result": "空腹血糖7.0mmol/L略高于正常范围(正常空腹血糖3.9-6.1mmol/L),对于糖尿病患者而言,需警惕血糖控制不佳。建议:1. 监测餐后2小时血糖,观察波动情况;2. 饮食上减少精制碳水(如白米饭、面条)摄入,增加膳食纤维(蔬菜、杂粮);3. 适量运动(如快走、太极拳),每次30分钟,每周5次;4. 遵医嘱服用降糖药,不可自行停药或调整剂量;5. 每周监测1-2次空腹+餐后血糖,记录波动。", "success": true, "message": "技能执行成功"} - input: {"query": "糖尿病患者能吃水果吗?可以吃哪些水果?"} output: {"result": "糖尿病患者可以适量吃水果,建议选择低GI(升糖指数)水果,控制食用量。推荐水果:苹果、柚子、草莓、蓝莓、猕猴桃(每天总量控制在200-350g);避免水果:荔枝、芒果、榴莲、龙眼(高GI水果,易导致血糖飙升)。食用时间:建议在两餐之间(如上午10点、下午3点),避免餐后立即吃,防止血糖叠加升高。", "success": true, "message": "技能执行成功"} - input: {"query": "我最近总是口渴、多尿,是不是得了糖尿病?"} output: {"result": "口渴、多尿是糖尿病的典型症状之一,但并非所有口渴多尿都是糖尿病(如饮水过多、甲亢、尿路感染也可能出现类似症状)。建议:1. 及时到医院检测空腹血糖、餐后2小时血糖及糖化血红蛋白,明确诊断;2. 暂时减少高糖、高油食物摄入,多喝水(避免饮料);3. 注意休息,避免熬夜,观察症状是否缓解。若血糖检测异常,及时就医制定治疗方案。", "success": true, "message": "技能执行成功"} # 依赖关系(技能执行所需的外部资源、权限) dependencies: api: ["AntAngelMed"] # 依赖的API/模型(必须依赖AntAngelMed医学模型) skills: [] # 依赖的其他技能(该技能独立执行,不依赖其他技能) permissions: ["all"] # 访问权限(所有用户均可使用,无限制) # 技能限制(保障系统稳定,避免异常) limits: max_retries: 2 # 执行失败时,最大重试次数(2次) timeout: 8 # 超时时间(8秒,超过8秒视为执行失败) rate_limit: "15/min" # 限流配置(每分钟最多调用15次,避免频繁调用导致模型异常) --- # 糖尿病评估技能说明(人类可读,供开发者、运维人员参考) ## 功能概述 本技能是慢病管理智能体的核心技能之一,专注于糖尿病相关全场景咨询,覆盖血糖解读、风险评估、症状分析、饮食运动指导、用药建议等,为糖尿病患者提供专业、可落地的日常管理建议,辅助患者控制血糖、预防并发症。 ## 执行流程 1. 接收用户输入的糖尿病相关查询(如血糖解读、饮食疑问等); 2. 对用户查询进行简单解析,提取核心需求(如“血糖是否正常”“能吃什么”); 3. 调用AntAngelMed医学模型,传入格式化后的查询,获取专业医学建议; 4. 对模型返回的建议进行简单优化(简化专业术语,确保普通用户可理解); 5. 按照output_schema规范,返回执行结果(包含建议、执行状态)。 ## 异常处理 1. 模型调用失败:返回友好提示,告知用户“暂时无法提供咨询,请稍后再试”,并记录错误信息; 2. 用户输入为空:返回提示“请输入具体的糖尿病相关问题”; 3. 超时异常:超过8秒未获取模型响应,视为执行失败,返回超时提示。 ## 业务边界 1. 本技能仅提供糖尿病相关咨询建议,不替代专业医疗诊断,不开具处方; 2. 若用户涉及紧急情况(如血糖急剧升高、出现严重并发症症状),会提示用户及时就医; 3. 支持的咨询范围:糖尿病预防、血糖监测、饮食运动、用药指导、症状分析、并发症预防,不涉及其他慢病(如高血压单独咨询,将匹配高血压评估技能)。
1.2 skills/diabetes_assess/impl.py
from openai import OpenAI import os from dotenv import load_dotenv # 加载.env环境变量(获取模型配置,避免硬编码) load_dotenv() # 初始化医学模型客户端(严格按照用户提供的格式配置) medical_client = OpenAI( base_url=os.getenv("OPENAI_BASE_URL"), api_key=os.getenv("OPENAI_API_KEY") ) class DiabetesAssessSkill: """ 糖尿病评估技能类(核心逻辑:处理糖尿病相关咨询,调用医学模型返回专业建议) 方法:execute - 执行技能,接收用户查询,返回格式化结果 """ def execute(self, input_data: dict) -> dict: """ 执行糖尿病评估技能 参数:input_data - 包含用户查询的字典(key: query,value: 用户输入的问题) 返回:字典,包含技能执行结果、状态、提示信息(符合output_schema规范) """ try: # 1. 提取用户查询(从input_data中获取,确保参数存在) user_query = input_data.get("query", "").strip() if not user_query: # 若用户查询为空,返回失败结果 return { "result": "", "success": False, "message": "请输入具体的糖尿病相关问题(如:空腹血糖7.0严重吗?)" } # 2. 格式化prompt(优化提问方式,让模型返回更精准、可执行的建议) prompt = f"""你是专业的糖尿病慢病管理医生,根据用户的问题,提供简洁、专业、可执行的医学建议,要求如下: 1. 语言通俗易懂,避免过于晦涩的专业术语,适配普通糖尿病患者理解; 2. 建议具体、可落地,比如饮食、运动建议要明确“能吃什么、不能吃什么”“运动时间、方式”; 3. 若用户涉及血糖异常,需明确告知正常范围,并给出具体的控制建议; 4. 若用户症状可能涉及严重情况,需提示“及时就医”,不替代专业诊断; 5. 聚焦糖尿病相关内容,不回答与糖尿病无关的问题; 6. 篇幅适中,避免过长,重点突出核心建议。 用户问题:{user_query}""" # 3. 调用AntAngelMed医学模型(严格按照用户提供的格式) model_response = medical_client.chat.completions.create( model=os.getenv("MODEL_NAME"), # 模型名称:AntAngelMed messages=[{"role": "user", "content": prompt}] # 消息格式 ) # 4. 提取模型返回结果,格式化输出(符合output_schema规范) return { "result": model_response.choices[0].message.content, "success": True, "message": "技能执行成功" } except Exception as e: # 捕获所有异常(模型调用失败、超时等),返回友好提示 return { "result": "", "success": False, "message": f"技能执行失败:{str(e)[:50]}(请稍后再试)" } def get_skill(): """ 技能入口函数(必须实现,供SkillRegistry调用,返回技能实例) 返回:DiabetesAssessSkill实例 """ return DiabetesAssessSkill()
2. 技能2:高血压评估
2.1 skills/hypertension_assess/SKILL.md
--- name: hypertension_assess description: 高血压相关全场景咨询,包括血压解读、高血压风险评估、症状分析、饮食运动建议、用药指导,聚焦高血压患者日常管理,提供专业、可执行的医学建议。 version: 1.0.0 author: 慢病管理开发团队 category: chronic_hypertension priority: 8 trigger: keywords: ["血压", "高血压", "低血压", "收缩压", "舒张压", "血压高", "血压低", "降压", "高血压饮食", "高血压运动", "高血压用药", "高血压并发症", "高血压症状"] intent: ["高血压咨询", "血压解读", "高血压风险评估", "高血压饮食建议", "高血压用药指导"] context: ["慢病管理", "日常护理", "血压监测", "高血压预防"] confidence: 0.75 input_schema: type: object properties: query: type: string description: 用户关于高血压的咨询问题,如“血压150/95mmHg需要吃药吗?”“高血压患者能吃盐吗?” required: ["query"] output_schema: type: object properties: result: type: string description: 针对用户高血压咨询的专业医学建议,简洁、可执行,适配普通用户理解,符合AntAngelMed模型输出规范。 success: type: boolean description: 技能执行是否成功 message: type: string description: 执行状态提示 examples: - input: {"query": "血压150/95mmHg属于高血压吗?需要吃药吗?"} output: {"result": "血压150/95mmHg属于1级高血压(正常血压<120/80mmHg,1级高血压140-159/90-99mmHg)。是否需要吃药需分情况:1. 若为首次检测,建议连续3天不同时间监测,确认是否为持续性高血压;2. 若确诊为原发性高血压,且无其他并发症(如糖尿病、肾病),可先通过生活方式干预(低盐饮食、规律运动、戒烟限酒)3-6个月,若血压仍未控制在140/90mmHg以下,需遵医嘱服药;3. 若合并糖尿病、肾病等,需立即就医,在医生指导下服药。", "success": true, "message": "技能执行成功"} - input: {"query": "高血压患者饮食需要注意什么?能吃盐吗?"} output: {"result": "高血压患者饮食核心是“低盐、低脂、低糖”,具体建议:1. 严格控盐:每天食盐摄入量不超过5g(约1个啤酒瓶盖),避免咸菜、腌制品、加工肉(如腊肉、香肠);2. 多吃蔬菜(每天500g以上)、水果、全谷物(如燕麦、糙米);3. 减少高脂食物摄入(如肥肉、动物内脏、油炸食品);4. 戒烟限酒,避免浓茶、咖啡;5. 控制体重,避免肥胖(肥胖会加重高血压)。可以吃盐,但必须严格控制量。", "success": true, "message": "技能执行成功"} - input: {"query": "高血压患者适合做什么运动?"} output: {"result": "高血压患者适合温和的有氧运动,避免剧烈运动,具体建议:1. 推荐运动:快走、慢跑、太极拳、游泳、骑自行车,每次30分钟,每周5次;2. 运动禁忌:避免空腹运动、剧烈运动(如冲刺跑、举重),血压控制不佳(>160/100mmHg)时,暂时不建议运动;3. 运动注意事项:运动前热身5-10分钟,运动后放松5-10分钟,运动中若出现头晕、胸闷,立即停止休息;4. 运动后监测血压,观察波动情况。", "success": true, "message": "技能执行成功"} dependencies: api: ["AntAngelMed"] skills: [] permissions: ["all"] limits: max_retries: 2 timeout: 8 rate_limit: "15/min" --- # 高血压评估技能说明 ## 功能概述 本技能专注于高血压相关全场景咨询,覆盖血压解读、风险评估、症状分析、饮食运动指导、用药建议等,为高血压患者提供专业、可落地的日常管理建议,辅助患者控制血压、预防并发症(如脑梗、心梗、肾病等)。 ## 执行流程 1. 接收用户输入的高血压相关查询; 2. 解析用户核心需求,格式化prompt,确保模型返回精准建议; 3. 调用AntAngelMed医学模型,获取专业医学建议; 4. 优化建议表述,简化专业术语,确保普通用户可理解; 5. 按照output_schema规范,返回执行结果。 ## 异常处理 1. 模型调用失败:返回友好提示,告知用户暂时无法提供咨询; 2. 用户输入为空:提示用户输入具体的高血压相关问题; 3. 超时异常:超过8秒未获取模型响应,视为执行失败,返回超时提示。 ## 业务边界 1. 仅提供高血压相关咨询建议,不替代专业医疗诊断,不开具处方; 2. 若用户血压急剧升高(如>180/110mmHg)或出现头晕、胸闷、呕吐等紧急症状,提示用户立即就医; 3. 不涉及其他慢病咨询,若用户同时咨询糖尿病+高血压,会分别调用对应技能,整合建议。
2.2 skills/hypertension_assess/impl.py
from openai import OpenAI import os from dotenv import load_dotenv load_dotenv() # 初始化医学模型客户端 medical_client = OpenAI( base_url=os.getenv("OPENAI_BASE_URL"), api_key=os.getenv("OPENAI_API_KEY") ) class HypertensionAssessSkill: """高血压评估技能类,处理高血压相关咨询,调用医学模型返回专业建议""" def execute(self, input_data: dict) -> dict: try: # 提取用户查询 user_query = input_data.get("query", "").strip() if not user_query: return { "result": "", "success": False, "message": "请输入具体的高血压相关问题(如:血压150/95需要吃药吗?)" } # 格式化prompt,优化模型响应 prompt = f"""你是专业的高血压慢病管理医生,根据用户的问题,提供简洁、专业、可执行的医学建议,要求如下: 1. 语言通俗易懂,避免晦涩的专业术语,适配普通高血压患者理解; 2. 建议具体可落地,比如饮食、运动建议明确具体做法和用量; 3. 解读血压数值时,明确告知正常范围和当前血压等级; 4. 涉及用药建议时,强调“遵医嘱”,不自行推荐具体药物; 5. 若用户症状紧急,提示“立即就医”,不替代专业诊断; 6. 聚焦高血压相关内容,不回答无关问题,篇幅适中。 用户问题:{user_query}""" # 调用AntAngelMed模型 model_response = medical_client.chat.completions.create( model=os.getenv("MODEL_NAME"), messages=[{"role": "user", "content": prompt}] ) # 返回格式化结果 return { "result": model_response.choices[0].message.content, "success": True, "message": "技能执行成功" } except Exception as e: return { "result": "", "success": False, "message": f"技能执行失败:{str(e)[:50]}(请稍后再试)" } def get_skill(): """技能入口,返回技能实例""" return HypertensionAssessSkill()
3. 技能3:饮食指导
3.1 skills/diet_guide/SKILL.md
--- name: diet_guide description: 糖尿病+高血压双慢病患者饮食指导,结合两种慢病特点,提供个性化、可执行的饮食建议,包括食材选择、烹饪方式、饮食禁忌、三餐搭配,帮助患者通过饮食控制血糖、血压。 version: 1.0.0 author: 慢病管理开发团队 category: chronic_diet priority: 7 trigger: keywords: ["饮食", "吃饭", "食材", "食谱", "三餐", "忌口", "能吃", "不能吃", "烹饪", "低盐", "低糖", "低脂", "糖尿病饮食", "高血压饮食"] intent: ["饮食指导", "食谱推荐", "饮食禁忌", "食材选择", "三餐搭配"] context: ["慢病管理", "日常饮食", "血糖控制", "血压控制"] confidence: 0.7 input_schema: type: object properties: query: type: string description: 用户关于糖尿病+高血压患者的饮食咨询,如“糖尿病高血压患者能吃米饭吗?”“双慢病患者一日三餐食谱” required: ["query"] output_schema: type: object properties: result: type: string description: 针对双慢病患者的饮食建议,结合糖尿病低糖、高血压低盐的特点,具体、可执行,适配普通用户理解。 success: type: boolean description: 技能执行是否成功 message: type: string description: 执行状态提示 examples: - input: {"query": "糖尿病高血压患者能吃主食吗?推荐吃什么主食?"} output: {"result": "糖尿病高血压患者可以吃主食,但需控制量、选对种类,核心原则:低糖、高纤维、低升糖。推荐主食:1. 杂粮杂豆(燕麦、糙米、藜麦、红豆、绿豆),富含膳食纤维,升糖慢,还能控制血压;2. 薯类(红薯、紫薯、山药),可替代部分精米白面;3. 避免主食:白米饭、白面条、馒头、糕点(精制碳水,升糖快,加重血糖负担)。食用量:每天主食总量控制在200-300g(约1-1.5碗),分三餐食用,每餐70-100g,避免一餐吃太多。", "success": true, "message": "技能执行成功"} - input: {"query": "糖尿病高血压患者一日三餐食谱推荐"} output: {"result": "双慢病患者一日三餐食谱(适配普通患者,可根据自身情况调整):\n早餐:燕麦粥1碗(约50g燕麦)+ 水煮蛋1个 + 凉拌黄瓜1份(无盐);\n午餐:杂粮饭1小碗(约70g)+ 清蒸鱼1块(约100g)+ 清炒时蔬2份(如菠菜、西兰花,少油少盐);\n晚餐:小米粥1碗(约50g小米)+ 瘦肉炒芹菜(瘦肉50g、芹菜100g,少油少盐)+ 凉拌番茄1份;\n加餐(两餐之间):苹果1个(约150g)或蓝莓50g,避免空腹吃,控制总量。\n注意:烹饪方式以蒸、煮、凉拌、清炒为主,避免油炸、红烧;每天食盐摄入量不超过5g,不喝含糖饮料。", "success": true, "message": "技能执行成功"} - input: {"query": "糖尿病高血压患者不能吃什么食物?"} output: {"result": "双慢病患者饮食禁忌(重点规避以下食物):1. 高糖食物:糖果、蛋糕、含糖饮料、蜂蜜、荔枝、芒果(升高血糖);2. 高盐食物:咸菜、腌制品、加工肉、酱类(升高血压);3. 高脂食物:肥肉、动物内脏、油炸食品、黄油(加重血管负担,影响血糖和血压控制);4. 刺激性食物:浓茶、咖啡、辛辣食物(可能导致血压波动);5. 酒精类:白酒、啤酒、红酒(升高血压,影响血糖控制,建议戒烟限酒)。", "success": true, "message": "技能执行成功"} dependencies: api: ["AntAngelMed"] skills: [] permissions: ["all"] limits: max_retries: 2 timeout: 8 rate_limit: "15/min" --- # 饮食指导技能说明 ## 功能概述 本技能专注于糖尿病+高血压双慢病患者的饮食指导,结合两种慢病的核心饮食需求(糖尿病低糖、高血压低盐),提供个性化、可执行的饮食建议,包括食材选择、烹饪方式、饮食禁忌、三餐搭配等,帮助患者通过科学饮食控制血糖、血压,辅助慢病管理,预防并发症。 ## 执行流程 1. 接收用户输入的饮食相关查询(聚焦双慢病患者); 2. 解析用户核心需求(如“能吃什么”“食谱推荐”“饮食禁忌”); 3. 格式化prompt,明确要求模型结合双慢病特点,提供具体可执行的建议; 4. 调用AntAngelMed医学模型,获取专业饮食建议; 5. 优化建议表述,确保简洁、易懂、可落地,按照output_schema规范返回结果。 ## 异常处理 1. 模型调用失败:返回友好提示,告知用户暂时无法提供饮食建议; 2. 用户输入为空:提示用户输入具体的饮食咨询问题; 3. 超时异常:超过8秒未获取模型响应,视为执行失败,返回超时提示。 ## 业务边界 1. 仅提供糖尿病+高血压双慢病患者的饮食建议,不涉及其他疾病的饮食指导; 2. 饮食建议仅作为日常参考,不替代专业营养师或医生的指导; 3. 若用户有特殊情况(如过敏、合并其他疾病),会提示用户结合自身情况调整,或咨询专业人士。
3.2 skills/diet_guide/impl.py
from openai import OpenAI import os from dotenv import load_dotenv load_dotenv() medical_client = OpenAI( base_url=os.getenv("OPENAI_BASE_URL"), api_key=os.getenv("OPENAI_API_KEY") ) class DietGuideSkill: def execute(self, input_data: dict) -> dict: try: user_query = input_data.get("query", "").strip() if not user_query: return { "result": "", "success": False, "message": "请输入具体的饮食问题" } prompt = f"""你是专业的慢病营养师,专门为糖尿病+高血压双慢病患者提供饮食指导。 要求: 1. 同时兼顾“低糖、低盐、低脂”三大原则,不能顾此失彼。 2. 语言通俗、具体、可执行,给出明确的“能吃/少吃/禁止”。 3. 食谱要实用,适合家庭日常,不要复杂食材。 4. 不使用专业术语堆砌,中老年能看懂。 5. 不提供处方类建议,只做饮食指导。 用户问题:{user_query} """ resp = medical_client.chat.completions.create( model=os.getenv("MODEL_NAME"), messages=[{"role": "user", "content": prompt}] ) return { "result": resp.choices[0].message.content, "success": True, "message": "ok" } except Exception as e: return { "result": "", "success": False, "message": f"饮食建议获取失败:{str(e)}" } def get_skill(): return DietGuideSkill()
4. 技能4:风险预警技能
4.1 skills/risk_warning/SKILL.md
--- name: risk_warning description: 糖尿病、高血压风险预警与并发症提醒,根据指标异常给出危险等级、注意事项、就医提示 version: 1.0.0 author: 慢病AI团队 category: chronic_risk priority: 9 trigger: keywords: ["危险", "风险", "严重吗", "并发症", "脑梗", "心梗", "肾病", "失明", "足坏疽", "头晕", "胸闷", "很高", "危急"] intent: ["风险评估", "并发症预防", "危险程度判断", "紧急情况处理"] context: ["慢病急症", "指标异常", "健康预警"] confidence: 0.7 input_schema: type: object properties: query: type: string required: ["query"] output_schema: result: string success: bool message: string examples: - input: {"query":"血压180/110危险吗?"} output: {"result":"属于高血压3级高危,极易引发脑出血、脑梗、心衰,必须立即就医或含服急救降压药,静卧休息。","success":true} - input: {"query":"血糖长期12以上有什么危害?"} output: {"result":"长期高血糖会损伤眼底、肾脏、神经和血管,可能导致肾病、失明、糖尿病足、心梗脑梗等严重并发症。","success":true} dependencies: api: ["AntAngelMed"] limits: max_retries: 2 timeout: 8 --- # 风险预警技能说明 用于识别用户描述的危险指标、危急症状,自动判断风险等级,给出预警和就医提示,是慢病管理的安全底线。
4.2 skills/risk_warning/impl.py
from openai import OpenAI import os from dotenv import load_dotenv load_dotenv() client = OpenAI(base_url=os.getenv("OPENAI_BASE_URL"), api_key=os.getenv("OPENAI_API_KEY")) class RiskWarningSkill: def execute(self, data): try: q = data["query"].strip() prompt = f"""你是专业慢病急诊助手,判断糖尿病/高血压相关风险等级: - 明确标注:低危 / 中危 / 高危 / 危急 - 简要说明危害 - 给出立即行动建议(观察/就医/急诊) - 语言严肃、清晰、简短 用户描述:{q} """ res = client.chat.completions.create( model=os.getenv("MODEL_NAME"), messages=[{"role":"user","content":prompt}] ) return { "result": res.choices[0].message.content, "success": True, "message": "ok" } except Exception as e: return {"result":"","success":False,"message":str(e)} def get_skill(): return RiskWarningSkill()
六、运行与演示
首先确认最终的目录结构:
服务启动:
注意进入到命令进入到chronic_agent目录,执行python main.py启动即可:
在运行后输入问题会自动匹配到对应的SKILL技能,并进行模型调用输出:
不同类型会匹配到不同的技能,进行差异化的输入输出约定,以满足不同场景的需求:
运行过程中,有完整的日志记录细节,便于测试和了解系统运行过程:
基于实际场景的技能调用分布统计:
六、总结
简单来说,咱们这个慢病管理智能体,核心就是靠SKILL技能体系来实现的,专门针对糖尿病、高血压这两种常见慢病,做专业的健康咨询和管理。区别于以往的智能体构建模式,今天是把慢病管理的核心能力,拆成了 4 个独立的 SKILL 技能:糖尿病评估、高血压评估、饮食指导、风险预警,每个技能各司其职,比如血糖解读找糖尿病SKILL,血压异常找高血压SKILL,饮食搭配就用饮食指导SKILL,遇到危险指标还有风险预警SKILL 及时提醒。
这种SKILL 拆分的好处特别实在,不用改核心代码,想加新功能、升级某个技能,直接单独调整对应的SKILL就行,后期维护起来特别省心。通过调用AntAngelMed 专业医学模型,给出的建议都是符合临床规范的,不瞎忽悠。整体来看,这个智能体就是用 SKILL 这种模块化的方式,把专业的医学能力落地成了普通人能用的工具,既能解决糖尿病、高血压患者日常的咨询需求,又兼顾了系统的可扩展性,算是把 SKILL 架构和慢病管理结合得很实用的一个案例。