news 2026/5/13 10:11:29

基于大语言模型的私有化AI健康助手:Open Health Agent设计与实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于大语言模型的私有化AI健康助手:Open Health Agent设计与实践

1. 项目概述:一个真正属于你的AI健康数据管家

最近几年,我自己的健康数据越来越“散装”了。体重秤的数据在App A里,跑步机的记录在App B里,偶尔在微信上跟朋友吐槽一句“昨晚又没睡好”,这些碎片化的信息就像沙滩上的贝壳,看着挺多,但一阵浪打过来就全没了。更关键的是,这些数据都躺在别人的服务器上,隐私问题始终是悬在头顶的剑。我一直想找一个能自己掌控、能长期积累、并且能用AI帮我看出点名堂的工具,但市面上的产品要么太重(全家桶式健康管理平台),要么太轻(简单的日记App),要么就是隐私不保。

直到我开始动手搞这个项目——Open Health Agent(OHA)。它的核心目标非常明确:帮你把散落在各处的健康数据,统一收集到你自己的设备上,永久保存,并利用大语言模型(LLM)进行智能分析和主动关怀。这不是一个试图替代医生或专业医疗软件的工具,而是一个专注于“数据主权”和“长期趋势”的个人健康数据伴侣。你可以把它想象成一个永远在线、绝对忠诚、且不断进化的私人健康秘书,它的“大脑”(AI模型)可以更换和升级,但所有的“记忆”(你的健康数据)都牢牢掌握在你自己手里。

这个项目适合所有对个人健康数据有长期管理需求,同时又注重隐私和自主权的朋友。无论你是健身爱好者想追踪训练效果,是慢性病患者需要记录日常指标,还是单纯想更了解自己的身体状态,OHA都试图提供一个简单、私密且智能的起点。它的使用门槛被设计得很低——像聊天一样记录,但背后的数据架构和AI能力却足够扎实,能随着你的数据积累和AI技术的发展,提供越来越有价值的洞察。

2. 核心设计哲学:为什么OHA要这么设计?

在动手写代码之前,我花了很长时间思考这个系统的根基应该是什么。市面上很多健康类应用,其设计逻辑是“功能驱动”或“服务驱动”,而OHA选择了一条不同的路:“数据与隐私驱动”。这决定了整个项目的技术选型和架构面貌。

2.1 隐私优先:数据不出你的门

健康数据可能是我们最敏感的个人信息之一,它包含了体重变化、睡眠习惯、用药记录甚至症状描述。把这些数据上传到第三方云端服务器,意味着你将数据的控制权完全交给了服务提供商。数据泄露、服务器被黑、甚至公司政策变更导致服务关闭,都是潜在的风险。

因此,OHA的第一个,也是最重要的设计原则就是私有化部署。整个系统运行在你自己的电脑、NAS或者云服务器上。所有数据,从你聊天记录里的一句“头疼”,到AI分析生成的周报,都存储在一个本地SQLite数据库文件中。这个.db文件你可以随意备份、加密、甚至物理隔离。没有数据会未经你的允许离开你的设备。这意味着,你需要付出自己维护服务器的成本(主要是电费和网络),但换来的是对数据的绝对掌控。这是一种权衡,但对于健康数据,我认为这种权衡是值得的。

2.2 永久保留:为未来的AI保存今天的“真相”

大多数应用为了性能和存储成本考虑,会对历史数据进行归档、压缩甚至删除。但对于健康分析而言,时间本身就是最重要的维度。单独看某一天的体重毫无意义,但连续一年的体重曲线就能清晰反映生活方式的改变。更关键的是,当前AI对健康数据的分析能力(比如从一句“没精神”推断出可能与睡眠不足和饮食有关)可能只是及格水平。但三年后,更强大的AI模型或许能从同样的历史对话中,提前识别出某种潜在健康风险的早期模式。

所以,OHA采用了**“原始消息永久存储,永不删除”**的策略。所有你发送的原始文本、时间戳、通道信息都被完整保存。这些原始消息是“事实之源”(Source of Truth)。即使当前的分析提示词不够完美,导致提取的数据有偏差,未来我们也可以基于这些原始的、未经篡改的聊天记录,用更好的模型和提示词重新分析一遍,从而获得更准确的洞察。这相当于为你未来的健康AI,保存了一份高质量的训练和推理素材。

2.3 零硬编码:用提示词,而不是代码,定义健康逻辑

传统健康软件里充满了硬编码的逻辑:BMI超过24就是超重,每日饮水量要达2000毫升,睡眠少于7小时就是不足。这些标准是普适的,但未必是个性化的。一个健身运动员的“健康”BMI和一个办公室职员的“健康”BMI可能完全不同。

OHA选择将所有这些判断逻辑都交给大语言模型,通过提示词(Prompt)来驱动。代码层只负责最基础的基础设施:如何存储数据、如何连接通信通道、如何调度任务。至于“从‘中午吃了排骨饭’这句话里提取热量和营养信息”、“判断用户最近一周睡眠趋势是否恶化”、“结合花粉季节和用户过敏史给出建议”,这些全部由AI根据我们编写的提示词来完成。

这样做带来了巨大的灵活性:

  1. 模型升级即能力升级:当GPT-5、Claude-4发布时,我只需要更换API的模型参数,你的健康顾问就会立刻变得更聪明、更细致,无需修改任何一行业务代码。
  2. 迭代成本极低:发现AI对某种症状的分析不准?我不用发版更新客户端,只需要优化一下对应功能的提示词,所有用户的分析质量立刻得到提升。
  3. 高度个性化:理论上,可以为不同用户配置不同的提示词集。例如,为糖尿病患者强化血糖相关数据的关注度,为孕妇调整体重增长的分析标准。

