团队项目第一次作业
天气与出行智能助手:让行程建议经得起天气变化
博客信息
| 项目 | 内容 |
|---|---|
| 作业所属课程 | 【软件工程】 |
| 班级的链接 | 【团队项目第一次作业 团队展示+选题报告+需求分析 - 作业 - 计科24级56班 - 班级博客 - 博客园】 |
| 作业要求 | 课程作业要求 |
| 作业的目标 | 开发并上线一个嵌入智能体能力的软件产品,围绕真实需求完成选题、需求分析与团队协作,并通过答辩和博客展示成果。 |
| 团队名称 | 慢游指南团队 |
| 团队成员学号-名字 | 3224004083-许艺琳;3224004120-曾盈洁;3224004080-李蔓淇;3224004116-邓炜娟;3224004119-严翊郗 |
| 项目名称 | 天气与出行智能助手(Weather Travel Assistant) |
| 项目地址 | 在线体验 · GitHub 仓库 |
一、团队展示
1. 队名:漫游指南
我们的目标不是只给出一份“看起来不错”的旅游推荐,而是让每一项出行建议都能够结合目的地天气、景点信息和交通路线,在天气变化时给出可执行的调整方案。
2. 团队项目:天气与出行智能助手
“天气与出行智能助手”是一款面向短途出游、周末出行和陌生城市游玩的 Web 应用。用户输入城市、日期、偏好和预算后,系统会查询天气、搜索真实景点、生成早中晚行程,并给出景点之间的交通方案;用户也可以使用自然语言在聊天页面中继续追问或修改计划。
项目由 Spring Boot 后端、网页交互界面和第三方服务协同完成。天气数据来自 Open-Meteo;景点和路线数据来自高德 Web 服务;聊天 Agent 通过 DashScope 的兼容接口进行自然语言理解。所有密钥只通过部署环境变量读取,不出现在前端、代码仓库或博客中。
3. 队员风采
以下信息请按实际成员资料补全。若课堂允许使用昵称,可将姓名替换为昵称。
| 成员 | 学号 | 性格 | 兴趣爱好 | 期望软工角色 |
|---|---|---|---|---|
| A: 许艺琳 | 3224004083 | 随意 | 读书 | 后端开发者 |
| B: 李蔓淇 | 3224004080 | 内向 | 看书 | 前端开发 |
| C: 邓炜娟 | 3224004116 | 活泼 | 看小说 | 嵌入式软件 |
| D: 严翊郗 | 3224004119 | 内向 | 看书 | 产品 |
| E: 曾盈洁 | 3224004120 | 耐心 | 看书 | 后端 |
4. 项目愿景
我们希望把“查天气”和“做攻略”从彼此独立的信息搜索,变成一次可持续的出行决策过程。用户不必在多个应用之间反复切换,也不必依据过期攻略盲目安排行程;系统应基于真实天气、真实景点和真实路线,主动识别高温、暴雨、大风等风险,并在用户确认后调整计划。未来项目将完善语音交互、多人共享行程与线上部署,让它真正成为出发前和旅途中的轻量出行助手。
二、选题报告
项目标志
标志以太阳、云朵、定位图钉和路线为核心元素:太阳和云朵代表天气感知,图钉代表目的地,弯曲路线代表从信息查询到可执行行程的连接。蓝绿色表达可靠、清晰的数字服务,黄色强调出行的活力与晴朗体验。
1. 问题背景与真实需求
许多用户的出行决策存在三个断层:
- 天气应用只给数据,用户仍要自行判断是否适合户外活动;
- 攻略平台给出景点推荐,但常常没有把当天的天气、距离和交通时长一起考虑;
- 行程一旦生成,天气突变或偏好改变时,用户需要重新搜索、重新安排,缺少连续修改能力。
因此,本项目选择“天气 + 真实地点 + 路线 + 对话式调整”的组合。它服务于城市一日游、周末游、亲子游、美食探索等高频场景,适用范围覆盖学生、家庭、游客和短期差旅人群。
2. 产品定位与核心用户
| 用户类型 | 典型场景 | 核心痛点 | 本项目价值 |
|---|---|---|---|
| 学生/年轻游客 | 周末临时决定出游 | 时间有限,攻略信息分散 | 快速得到当天可执行的一日计划 |
| 家庭用户 | 带儿童或老人出行 | 对天气风险和室内备选敏感 | 根据天气提示风险并切换活动偏好 |
| 外地游客 | 初到陌生城市 | 不熟悉景点位置与交通方式 | 使用真实 POI 和路线数据减少猜测 |
| 测试/项目演示人员 | 复现系统能力 | 需要可验证的结果与边界 | 提供结构化 API、测试命令和健康检查 |
3. 创新点与杀手级功能
杀手级功能:天气冲突驱动的“确认后改计划”闭环
普通推荐系统往往在生成行程后结束。本项目将天气风险检测嵌入行程修改流程:当用户计划户外活动,而天气预报出现高温、强降雨、大风或雷暴时,系统不会悄悄替用户改行程,也不会假装天气正常,而是:
生成计划 → 检测天气冲突 → 明确展示风险 → 询问用户是否确认调整
→ 用户确认 → 修改指定时段 → 再次检测冲突 → 返回新计划
这种“人机协商”机制解决了自动化建议与用户自主决策之间的矛盾:系统负责发现风险并提供方案,用户保留最终选择权。当前已支持高温、低温、大风、降雨、雷暴、天气数据不完整以及部分开放时间冲突等规则。
其他亮点
- 真实数据优先。 景点名称、POI ID、坐标、地址、路线距离和时间均由高德服务返回;无数据时保持
null或返回明确错误,不编造评分、营业时间或路线价格。 - 多轮自然语言交互。 用户可以先问天气,再请求生成一日游,最后说“下午改成室内活动”,系统使用同一会话保存上下文。
- 同名城市的候选确认。 对存在歧义的地点,系统返回候选信息并等待用户确认,避免将用户带到错误城市。
- 可插拔的服务设计。 天气、景点、路线、冲突检测、MCP 工具、语音 ASR/TTS 均通过明确接口衔接,便于替换第三方服务或独立测试。
- 可验证的工程交付。 后端提供
/health健康检查、单元测试、接口测试和开发环境冒烟接口,便于复测和部署。
4. 技术方案为何适合问题
| 层次 | 技术/服务 | 解决的问题 |
|---|---|---|
| 后端 | Java 21、Spring Boot | 快速构建稳定的 Web API、业务服务与配置管理 |
| 天气 | Open-Meteo Geocoding + Forecast | 将城市解析为经纬度并获取预报数据,无需天气密钥 |
| 景点/路线 | 高德 Web 服务 | 获取真实景点 POI、地址、坐标及多交通方式路线 |
| 对话 | DashScope OpenAI 兼容接口 | 让用户用自然语言调用天气、计划和修改工具 |
| 工具协作 | MCP/本地工具适配 | 将天气、景点、路线、计划能力以统一工具形式提供给 Agent |
| 风险控制 | 规则引擎式冲突服务 | 用可解释阈值识别风险,不把安全判断完全交给模型 |
| 测试与运维 | Maven 测试、/health |
支持自动化回归和部署后健康探测 |
三、需求分析
0. 产品思维导图
下图可直接粘贴到支持 Mermaid 的 Markdown 编辑器或博客插件中渲染;若博客园编辑器不支持 Mermaid,可在本地渲染后导出为图片上传。
1. 功能需求
| 编号 | 功能模块 | 用户需求 | 当前实现与验收方式 |
|---|---|---|---|
| FR-01 | 城市天气查询 | 查询指定城市、日期的天气 | Open-Meteo 地理编码 + 天气预报;返回温度、降水、风速、天气码等 |
| FR-02 | 城市歧义处理 | 同名地点不能直接误查 | 返回候选城市,用户按编号或完整名称确认后继续 |
| FR-03 | 景点检索 | 按城市和偏好寻找真实景点 | GET /api/attractions,返回高德 POI、地址、坐标和来源 |
| FR-04 | 景点详情 | 查看具体景点资料 | GET /api/attractions/{poiId},只接受真实 POI ID |
| FR-05 | 多方式路线 | 比较公交、步行、驾车等交通方式 | POST /api/routes/plan,返回距离、时长、摘要和分段 |
| FR-06 | 一日行程生成 | 根据日期、偏好、预算生成早中晚安排 | POST /api/plans/generate,组合景点、路线和日程 |
| FR-07 | 天气冲突识别 | 知道行程是否受恶劣天气影响 | 检测高温、低温、大风、降雨、雷暴和数据缺失 |
| FR-08 | 确认后修改 | 修改下午活动等要求不应误改其他安排 | /api/plans/modify:未确认只提示,确认后修改并重新检测 |
| FR-09 | 聊天式使用 | 用自然语言完成查询、生成和修改 | /chat 页面与 POST /api/chat,会话按 sessionId 隔离 |
| FR-10 | 语音入口 | 通过音频请求复用聊天能力 | POST /api/voice/chat;当前 mock 语音流程可测,真实 ASR/TTS 待接入 |
| FR-11 | 系统可用性 | 部署或联调时快速确认服务是否存活 | GET /health 返回 UP |
2. 核心业务流程
用户输入城市、日期、偏好
│
▼
城市地理编码与候选确认 ── 有歧义 ──► 用户选择候选
│
▼
查询天气 + 检索真实景点 + 计算真实路线
│
▼
生成早/午/晚行程
│
▼
天气冲突检测 ── 无冲突 ──► 展示计划
│
└── 有冲突 ──► 展示风险并询问是否调整
│
用户确认
│
▼
修改指定时段并重新检测
3. 非功能需求
- 正确性: 真实地点和路线必须来自高德服务;天气数据必须来自 Open-Meteo;缺失字段不伪造。
- 可解释性: 冲突结果应包含类型、级别和原因,例如“预计最高温约 36℃,户外活动舒适度可能较低”。
- 安全性: DashScope、高德等密钥只通过
DASHSCOPE_API_KEY、AMAP_WEB_KEY等环境变量读取,不提交仓库。 - 可测试性: 无模型密钥时,天气、景点、路线、冲突、MCP 和旧页面仍可独立验证;模型相关成功路径单独配置后复测。
- 可维护性: 外部 API 封装在 Client/Service 层,Controller 不直接拼接第三方请求;接口使用统一响应结构。
- 性能与稳定性: 外部请求设置超时;健康检查不依赖不稳定的第三方服务,避免临时网络波动误判服务下线。
4. 接口需求概览
| 接口 | 方法 | 作用 |
|---|---|---|
/weather |
GET | 原有天气页面查询入口 |
/api/attractions |
GET | 查询指定城市的真实景点 |
/api/attractions/{poiId} |
GET | 查询景点详情 |
/api/routes/plan |
POST | 计算两景点间的路线 |
/api/plans/generate |
POST | 生成包含景点与路线的行程 |
/api/plans/modify |
POST | 在确认冲突后修改行程 |
/api/chat |
POST | 多轮文本对话 |
/api/voice/chat |
POST | 音频对话入口 |
/health |
GET | 服务健康检查 |
所有新增业务接口使用统一结构:
{
"code": 200,
"message": "success",
"data": {},
"timestamp": "2026-11-08T00:00:00"
}
5. 功能描述
| 功能 | 用户操作 | 系统处理 | 输出/边界 |
|---|---|---|---|
| 城市天气查询 | 输入城市和日期,或发送“查询明天广州天气” | 先使用地理编码查找城市,再按经纬度请求天气预报 | 返回最高/最低温、降水、风速、天气现象;同名城市先要求确认 |
| 景点发现 | 选择城市与“历史文化、自然风光、美食”等偏好 | 将偏好转换为检索关键词,调用高德 POI 服务 | 返回真实景点名称、地址、坐标和 POI ID;评分、营业时间缺失时保持空值 |
| 路线比较 | 选择两个真实景点和交通方式 | 根据 POI 坐标调用高德路线服务 | 返回公交、步行、驾车、骑行的距离、时长和分段;不虚构票价 |
| 一日游生成 | 填写城市、日期、偏好、预算和交通偏好 | 组合真实景点与相邻路线,形成早/午/晚日程 | 返回结构化计划、景点列表、路线列表;预算是约束条件而非编造价格 |
| 天气冲突提醒 | 在恶劣天气下生成或修改户外计划 | 用统一阈值检查高温、低温、大风、降雨、雷暴和数据缺失 | 返回冲突类型、等级和理由;有风险时 needConfirm=true |
| 确认后修改行程 | 例如“下午改为室内活动”,并确认调整 | 只修改目标时段,保留其他时段;修改后再次检查冲突 | 未确认不改变原计划;确认后返回新计划和剩余风险 |
| 多轮聊天 | 连续输入天气、计划、修改要求 | 按 sessionId 保存会话上下文,模型按工具白名单调用后端能力 |
支持“天气 → 计划 → 修改”;会话隔离,闲置后清理 |
| 语音入口 | 上传符合格式的 WAV 文件 | 校验音频格式,ASR 转写后复用聊天服务,再由 TTS 输出 | 当前 mock 流程可测;真实 ASR/TTS 尚待接入,失败返回明确状态而非 500 |
硬件相关接口:系统采用手机 BLE 蓝牙与 ESP32-S3 建立连接,用户通过手机端蓝牙调试工具发送文本指令,ESP32-S3 利用 NimBLE 协议栈接收数据,并通过 FreeRTOS 队列将指令传递给 HTTP 任务。随后,主控通过 Wi-Fi 接入网络,使用 HTTP POST 请求将指令封装为 JSON 数据发送至后端 AI Agent。后端完成指令解析与智能处理后,将生成的回答以 JSON 格式返回,ESP32-S3 解析响应并提取文本内容,经过特殊字符清洗和格式重排后,最终通过 LCD 显示屏呈现给用户,实现从手机指令输入到 AI 回复显示的完整交互流程。
6. 主要类图
类图强调职责分离:控制器负责 HTTP 输入输出,服务层承担业务规则,Open-Meteo 客户端和高德客户端封装外部服务;智能体和语音服务复用已有业务能力,而不重复实现天气、景点和路线逻辑。图中尖括号内保留真实 Java 类名,便于与仓库代码对应。
四、团队分工与协作方式
| 角色 | 主要职责 | 关键交付 |
|---|---|---|
| A | 天气服务、第三方接口接入、Agent 与景点交通模块集成 | Open-Meteo 查询、Amap POI/路线、MCP 工具、接口文档与联调 |
| B | 旅游规划业务规则 | 偏好、预算、时段安排及计划生成逻辑 |
| C | 对话交互与前端/Agent 体验 | 聊天页面、会话状态、工具调用衔接与页面展示 |
| D | 测试与验收 | 测试用例、复测记录、异常场景验证、部署后冒烟检查 |
团队采用 Git 分支协作:开发者在功能分支完成代码与测试,推送后通过 Pull Request 合并到 main;合并前运行 Maven 测试,合并后由测试同学按照接口文档复测。外部密钥不写入代码,统一由本地或部署平台环境变量提供。
迭代记录
| 迭代 | 目标 | 完成内容 | 验证结果/遗留项 |
|---|---|---|---|
| Iteration 0:项目初始化 | 建立可协作的工程骨架 | Spring Boot 项目、Maven Wrapper、基础页面、Git 分支协作规范 | 后端可启动;Java 21 和 JAVA_HOME 为本地必备环境 |
| Iteration 1:天气与基础行程 | 打通“城市—天气—计划”主链路 | Open-Meteo 地理编码与天气查询、天气 DTO、基础行程服务、天气页面 | 单元测试通过;同名城市场景需要候选确认 |
| Iteration 2:对话 Agent | 自然语言使用天气与行程能力 | /chat、/api/chat、会话状态、DashScope 配置、工具调用记录 |
配置真实模型 Key 后完成天气→计划→修改多轮验证 |
| Iteration 3:真实景点与交通 | 消除虚构地点和路线 | 高德 POI 检索、详情、公交/步行/驾车/骑行路线、完整行程 API | 广州真实景点及三种路线方式已联调;需通过环境变量配置高德 Key |
| Iteration 4:风险闭环与语音 | 让计划能应对恶劣天气与多入口交互 | 天气冲突规则、确认后修改、MCP 工具、/health、语音 mock 接口 |
冲突和修改闭环已验证;真实 ASR/TTS、生成入口冲突注入待后续迭代 |
| Iteration 5:部署与体验优化(计划) | 面向真实用户发布 | 公共部署、生产环境密钥、前端展示统一、真实语音、共享行程 | 待执行:线上冒烟、回滚演练、性能与安全复测 |
五、阶段性成果与测试证据
目前已完成的可验证能力包括:
- 天气模块: 可以完成城市地理编码、天气预报获取和多候选城市确认;
- 景点与交通模块: 已使用真实高德 POI 查询广州景点,并验证公交、步行、驾车路线均可返回距离与时间;
- 行程与冲突模块: 在模拟 36℃、80% 降水概率、雷暴和大风条件下,系统能返回
HEAT、RAIN、WIND、THUNDERSTORM等风险,并要求用户确认后才修改下午活动; - Agent: 在正确配置模型密钥后,可以完成“查询天气 → 生成计划 → 修改计划”的连续对话;
- 语音接口: 已验证 WAV 文件校验和无模型密钥时的
AGENT_FAILED边界处理;mock + 模型密钥的成功路径可返回音频 Base64; - 健康检查:
/health可返回UP,适用于平台部署健康探测。
可复现的基础验收命令:
cd backend
.\mvnw.cmd clean test
.\mvnw.cmd spring-boot:run
另开终端验证:
Invoke-RestMethod "http://localhost:8080/health"
Invoke-RestMethod "http://localhost:8080/api/attractions?city=广州&keyword=历史文化&limit=3"
运行模型和高德相关功能前,应在启动后端的同一个终端窗口设置真实密钥;密钥不得写入本文档:
$env:AMAP_WEB_KEY = "你的真实高德 Web 服务 Key"
$env:DASHSCOPE_API_KEY = "团队真实 DashScope Key"
验收标准
以下标准既可作为课程验收清单,也可作为测试同学的复测依据。除“已完成”外,还应保存命令输出、接口响应或页面截图作为证据。
| 编号 | 验收项 | 通过标准 | 建议验证方式 |
|---|---|---|---|
| AC-01 | 自动化测试 | ./mvnw.cmd clean test 退出码为 0,无失败测试 |
Maven 控制台保留 BUILD SUCCESS |
| AC-02 | 服务健康 | GET /health 返回 HTTP 200,status 为 UP |
Invoke-RestMethod http://localhost:8080/health |
| AC-03 | 天气查询 | 广州等唯一城市能返回与请求日期对应的天气字段 | 浏览器 /weather 或天气 API;检查城市、日期、温度、风速 |
| AC-04 | 歧义城市保护 | 候选城市不唯一时不直接选择错误地点,而是要求用户确认 | 输入易歧义地名,检查候选列表与确认提示 |
| AC-05 | 真实景点 | 景点接口返回 source=AMAP、有效 poiId、名称、地址、坐标 |
GET /api/attractions?city=广州&keyword=历史文化&limit=3 |
| AC-06 | 路线比较 | 用两个真实 POI ID 调用后,至少返回请求的交通方式、距离和时长 | POST /api/routes/plan,核对 source=AMAP |
| AC-07 | 完整行程 | 生成结果包含景点、路线、早中晚日程,且相邻地点路线可追溯 | POST /api/plans/generate |
| AC-08 | 风险识别 | 模拟高温/降雨/大风/雷暴天气时,返回对应冲突,needConfirm=true |
调用 /api/plans/smoke/generate 或相关单测 |
| AC-09 | 确认后修改 | confirmConflicts=false 时计划不变;true 时仅目标时段变化并重新检查冲突 |
连续调用 /api/plans/smoke/modify 两次对比日程 |
| AC-10 | Agent 多轮 | 配置真实 DashScope Key 后,同一 sessionId 完成“天气→计划→修改” |
POST /api/chat 连续三轮,检查 toolCalls、天气和计划结构 |
| AC-11 | 语音边界与成功路径 | 无模型 Key 时返回 AGENT_FAILED 而非 500;mock+有效 Key 时返回 OK、hasAudio=true |
上传合法 WAV 到 /api/voice/chat?format=json |
| AC-12 | 密钥安全 | Git 仓库、前端资源、日志和文档不包含真实 Key | 搜索 sk-、AMAP_WEB_KEY=,检查仅部署/本地环境变量保存 |
| AC-13 | 部署可用性 | 公网部署后健康检查、聊天页面和至少一条真实景点查询成功 | 访问部署域名;平台配置健康检查路径 /health |
验收判定: AC-01 至 AC-09 为无模型环境下的基础必过项;AC-10、AC-11 的成功路径需要测试环境合法配置模型 Key;AC-13 在部署阶段执行。若外部服务不可用,应记录服务名称、请求时间、HTTP 状态与响应体,不能以“接口异常”代替测试结论。
六、当前边界与下一步计划
为保证项目描述真实可靠,团队明确以下边界:
- 当前天气服务使用 Open-Meteo,不需要天气 API Key;景点/路线需要高德 Web 服务 Key;聊天成功路径需要 DashScope Key。
- 语音接口已经完成文件校验、会话接入和 mock 流程,但真实 DashScope ASR/TTS 尚未实现,不能表述为“已完成真实语音识别与合成”。
/api/plans/generate当前负责真实景点与路线编排;“生成即提示天气冲突”的统一 HTTP 入口仍可在后续版本继续整合。- 项目本地测试已具备基础条件;要让普通用户直接访问,需要部署到公共服务器,并在部署平台设置环境变量,而不是让每个用户配置 Key。
下一阶段我们将完成线上部署和回滚演练,补全真实语音能力,统一前端的时段字段显示,并增加多人共享行程、收藏与历史记录等功能。我们也会继续关注“建议是否可信”这一核心问题:让每条推荐都能追溯到天气、地点、路线或明确的规则依据。
七、结语
这个项目让我们体会到,软件工程不只是把多个接口拼到一起,更重要的是明确数据来源、处理异常、保留用户确认权,并让每一项能力能够被复现和验收。天气与出行看似是轻量场景,却涉及真实数据、规则解释、对话状态、跨模块协作与安全配置。后续团队将继续把它从“能演示的课程项目”打磨成“值得用户实际使用的出行助手”。

浙公网安备 33010602011771号