私有化AI健康助手Open Health Agent:数据自主与智能分析实践
1. 项目概述一个真正属于你的AI健康数据管家健康数据可能是我们每个人最熟悉却又最陌生的资产。说熟悉是因为我们每天都在产生它——早上称体重、中午记录午餐、晚上看睡眠报告。说陌生是因为这些数据就像散落在沙滩上的珍珠东一颗西一颗永远拼不成完整的项链。它们被困在Apple Health、小米运动、华为健康这些互不相通的“数据孤岛”里换一次手机、换一个平台就丢失一部分历史。更让人不安的是这些包含了体重、病史、用药、睡眠习惯的极度敏感信息正躺在别人的服务器上你既无法完全掌控也难以进行长期、深度的分析。这就是我决定动手搭建Open Health Agent的初衷。它不是一个简单的健康记录App而是一个基于大语言模型LLM的、私有化部署的AI健康顾问Agent。它的核心使命很简单帮你把散落的健康数据统一收集起来永久保存在你自己的设备上然后交给AI进行智能分析和趋势洞察。你可以把它理解为一个24小时在线的、只为你服务的私人健康助理但它不依赖任何云端服务所有数据、所有分析过程都发生在你完全掌控的环境里。这个项目适合谁如果你和我一样对个人数据隐私有要求希望长期追踪自己的健康趋势又厌倦了在不同App间手动同步数据的繁琐那么OHA就是你一直在找的解决方案。它不需要你填写复杂的表格像和朋友聊天一样随口说一句“今天跑了5公里感觉有点累”AI就能理解并记录还能关联你之前的睡眠数据提醒你可能是休息不足。接下来我将从设计思路、实操部署到深度使用为你完整拆解这个项目。2. 核心设计哲学为什么“私有化”和“数据永存”是基石在动手写一行代码之前我花了大量时间思考这个系统的根基应该是什么。市面上不缺健康类App但它们大多逃不开两个问题一是数据隐私二是数据价值被短期化。OHA的设计哲学正是针对这两个痛点提出的彻底解决方案。2.1 隐私优先为什么健康数据必须“私有化”健康数据可能是比银行卡密码更敏感的信息。你的体重变化、睡眠障碍、用药历史、甚至是不经意间提到的“最近压力大胃不舒服”这些信息一旦泄露后果不堪设想。很多云服务承诺加密和安全但本质上只要数据离开你的设备控制权就不完全在你手中。服务器被攻击、内部人员泄露、甚至是服务商变更隐私政策都是潜在风险。因此OHA的第一个设计原则就是“私有化部署”。整个系统——包括后端API、前端界面、数据库——都运行在你自己的服务器、NAS甚至是高性能的个人电脑上。数据从产生你发送消息、到处理AI分析、到存储SQLite数据库全链路都在你的本地网络或你信任的VPS中完成不经过任何第三方服务器。SQLite单文件数据库的设计让你可以随时用U盘拷贝备份或者整个迁移到新设备赋予了数据真正的物理可携带性。2.2 数据永存让时间成为你健康分析的朋友绝大多数健康App为了性能和存储成本都会对历史数据做清理或聚合。比如只保留最近一年的详细记录更早的数据则被压缩成月度平均值。这对于健康分析来说是致命的因为健康是一个长期、连续的状态。单独看三个月前的某次体重毫无意义但把它放在一整年的体重曲线里你就能清晰看到季节变化、生活习惯调整带来的影响。OHA采用了“原始消息永久存储永不删除”的策略。所有你发送的原始聊天记录都会被原封不动地保存下来作为唯一的“事实来源”。这意味着即使今天AI的分析模型还不够完美只做了简单的记录和归类等到明年更强大的模型出现时你可以用新的模型重新分析过去一整年的原始对话挖掘出更深层次的关联和洞察。数据的价值会随着时间积累和AI技术的进步而不断增值。这个设计让OHA从一个记录工具变成了一个可以伴随你十年、二十年的个人健康数据资产库。2.3 零硬编码用提示词驱动拥抱AI的进化传统软件的功能边界是由代码写死的。比如代码里会硬编码“BMI大于24属于超重”那么无论未来医学界对BMI标准有何修正你的系统判断逻辑都是过时的。OHA彻底摒弃了这种模式采用了“数据 提示词驱动”的架构。代码层只负责最基础的基础设施安全地存取数据、在不同通道微信、QQ间传输消息、调度AI任务。而所有关于“这是什么健康数据”、“如何分析”、“给出什么建议”的智能部分全部交给大语言模型并通过精心设计的提示词来引导。例如判断一次运动是否过量不是靠代码判断“心率180持续10分钟”而是由提示词告诉AI“请根据用户年龄、日常运动水平和本次运动后的主观感受如‘非常累’综合评估本次运动强度是否合理并给出恢复建议。”这样做的好处是巨大的模型越强顾问越智能今天你用的是GPT-4它可能只能做基础记录。明天你换成了Claude-4它就能进行更复杂的因果推理。系统能力随着你更换LLM提供商而自动升级。迭代无需改代码当你需要增加对“间歇性断食”这种新健康理念的支持时你不需要找开发者更新App。你只需要在提示词库中增加关于断食的规则和分析逻辑AI立刻就能理解并应用。个性化成为可能你可以微调提示词让AI更符合你的个人偏好。比如如果你不喜欢严厉的督促可以加入“建议语气以鼓励为主”的指令。3. 系统架构深度解析一个高效、可扩展的Agent引擎理解了设计哲学我们再来看看OHA是如何用代码将这些理念落地的。它的架构清晰体现了“关注点分离”和“可插拔”的设计思想这让它既稳定又易于扩展。3.1 核心模块分工整个项目的源代码结构非常清晰每个目录都有明确的职责src/features/这是业务功能的核心。每个健康功能如饮食、运动、睡眠都是一个独立的“特性模块”。每个模块通常包含三部分store定义数据表、tools提供给AI调用的工具函数如“记录一次饮食”、prompts指导AI如何理解和处理该功能相关对话的提示词。这种模块化设计意味着新增一个“血糖追踪”功能只需要在此目录下新建一个文件夹而不影响其他任何代码。src/agent/这里是AI智能的“大脑”所在。它负责管理所有从features/收集来的工具Tools并根据当前对话的上下文决定调用哪个工具或者如何组合多个工具来完成任务。它包含一个“工具查询工厂”能快速为AI匹配可用的操作。src/bot/这是“用户会话”的管理层。每个连接到OHA的用户无论是通过微信还是QQ都会在这里创建一个独立的Bot实例。这个实例持有该用户的所有上下文、记忆和AI对话状态确保了用户间的完全隔离和数据安全。src/prompts/系统的“知识库”和“行为准则”。这里存放了系统级的提示词定义了AI健康顾问的核心角色“你是一位细心、严谨的私人健康助理”、行为规则“优先考虑用户隐私不追问敏感细节”以及分析框架。修改这里的提示词就能全局改变AI的“性格”和分析深度。src/heartbeat/与src/cron/这两个模块共同实现了系统的“主动性”。cron是传统的定时任务系统处理“每晚10点提醒吃药”这种固定任务。而heartbeat心跳机制则更加智能它周期性地如每15分钟唤醒AI让它主动“思考”“用户上次提到胃不舒服是两天前我现在是否需要主动问候一下恢复情况” 这使OHA从一个被动的问答机器变成了一个有关怀感的主动型助手。3.2 数据流与工作流程一次典型的交互流程是这样的消息接收你在微信上对OHA说“中午吃了麻辣香锅好饱。”通道路由channels/wechat模块收到消息将其转化为内部统一的事件格式发送给核心服务器。会话处理session/模块根据你的用户ID找到或创建对应的会话加载最近的对话历史短期记忆和你的用户档案长期记忆。Agent决策agent/核心被触发。它将你的消息、历史上下文以及所有可用的健康工具列表一起封装成一个提示词发送给配置好的LLM比如Claude。AI分析与工具调用LLM理解到这是一条“饮食记录”。它可能会做两件事调用工具决定调用features/diet/tools.ts中的recordMeal工具并生成结构化参数{ food: “麻辣香锅” estimatedCalories: 850, mealType: “lunch” }。生成回复同时它会根据features/diet/prompts.ts中的指导生成一条友好且有用的回复“已为您记录午餐麻辣香锅约850大卡。这道菜通常油脂和钠含量较高建议晚餐可以清淡一些多吃些蔬菜。”数据持久化与响应工具函数被调用将这条结构化记录写入features/diet/store.ts定义的SQLite数据表中。AI生成的文本回复被传回channels/wechat模块最终以微信消息的形式发送给你。整个对话的摘要可能会被更新到会话的短期记忆中供下次交互参考。这个流程充分体现了“数据驱动”和“提示词驱动”代码不关心“麻辣香锅”是什么它只提供记录饮食的“工具”是AI和提示词共同决定了这是一条需要记录的数据并估算其热量。所有原始消息“中午吃了麻辣香锅好饱”都会被永久保存未来可以用更精准的营养模型重新分析。4. 从零开始部署与配置实战理论讲得再多不如亲手跑起来。OHA的部署相对简单但其中有些配置细节关乎稳定性和使用体验这里我会结合自己的踩坑经验带你走一遍。4.1 基础环境搭建OHA使用Bun作为运行时这是一个新兴的、速度极快的JavaScript/TypeScript工具链。第一步就是安装它。# 在Linux/macOS上安装Bun curl -fsSL https://bun.sh/install | bash # 安装完成后重启你的终端或运行 source ~/.bashrc (或 ~/.zshrc) # 验证安装 bun --version # 应该输出 1.0.x 或更高版本注意如果你在国内网络环境使用官方脚本安装Bun可能会很慢或失败。一个更可靠的方法是使用镜像。可以先安装一个简单的包管理器比如用npm安装bunnpm install -g bun但这种方式可能不是最新版。最稳妥的方式还是通过科学上网环境执行官方安装脚本。接下来获取项目代码并安装依赖git clone https://github.com/yaotutu/open-health-agent.git cd open-health-agent bun installbun install的速度通常比npm install快很多这是选择Bun的一个实际好处。4.2 关键配置详解.env文件项目根目录下的.env文件是整个系统的配置核心。复制.env.example文件并重命名然后开始编辑。下面我逐项解释关键配置# 服务器配置 PORT3001 DB_PATH./data/oha.dbPORTAPI服务监听的端口。如果3001被占用可以改成其他端口比如3002。DB_PATHSQLite数据库文件的路径。默认放在项目下的data目录。强烈建议你将它改为一个绝对路径例如DB_PATH/home/yourname/oha-data/oha.db。这样即使你以后移动项目代码位置数据库文件也不会丢失。记得提前创建好对应的目录mkdir -p /home/yourname/oha-data。# LLM 提供商配置核心 LLM_PROVIDERanthropic LLM_MODELclaude-3-5-sonnet-20241022 ANTHROPIC_API_KEYsk-ant-xxxx...你的API密钥这是最重要的部分决定了AI的“智力”来源。OHA通过pi-ai库支持多家提供商你需要选择一家服务商并获取API Key例如去Anthropic或OpenAI官网注册购买。设置LLM_PROVIDER为对应的提供商标识如anthropic,openai。设置LLM_MODEL为具体的模型名称。这里有个大坑项目文档的示例模型可能已过时。比如Anthropic的最新模型是claude-3-5-sonnet-20241022而不是文档里的claude-sonnet-4-6。务必去对应厂商的官方文档查看最新的、可用的模型名称。设置对应的环境变量如ANTHROPIC_API_KEY或OPENAI_API_KEY。# 心跳与任务间隔 HEARTBEAT_INTERVAL_MS900000这个配置定义了AI“主动关怀”的检查频率默认15分钟900000毫秒。AI会在这个间隔内扫描用户状态决定是否主动发送问候或提醒。如果你觉得太频繁可以调大这个值比如36000001小时。# 日志级别 LOG_LEVELinfo开发调试时可以设为debug会打印非常详细的日志包括AI思考过程。生产环境建议用info或warn减少日志量。4.3 数据库初始化与启动配置好.env后就可以启动了。数据库会在首次启动时自动创建。# 开发模式启动同时启动后端API和前端Web界面 bun run dev如果一切顺利终端会输出服务启动成功的日志并自动打开浏览器访问http://localhost:5173前端。API服务运行在http://localhost:3001。首次启动常见问题排查端口冲突如果PORT3001已被占用修改.env文件中的端口号并重启服务。前端开发服务器端口是固定的5173通常不会冲突。数据库权限错误如果你将DB_PATH改到了如/opt/oha/data.db这样的系统目录确保运行Bun的用户对该目录有读写权限sudo chown -R $USER:$USER /opt/oha。API Key错误如果LLM服务连接失败控制台会报错。请仔细检查API Key是否正确是否包含多余空格。LLM_PROVIDER和LLM_MODEL的名称是否完全正确区分大小写。你的API账户是否有余额或调用权限。依赖安装失败如果bun install失败可以尝试删除node_modules和bun.lockb文件再重新运行。有时网络问题会导致依赖不完整。4.4 通道绑定连接你的聊天软件启动成功后访问http://localhost:5173你会看到一个简洁的Web界面。这里有三个主要的通道绑定选项WebSocket直连这是最简单的方式适合开发者或喜欢用命令行工具的用户。你不需要绑定任何第三方服务直接使用WebSocket客户端连接ws://localhost:3001/ws即可收发消息。你可以用wscat这样的工具快速测试。# 安装wscat npm install -g wscat # 连接OHA的WebSocket wscat -c ws://localhost:3001/ws # 连接成功后直接输入文字消息即可与AI交互微信绑定这是对普通用户最友好的方式。点击Web界面上的“微信”标签页会显示一个二维码。你需要使用手机微信扫描这个二维码进行绑定。重要提示这个功能基于作者另一个开源项目pure-wechatbot它使用的是微信的iLink协议一种非官方的开发协议。这意味着存在封号风险使用非官方协议可能导致微信账号被限制登录。强烈建议使用一个小号或不太重要的微信账号进行绑定切勿使用主力账号扫码后你的微信会在电脑上登录一个“微信网页版”OHA通过这个登录会话来收发消息。请确保你的微信支持网页登录。QQ Bot绑定点击“QQ”标签页你需要填入从QQ开放平台申请的Bot的App ID和App Secret。申请QQ机器人需要企业资质流程相对复杂个人用户使用微信或WebSocket通道更为方便。绑定成功后你就可以在对应的聊天窗口里像和朋友聊天一样开始记录你的健康数据了。5. 日常使用技巧与深度功能探索系统跑起来了但怎么用它才能真正发挥价值这部分分享一些我深度使用后的心得和进阶技巧。5.1 聊天记录的艺术如何与AI高效沟通OHA的核心交互是自然语言但说得好AI理解得才准。下面是一些高效记录的句式记录数据时尽量包含上下文低效“体重 65”。AI不知道是早上还是晚上穿衣服了吗高效“早上起床空腹称重65公斤。” AI会记录为一次标准的晨间空腹体重高效“健身后感觉好累晚餐吃了一份鸡胸肉沙拉。” AI能关联“运动”和“饮食”并理解“累”是运动后的正常反应描述症状时具体化模糊“头疼。”具体“从下午开始右侧太阳穴一阵一阵地胀痛没有发烧。” AI可以更精确地记录并在未来你提到“睡眠不足”时可能将两者关联利用AI的关联分析能力你可以主动提问“我这周睡眠和头疼有关系吗” AI会检索你过去一周的睡眠记录和症状记录尝试找出模式。记录时也可以暗示关联“昨晚只睡了5小时今天一整天都没精神还头疼。” AI在记录这两条信息时可能会在内部笔记中标记它们的潜在联系。5.2 用户档案让你的AI顾问更懂你在Web界面的设置中有一个“用户档案”区域。花10分钟认真填写这里AI的分析质量会提升一个档次。基础信息身高、年龄、性别。这是计算BMI、评估热量需求的基础。健康目标“减重”、“增肌”、“维持健康”、“改善睡眠”。AI会根据你的目标调整建议的语气和侧重点。比如目标是“减重”当你记录高热量食物时它的提醒可能会更明确一些。疾病史与过敏史这里填写的信息会成为AI的“长期记忆”。例如你填写了“过敏性鼻炎花粉”那么当春天你提到“鼻子不舒服”时AI会主动关联到花粉过敏并给出“注意关窗、使用空气净化器”的建议而不是笼统地说“可能感冒了”。饮食偏好“素食”、“不吃辣”、“乳糖不耐”。AI在给出饮食建议时会避开这些。比如你记录了“喝了牛奶胃痛”AI可能会提醒“您之前标记过乳糖不耐建议选择无乳糖牛奶”。5.3 主动关怀与定时任务从被动记录到主动管理这是OHA区别于普通记录App的亮点功能。主动关怀Heartbeat系统每隔一段时间默认15分钟会“唤醒”AI让它检查所有用户的状态。AI会根据一套内置的提示词规则来判断是否需要主动发言。例如规则“如果用户超过24小时没有记录任何数据且之前活跃则发送一条友好的关怀问候。”规则“如果用户昨天记录了‘感冒症状’但今天没有更新则主动询问恢复情况。” 你会偶尔收到AI发来的“今天感觉怎么样”或“记得上次你说肩膀酸好点了吗”这样的消息这种“被记得”的感觉是坚持记录的一大动力。定时任务Cron这是完全可定制的提醒系统。在Web界面的“定时任务”板块你可以创建周期任务每天 22:00- 任务内容“提醒用户服用降压药”。固定时间提醒一次性任务2023-10-27 09:00- 任务内容“明天上午体检今晚10点后禁食禁水。”特定事件提醒基于数据的智能任务需手动或扩展这是更高级的用法。理论上你可以写一个脚本监控数据库当“连续三天平均睡眠时长6小时”时自动创建一个“建议调整作息”的提醒任务。目前版本需要一定开发能力来实现。5.4 数据查看与导出掌握你的健康全景图所有记录的数据除了通过聊天查询都可以在Web前端清晰地查看。时间线视图按时间顺序展示所有类型的记录饮食、运动、症状等一眼看清每天发生了什么。图表分析对于体重、睡眠时长等数值型数据系统会自动生成趋势折线图。这是观察长期变化最直观的方式。原始数据导出在设置页面你可以将整个SQLite数据库文件备份出来。由于是标准的SQLite格式你可以用任何数据库工具如DB Browser for SQLite打开执行自定义的SQL查询做更复杂的分析。也可以定期导出.csv文件导入到Excel或专业统计软件中。6. 常见问题、故障排查与进阶维护即使设计再完善在实际部署和长期使用中总会遇到一些问题。这里我整理了可能遇到的坑和解决办法。6.1 部署与连接问题问题现象可能原因排查步骤与解决方案运行bun run dev后无法访问localhost:51731. 前端依赖安装失败。2. 端口被占用。3. 防火墙阻止。1. 查看终端日志是否有编译错误。尝试rm -rf node_modules bun.lockb后重新bun install。2. 使用lsof -i:5173查看端口占用杀死相关进程或修改Vite配置vite.config.ts。3. 检查本地防火墙设置。微信扫码后无法绑定或收不到消息1. 微信账号风控网页登录被限制。2.pure-wechatbot服务异常。3. 网络问题。1.这是最常见原因。换一个微信小号尝试。确保该微信号近期有正常登录和使用记录。2. 查看后端日志搜索wechat相关错误。重启服务试试。3. 确保运行OHA的服务器可以访问互联网。AI回复慢或无响应1. LLM API请求超时或失败。2. 本地网络到API服务商延迟高。3. 提示词过于复杂导致AI“思考”时间过长。1. 检查终端日志看是否有LLM API Error。确认API Key有效、模型名称正确、账户有余额。2. 如果你在国外调用国内智谱AI可能快在国内调用Anthropic/OpenAI可能慢。考虑选择网络延迟低的提供商。3. 暂时简化提示词测试。数据库文件损坏或无法写入1. 磁盘空间不足。2. 文件权限错误。3. 多进程同时写入罕见。1. 检查磁盘空间df -h。2. 检查DB_PATH指向的文件和目录权限确保运行进程的用户有读写权。3. 确保没有同时运行多个OHA实例。备份当前数据库文件尝试用SQLite工具修复。6.2 功能与使用问题问题现象可能原因排查步骤与解决方案AI无法正确理解我的记录如把“跑步”记录成“饮食”1. 当前LLM模型的理解能力有限。2. 提示词对于模糊语句的引导不够强。1. 尝试更换更强大的模型如从gpt-3.5-turbo换到gpt-4或claude-3.5-sonnet。2. 可以微调对应功能的提示词。例如在features/exercise/prompts.ts中更明确地列举运动相关的关键词。需要开发知识主动关怀功能从未触发1.HEARTBEAT_INTERVAL_MS设置过长。2. 心跳服务未正常启动。3. AI判断“无需关怀”。1. 检查.env配置可以暂时改为600001分钟测试。2. 查看日志搜索heartbeat关键词看是否有定时执行的记录。3. 主动关怀的触发依赖于AI的判断如果它认为你最近很“活跃”或状态“良好”可能不会打扰。你可以尝试24小时不互动看是否会触发。我想增加新的健康数据类型如“血压”系统默认不支持。这是OHA扩展性的体现。你需要1. 在src/features/下新建blood-pressure目录。2. 创建store.ts定义数据表。3. 创建tools.ts定义“记录血压”的工具函数。4. 创建prompts.ts教AI如何从对话中识别血压信息如“高压120低压80”。5. 在src/agent/tool-provider.ts中注册这个新工具。这是一个标准的二次开发过程。6.3 数据安全与备份策略这是私有化部署项目的生命线务必重视。定期备份数据库DB_PATH指定的.db文件就是你的全部健康数据。最简单的备份方式就是定期复制这个文件。# 示例每天凌晨3点备份一次保留最近7天 # 可以将此命令加入 crontab 0 3 * * * cp /path/to/your/oha.db /path/to/backup/oha-$(date \%Y\%m\%d).db # 再配合一个清理旧备份的脚本 0 4 * * * find /path/to/backup -name oha-*.db -mtime 7 -delete加密备份如果备份到云盘如Dropbox, iCloud建议先对数据库文件进行加密。可以使用gpg或openssl。# 使用openssl加密备份 openssl enc -aes-256-cbc -salt -in oha.db -out oha-$(date \%Y\%m\%d).db.enc -pass pass:你的强密码 # 解密 openssl enc -d -aes-256-cbc -in oha-20231027.db.enc -out restored.db -pass pass:你的强密码版本升级当项目代码更新时数据库表结构schema可能会变更。在拉取最新代码后运行bun run db:push命令来同步数据库结构。务必在操作前备份数据库6.4 性能优化与长期运行如果你打算在树莓派或低配VPS上7x24小时运行可以考虑以下优化使用进程守护不要让OHA仅仅运行在终端前台使用systemd或pm2来管理进程保证崩溃后自动重启。# 使用pm2示例 bun install -g pm2 cd /path/to/open-health-agent pm2 start bun run server --name oha-agent pm2 save pm2 startup # 设置开机自启优化LLM调用成本如果使用按Token收费的API如OpenAI频繁的主动关怀和长对话历史会增加成本。可以考虑调低HEARTBEAT_INTERVAL_MS频率。在src/session/的摘要逻辑中调整对话历史压缩的策略减少每次请求的Token数量。对于非核心分析可以考虑使用更便宜的小模型如gpt-3.5-turbo在配置中切换。日志管理长期运行会产生大量日志。配置LOG_LEVELwarn减少日志输出并设置日志轮转logrotate避免日志文件撑满磁盘。这个项目最吸引我的地方在于它不仅仅是一个工具更是一个关于个人数据主权的实践。它把数据的控制权和所有权连同其未来可能产生的所有价值都完整地交还给了用户自己。在使用的这几个月里我养成了随手记录的习惯而AI偶尔发来的、基于我一周数据生成的简短周报或者一句恰到好处的问候让我感觉它不像一个程序更像一个逐渐了解我生活节奏的伙伴。如果你也厌倦了数据孤岛和隐私担忧不妨花上一个下午把它部署起来开始积累这份真正属于你自己的数字健康资产。