2.4 统一入口:从“随手记”到“全景图”

最终目标是建立一个统一的健康数据枢纽。理想状态下,Apple Health、小米运动、华为健康、甚至纸质体检报告OCR后的数据,都能汇聚到OHA中。目前,我们通过最自然的方式启动这个数据积累过程:聊天

你不需要打开一个复杂的表单,选择日期、填写数值。就像给朋友发消息一样,告诉你的AI健康助手:“昨晚睡了6个半小时,但醒了两次”、“下午跑步5公里,感觉有点喘”、“今天眼睛特别干”。AI会从中提取结构化信息,并与历史数据关联。虽然当前版本主要支持手动聊天输入和Web界面,但“多源数据汇聚”的架构已经预留,这是未来扩展的核心方向。

3. 技术栈选型与架构解析

选择一个轻量、高效、现代的技术栈,对于个人部署和维护的项目至关重要。OHA的每一个技术选型都围绕着“简单”、“快”和“够用”这三个原则。

3.1 运行时与语言:为什么是Bun和TypeScript?

  • Bun:这是一个新兴的JavaScript运行时,但它不仅仅是Node.js的替代品。我选择Bun的核心原因是它的“全家桶”特性和极致的启动速度。它内置了打包器、测试运行器、包管理器(bun install的速度快得惊人),并且原生支持TypeScript和JSX。对于OHA这样一个包含前端(Vue)和后端(API服务)的全栈项目,使用Bun可以极大简化工具链,bun run dev一条命令就能拉起前后端,开发体验非常流畅。此外,Bun的SQLite驱动性能也非常优秀,直接满足了本项目核心的数据库需求。
  • TypeScript:在涉及数据模型(如健康记录、用户档案)和复杂AI交互逻辑的项目中,类型安全不是奢侈品,而是必需品。TypeScript能在编译期捕捉大量潜在的错误,比如错误地给“体重”字段赋值一个字符串,或者调用一个不存在的AI工具函数。这对于长期维护和团队协作(如果未来有的话)的价值是巨大的。Drizzle ORM与TypeScript的集成堪称完美,能实现从数据库表结构到前端类型的端到端类型安全。

3.2 数据层:SQLite与Drizzle ORM的轻量组合

数据存储是隐私优先原则的基石,选择SQLite是自然而然的事。

  • SQLite:它是一个服务器进程,只是一个磁盘文件。这意味着备份就是复制一个文件,迁移就是移动一个文件,无比简单。虽然它在高并发写入场景下可能不如PostgreSQL,但对于个人或家庭级别的健康数据记录(每秒几次写入顶天了),它的性能绰绰有余。*.db文件的可移植性和自包含性完美契合“私有化部署”和“数据主权”的理念。
  • Drizzle ORM:这是一个新兴的ORM,它的设计哲学是“如果它可以在SQL中完成,就应该在SQL中完成”。与一些重度抽象、学习曲线陡峭的ORM不同,Drizzle的API非常接近原生SQL,同时提供了极佳的类型推导。它的schema定义方式清晰直观,并且能生成高效的迁移文件。对于OHA这种表结构相对稳定但未来可能演进的项目,Drizzle在类型安全和开发效率之间取得了很好的平衡。

3.3 AI层:通过pi-ai实现多模型无感切换

AI能力是OHA的“大脑”,但我不想把用户锁定在某一个特定的模型提供商(如OpenAI)上。一方面,不同用户可能有不同的偏好和可访问性(例如国内用户访问Claude可能不便);另一方面,多模型支持也是应对某个服务商API不稳定或价格变动的技术对冲。

我选择了pi-ai这个库作为LLM的抽象层。它提供了一个统一的接口,背后可以连接Anthropic、OpenAI、智谱、Google、Mistral等几乎所有主流的大模型API。在OHA的配置中,你只需要设置LLM_PROVIDERLLM_MODEL,以及对应的API Key,代码中的AI调用逻辑完全不用改变。这种设计使得“换脑子”变得异常简单。今天你用Claude-3.5 Sonnet觉得分析得很到位,明天你想试试GPT-4o-mini看看成本,只需要修改两行环境变量,重启服务即可。

实操心得:在实际测试中,不同模型对同一提示词的反应差异很大。例如,在提取“中午吃了排骨饭”的营养信息时,有的模型会直接估算热量和宏观营养素,有的则会追问“排骨是红烧的还是清炖的?饭吃了大概几两?”。因此,提示词的编写需要有一定的鲁棒性,或者针对你主要使用的模型进行微调。项目目前主要使用智谱GLM模型进行开发和测试,因其对中文语境和本土化健康概念理解较好。

3.4 前后端与通信:全栈的轻量组合

  • 后端框架 (Hono):这是一个为边缘计算设计的超轻量级Web框架。它的API设计优秀,性能出色,而且非常小巧。对于OHA这种API路由不算特别复杂的项目,Hono比Express或Nest.js更简洁,没有历史包袱,与Bun的兼容性也极好。
  • 前端框架 (Vue 3 + Vite):选择Vue 3是因为其组合式API对于构建复杂的交互界面(如健康数据图表、聊天界面)非常直观。Vite作为构建工具,提供了闪电般的冷启动和热更新,与Bun的开发模式契合。
  • 通信通道 (Channels):这是架构中一个关键抽象层。channels/目录下的适配器,将不同的消息来源(微信、QQ、WebSocket)统一成内部可处理的“用户消息”。无论你从哪个入口发来“我头疼”,后端处理逻辑都是一样的。这为未来接入更多平台(如Telegram、Slack)铺平了道路。

