BabyMind 项目后端第八周周报进入第八周后项目的工作重心从功能完整转向体验可用。前七周已建立起完整的多Agent问答、RAG知识库和语音交互框架但在实际测试中暴露出一批影响演示质量的问题Agent响应时间过长、同一问题出现两段重复回答、营养问题误触发医疗风险警告、TTS语音无法播放等。本周围绕这些问题展开了系统性的修复与增强同时新增了多模态图片识别和停止生成两项功能进一步提升系统的实用性。一、本周整体完成内容1. 实现SSE流式传输解决感知延迟问题此前系统采用阻塞式请求Agent完整生成答案约20秒后才一次性返回前端白屏等待体验极差。本周在后端新增/qa/ask/stream接口基于FastAPI的StreamingResponse实现服务器发送事件SSE。后端通过接入LangGraph的astream_events(versionv1)接口在Agent执行的各关键节点依次推送状态消息请求到达后100ms内推送BabyMind 正在为您调度专家...Supervisor路由完成后推送具体专家名称健康专家/成长顾问/营养师RAG检索开始时推送正在翻阅权威育儿指南...最终逐token流式推送答案内容完成后发送携带完整结构化答案的done事件。前端相应改造了SSE客户端基于OkHttp EventSourceQAViewModel新增statusText和streamingAnswer两个状态流QAScreen和HomeScreen均加入脉冲动画状态栏用户在发送问题后不足1秒即可看到界面动态反馈首字延迟从20秒降至1秒以内。2. 修复双重回复问题测试中发现Agent对同一问题会在同一输出中出现两段完整答案。通过在qa_stream_service.py中记录每个token事件的langgraph_node字段确认了根本原因LangGraph图中存在两条生成路径。正常路径下create_react_agent内部的agent节点产生答案其langgraph_node为agent兜底路径下_run_agent中的_synthesize_final_answer直接调用llm.invoke产生的token的langgraph_node为外层专家节点名nutrition/health/timeline。原有过滤条件node ! supervisor仅过滤了路由层两条生成路径的token均被放通导致用户看到两段答案。修复方案是新增_NON_STREAMING_NODES {supervisor, health, timeline, nutrition}集合将过滤条件改为node not in _NON_STREAMING_NODES仅保留嵌套的agent节点token进入流式输出。兜底路径产生的答案仍通过done事件的full_response字段送达客户端确保两种路径下用户各只看到一次完整答案。3. 修复风险等级误触发此前营养类问题如0个月宝宝能吃辅食吗会触发高风险警告弹窗原因有二一是风险等级字段在三个Agent的所有回答中均存在二是SSE路径使用关键词启发式推断风险等级过敏风险、消化负担、避免等正常营养建议用语误触发了高风险判定。修复分为两层。后端层面agent_router_service在营养和时间轴分支强制将risk_level置为None仅健康Agent保留该字段SSE路径的关键词推断同样以is_health标志门控且高风险触发词收窄为真正的医疗紧急词汇高热不退、抽搐、惊厥、拨打120等。前端层面新增shouldShowQaRisk()防御函数仅当agentType health且riskLevel为中/高时才渲染风险标签低风险标签对用户不可见。4. 新增多模态图片识别育儿场景中家长拍照询问宝宝皮疹、上传食品标签核查过敏原、发送宝宝动作视频截图确认发育里程碑等需求自然且高频。本周基于Qwen/Qwen3-VL-32B-Instruct实现了三个Agent的图片理解能力。后端新建backend/utils/vision_utils.py提供build_multimodal_message()工具函数将图片base64和文字拼装为符合OpenAI多模态格式的消息体。配置层新增独立的vision_llm实例仅当请求中携带image_base64字段时切换至视觉模型文字路径零改动。三个Agent的系统提示词各自增加了领域专属的图片分析指令健康Agent专注皮肤/伤口描述与症状判断时间轴Agent对比宝宝动作与月龄里程碑营养Agent提取食品标签成分并核查过敏原。后端同时添加了2MB的图片大小限制超限返回413错误。前端在输入框上方新增ImageInputRow组件支持拍照和相册两种来源图片压缩至800×800px以内转为base64随请求发送完成后自动清除预览。5. 修复TTS语音播报语音播报功能此前持续返回HTTP 403本次排查确认根本原因是音色字段格式错误SiliconFlow的CosyVoice2-0.5B要求音色字段使用完整前缀格式如FunAudioLLM/CosyVoice2-0.5B:claire而原代码直接传裸名如claire导致鉴权失败。修复后后端新增resolve_voice()函数统一处理音色字符串兼容旧格式的同时保证新请求始终使用完整前缀。音色选项对应关系更新为温柔女声→claire沉稳男声→alex欢快女声→diana。前端同步实现了TTS音频播放链路收到MP3二进制数据后写入临时文件通过MediaPlayer播放完成后删除临时文件Agent回答完成后自动触发朗读消息气泡出现脉冲喇叭图标点击可停止播放语音设置页新增语音播报开关默认开启。6. 新增停止生成功能用户在Agent回答过程中无法中断遇到答非所问的回答只能等待完成再重新提问体验较差。本周在前端新增停止按钮流式传输进行中时替换发送按钮显示点击后取消streamingJob协程OkHttp EventSource随之关闭后端通过await request.is_disconnected()检测到连接断开后退出生成循环。已生成的部分内容以⏹ 已停止后缀追加至消息列表保留并计入下一轮的conversation_history避免上下文断裂。输入框在流式传输期间保持可用状态用户可提前准备下一个问题。7. 清除Agent回答中的Markdown符号Agent回答中频繁出现#、**、*等Markdown符号Android原生文本组件不做渲染这些符号原样呈现影响阅读。修复分两层在三个Agent及Supervisor的系统提示词首行加入不得使用任何Markdown格式的明确约束后端输出层同时对所有用户可见的文本字段core_conclusion、action_steps、cautions应用strip_markdown()后处理函数确保即便模型偶发违反指令符号也不会透传到前端。二、本周核心代码与模块SSE流式传输backend/services/qa_stream_service.py新建backend/api/routers/qa.pyfrontend/.../network/SseClient.kt新建frontend/.../viewmodel/QAViewModel.kt双重回复修复backend/services/qa_stream_service.py_NON_STREAMING_NODES过滤集合风险等级修复backend/services/agent_router_service.pybackend/utils/ui_helpers.pyshouldShowQaRiskfrontend/.../screens/QAScreen.ktfrontend/.../screens/HomeScreen.kt多模态图片识别backend/utils/vision_utils.py新建backend/agents/multi_agent_graph.pybackend/api/routers/qa.pyfrontend/.../ui/utils/ImagePickerHelper.kt新建frontend/.../ui/components/ImageInputRow.kt新建TTS语音播报backend/services/voice_service.pybackend/core/config.pyfrontend/.../ui/utils/AudioPlayer.kt新建frontend/.../data/VoiceRepository.ktfrontend/.../screens/VoiceSettingsScreen.kt停止生成frontend/.../viewmodel/QAViewModel.ktfrontend/.../screens/QAScreen.ktfrontend/.../screens/HomeScreen.ktbackend/services/qa_stream_service.py三、本周遇到的问题与解决思路1. TTS 403的根本原因定位TTS功能自接入以来持续返回HTTP 403最初判断为SiliconFlow账号权限问题花费了较多时间在账号配置上排查。最终通过对比SiliconFlow官方API文档示例发现问题根源是音色字段必须携带模型前缀FunAudioLLM/CosyVoice2-0.5B:claire而非裸名。这一格式要求在文档中仅以示例形式体现并无显眼的错误说明导致排查路径走了弯路。修复后语音播报功能完全正常端到端延迟约1.5秒。2. 兜底合成路径与正常路径的token过滤冲突修复双重回复时最初考虑将过滤条件改为白名单只放通health/timeline/nutrition节点的token但实际测试发现这恰好相反兜底合成路径的token节点名正是这三个专家节点白名单反而会流出重复内容并屏蔽正确的agent节点token。通过日志记录全部token事件的节点名后明确了正确答案由嵌套的agent节点产生修复方向随即明确将三个专家节点名加入排除集合仅保留agent节点的token进入流式输出。四、阶段性成果经过第八周的集中修复与增强BabyMind项目完成了从功能能跑到体验可用的关键跨越。语音播报全链路打通多模态图片识别覆盖三个核心Agent流式传输让首字延迟从20秒降至1秒以内长期存在的双重回答和风险误报问题均得到根本性修复。当前系统能力可以概括为用户输入文字 / 语音 / 图片 ↓ 确定性路由 LangGraph Supervisor 分发 ↓ 三专家Agent健康 / 时间轴 / 营养并行工具调用 ↓ RAG检索权威知识库876条含国家卫健委 / WHO / 中华医学会来源 ↓ 结合宝宝个人档案月龄 / 过敏原 / 健康记录 / 对话历史 ↓ SSE流式输出结构化中文回答附来源标注 TTS语音朗读 ↓ 必要时自动联动疫苗计划 / 营养推荐 / 健康档案第八周是项目进入答辩准备阶段前的最后一次集中整改后续工作重心将转向演示流程打磨、验收指标补全和线上环境稳定性保障。
BabyMind 项目后端第八周周报
BabyMind 项目后端第八周周报进入第八周后项目的工作重心从功能完整转向体验可用。前七周已建立起完整的多Agent问答、RAG知识库和语音交互框架但在实际测试中暴露出一批影响演示质量的问题Agent响应时间过长、同一问题出现两段重复回答、营养问题误触发医疗风险警告、TTS语音无法播放等。本周围绕这些问题展开了系统性的修复与增强同时新增了多模态图片识别和停止生成两项功能进一步提升系统的实用性。一、本周整体完成内容1. 实现SSE流式传输解决感知延迟问题此前系统采用阻塞式请求Agent完整生成答案约20秒后才一次性返回前端白屏等待体验极差。本周在后端新增/qa/ask/stream接口基于FastAPI的StreamingResponse实现服务器发送事件SSE。后端通过接入LangGraph的astream_events(versionv1)接口在Agent执行的各关键节点依次推送状态消息请求到达后100ms内推送BabyMind 正在为您调度专家...Supervisor路由完成后推送具体专家名称健康专家/成长顾问/营养师RAG检索开始时推送正在翻阅权威育儿指南...最终逐token流式推送答案内容完成后发送携带完整结构化答案的done事件。前端相应改造了SSE客户端基于OkHttp EventSourceQAViewModel新增statusText和streamingAnswer两个状态流QAScreen和HomeScreen均加入脉冲动画状态栏用户在发送问题后不足1秒即可看到界面动态反馈首字延迟从20秒降至1秒以内。2. 修复双重回复问题测试中发现Agent对同一问题会在同一输出中出现两段完整答案。通过在qa_stream_service.py中记录每个token事件的langgraph_node字段确认了根本原因LangGraph图中存在两条生成路径。正常路径下create_react_agent内部的agent节点产生答案其langgraph_node为agent兜底路径下_run_agent中的_synthesize_final_answer直接调用llm.invoke产生的token的langgraph_node为外层专家节点名nutrition/health/timeline。原有过滤条件node ! supervisor仅过滤了路由层两条生成路径的token均被放通导致用户看到两段答案。修复方案是新增_NON_STREAMING_NODES {supervisor, health, timeline, nutrition}集合将过滤条件改为node not in _NON_STREAMING_NODES仅保留嵌套的agent节点token进入流式输出。兜底路径产生的答案仍通过done事件的full_response字段送达客户端确保两种路径下用户各只看到一次完整答案。3. 修复风险等级误触发此前营养类问题如0个月宝宝能吃辅食吗会触发高风险警告弹窗原因有二一是风险等级字段在三个Agent的所有回答中均存在二是SSE路径使用关键词启发式推断风险等级过敏风险、消化负担、避免等正常营养建议用语误触发了高风险判定。修复分为两层。后端层面agent_router_service在营养和时间轴分支强制将risk_level置为None仅健康Agent保留该字段SSE路径的关键词推断同样以is_health标志门控且高风险触发词收窄为真正的医疗紧急词汇高热不退、抽搐、惊厥、拨打120等。前端层面新增shouldShowQaRisk()防御函数仅当agentType health且riskLevel为中/高时才渲染风险标签低风险标签对用户不可见。4. 新增多模态图片识别育儿场景中家长拍照询问宝宝皮疹、上传食品标签核查过敏原、发送宝宝动作视频截图确认发育里程碑等需求自然且高频。本周基于Qwen/Qwen3-VL-32B-Instruct实现了三个Agent的图片理解能力。后端新建backend/utils/vision_utils.py提供build_multimodal_message()工具函数将图片base64和文字拼装为符合OpenAI多模态格式的消息体。配置层新增独立的vision_llm实例仅当请求中携带image_base64字段时切换至视觉模型文字路径零改动。三个Agent的系统提示词各自增加了领域专属的图片分析指令健康Agent专注皮肤/伤口描述与症状判断时间轴Agent对比宝宝动作与月龄里程碑营养Agent提取食品标签成分并核查过敏原。后端同时添加了2MB的图片大小限制超限返回413错误。前端在输入框上方新增ImageInputRow组件支持拍照和相册两种来源图片压缩至800×800px以内转为base64随请求发送完成后自动清除预览。5. 修复TTS语音播报语音播报功能此前持续返回HTTP 403本次排查确认根本原因是音色字段格式错误SiliconFlow的CosyVoice2-0.5B要求音色字段使用完整前缀格式如FunAudioLLM/CosyVoice2-0.5B:claire而原代码直接传裸名如claire导致鉴权失败。修复后后端新增resolve_voice()函数统一处理音色字符串兼容旧格式的同时保证新请求始终使用完整前缀。音色选项对应关系更新为温柔女声→claire沉稳男声→alex欢快女声→diana。前端同步实现了TTS音频播放链路收到MP3二进制数据后写入临时文件通过MediaPlayer播放完成后删除临时文件Agent回答完成后自动触发朗读消息气泡出现脉冲喇叭图标点击可停止播放语音设置页新增语音播报开关默认开启。6. 新增停止生成功能用户在Agent回答过程中无法中断遇到答非所问的回答只能等待完成再重新提问体验较差。本周在前端新增停止按钮流式传输进行中时替换发送按钮显示点击后取消streamingJob协程OkHttp EventSource随之关闭后端通过await request.is_disconnected()检测到连接断开后退出生成循环。已生成的部分内容以⏹ 已停止后缀追加至消息列表保留并计入下一轮的conversation_history避免上下文断裂。输入框在流式传输期间保持可用状态用户可提前准备下一个问题。7. 清除Agent回答中的Markdown符号Agent回答中频繁出现#、**、*等Markdown符号Android原生文本组件不做渲染这些符号原样呈现影响阅读。修复分两层在三个Agent及Supervisor的系统提示词首行加入不得使用任何Markdown格式的明确约束后端输出层同时对所有用户可见的文本字段core_conclusion、action_steps、cautions应用strip_markdown()后处理函数确保即便模型偶发违反指令符号也不会透传到前端。二、本周核心代码与模块SSE流式传输backend/services/qa_stream_service.py新建backend/api/routers/qa.pyfrontend/.../network/SseClient.kt新建frontend/.../viewmodel/QAViewModel.kt双重回复修复backend/services/qa_stream_service.py_NON_STREAMING_NODES过滤集合风险等级修复backend/services/agent_router_service.pybackend/utils/ui_helpers.pyshouldShowQaRiskfrontend/.../screens/QAScreen.ktfrontend/.../screens/HomeScreen.kt多模态图片识别backend/utils/vision_utils.py新建backend/agents/multi_agent_graph.pybackend/api/routers/qa.pyfrontend/.../ui/utils/ImagePickerHelper.kt新建frontend/.../ui/components/ImageInputRow.kt新建TTS语音播报backend/services/voice_service.pybackend/core/config.pyfrontend/.../ui/utils/AudioPlayer.kt新建frontend/.../data/VoiceRepository.ktfrontend/.../screens/VoiceSettingsScreen.kt停止生成frontend/.../viewmodel/QAViewModel.ktfrontend/.../screens/QAScreen.ktfrontend/.../screens/HomeScreen.ktbackend/services/qa_stream_service.py三、本周遇到的问题与解决思路1. TTS 403的根本原因定位TTS功能自接入以来持续返回HTTP 403最初判断为SiliconFlow账号权限问题花费了较多时间在账号配置上排查。最终通过对比SiliconFlow官方API文档示例发现问题根源是音色字段必须携带模型前缀FunAudioLLM/CosyVoice2-0.5B:claire而非裸名。这一格式要求在文档中仅以示例形式体现并无显眼的错误说明导致排查路径走了弯路。修复后语音播报功能完全正常端到端延迟约1.5秒。2. 兜底合成路径与正常路径的token过滤冲突修复双重回复时最初考虑将过滤条件改为白名单只放通health/timeline/nutrition节点的token但实际测试发现这恰好相反兜底合成路径的token节点名正是这三个专家节点白名单反而会流出重复内容并屏蔽正确的agent节点token。通过日志记录全部token事件的节点名后明确了正确答案由嵌套的agent节点产生修复方向随即明确将三个专家节点名加入排除集合仅保留agent节点的token进入流式输出。四、阶段性成果经过第八周的集中修复与增强BabyMind项目完成了从功能能跑到体验可用的关键跨越。语音播报全链路打通多模态图片识别覆盖三个核心Agent流式传输让首字延迟从20秒降至1秒以内长期存在的双重回答和风险误报问题均得到根本性修复。当前系统能力可以概括为用户输入文字 / 语音 / 图片 ↓ 确定性路由 LangGraph Supervisor 分发 ↓ 三专家Agent健康 / 时间轴 / 营养并行工具调用 ↓ RAG检索权威知识库876条含国家卫健委 / WHO / 中华医学会来源 ↓ 结合宝宝个人档案月龄 / 过敏原 / 健康记录 / 对话历史 ↓ SSE流式输出结构化中文回答附来源标注 TTS语音朗读 ↓ 必要时自动联动疫苗计划 / 营养推荐 / 健康档案第八周是项目进入答辩准备阶段前的最后一次集中整改后续工作重心将转向演示流程打磨、验收指标补全和线上环境稳定性保障。