【单智能体】AI健康与健身规划师 - 案例讲解(附完整源码)
目录
1. 案例简介
2. 案例目标
2.1 核心功能
2.2 技术要点
3. 技术栈与核心依赖
4. 项目结构
4.1 关键文件说明
5. 核心代码实现
5.1 页面配置与样式
5.2 饮食计划显示函数
5.3 健身计划显示函数
5.4 AI代理初始化
6. 运行与测试
6.1 环境准备
6.2 安装依赖
6.3 启动应用
6.4 使用流程
7. 实现思路与扩展建议
7.1 核心设计思想
7.2 扩展建议
完整源码
health_agent.py
requirements.txt
README.md
1. 案例简介
AI健康与健身规划师是一个由Agno AI代理框架驱动的个性化健康与健身应用。该应用根据用户输入(如年龄、体重、身高、活动水平、饮食偏好和健身目标)生成量身定制的饮食和健身计划。
学习目标:
- 理解如何使用Agno AI框架构建智能代理应用
- 学习如何集成Google Gemini大语言模型
- 掌握Streamlit快速开发Web应用的技巧
- 了解多代理协作的架构设计
2. 案例目标
2.1 核心功能
- 个性化饮食计划:生成详细的餐食计划(早餐、午餐、晚餐和零食)
- 个性化健身计划:根据健身目标提供定制的运动计划
- 互动问答:允许用户就其计划提出后续问题
2.2 技术要点
- 使用Agno AI框架创建专业化的AI代理
- 集成Google Gemini API进行智能内容生成
- 使用Streamlit构建交互式Web界面
- 会话状态管理(Session State)
3. 技术栈与核心依赖
| 技术/依赖 | 版本 | 用途 |
|---|---|---|
| Python | 3.8+ | 编程语言 |
| agno | ≥2.2.10 | AI代理框架 |
| google-generativeai | 0.8.3 | Google Gemini模型接口 |
| streamlit | 1.40.2 | Web应用框架 |
4. 项目结构
ai_health_fitness_agent-zh/ ├── README.md # 项目说明文档 ├── health_agent.py # 主程序文件 └── requirements.txt # 依赖配置文件4.1 关键文件说明
- health_agent.py:程序主入口,包含Streamlit界面和AI代理逻辑
- requirements.txt:Python依赖包列表
- README.md:项目使用说明
5. 核心代码实现
5.1 页面配置与样式
st.set_page_config( page_title="AI健康与健身规划师", page_icon="🏋️♂️", layout="wide", initial_sidebar_state="expanded" )5.2 饮食计划显示函数
def display_dietary_plan(plan_content): """ 显示个性化饮食计划 参数: plan_content: 包含饮食计划信息的字典 """ with st.expander("📋 您的个性化饮食计划", expanded=True): col1, col2 = st.columns([2, 1]) with col1: st.markdown("### 🎯 为什么这个计划有效") st.info(plan_content.get("why_this_plan_works", "信息不可用")) st.markdown("### 🍽️ 餐食计划") st.write(plan_content.get("meal_plan", "计划不可用")) with col2: st.markdown("### ⚠️ 重要注意事项") considerations = plan_content.get("important_considerations", "").split('\n') for consideration in considerations: if consideration.strip(): st.warning(consideration)5.3 健身计划显示函数
def display_fitness_plan(plan_content): """ 显示个性化健身计划 参数: plan_content: 包含健身计划信息的字典 """ with st.expander("💪 您的个性化健身计划", expanded=True): col1, col2 = st.columns([2, 1]) with col1: st.markdown("### 🎯 目标") st.success(plan_content.get("goals", "未指定目标")) st.markdown("### 🏋️♂️ 运动计划") st.write(plan_content.get("routine", "计划不可用")) with col2: st.markdown("### 💡 专业建议") tips = plan_content.get("tips", "").split('\n') for tip in tips: if tip.strip(): st.info(tip)5.4 AI代理初始化
dietary_agent = Agent( name="饮食专家", role="提供个性化饮食建议", model=gemini_model, instructions=[ "考虑用户的输入,包括饮食限制和偏好。", "为一天建议详细的餐食计划,包括早餐、午餐、晚餐和零食。", "简要解释为什么该计划适合用户的目标。", "注重建议的清晰性、连贯性和质量。", ] )6. 运行与测试
6.1 环境准备
注意:需要先获取Google Gemini API密钥,访问地址:https://aistudio.google.com/apikey
6.2 安装依赖
pip install -r requirements.txt6.3 启动应用
streamlit run health_agent.py6.4 使用流程
- 在侧边栏输入Gemini API密钥
- 填写个人信息(年龄、体重、身高等)
- 选择活动水平、饮食偏好和健身目标
- 点击"生成我的个性化计划"按钮
- 查看生成的饮食和健身计划
- 通过问答功能进行后续咨询
7. 实现思路与扩展建议
7.1 核心设计思想
- 职责分离:饮食专家和健身专家各司其职
- 用户至上:完全根据用户个人情况定制方案
- 交互友好:提供简洁直观的Web界面
7.2 扩展建议
- 添加数据持久化,保存用户历史计划
- 集成运动追踪API,记录实际运动数据
- 添加进度图表和分析报告
- 支持多语言切换
- 添加社交分享功能
完整源码
health_agent.py
import streamlit as st from agno.agent import Agent from agno.run.agent import RunOutput from agno.models.google import Gemini st.set_page_config( page_title="AI健康与健身规划师", page_icon="🏋️♂️", layout="wide", initial_sidebar_state="expanded" ) st.markdown(""" <style> .main { padding: 2rem; } .stButton>button { width: 100%; border-radius: 5px; height: 3em; } .success-box { padding: 1rem; border-radius: 0.5rem; background-color: #f0fff4; border: 1px solid #9ae6b4; } .warning-box { padding: 1rem; border-radius: 0.5rem; background-color: #fffaf0; border: 1px solid #fbd38d; } div[data-testid="stExpander"] div[role="button"] p { font-size: 1.1rem; font-weight: 600; } </style> """, unsafe_allow_html=True) def display_dietary_plan(plan_content): """ 显示个性化饮食计划 参数: plan_content: 包含饮食计划信息的字典 """ with st.expander("📋 您的个性化饮食计划", expanded=True): col1, col2 = st.columns([2, 1]) with col1: st.markdown("### 🎯 为什么这个计划有效") st.info(plan_content.get("why_this_plan_works", "信息不可用")) st.markdown("### 🍽️ 餐食计划") st.write(plan_content.get("meal_plan", "计划不可用")) with col2: st.markdown("### ⚠️ 重要注意事项") considerations = plan_content.get("important_considerations", "").split('\n') for consideration in considerations: if consideration.strip(): st.warning(consideration) def display_fitness_plan(plan_content): """ 显示个性化健身计划 参数: plan_content: 包含健身计划信息的字典 """ with st.expander("💪 您的个性化健身计划", expanded=True): col1, col2 = st.columns([2, 1]) with col1: st.markdown("### 🎯 目标") st.success(plan_content.get("goals", "未指定目标")) st.markdown("### 🏋️♂️ 运动计划") st.write(plan_content.get("routine", "计划不可用")) with col2: st.markdown("### 💡 专业建议") tips = plan_content.get("tips", "").split('\n') for tip in tips: if tip.strip(): st.info(tip) def main(): """ 主函数:运行AI健康与健身规划师应用 """ if 'dietary_plan' not in st.session_state: st.session_state.dietary_plan = {} st.session_state.fitness_plan = {} st.session_state.qa_pairs = [] st.session_state.plans_generated = False st.title("🏋️♂️ AI健康与健身规划师") st.markdown(""" <div style='background-color: #00008B; padding: 1rem; border-radius: 0.5rem; margin-bottom: 2rem;'> 获取根据您的目标和偏好量身定制的个性化饮食和健身计划。 我们的AI驱动系统会考虑您的独特个人资料,为您打造完美的计划。 </div> """, unsafe_allow_html=True) with st.sidebar: st.header("🔑 API配置") gemini_api_key = st.text_input( "Gemini API密钥", type="password", help="输入您的Gemini API密钥以访问服务" ) if not gemini_api_key: st.warning("⚠️ 请输入您的Gemini API密钥以继续") st.markdown("[在此获取您的API密钥](https://aistudio.google.com/apikey)") return st.success("API密钥已接受!") if gemini_api_key: try: gemini_model = Gemini(id="gemini-2.5-flash-preview-05-20", api_key=gemini_api_key) except Exception as e: st.error(f"❌ 初始化Gemini模型时出错: {e}") return st.header("👤 您的个人资料") col1, col2 = st.columns(2) with col1: age = st.number_input("年龄", min_value=10, max_value=100, step=1, help="输入您的年龄") height = st.number_input("身高 (厘米)", min_value=100.0, max_value=250.0, step=0.1) activity_level = st.selectbox( "活动水平", options=["久坐", "轻度活动", "中度活动", "高度活动", "极度活动"], help="选择您的典型活动水平" ) dietary_preferences = st.selectbox( "饮食偏好", options=["素食", "生酮", "无麸质", "低碳水", "无乳制品"], help="选择您的饮食偏好" ) with col2: weight = st.number_input("体重 (公斤)", min_value=20.0, max_value=300.0, step=0.1) sex = st.selectbox("性别", options=["男性", "女性", "其他"]) fitness_goals = st.selectbox( "健身目标", options=["减重", "增肌", "耐力训练", "保持健康", "力量训练"], help="您想要实现什么目标?" ) if st.button("🎯 生成我的个性化计划", use_container_width=True): with st.spinner("正在为您创建完美的健康和健身计划..."): try: dietary_agent = Agent( name="饮食专家", role="提供个性化饮食建议", model=gemini_model, instructions=[ "考虑用户的输入,包括饮食限制和偏好。", "为一天建议详细的餐食计划,包括早餐、午餐、晚餐和零食。", "简要解释为什么该计划适合用户的目标。", "注重建议的清晰性、连贯性和质量。", ] ) fitness_agent = Agent( name="健身专家", role="提供个性化健身建议", model=gemini_model, instructions=[ "提供适合用户目标的运动建议。", "包括热身、主要锻炼和放松运动。", "解释每个推荐运动的好处。", "确保计划可执行且详细。", ] ) user_profile = f""" 年龄: {age} 体重: {weight}公斤 身高: {height}厘米 性别: {sex} 活动水平: {activity_level} 饮食偏好: {dietary_preferences} 健身目标: {fitness_goals} """ dietary_plan_response: RunOutput = dietary_agent.run(user_profile) dietary_plan = { "why_this_plan_works": "高蛋白、健康脂肪、适量碳水化合物和热量平衡", "meal_plan": dietary_plan_response.content, "important_considerations": """ - 补水:全天多喝水 - 电解质:监测钠、钾和镁的水平 - 纤维:通过蔬菜和水果确保充足摄入 - 倾听身体的声音:根据需要调整份量 """ } fitness_plan_response: RunOutput = fitness_agent.run(user_profile) fitness_plan = { "goals": "增强力量、提高耐力并保持整体健康", "routine": fitness_plan_response.content, "tips": """ - 定期跟踪您的进度 - 在锻炼之间安排适当的休息 - 专注于正确的动作姿势 - 保持规律的锻炼习惯 """ } st.session_state.dietary_plan = dietary_plan st.session_state.fitness_plan = fitness_plan st.session_state.plans_generated = True st.session_state.qa_pairs = [] display_dietary_plan(dietary_plan) display_fitness_plan(fitness_plan) except Exception as e: st.error(f"❌ 发生错误: {e}") if st.session_state.plans_generated: st.header("❓ 对您的计划有疑问?") question_input = st.text_input("您想了解什么?") if st.button("获取答案"): if question_input: with st.spinner("正在为您寻找最佳答案..."): dietary_plan = st.session_state.dietary_plan fitness_plan = st.session_state.fitness_plan context = f"饮食计划: {dietary_plan.get('meal_plan', '')}\n\n健身计划: {fitness_plan.get('routine', '')}" full_context = f"{context}\n用户问题: {question_input}" try: agent = Agent(model=gemini_model, debug_mode=True, markdown=True) run_response: RunOutput = agent.run(full_context) if hasattr(run_response, 'content'): answer = run_response.content else: answer = "抱歉,我暂时无法生成回复。" st.session_state.qa_pairs.append((question_input, answer)) except Exception as e: st.error(f"❌ 获取答案时发生错误: {e}") if st.session_state.qa_pairs: st.header("💬 问答历史") for question, answer in st.session_state.qa_pairs: st.markdown(f"**问:** {question}") st.markdown(f"**答:** {answer}") if __name__ == "__main__": main()requirements.txt
google-generativeai==0.8.3 streamlit==1.40.2 agno>=2.2.10