3.5 核心架构目录解读

看一下src/的核心目录结构,就能理解OHA是如何组织的:

  • features/:这是业务功能的核心。每个健康功能(如diet饮食、sleep睡眠)都是一个独立的模块,包含自己的数据存储逻辑(store)、AI工具定义(tools)和专用的提示词(prompt)。这种模块化设计使得添加一个新健康数据类型(比如“血糖”)变得非常容易:新建一个feature,实现存储、工具和提示词即可。
  • agent/bot/:这是AI智能体的核心调度系统。agent/负责管理所有可用的工具(来自各个feature),并根据AI的请求调用正确的工具。bot/则为每个连接的用户维护一个独立的AI智能体实例,保存其会话状态和记忆,实现多用户隔离。
  • prompts/:存放所有系统级的提示词,例如AI的“核心人格”设定(“你是一个专业、细心且鼓励式的健康顾问”)、行为规则、以及各功能模块提示词的组装逻辑。
  • heartbeat/cron/:这是实现“主动关怀”的引擎。heartbeat是一个定时触发的AI任务,它会扫描用户近期状态,由AI判断“用户已经三天没记录饮食了,是不是该问候一下?”或者“用户上周提到眼睛干涩,今天花粉指数高,需要提醒吗?”。cron则处理更确定性的定时任务,如“每晚9点提醒吃药”。

这种架构确保了关注点分离,数据流清晰:消息从通道进入 -> 路由到对应用户的Bot -> Bot的Agent根据消息内容和历史,决定调用哪些Feature的工具 -> 工具执行(存储数据或查询数据)并返回结果 -> Agent将结果格式化为自然语言回复 -> 通过原通道返回给用户。

4. 从零开始:私有化部署与配置详解

理论说了这么多,现在我们来动手,把你自己的OHA服务跑起来。整个过程大约需要15-30分钟。

4.1 环境准备:安装Bun

OHA的核心依赖是Bun。访问 bun.sh 官网,根据你的操作系统选择安装方式。通常,在Mac/Linux上一条命令即可:

# 使用 curl 安装 curl -fsSL https://bun.sh/install | bash

安装完成后,在终端输入bun --version验证。确保版本在1.0以上。

4.2 获取代码与安装依赖

接下来,克隆项目仓库并安装依赖。依赖安装是Bun的强项,速度非常快。

# 克隆项目代码 git clone https://github.com/yaotutu/open-health-agent.git cd open-health-agent # 使用 bun 安装所有依赖 (包括前后端) bun install

这个命令会读取package.json,安装项目运行所需的所有Node模块。你会注意到,这里没有分别运行npm installnpm run client-install,因为Bun统一管理了前后端的依赖。

4.3 关键一步:配置环境变量

OHA的所有配置都通过根目录下的.env文件管理。你需要创建这个文件并填入关键信息。

# 在项目根目录,复制提供的示例配置文件 cp .env.example .env # 然后编辑 .env 文件

用文本编辑器打开.env文件,以下是最关键的配置项:

# 服务器设置 PORT=3001 # API服务端口,可自定义 DB_PATH=./data/oha.db # SQLite数据库文件路径,建议保持默认 # >>> 核心:LLM配置 <<< LLM_PROVIDER=anthropic # 或 openai, zai, google 等 LLM_MODEL=claude-3-5-sonnet-20241022 # 对应提供商的具体模型名 # 根据你选择的 LLM_PROVIDER,设置对应的 API Key ANTHROPIC_API_KEY=sk-ant-xxx... # 如果 PROVIDER=anthropic # OPENAI_API_KEY=sk-xxx... # 如果 PROVIDER=openai # ZAI_API_KEY=xxx... # 如果 PROVIDER=zai (智谱) # 心跳间隔(毫秒),默认15分钟检查一次用户状态 HEARTBEAT_INTERVAL_MS=900000 # 日志级别 LOG_LEVEL=info

关于LLM配置的深度解析:这是整个项目能“智能”起来的核心。你需要一个LLM API的访问权限和相应的Key。

  • 对于国际用户Anthropic(Claude) 和OpenAI(GPT) 是成熟稳定的选择。在.env中设置LLM_PROVIDER=anthropic,然后将你在Anthropic控制台获取的API Key填入ANTHROPIC_API_KEY即可。模型名可以在提供商文档中查到。
  • 对于国内用户:访问国际服务可能存在不便。智谱AI(Z.ai)是一个非常好的替代选择。它提供了对标GPT-4级别的GLM系列模型,对中文支持原生优秀,且API调用稳定。你需要注册智谱开放平台,获取API Key,然后设置LLM_PROVIDER=zaiLLM_MODEL=glm-4glm-5,并将Key填入ZAI_API_KEY。项目作者主要使用此模型进行测试,兼容性最有保障。
  • 其他提供商:如Google Gemini、Mistral、Groq等,理论上只需按格式配置即可使用,但可能需要根据其API特性微调提示词。

重要提示:API Key是高度敏感信息,务必确保.env文件不被提交到公开的Git仓库。项目中的.gitignore文件已经默认忽略了.env

