山东大学软件学院-项目实训-个人开发日志(六):生长曲线、儿保检查与成长阶段能力深化
引言
大家好,我是山东大学软件学院2023级本科生张钧虹,“字节摇篮队”负责人。
在前一阶段开发中,我主要围绕BabyMind的统一问答入口、RAG知识库和多Agent路由推进项目的AI核心能力建设。那一阶段的重点,是让系统具备“能理解问题、能调用知识、能输出结构化回答”的能力。而在这一阶段中,我重新把注意力拉回到了BabyMind作为“科学育儿辅助平台”的另一条核心主线:成长管理。
对于0-3岁婴幼儿家庭来说,真正重要的不只是“问一句能不能答出来”,更在于系统能不能围绕宝宝成长过程中的连续数据,提供长期可追踪、可提醒、可解释的服务能力。也正因为如此,这一阶段我主要推进了以下几项工作:
- 新增宝宝生长曲线追踪能力,引入WHO标准曲线和异常检测;
- 补充儿保检查独立调度逻辑,使成长管理不再只依赖普通提醒;
- 将原来的成长时间轴进一步重构为1-36月龄独立阶段组织方式;
- 增加本地推送通知,让提醒能力真正从“页面内可见”走向“主动触达”。
一、为什么这一阶段要优先生长管理能力,而不是继续只做AI对话
在项目推进过程中,我越来越明确地意识到:BabyMind不能只是一个“会回答问题的育儿问答工具”,它还必须是一个能够围绕宝宝成长过程持续积累信息、持续给出反馈的系统。
因为在真实使用场景下,很多家长并不是每天都来主动提问,而是希望系统能够帮助他们回答这些更长期的问题:
- 宝宝最近体重和身高增长是否正常?
- 当前月龄除了疫苗之外,还有哪些儿保检查需要注意?
- 这个月龄阶段的发育重点到底是什么?
- 如果宝宝近期出现了生长偏低、偏高等情况,系统能不能主动提醒,而不是等家长发现异常后再来提问?
这些问题说明,育儿平台如果只停留在“被动对话”层面,能力仍然是不完整的。系统必须进一步具备:
- 成长数据记录能力;
- 阶段性发育信息组织能力;
- 异常提醒能力;
- 主动通知能力。
所以这一阶段,我把更多精力投入到了成长管理相关模块,而不是单纯继续堆叠对话能力。
二、生长曲线模块开发:让宝宝成长情况能够被量化追踪
在成长管理能力中,我认为最基础、也最有价值的一项,就是生长曲线。因为宝宝的体重、身高、头围等数据,本身就是最典型、最连续、也最能反映发育状态的一类信息。如果系统无法对这些数据进行记录和解释,那么“科学育儿”就缺少了非常关键的一部分依据。
这一阶段,我新增了生长曲线服务,对应核心逻辑位于backend/services/growth_service.py。这一模块中,我直接内嵌了0-36月龄WHO标准曲线数据,覆盖男孩和女孩的体重、身高两类参考值。每个月龄都给出了多个百分位点:
WHO_WEIGHT_BOYS: dict[int, tuple] = {
0: (2.5, 2.9, 3.3, 3.9, 4.4),
1: (3.4, 3.9, 4.5, 5.1, 5.8),
2: (4.3, 4.9, 5.6, 6.3, 7.1),
...
}
在此基础上,我进一步实现了简化的z分数估算与异常检测逻辑。例如:
def compute_z_score(value: float, age_months: float, metric: str, sex: str) -> float:
p3, p15, p50, p85, p97 = _percentiles_for_age(_table(metric, sex), age_months)
spread = (p85 - p15) / 2
if spread <= 0:
return 0.0
return (value - p50) / spread
同时,系统会根据实测值与P3、P97的关系判断是否需要提示异常。例如:
- 低于P3:提示偏低;
- 高于P97:提示偏高;
- 位于P15-P85之外但未超出红线:标记为边缘区间。
具体写入和检测逻辑位于:
def add_growth_record(
db: Session,
user,
baby: BabyProfile,
weight_kg: float | None,
height_cm: float | None,
head_cm: float | None,
recorded_at: datetime,
notes: str | None,
) -> tuple[GrowthRecord, list[str]]:
这里我不仅返回了保存后的记录,还会返回一组alerts,用于提示当前测量是否存在明显异常。生长曲线模块开始具备基础的分析能力。
三、从记录数据到联动系统:生长异常开始影响其他模块
我在这一阶段最关注的一点是这些数据能不能进一步影响系统中的其他能力。如果生长曲线只是一个孤立页面,那么它的价值其实还是有限的。真正重要的是:一旦系统检测到生长异常,能不能继续把这种变化传给其他模块。
因此,在生长曲线接口层中,我增加了检测异常后异步通知其他Agent的逻辑。对应代码位于backend/api/routers/growth.py,其中新增记录接口如下:
@router.post("/record", response_model=GrowthRecordResponse, status_code=status.HTTP_201_CREATED)
def add_record(
payload: GrowthRecordCreate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> GrowthRecordResponse:
在保存成功之后,如果检测到alerts非空,就会继续异步通知营养Agent和时间轴Agent:
if alerts:
alert_text = ";".join(alerts)
_dispatch_growth_notification(
baby_id=baby.id,
alert_text=alert_text,
baby_name=baby.name,
age_months=record.age_months,
)
这里的设计思路非常符合BabyMind整体架构方向:
- 生长异常可以推动营养Agent调整饮食建议;
- 生长异常也可以推动时间轴Agent增加儿保随访提醒。
也就是说,生长数据开始不再只是“被动展示”,而是成为系统内部联动的新触发点。
四、儿保检查独立调度:让成长管理不只停留在普通提醒层
在之前的提醒模块中,系统已经可以根据宝宝月龄给出成长提醒和疫苗提醒。但随着项目继续推进,我越来越觉得:儿保检查这一类事项不能只被简单地看成“普通提醒”。原因很简单,儿保检查本身具有更强的阶段性、标准性和结构化特征。它和普通的成长提示不同,更像是成长管理中的一条独立主线。
因此,这一阶段我新增了儿保检查独立调度逻辑,对应核心服务位于backend/services/checkup_service.py,这个模块会在宝宝档案创建后,一次性生成标准儿保检查记录。
def create_checkups_for_baby(db: Session, baby: BabyProfile) -> list[PediatricCheckup]:
existing_ages = {
checkup.age_months for checkup in db.scalars(
select(PediatricCheckup).where(PediatricCheckup.baby_id == baby.id)
).all()
}
created = False
for age_months in CHECKUP_AGES:
if age_months in existing_ages:
continue
db.add(
PediatricCheckup(
baby_id=baby.id,
age_months=age_months,
scheduled_date=_compute_scheduled_date(baby.birth_date, age_months),
status=CheckupStatus.PENDING.value,
)
)
这里的核心设计点是,儿保检查不再由前端手工录入也不只是简单依赖提醒模板即时算出,而是以独立数据记录的方式,成为成长管理中的正式对象。
同时,在状态处理上,我也没有强制依赖后台定时任务,而是在读取时动态推导逾期状态:
def _effective_status(checkup: PediatricCheckup, *, today: date | None = None) -> str:
if checkup.status == CheckupStatus.COMPLETED.value:
return CheckupStatus.COMPLETED.value
if checkup.scheduled_date < today:
return CheckupStatus.OVERDUE.value
return CheckupStatus.PENDING.value
五、成长时间轴重构:从粗粒度年龄段走向1-36月龄独立阶段
在此前的开发中,成长时间轴已经具备了聚合提醒、疫苗和健康记录的基础能力。但随着系统中成长相关数据越来越多,我逐渐发现:仅靠原有的统一事件流式展示,还不足以支撑“成长阶段管理”这一需求。
因为对于0-3岁育儿场景来说,很多信息本质上是以“月龄阶段”为单位组织的。家长真正关心的问题通常是:
- 3月龄重点关注什么?
- 6月龄有哪些发育和喂养变化?
- 12月龄有哪些疫苗和儿保节点?
- 24月龄又有哪些新的阶段任务?
因此,这一阶段我进一步引入了月龄阶段化组织方式,对应逻辑位于backend/services/timeline_stage_service.py。这一层的目标,是将已有的成长提醒、疫苗安排、儿保检查、早教建议按月龄重新聚合,形成1-36月龄的离散阶段结构。
核心构建逻辑如下:
def build_monthly_stage(month: int) -> MonthlyStage:
growth = _GROWTH_BY_MONTH.get(month)
tips = find_tips_for_age(month)
vaccines = [
StageVaccine(title=template.title, description=template.description, target_month=template.target_month_age)
for template in _VACCINES_BY_MONTH.get(month, [])
]
checkup_data = CHECKUP_SCHEDULE.get(month)
同时,我还提供了完整的阶段列表构建方法:
def build_monthly_stages(
start_month: int = TIMELINE_MIN_MONTH,
end_month: int = TIMELINE_MAX_MONTH,
) -> list[MonthlyStage]:
start = max(start_month, TIMELINE_MIN_MONTH)
end = min(end_month, TIMELINE_MAX_MONTH)
return [build_monthly_stage(month) for month in range(start, end + 1)]
这一部分对我来说非常重要,因为它意味着成长管理开始有了“阶段视图”这一新的组织方式。也就是说,BabyMind不再只是按时间线堆叠事件,而是能进一步从“月龄成长结构”角度重新整理信息。这比简单的列表式事件聚合,更符合家长理解宝宝成长节律的方式。
六、本地推送通知:让系统开始具备主动触达能力
在育儿场景中,我一直觉得提醒功能如果只能停留在页面里,其实价值是有限的。
因为很多真正重要的节点,比如:
- 未来几天需要接种疫苗;
- 儿保检查即将到期;
- 生长异常需要关注;
- 宝宝接近新的月龄里程碑;
如果必须依赖用户主动打开App才能看到,那它就仍然是“被动信息展示”,而不是“主动辅助”。所以这一阶段,我进一步增加了待推送通知聚合能力,对应服务位于backend/services/notification_service.py,这个模块会统一汇总多类可推送事件,例如:
- 未来7天内待接种的疫苗;
- 未来14天内的儿保检查;
- 生长异常告警;
- 接近整月生日时的里程碑提醒。
聚合入口如下:
def get_pending_notifications(
db: Session,
user: User,
baby: BabyProfile,
) -> list[PendingNotification]:
today = date.today()
results: list[PendingNotification] = []
plans = list_vaccine_plans_for_baby(db, baby)
results.extend(_build_vaccine_notifications(plans, baby=baby, today=today))
results.extend(_build_growth_alert_notifications(db, baby, today=today))
然后在接口层,通过backend/api/routers/notifications.py向前端提供统一的待推送通知列表:
@router.get("/pending", response_model=list[PendingNotification])
def list_pending_notifications(
baby_id: int = Query(..., description="目标宝宝 id"),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> list[PendingNotification]:
前端方面,我在Android端通过WorkManager增加了后台轮询逻辑。对应代码位于frontend/app/src/main/java/com/babymind/notifications/NotificationWorker.kt,核心处理过程如下:
override suspend fun doWork(): Result {
val session = SessionManager(applicationContext)
val token = session.getAuthToken() ?: return Result.success()
val babyId = session.getCurrentBabyId() ?: return Result.success()
val response = RetrofitClient.instance.getPendingNotifications("Bearer $token", babyId)
...
}
七、前端页面补充:让成长管理能力真正可见、可操作
除了后端逻辑,我也同步推进了Android端页面实现。
1、生长曲线页
对应代码位于frontend/app/src/main/java/com/babymind/ui/screens/GrowthCurveScreen.kt,在这一页中,我实现了:
- 体重/身高曲线切换;
- WHO参考线展示;
- 生长记录录入;
- 数据点点击查看详情;
- 历史记录展示与删除。
这意味着生长曲线不只是后端有了数据结构,而是真正具备了前端交互能力。
2、成长阶段页
对应代码在frontend/app/src/main/java/com/babymind/ui/screens/GrowthStagesScreen.kt,这一页把1-36月龄阶段按卡片形式展示出来,并支持快速跳转月份、展开查看本月疫苗、儿保与早教建议。
八、这一阶段的主要收获与后续计划
这一阶段开发完成后,我对BabyMind整体结构有了更清晰的认识:
第一,项目中的“成长管理”能力开始真正成形。它已经不再只是几个零散页面,而是逐渐包含了:
- 生长记录;
- 曲线分析;
- 儿保调度;
- 月龄阶段组织;
- 主动提醒。
第二,项目中的数据联动进一步加深。生长异常不再只是显示出来,而是开始推动营养和时间轴能力联动,这说明系统内部不同模块之间的关系更加真实。
第三,前端和后端开始共同支撑“长期陪伴式育儿辅助”这一定位。从记录、展示到提醒,这些能力都比单次问答更贴近真实产品形态。
接下来,我会继续围绕以下方向推进:
- 继续优化成长曲线与时间轴的前端交互体验;
- 进一步增强成长数据与Agent问答之间的结合;
- 在现有成长管理基础上,继续推进多模态输入、语音交互和更自然的对话体验。
结语
这一阶段,我主要围绕生长曲线、儿保检查、成长阶段组织和本地通知等能力推进了BabyMind的成长管理模块开发。
相比前一阶段更多聚焦在“AI能不能回答问题”,这一阶段我更关注的是:系统能不能围绕宝宝的成长过程,持续记录、持续分析、持续提醒,并在关键节点主动参与育儿过程。
欢迎各位老师、同学批评指正!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)