4.4 启动服务与初始化数据库

配置完成后,启动服务就非常简单了。

# 开发模式启动(同时启动后端API和前端开发服务器) bun run dev

第一次运行这个命令时,会发生以下几件事:

  1. Bun会启动后端Hono服务器,运行在http://localhost:3001
  2. Bun会同时启动Vite前端开发服务器,运行在http://localhost:5173
  3. 后端服务会检查DB_PATH指定的SQLite数据库文件是否存在。如果不存在,Drizzle ORM会自动根据代码中定义的Schema创建数据库和所有表结构。你会在项目根目录下看到一个新生成的data/文件夹,里面包含oha.db文件。

这个过程完全自动化,无需你手动运行任何数据库迁移命令。只有当未来项目版本升级,数据库表结构有变更时,你才需要运行bun run db:push来同步Schema。

4.5 绑定你的聊天渠道

服务启动后,打开浏览器访问http://localhost:5173。你会看到OHA的Web管理界面。这里也是你绑定聊天渠道的入口。

方式一:Web界面直接交互这是最简单的开始方式。在Web界面的聊天框中,你就可以直接像使用ChatGPT一样与你的健康助手对话,例如输入“记录一下,今天体重70.5公斤”。所有记录会直接保存到本地数据库。

方式二:绑定微信(功能更完整)Web界面提供了微信绑定功能。点击“微信”标签页,用手机微信扫描弹出的二维码。扫码后,你的微信就成为了一个“机器人”好友。之后,你可以直接在微信里像跟朋友聊天一样,给它发送健康信息。这是最推荐的使用方式,因为它无缝融入你的日常通讯,记录成本最低。

方式三:绑定QQ Bot如果你更常用QQ,过程类似。你需要先前往QQ开放平台申请一个机器人,获得App ID和App Secret,然后在Web界面的QQ标签页填入,完成绑定。

方式四:通过WebSocket连接(开发者/第三方集成)对于开发者,或者你想自己开发一个客户端,可以直接连接ws://localhost:3001/ws这个WebSocket端点,按照定义好的协议进行通信。这为深度定制打开了大门。

绑定后的隐私提醒:无论是微信还是QQ,绑定过程只是建立了你的聊天工具与本地OHA服务之间的通信链路。所有消息内容都只在你的本地服务器和你的聊天工具之间传输,不会经过任何第三方中转服务器。你的健康数据依然安全地躺在你的oha.db文件里。

5. 核心功能实操:像聊天一样管理健康

服务跑起来了,我们来实际体验一下OHA的核心功能。记住,它的设计理念是“无感记录,智能分析”,所以你完全不需要学习任何复杂的操作。

5.1 聊天式记录:自然语言的力量

打开你已绑定的微信,找到你的OHA机器人,尝试发送以下任意一条消息:

  • “早上称重,71.2公斤。”
  • “昨晚大概12点睡,早上7点醒的,中间好像醒了一次。”
  • “午餐吃了一份鸡胸肉沙拉,一杯美式咖啡。”
  • “下午去健身房练了胸,卧推4组,感觉状态不错。”
  • “今天鼻炎好像有点犯了,鼻子不太通气。”

发送后,观察AI的回复。它不会只是简单地说“好的,已记录”。你会看到类似这样的回复:

“已为你记录体重:71.2公斤。对比三天前的70.8公斤略有上升,最近饮食和运动有什么变化吗?保持关注哦。”

“记录到睡眠时长约7小时。你提到中途醒来一次,最近睡眠连续性似乎有波动,建议睡前减少屏幕时间试试看。”

“已记录午餐:鸡胸肉沙拉和黑咖啡。这是一顿高蛋白、低脂的优质午餐!估算热量约350大卡。晚餐可以适当补充一些复合碳水。”

“记录了一次胸部训练。力量训练有助于提升代谢和体能,记得训练后及时补充蛋白质,帮助肌肉恢复。”

“已记录‘鼻炎’症状。当前是春季花粉季,如果是过敏性鼻炎,建议注意关窗,外出可佩戴口罩。症状持续或加重请及时就医。”

你会发现,AI做了三件事:

  1. 信息提取与结构化:从你的自然语言中,准确识别出数据类型(体重、睡眠、饮食、运动、症状)和关键数值/描述。
  2. 数据存储:将这些结构化数据存入SQLite数据库对应的表中。
  3. 上下文分析与即时反馈:结合你有限的历史数据(如果有的话),给出一个简短、相关且有鼓励性的反馈或建议。

这就是“聊天式记录”的精髓:你以最自然的方式提供信息,AI负责完成所有繁琐的结构化工作,并即时给你一个正反馈,形成记录的健康闭环。

5.2 数据类型的深度解析

OHA目前支持9大类健康数据,每一类在数据库中都对应着精心设计的表结构,以确保数据的可分析性。

数据类型核心字段与设计考量
身体数据weight(体重),body_fat_rate(体脂率),bmi(BMI)。BMI通常由系统根据体重和用户档案中的身高自动计算,避免重复输入。
饮食记录food_items(食物列表),calories(估算热量),protein/carbs/fat(宏量营养素),meal_type(早/午/晚/加餐)。AI会尝试从描述中估算营养值,这对于非精确计量饮食已足够发现趋势。
运动记录activity_type(运动类型),duration_minutes(时长),calories_burned(消耗),avg_heart_rate(平均心率),distance_km(距离)。类型和时长是核心,其他字段AI会尽力从描述中提取或合理估算。
睡眠记录sleep_duration_minutes(总时长),quality_score(自评质量),bedtime/waketime(时间点),deep_sleep_minutes(深睡时长)。时间点用于分析作息规律性。
症状记录description(描述),severity(轻度/中度/重度),body_part(身体部位),related_record_ids(关联记录)。related_record_ids是一个强大设计,例如,AI可以将“运动后膝盖疼”的症状记录,与之前“跑步10公里”的运动记录自动关联起来。
用药记录medication_name(药品),dosage(剂量),taken_at(服用时间),is_stopped(是否停药)。支持标记停药,对于追踪疗程非常重要。
慢性病追踪condition_name(疾病名),status(活跃/缓解/稳定),diagnosed_date(确诊日期)。用于长期健康管理背景。
健康观察observation(自由文本)。一个“杂物抽屉”,记录任何不适合上述分类但又重要的信息,如“今天心情很好”、“体检报告显示胆固醇偏高”。
用户档案height,birth_year,gender,medical_history,allergies,dietary_preferences,health_goals。这是AI进行个性化分析的基石,在Web界面中一次性配置好。

实操心得:如何让AI理解得更准?初期使用,AI的提取可能不够精确。你可以通过“微调”你的说话方式来引导它。例如:

  • 模糊描述:“中午吃了好多。”-> AI可能无法记录任何具体数据。
  • 优化描述:“午餐:一碗米饭,一份青椒肉丝,一碗番茄蛋汤。”-> AI更有可能识别出食物种类,并进行粗略的热量估算。
  • 带数值描述:“晚餐估计吃了600大卡左右,主要是蔬菜和鸡肉。”-> AI会直接记录你提供的热量估值,并补充食物类型。

记住,我们的首要目标是养成记录的习惯,数据的精确度可以随着AI模型的升级和你的描述优化逐步提高。即使最初只有“吃了排骨饭”这样的记录,长期积累下来,你也能看出“每周吃几次外卖”这样的模式。

5.3 智能特性体验:不止是被动记录

OHA的“智能”体现在它的主动性上。

1. 主动关怀(Heartbeat)这是由heartbeat/模块驱动的。服务启动后,一个后台定时器(默认每15分钟)会触发“心跳”任务。这个任务会:

  • 扫描所有用户最近一段时间(比如24小时)的活动记录。
  • 将用户状态(如“最近一次记录是2天前”、“最近3条记录都提到疲劳”)汇总给AI。
  • 由AI判断:“这个用户已经两天没说话了,是不是该发个消息问候一下,鼓励他记录?”或者“用户最近连续记录疲劳,结合天气变化,可以提醒他注意休息和保暖”。
  • 如果AI认为有必要,它会生成一条关怀消息,并通过绑定的通道(微信)发送给你。

这彻底改变了传统App“等你来输入”的模式,变成了一个会主动关心你的伙伴。这个判断逻辑完全由提示词控制,你可以修改提示词来调整AI的“关怀敏感度”。

2. 定时任务(Cron)对于规律性事件,比如每日服药提醒,OHA提供了标准的定时任务功能。你可以在Web界面或通过聊天(未来计划)设置:“每天晚上9点提醒我吃降压药”。到点后,AI会准时推送提醒。这比手机自带的闹钟更智能,因为它是在对话上下文中提醒,你可以直接回复“吃过了”或“今天忘了,现在补上”,AI会同步更新用药记录。

3. 记忆系统OHA为每个用户维护着两种记忆:

  • 长期记忆:存储在数据库中,包括你的用户档案、重要的健康事实(如“对花粉过敏”)、以及AI总结出的你的偏好(如“不喜欢吃西兰花”)。这些信息会在相关的分析中被持续引用。
  • 短期记忆/会话记忆:由于LLM有上下文长度限制,不可能把过去所有的聊天记录都塞进每次对话。因此,OHA采用了“摘要”策略。当一次对话较长时,AI会自动将之前的对话内容总结成一段简短的摘要,在后续对话中,将这份摘要和最近的几条消息一起送给AI,从而保持对话的连贯性,实现“它记得你刚才说过什么”。

6. 深入原理:提示词工程与Agent工作流

OHA的“智能”并非魔法,而是由精心设计的提示词和稳定的Agent工作流共同实现的。理解这部分,你就能真正掌控你的AI健康助手,甚至定制它。

6.1 模块化提示词架构

所有提示词都放在src/prompts/目录下,采用模块化设计。

  • system/:存放核心系统提示词。最重要的是core.txt,它定义了AI的“人设”和行为准则。例如:

    “你是一个专业、细心、富有同理心且鼓励式的个人健康顾问。你的目标是帮助用户轻松记录健康数据,并从长期视角提供温和、个性化的见解和建议。你绝不提供医疗诊断,总是建议用户对于严重的健康问题咨询专业医生。你的语气应友好、自然,像一位关心你的朋友。”

    这个核心提示词会在每次AI调用时被加载,奠定了所有交互的基调。

  • features/:每个健康功能模块都有自己的提示词文件。例如diet.prompt.txt里包含了如何从用户消息中提取饮食信息、如何估算热量、如何给出饮食建议的具体指令。

  • tools/:这里定义了AI可以使用的“工具”的描述。当AI认为需要执行某个操作(如“记录饮食”、“查询最近一周的睡眠”)时,它会根据这里的描述来匹配和调用后端实际实现的工具函数。

这种模块化使得管理和迭代提示词变得非常清晰。如果你想优化饮食分析,只需修改diet.prompt.txt;如果你想调整AI的说话风格,只需修改core.txt

6.2 Agent的思考与行动循环

当用户发送一条消息“中午吃了排骨饭”后,后台发生了什么?

  1. 消息接收与路由:微信通道适配器收到消息,将其转化为内部事件,路由到对应用户的Bot实例。
  2. 构造对话上下文Bot从数据库中加载该用户的近期对话历史摘要、长期记忆(档案、偏好等),连同用户的新消息一起,组装成发送给LLM的“对话上下文”。
  3. AI思考与工具调用:这个上下文被送入LLM。由于系统提示词中说明了“你可以使用工具”,LLM会分析用户意图。它识别出这是一条“饮食记录”,于是决定调用record_diet这个工具。它在回复中返回一个特殊的结构化数据,指明要调用的工具名和参数(如{“tool”: “record_diet”, “food_description”: “排骨饭”})。
  4. 工具执行Agent解析AI的返回,找到对应的record_diet工具函数(位于src/features/diet/tools.ts)并执行。这个函数会: a. 可能调用AI子过程,利用diet.prompt.txt进一步提取排骨饭的细节(数量、烹饪方式)。 b. 将结构化数据(食物:“排骨饭”,估算热量:约650大卡,餐次:“午餐”)存入diet_records表。 c. 可能查询用户最近的饮食记录,计算一些简单统计。
  5. 生成自然语言回复:工具执行的结果(成功记录、提取的数据、关联的统计)被返回给AgentAgent再次将这些结果作为新上下文,请求LLM:“用户说了‘中午吃了排骨饭’,你已经调用了工具并记录了这些数据,现在请生成一段给用户的友好回复。” LLM会生成如“已为你记录午餐:排骨饭,估算热量约650大卡。看起来是一顿丰盛的午餐!晚餐可以搭配一些清淡的蔬菜哦。”的回复。
  6. 回复发送与记忆更新:最终的回复通过微信通道发送给用户。同时,系统会将本轮完整的交互(用户消息、AI思考、工具调用、结果、最终回复)压缩摘要,更新到用户的会话记忆中,供下次对话使用。

这个“接收 -> 思考 -> 调用工具 -> 执行 -> 生成回复”的循环,是AI Agent典型的工作流。OHA的架构清晰地将这个流程实现出来,并且每个环节都是可观察、可调试的。

6.3 如何自定义与扩展?

理解了原理,你就可以动手定制你的OHA了。

1. 调整AI性格与规则直接修改src/prompts/system/core.txt。比如,如果你希望AI更严谨、更少用感叹号,或者增加一条“永远优先询问用户症状的持续时间”,在这里修改即可。修改后重启服务生效。

2. 优化现有功能假设你觉得AI对运动强度的判断不准,你可以修改src/features/sport/sport.prompt.txt。在提示词中更详细地定义不同运动类型(如“慢跑”、“高强度间歇训练”)对应的强度系数,或者提供更具体的描述示例。你甚至可以在工具函数(sport/tools.ts)中加入调用外部API(如计算MET值的API)来获取更精确的热量消耗。

3. 添加一个新健康数据类型这是更高级的扩展。假设你想增加“情绪记录”。

  • 第一步:在src/features/下创建mood目录。
  • 第二步:在mood/下创建store.ts,用Drizzle定义mood_records表(字段如mood_type(开心/平静/焦虑等)、intensitynote)。
  • 第三步:在mood/下创建tools.ts,实现record_moodquery_mood等工具函数。
  • 第四步:在mood/下创建mood.prompt.txt,编写如何从用户消息(如“今天心情有点低落”)中提取情绪数据,以及如何分析情绪与睡眠、运动等关联的提示词。
  • 第五步:在src/agent/tools.ts中注册这个新工具。
  • 第六步:重启服务。现在你就可以对AI说“今天心情有点低落”,它会自动记录并可能关联你最近的睡眠数据进行分析。

这种扩展方式完全遵循了“数据+提示词驱动”的原则,无需修改核心调度代码。

7. 常见问题、排查与优化指南

在实际部署和使用中,你可能会遇到一些问题。这里汇总了一些常见情况及解决方法。

7.1 部署与启动问题

Q1: 运行bun run dev时报错,提示端口被占用。A1: 默认端口是3001(后端)和5173(前端)。你可以修改.env中的PORT变量来更改后端端口。前端端口修改需要在vite.config.ts中调整。或者,先找出占用端口的进程并关闭它(在Linux/Mac上用lsof -i :3001,在Windows上用netstat -ano | findstr :3001)。

Q2: 启动成功,但访问http://localhost:5173前端页面空白或报错。A2:

  • 检查后端API服务是否真的在运行。访问http://localhost:3001/health,应该返回{"status":"ok"}
  • 检查浏览器控制台(F12)的Network标签,看前端是否成功加载了JS资源,或者是否有CORS错误。OHA的前后端在开发模式下通过Vite代理连接,通常不会有CORS问题,如果遇到,请检查vite.config.ts中的代理配置。
  • 尝试清除浏览器缓存或使用无痕模式。

Q3: 微信/QQ扫码绑定失败。A3:

  • 确保你的服务能被外网访问:微信/QQ机器人需要回调你的服务器。如果你在本地电脑运行,需要做内网穿透(如使用ngrok、frp等工具),将localhost:3001暴露到一个公网HTTPS地址,并在对应的Bot配置中(如pure-wechatbot的配置)填写这个公网回调地址。
  • 检查日志:查看服务启动时的日志,确认微信/QQ通道的适配器是否成功初始化,以及是否打印了正确的二维码或登录URL。
  • 确认依赖:确保pure-wechatbotpure-qqbot这些通道依赖已正确安装。

7.2 AI功能相关问题

Q4: AI回复慢,或者经常超时。A4:

  • 网络问题:首先检查你的服务器到LLM API服务(如智谱、OpenAI)的网络连接是否稳定。可以尝试用curlping测试。
  • 模型太大:如果你使用的是GPT-4Claude-3.5-Sonnet这类大型模型,推理速度本身就会慢于小模型。可以尝试切换到更快的模型,如GPT-4o-miniClaude-3.5-Haiku或智谱的GLM-4-Flash
  • 上下文过长:如果用户的历史对话很长,每次都会携带大量上下文,会导致API调用缓慢且昂贵。OHA的摘要机制就是为了缓解这个问题。检查src/session/下的摘要逻辑,看是否正常工作。
  • 提示词过于复杂:过于冗长或复杂的提示词会增加AI的思考时间。尝试优化提示词,使其更简洁、指令更明确。

Q5: AI提取信息不准确,比如把“散步”识别成“跑步”。A5:

  • 优化提示词:这是最主要的手段。去对应的功能提示词文件(如src/features/sport/sport.prompt.txt)中,增加更明确的示例和规则。例如,明确写出:“如果用户描述中包含‘慢走’、‘散步’、‘溜达’等词,则运动类型为‘步行’;如果包含‘快跑’、‘跑步’、‘慢跑’等词,则类型为‘跑步’。”
  • 提供更明确的输入:用户也可以调整表达方式,如说“散步30分钟”而不是“走了半小时”。
  • 切换或微调模型:不同模型的理解能力不同。可以尝试更换一个在中文或特定领域表现更好的模型。对于复杂场景,可以考虑在调用工具前,增加一个“澄清”步骤,让AI先反问用户确认细节。

Q6: 主动关怀(Heartbeat)没有触发。A6:

  • 检查配置:确认.envHEARTBEAT_INTERVAL_MS的值不是0或过大。默认900000毫秒(15分钟)是合理的。
  • 检查日志:启动服务时,日志中应该会打印“Heartbeat scheduler started”。在心跳触发时,也会有相应的日志。查看日志级别是否设置为infodebug
  • 理解触发逻辑:主动关怀不是定时群发消息。它是AI基于对用户近期状态的分析后“决定”是否发送。如果用户最近记录很频繁,AI可能认为不需要问候。你可以修改src/heartbeat/下的提示词,降低AI发送关怀消息的“阈值”。

7.3 数据与备份

Q7: 数据库文件 (data/oha.db) 越来越大,怎么办?A7: SQLite数据库文件会随着使用增长,这是正常的。由于OHA设计为“永不删除”原始数据,文件会持续增大。你需要定期备份这个文件。

  • 手动备份:直接复制oha.db文件到其他安全位置(如加密云盘、外部硬盘)。
  • 自动化备份:可以写一个简单的脚本(Shell或Python),定期(如每天)复制数据库文件并压缩归档。由于SQLite在备份时允许读取,可以在服务运行时直接复制,但为了数据一致性,建议在低峰期或短暂停止服务时进行。
  • 数据导出:未来可以考虑开发一个数据导出功能,将数据以CSV或JSON格式导出,方便用其他工具分析。

Q8: 我想迁移服务器,如何操作?A8: OHA的迁移极其简单,得益于其“单文件存储”设计。

  1. 在新服务器上按照“快速开始”步骤安装环境、克隆代码、安装依赖。
  2. 将旧服务器上的整个data/目录(或者至少是oha.db文件)复制到新服务器的项目对应位置。
  3. 将旧的.env配置文件复制到新服务器(注意修改其中可能与环境相关的路径,如果没改则不用动)。
  4. 在新服务器上运行bun run devbun run server启动服务。
  5. 重新在Web界面绑定你的微信/QQ(因为Bot的登录状态通常与本地存储的token有关,迁移后需要重新登录)。你的所有历史数据都完整地保存在oha.db文件中,会随之迁移。

7.4 安全与隐私强化

Q9: 如何让我的OHA服务更安全?A9: 私有化部署本身已是最大安全保障,但你还可以:

  • 服务器安全:确保运行OHA的服务器系统及时更新补丁,使用强密码,关闭不必要的端口。
  • 网络隔离:如果不需从外网访问,仅在家庭内网使用,那么风险极低。如果需要外网访问以便在外使用微信Bot,务必使用HTTPS。可以通过Nginx反向代理并配置SSL证书来实现。
  • 数据库加密:SQLite本身不提供加密。对于极度敏感的数据,可以考虑使用支持加密的SQLite版本(如SQLCipher),但这需要修改代码中的数据库驱动。
  • 环境变量保护:确保.env文件权限设置为仅当前用户可读(chmod 600 .env),并且绝不泄露其中的API Key。

Q10: 我的API Key存在.env里安全吗?如果泄露了怎么办?A10: 在私有服务器上,.env文件是相对安全的存储方式,远好于将Key硬编码在代码中。但如果服务器被入侵,Key仍会泄露。最佳实践是:

  • 为OHA创建一个专用的API Key,并设置使用限额(如每月花费上限)。
  • 定期轮换(更换)API Key。
  • 如果使用云服务商的LLM,查看其控制台是否有IP白名单功能,将Key限制为只能从你的服务器IP调用。
  • 一旦怀疑泄露,立即在对应平台撤销旧的Key,生成新Key并更新.env文件。

8. 未来展望与进阶玩法

OHA作为一个开源项目,其生命力在于社区的扩展和个人的定制。除了基础的健康记录,它的架构允许它向更多有趣的方向发展。

1. 集成更多数据源这是最直接的扩展。可以开发“连接器”(Connectors)来同步其他平台的数据:

  • Apple Health / Google Fit:通过导出XML或使用(用户授权后的)API,将步数、心率、睡眠等数据定期同步到OHA。
  • 智能硬件:通过厂商API(如Withings、Garmin)或蓝牙直接连接,导入体脂秤、血压计的数据。
  • 电子病历/体检报告:通过OCR技术识别体检报告图片,结构化提取关键指标(如血脂、血糖)并记录。

2. 更强大的分析与可视化当前的分析主要基于LLM的即时推理。可以引入:

  • 时序数据分析:使用简单的统计库(如simple-statistics)计算移动平均、环比变化等,将结果提供给LLM,让它的周报或总结更有数据支撑。
  • 基础图表:在Web前端集成ECharts或Chart.js,自动生成体重曲线图、睡眠质量趋势图等。
  • 关联性分析:通过数据分析,尝试发现症状与饮食、运动与睡眠之间的潜在关联(例如,“每次喝咖啡的第二天,深睡时间减少”),并提示用户注意。

3. 个性化健康计划与干预基于长期数据,AI可以扮演更积极的角色:

  • 自动生成微习惯建议:分析用户数据后,提出“未来一周,尝试每天提前15分钟睡觉”这样的具体、可执行建议。
  • 用药依从性追踪:对于需要长期服药的用户,AI不仅可以提醒,还可以分析记录,生成服药依从性报告。
  • 与智能家居联动:通过Home Assistant或IFTTT等平台,实现“当AI检测到用户连续晚睡,自动调暗卧室灯光并播放助眠音乐”的场景。

4. 模型微调与本地化部署对于高级用户,可以探索:

  • 提示词优化社区:建立一个共享提示词库,用户可以导入别人优化好的“饮食分析”、“运动建议”提示词模块。
  • 本地模型部署:随着开源LLM(如Llama、Qwen)能力的提升,可以将模型部署在本地显卡上,实现完全离线的、零API成本的健康助手。这需要较强的硬件和技术知识,但无疑是隐私的终极解决方案。

Open Health Agent的旅程才刚刚开始。它从一个简单的想法出发——拿回自己健康数据的控制权,并用AI让它产生价值。它的代码是开源的,它的架构是开放的,它的未来取决于每一个使用它、改进它的你。无论是提交一个Bug修复,开发一个新的数据连接器,还是只是分享你使用它管理健康的故事,都是在共同构建一个更私密、更智能的个人健康未来。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/13 10:09:36

如何用pywencai快速获取同花顺问财数据:三步实现金融数据自动化

如何用pywencai快速获取同花顺问财数据&#xff1a;三步实现金融数据自动化 【免费下载链接】pywencai 获取同花顺问财数据 项目地址: https://gitcode.com/gh_mirrors/py/pywencai 在量化投资和金融数据分析的世界里&#xff0c;获取准确、及时的股票数据是每个投资者和…

作者头像 李华
网站建设 2026/5/13 10:08:28

具身智能(Embodied AI):当Agent拥有了物理身体

目录 具身智能&#xff08;Embodied AI&#xff09;&#xff1a;当Agent拥有了物理身体引言&#xff1a;AI的“身体觉醒”一、定义具身智能&#xff1a;不止是“给AI装个身体”1.1 具身智能的三个核心要素1.2 为什么“身体”对智能至关重要&#xff1f; 二、技术路线&#xff1…

作者头像 李华
网站建设 2026/5/13 10:07:32

Relic:为AI编码助手注入持久记忆与人格的开源系统

1. 项目概述&#xff1a;Relic&#xff0c;一个为AI编码助手注入灵魂与记忆的系统如果你和我一样&#xff0c;每天花大量时间与Claude Code、Cursor这类AI编码助手对话&#xff0c;你可能会发现一个痛点&#xff1a;每次开启一个新的会话&#xff0c;它都像一张白纸。你需要重新…

作者头像 李华
网站建设 2026/5/13 10:07:18

UI自动化+AI测试工具大全

UI自动化AI测试工具大全——除了Midscene.js&#xff0c;这些你也应该试试 上个月我接手了一个电商项目的前端自动化回归任务。按老办法&#xff0c;我用Playwright写了200个用例&#xff0c;跑一遍要40分钟&#xff0c;维护起来心累。更崩的是&#xff0c;活动页的弹窗样式隔两…

作者头像 李华
网站建设 2026/5/13 10:06:27

基于Nuxt 4与Shadcn/ui的现代全栈仪表板开发实战

1. 项目概述&#xff1a;一个现代全栈仪表板的技术栈选择 最近在做一个内部管理后台&#xff0c;需要快速搭建一个既美观又功能齐全的仪表板。我的核心需求很明确&#xff1a;开发要快、代码质量要高、用户体验要好&#xff0c;并且要能轻松应对多语言场景。在评估了市面上各种…

作者头像 李华