2026秋软工实践 跃动MoveMate——项目原型设计+概要设计
2026秋软工实践 跃动MoveMate——项目原型设计+概要设计
| 项目 | 内容 |
|---|---|
| 作业所属课程 | 202601 软件工程(福州大学 · 计算机与大数据学院) |
| 作业要求 | 2026秋软工实践团队作业-第二次(原型设计+概要设计) |
| 作业的目标 | 在第一次需求分析基础上,完成可交互原型、分层概要设计、UML 设计、数据库设计和后续开发协作计划,重点说明领域 Agent 如何与软件功能结合。 |
| 团队名称 | 迟到组 |
| 团队成员学号—姓名 | 102101215-华恺;102401423-刘弘毅;102201103-叶佳旺;102101627张志强;222100212-吴昕宇;谢昱扬;郭劲岐 |
一、原型设计(40%)
1.1 原型截图展示

图 1-1 用户端首页:以「今日动作」为中心,四个数据卡代替冗长报表
- 页面元素:问候卡(日期 + 当前计划周次 +「查看今日训练」主按钮)、4 个数据卡(连续打卡 / 本周训练 / 当前体重 / 目标进度)、3 个快捷入口(生成新处方、咨询智能体、打卡与进度)。
- 交互:数据卡与快捷入口均可点击,直达对应页面;主动作按钮永远是「查看今日训练」,不让用户在首页做选择。
- 规则:目标进度 =(起始体重 − 当前体重)/(起始体重 − 目标体重),四舍五入到整数百分比;连续打卡以「自然日」计,断签次日清零。
- 设计取舍:首页不展示完整处方(信息过载),只用「第 3 周减脂计划已准备好」提示计划处于活跃状态。
健康评估(智能体的输入入口)

图 1-2 健康档案与 PAR-Q 安全筛查:所有字段围绕「能不能安全地练」组织
- 页面元素:基础信息(性别 / 年龄 / 身高 / 体重)、活动水平、训练目标、PAR-Q 安全筛查三项勾选、旧伤与禁忌补充说明、主按钮「交给智能体生成处方」。
- 交互:勾选任意一项高风险项,页面顶部即时出现橙色提示条并给出「建议先就医」的引导;点击主按钮后进入智能体五步处理遮罩(图 2-7),处理完成自动跳转处方页。
- 规则:
- 数值校验:年龄 12–80、身高 120–230cm、体重 30–200kg,越界给出行内错误;
- 筛查为硬前置:三项中存在高风险勾选时不出处方,只输出就医建议与低风险运动提示(如散步);
- 旧伤描述参与生成:如「左膝有旧伤」会被解析为约束,产出低冲击替代方案;
- 同一用户重新评估会生成新版本处方,旧处方转为
archived,不覆盖历史。
- 异常:模型或工具调用失败时,遮罩内显示「第 4 步失败,正在重试(1/2)」,两次失败后降级为「已为你保存档案,可稍后重试生成」。
运动处方(智能体的输出载体)

图 1-3 运动处方页:先给结论(BMI / TDEE / 摄入目标),再给 FITT-VP 四块,最后给依据与免责
- 页面元素:顶部三个指标卡(BMI 25.9 超重、TDEE 2350 kcal、日摄入目标 1950 kcal)、FITT-VP 处方四块(有氧 / 抗阻 / 柔韧与恢复 / 进阶与安全)、依据出处、非医疗建议警示、底部两个动作(咨询智能体 / 打卡今日训练)。
- 交互:处方卡片整块可展开查看动作细节与组次;「依据出处」可点击展开命中的知识条目;跳转问答时自动携带当前处方上下文,用户不必复述。
- 规则:处方必须由工具算出的数值驱动(TDEE、心率区间、BMI 判定),不允许自由发挥;每条建议必须能对上知识库条目编号;出现旧伤时强制走「低冲击替代」分支。
- 可解释性设计:这是本页最重要的设计决策——把「为什么」写在页面上,而不是藏在客服入口里。用户看到「因为你标注了左膝旧伤,所以用椭圆机替代跑步」,才可能真的坚持下去。
智能体问答

图 1-4 智能体问答:回答下方固定展示「RAG 命中」或「工具调用」凭据
- 页面元素:3 个高频问题快捷 chips(为什么选低冲击动作 / 能把快走换成跳绳吗 / 强度会不会太低)、消息流、输入框。智能体消息底部固定一行工具调用凭据(如「RAG 检索命中:知识库 #K-042 低冲击有氧替代原则」)。
- 交互:支持回车发送、流式输出(WebSocket / SSE);快捷 chips 覆盖 80% 的重复提问;涉及医疗诊断的关键词(疼、伤、痛、病)自动切换到「引导就医」话术。
- 规则:回答必须基于「当前用户档案 + 当前处方 + 检索片段」三者,禁止脱离个体给通用建议;不提供诊断、不推荐药物、不评价医生方案;回答中的强度数字必须来自工具而非模型心算。
打卡与进度

图 1-5 打卡与进度:左表单、右曲线,底部周完成率
- 页面元素:打卡表单(训练内容下拉 / 当日体重 / 训练感受)、体重变化曲线(近 6 周,标注起始 82kg 与当前 79.6kg)、本周训练完成情况进度条。
- 交互:训练内容默认带出今日处方条目;提交后连续打卡 +1、曲线追加数据点;训练感受若包含「疼/痛」,次日推送计划调整建议。
- 规则:每日每类训练只能打卡一次;体重可空(只记训练);曲线采样按自然周聚合,缺测点用线性插值并标注为虚线。
1.2 领域智能体的交互界面与核心任务流程
这一节是本次作业的核心亮点:软件不是「加了个聊天框」,而是把智能体的一次完整任务编排,可视化地摊开在用户面前。
| 步骤 | 智能体内部动作 | 用到的能力 | 用户可见信息 | 失败降级 |
|---|---|---|---|---|
| ① 信息评估 | 解析档案:年龄/性别/身高/体重/活动水平/目标/运动史 | 结构化抽取 | 「信息评估:采集身体数据」 | 字段缺失 → 回填表单 |
| ② 安全筛查 | PAR-Q+ 与旧伤、慢病排查,识别高风险项 | 规则引擎 + 领域知识 | 「安全筛查:PAR-Q 与旧伤排查」 | 高风险 → 终止并引导就医 |
| ③ 知识检索 | 按「目标 + 约束 + 人群」构造检索式,召回 Top-K 知识片段 | RAG(RAGService) |
「知识检索:RAG 检索运动科学知识库」 | 召回为空 → 用内置基线模板并标注「依据较弱」 |
| ④ 数值计算 | 调 calc_bmi、calc_tdee、heart_rate_zone、training_volume |
Function Calling | 「数值计算:TDEE / BMI / 心率区间」 | 工具失败 → 重试 2 次后人工确认 |
| ⑤ 处方生成 | 按 FITT-VP 模板把知识、数值、约束组装成结构化处方 | LLM + plan_generator |
「处方生成:编排 FITT-VP 计划」 | 结构校验不通过 → 重新生成一次 |
为什么要把这五步显示出来? 因为对健身小白来说,「AI 给了一份计划」和「AI 看了我的旧伤、查了 ACSM 指南、算了我的心率区间之后给了一份计划」是两件完全不同的事。前者是黑箱,后者才敢照着练——过程可见,是信任的来源。
典型交互剧本(问答侧)
| 用户意图 | 智能体行为 | 展示的凭据 | 设计要点 |
|---|---|---|---|
| 「为什么我的有氧要选低冲击动作?」 | 回溯档案中的左膝旧伤 → 命中「低冲击有氧替代原则」→ 解释替代关系 | RAG 命中 #K-042 | 回答必须回到用户自己的数据,不讲通用道理 |
| 「可以把快走换成跳绳吗?」 | 判定跳绳为高冲击(落地冲击约为体重 3–5 倍)→ 拒绝并给出替代路径 | 工具 heart_rate_zone → 130~145 bpm |
会说「不」,是专业性的体现 |
| 「这个强度会不会太低?」 | 解释储备心率 60–70% 与 RPE 5–6 对应中等强度 → 说明渐进节奏 | 工具 heart_rate_zone + training_volume |
用数字说服,而不是「相信我」 |
| 「我膝盖疼还能练吗?」 | 识别医疗边界 → 不给诊断 → 引导就医 + 给出可执行的减量建议 | 护栏触发 | 宁可少说,也不能越界 |
1.3 后台管理端原型
管理端不是「给管理员看的表格」,而是智能体能够专业、安全工作的后台保障:知识库决定它「懂多少」,Agent 配置决定它「怎么说话、能调什么工具」,内容审核决定它「说错了能不能被发现」。
| 页面 | 主要功能 | 关键设计说明 |
|---|---|---|
| 用户管理 | 用户列表、角色、目标、状态(正常 / 待评估 / 管理员) | 状态用于运营触达:待评估 用户从未生成处方 |
| 知识库管理 | 文档上传、分类、切片数、向量化状态 | 「处理中 → 已就绪」状态机是 RAG 可用性的前提 |
| Agent 配置 | 系统提示词、模型、温度、已注册工具 | 提示词即护栏,工具集即能力边界,两者都可在页面调整 |
| 内容审核 | 问答记录按风险分级(医疗边界 / 正常) | 医疗边界类问题优先人工复核,形成护栏的反馈闭环 |
| 数据统计 | 注册用户、生成处方、问答量、知识库条目 | 以「处方生成/问答比」衡量智能体的真实使用深度 |
1.4 交互规则与异常处理汇总
| 场景 | 触发条件 | 系统行为 | 用户感知 |
|---|---|---|---|
| 高危筛查 | PAR-Q 任一项勾选 / 旧伤描述含急性症状 | 终止处方生成,输出就医建议 | 橙色提示条 + 明确的「先就医」文案 |
| 数值越界 | 身高/体重/年龄超范围 | 行内校验,禁止提交 | 输入框红框 + 具体范围提示 |
| 模型超时 | LLM 响应 > 10s | 显示重试进度,保留已算出的数值 | 「第 4 步重试中」而不是白屏 |
| 工具失败 | 计算工具连续失败 2 次 | 降级为基线公式并标注「未使用个性化计算」 | 处方页出现灰色说明 |
| 医疗越界 | 提问含诊断诉求 | 拒绝诊断 + 引导就医 | 回答首句即声明边界 |
| 断签 | 自然日无打卡 | 连续打卡清零,进度条按周重置 | 首页数值变化,不弹惩罚性提示 |
1.5 视觉与可用性
| 维度 | 规范 |
|---|---|
| 品牌色 | 主色 #2563eb(信任、专业)→ 辅色 #0ea5a4(健康、活力),渐变用于主动作;警示用 #f97316,通过用 #16a34a |
| 字体 | 系统中文字体栈(PingFang SC / Microsoft YaHei),正文 13.5–14px,指标数字 26px |
| 组件 | 卡片圆角 14px、1px 描边 #e5e9f0、极轻阴影;处方条目用 4px 左侧色条区分类型 |
| 信息密度 | 一屏一个主任务;指标先行、解释后置;凡是「为什么」都能一键展开 |
| 无障碍与移动端 | 触控目标 ≥ 40px;正文对比度 ≥ 4.5:1;860px 以下双列、560px 以下单列 |
二、概要设计(40%)
2.1 设计原则
- Agent 是架构中的一层,不是架构外的插件——它有自己的接口、自己的状态、自己的可观测点;
- 能力解耦:RAG 管「依据」、工具管「算数」、LLM 管「表达」,任何一环可单独替换;
- 安全前置:护栏在生成之前生效,而不是生成之后补救;
- 可溯源:每一条建议都能追到知识条目,每一次工具调用都留日志;
- 自顶向下分层:系统 → 服务 → 模块 → 类 → 表,逐层细化,层间单向依赖。
2.2 系统总体架构
系统由「用户端 / 管理端 Web 界面 + 五个业务服务 + Agent 编排层 + 数据层」四个部分协同组成,自上而下划分为五层:表现层 → 接口层 → 应用层 → Agent 编排层 → 数据层。层间单向依赖,Agent 编排层是核心枢纽,向下统一调度领域知识与工具。*
| 层 | 组成 | 职责 | 关键设计决策 |
|---|---|---|---|
| 表现层 | 用户端 Web App、管理端 Web App(Vue 3 + Element Plus) | 页面渲染、表单校验、状态展示 | 两端独立构建、共享组件库,避免管理端功能污染 C 端包体 |
| 接口层 | API Gateway:RESTful API + WebSocket | 鉴权、限流、路由、流式输出 | 对话用 WebSocket/SSE,因为「逐字出现」直接影响等待体验 |
| 应用层 | 用户/计划/追踪/知识库/管理 五个服务 | 业务编排与领域规则 | 按业务域拆分而非按技术分层,便于并行开发 |
| Agent 编排层 | 编排器、RAG 检索、工具调度、会话记忆、LLM 接入 | 多步任务闭环、知识召回、工具执行、模型适配 | 模型可替换:业务代码只依赖编排器接口,不依赖具体模型 |
| 数据层 | PostgreSQL、pgvector、Redis、OSS | 业务数据、向量检索、会话缓存、静态资源 | 业务库与向量库同库(pgvector),少一次跨系统一致性负担 |
运行逻辑(一次处方生成的跨层调用):表现层提交表单 → 接口层鉴权并转发 POST /api/plan/generate → 计划服务调用 AgentOrchestrator → 编排器依次执行「筛查 → 检索 → 计算 → 生成」→ 结果写入 exercise_plan / plan_item / tool_log → 沿原链路返回结构化处方。管理端链路为「表现层 → 接口层 → 知识库/管理服务 → 数据层」,仅在对知识切片与 Agent 配置时与编排层交互。
2.3 功能模块分解
| 功能需求 | 所属服务 | 主要程序单元(模块) | 优先级 |
|---|---|---|---|
| 用户档案与评估 | 用户服务 | AuthModule、ProfileModule、AssessmentModule |
P0 |
| 计划生成引擎 | 计划服务 + Agent 编排层 | PlanModule、AgentOrchestrator、RAGService、ToolRegistry |
P0 |
| 计划解释与问答 | 计划服务 + Agent 编排层 | ChatModule、AgentOrchestrator、RAGService |
P1 |
| 训练打卡与追踪 | 追踪服务 | CheckinModule、ProgressModule |
P1 |
| 动态调整 | 计划服务 | AdjustModule、AgentOrchestrator |
P1 |
| 知识库管理 | 知识库服务 | KnowledgeModule、ActionModule |
P2 |
| 用户/审核/统计 | 管理服务 | AdminUserModule、AuditModule、StatsModule |
P2 |
2.4 UML 设计
2.4.1 用例图(需求分析)
| 参与者 | 用例 | 说明 |
|---|---|---|
| 健身用户 | UC-01 注册/登录、UC-02 健康档案与评估、UC-03 生成运动处方、UC-04 智能体问答、UC-05 打卡与进度追踪、UC-06 动态计划调整 | UC-03 与 UC-04 存在扩展关系(对处方追问),UC-06 依赖 UC-04 完成解释 |
| 管理员 | UC-07 用户管理、UC-08 知识库管理、UC-09 Agent 配置、UC-10 问答内容审核 | UC-08/UC-09 直接影响 UC-03/UC-04 的质量与边界 |
用例 UC-03「生成运动处方」的描述
| 要素 | 内容 |
|---|---|
| 参与者 | 健身用户 |
| 前置条件 | 已登录;已填写健康档案 |
| 主流程 | ① 填写身高/体重/年龄/目标/运动史/禁忌 → ② 系统执行 PAR-Q 安全筛查 → ③ 通过后:RAG 检索知识、工具计算数值、LLM 生成 FITT-VP 处方 → ④ 用户确认或提出修改 → ⑤ 处方保存并展示 |
| 异常流程 | 筛查高风险 → 提示就医并终止;工具/模型失败 → 重试 2 次后降级提示;数值越界 → 行内校验拦截 |
| 后置条件 | 写入 exercise_plan 与 plan_item,tool_log 留痕 |
2.4.2 活动图(业务流程)
流程要点:
- 安全护栏前置:筛查在任何生成动作之前完成,高风险直接走「提示就医 → 终止」分支;
- 知识与计算分离:RAG 提供专业依据、工具提供数值、LLM 负责结构化表达,三者可独立替换与独立评测;
- 闭环反馈:打卡与身体数据回流后按周期重算(
ADJUST判断),计划随身体变化演进,而不是一次成型后永久不变; - 用户确认节点:
CONFIRM允许把「不信任」转成「再检索一次」,而不是让用户直接放弃。
2.4.3 类图(系统静态结构)
| 分类 | 类 | 职责 |
|---|---|---|
| 领域实体 | User、HealthProfile |
账号与角色;健康档案(含 PAR-Q 结果与禁忌) |
| 领域实体 | ExercisePlan、PlanItem |
处方头(FITT-VP 存为 JSON)+ 训练条目 |
| 领域实体 | WorkoutLog |
打卡与身体数据,是动态调整的输入 |
| 领域实体 | ChatSession、ChatMessage |
会话与消息,消息带 citations 引用 |
| 领域实体 | KnowledgeDoc、KnowledgeChunk |
文档与向量切片,RAG 的数据源 |
| 领域实体 | Action、ToolLog、AgentConfig |
动作库、工具调用日志、Agent 配置 |
| 服务/编排 | AgentOrchestrator |
驱动五步任务闭环,调度检索与工具 |
| 服务/编排 | RAGService |
检索(retrieve)与向量化(embed) |
| 服务/编排 | ToolRegistry |
工具注册(register)与执行(execute) |
关键关系:User 1—1 HealthProfile、User 1—N ExercisePlan、ExercisePlan 1—N PlanItem、PlanItem M—N Action、ChatMessage 1—N ToolLog、ChatMessage → AgentOrchestrator → RAGService / ToolRegistry。
2.4.4 时序图(核心算法模块)
「运动处方生成」是本系统最重要的算法模块,时序图刻画了它随时间的消息交互:

图 3-6 时序图:前端 → 编排器 → 工具/RAG → LLM → 数据库
| 序号 | 消息 | 说明 |
|---|---|---|
| 1–2 | 用户填表 → POST /api/plan/generate |
表单在前端完成基础校验,减少无效编排 |
| 3–4 | 编排器 → 工具执行器:PAR-Q 筛查 | 筛查先于一切生成动作 |
| 5–7 | 分支:高风险 → 返回就医建议并终止;通过 → RAG 检索 | 两条路径都必须在 10s 内给出确定结果 |
| 8–11 | 工具计算 TDEE / BMI / 心率 → LLM 生成 FITT-VP | 先有数、再有文,避免模型编造数值 |
| 12–15 | 落库 exercise_plan + tool_log → 返回结构化处方 → 渲染卡片 |
落库与返回解耦,失败可重试不重复开方 |
2.4.5 协作图(对象协作与消息传递)
协作图与时序图互补:时序图强调「时间顺序」,协作图强调「谁和谁协作」。其中 :Assessor 负责评估与筛查、:RAGService 负责依据、:Calculator 负责数值、:Generator 负责组装、:Repository 负责持久化——每个对象只有一个变化理由,这也是后续做单元测试的切分依据。
2.5 领域 Agent 的设计与集成
2.5.1 角色与护栏
智能体命名为「跃动处方师」,定位为「认证运动处方师助手」,语气专业但对小白友好。三条硬约束写进系统提示词:
- 必须先评估再开方:没有安全筛查结果,不出任何训练建议;
- 严禁越过医疗边界:不做诊断、不推荐药物、不评价医生方案,伤病问题一律引导就医;
- 结论必须注明出处:每条关键建议都要能对上知识条目编号。
2.5.2 领域知识(RAG 的知识底座)
| 知识域 | 内容 | 在系统中怎么用 |
|---|---|---|
| 运动处方学 | FITT-VP 六要素 | 处方输出的结构骨架 |
| 强度量化 | 储备心率法、卡氏公式、RPE、MET | heart_rate_zone 的依据与解释话术 |
| 能量代谢 | BMR、TDEE、热量缺口、宏量营养素 | calc_tdee 与摄入目标 |
| 训练类型 | 有氧/抗阻/柔韧/平衡/神经肌肉 | 处方分块与动作选型 |
| 进阶原则 | 渐进超负荷、周期化、恢复 | 「每 2 周 +10%」的规则来源 |
| 安全筛查 | PAR-Q+、运动禁忌、慢病注意 | 筛查分支与就医话术 |
| 数据标准 | BMI、体脂率、体质健康标准 | 指标判定与体测达标 |
| 动作库 | 动作规范、目标肌群、常见错误、替代动作 | 「换动作」问答与禁忌替代 |
知识源包括《ACSM 运动测试与运动处方指南》《中国居民膳食指南(2022)》《国家学生体质健康标准》与自建动作库;文档经切片、向量化后进入 knowledge_chunk,检索命中即标注出处。
2.5.3 工具调用(Function Calling)
| 工具 | 功能 | 输入 → 输出 | 在流程中的位置 |
|---|---|---|---|
calc_tdee |
按性别、年龄、身高、体重、活动系数计算每日总消耗 | 档案 → 2350 kcal |
第 4 步 |
calc_bmi |
计算 BMI 并判定区间 | 身高体重 → 25.9(超重) |
第 4 步 |
heart_rate_zone |
储备心率法计算目标区间 | 年龄、静息心率、强度% → 130–145 bpm |
第 4 步 / 问答 |
training_volume |
计算训练容量与渐进负荷 | 周次、组次 → 容量与 +5% 负荷 | 第 4、5 步 |
fitness_score |
按体测标准评定达标 | 体测项 → 得分与等级 | 打卡页 / 调整 |
plan_generator |
整合评估结果生成结构化处方 | 知识片段 + 数值 + 约束 → FITT-VP | 第 5 步 |
2.5.4 任务流程编排
单次任务被编排为六步闭环:评估 → 筛查 → 目标(SMART 化)→ 处方 → 打卡 → 调整。其中前四步在「生成处方」一次调用内完成(对应图 2-7 的遮罩:知识检索与数值计算是「处方生成」内部的子步骤),后两步由打卡事件与定时任务共同触发。编排器负责:状态机推进、超时控制、失败重试、工具入参校验、以及把每一步的中间结果写入 tool_log。
2.5.5 智能体与软件系统的四种集成方式
| 集成点 | 机制 | 效果 |
|---|---|---|
| 接口集成 | 应用层通过内部 API 调用编排器,业务代码不直接触碰模型 SDK | 换模型不改业务;可对编排层单独限流、熔断 |
| 领域知识集成 | 知识库服务维护文档与向量索引,RAGService 读取 pgvector |
回答有据可依,可溯源到条目;知识更新不必重训模型 |
| 工具集成 | 六个工具注册于 ToolRegistry,由 LLM 的调用意图驱动执行 |
数值可复现、可审计;避免模型「心算」出错 |
| 流程集成 | 编排器贯穿用户全生命周期,与计划、打卡、会话实体一一对应 | 计划能随数据演进,智能体不止于「一次问答」 |
2.5.6 领域知识、工具与流程在系统中的实际作用
- 领域知识决定了「说什么」:同样是「不建议跳绳」,有 ACSM 依据的表述才有说服力;
- 工具调用决定了「数字对不对」:心率区间、热量缺口不能由语言模型估算;
- 任务流程决定了「先后顺序」:筛查永远在生成之前,这一条靠流程保证,而不是靠提示词祈祷。
2.6 接口设计
外部接口:LLM API(统一接入层,输入提示词 + 上下文 + 工具定义,输出文本或工具调用请求)、向量库(写入切片向量、按相似度召回 Top-K)、对象存储(课件与动作图片,库中只存 URL)。
内部接口(RESTful,节选)
| 方法 | 路径 | 说明 | 幂等 |
|---|---|---|---|
| POST | /api/auth/register |
用户注册 | 否 |
| POST | /api/profile/assess |
提交健康档案与 PAR-Q 筛查 | 是(同版本覆盖) |
| POST | /api/plan/generate |
生成运动处方(触发 Agent 编排) | 否(按请求号去重) |
| POST | /api/chat/ask |
智能体问答(WebSocket 流式) | 否 |
| POST | /api/log/checkin |
训练打卡 | 是(同日同类去重) |
| GET | /api/progress/{userId} |
进度曲线数据 | 是 |
| POST | /api/admin/knowledge |
知识库条目维护(管理端) | 否 |
2.7 运行设计、出错处理与安全
| 类别 | 设计 |
|---|---|
| 运行模块组合 | 用户端链路:表现层 → 接口层 → 用户/计划/追踪服务 → 编排层 → 数据层;管理端链路:表现层 → 接口层 → 知识库/管理服务 → 数据层 |
| 运行控制 | 对话流式推送;工具按 LLM 意图串行执行,失败重试 2 次;处方生成受并发与限流控制,Redis 缓存热点会话 |
| 性能目标 | 处方生成端到端 < 10s;RAG 检索 < 1s;工具计算 < 0.5s;打卡写入 < 0.3s |
| 出错信息 | 统一错误码 + 中文友好提示;网络失败与模型超时给出明确重试引导 |
| 补救措施 | 工具/模型失败自动重试 2 次后降级为静态提示;处方生成失败回滚事务,不产生半成品 |
| 安全边界 | PAR-Q 高风险强制引导就医;问答涉及诊断一律不越界;全站标注「非医疗建议」 |
| 数据安全 | 密码哈希、健康数据加密存储、最小化收集;JWT 鉴权 + 角色分级 |
| 可维护性 | tool_log 记录工具入参与出参;知识库版本可回滚;模型与工具均可热替换 |
三、数据库设计
3.1 设计目标与选型
| 目标 | 措施 |
|---|---|
| 一致性 | 以领域模型为中心,业务实体与库表一一对应,各模块数据口径统一 |
| 完整性 | 主键、外键、唯一、检查约束齐备;删除采用级联或 SET NULL 分级策略 |
| 规范化 | 关系模式达到 3NF;仅对高频变动的处方结构与工具入出参使用 JSONB(可控反规范化) |
| 可扩展 | 模型、知识库、工具均可替换,agent_config 支持热配置 |
| 安全 | 健康数据加密、最小化收集、权限分级与审计日志 |
选型:主库 PostgreSQL 14+ 并启用 pgvector 扩展,实现「业务数据 + 向量检索」一体化——少一套中间件,就少一处一致性风险;Redis 承担会话缓存与限流;大文件走 OSS,库中只存 URL。
3.2 数据来源与存续
| 数据 | 来源与写入方 | 存续策略 | 生命周期 |
|---|---|---|---|
健康档案 health_profile |
用户填写(评估页),AssessmentModule 写入 |
常驻热库,再次评估即覆盖 | 注销时级联删除 |
运动处方 exercise_plan / plan_item |
Agent 生成后由 PlanModule 写入 |
新旧版本并存,旧版本置 archived |
注销时级联删除;归档版本留 2 年 |
打卡记录 workout_log |
用户打卡,CheckinModule 写入 |
近 6 个月热库,按月分区归档 | 归档留 3 年,支撑长期趋势 |
会话与消息 chat_session / chat_message |
流式问答结束后写入 | 会话 90 天热库,之后只留摘要 | 摘要长期保留,原文 180 天清理 |
工具日志 tool_log |
编排器每步调用后追加 | 只追加、不改写 | 保留 1 年,支撑审计与复盘 |
领域知识 knowledge_doc / knowledge_chunk |
管理端上传,切片与向量化任务写入 | 版本化,新版本生效后旧版本可回滚 | 下架后保留 90 天 |
Agent 配置 agent_config |
管理端修改,单例 | 变更留痕 | 长期保留 |
主要数据流:管理端维护知识 → 切片向量化入 pgvector → 用户提交档案 → 编排器检索知识并调用工具计算 → 处方与工具日志落库 → 用户打卡回流 → 触发周期性调整。
3.3 概念结构设计(ER 图)
| 实体 | 含义 | 主要关系(基数) |
|---|---|---|
USER |
用户(健身用户 / 管理员) | 1:1 HEALTH_PROFILE;1:N EXERCISE_PLAN、WORKOUT_LOG、CHAT_SESSION |
HEALTH_PROFILE |
健康档案与评估结果 | 1:1 属于 USER |
EXERCISE_PLAN |
运动处方头 | 1:N PLAN_ITEM |
PLAN_ITEM |
处方训练条目 | M:N ACTION(选用动作);1:N WORKOUT_LOG |
WORKOUT_LOG |
打卡与身体数据 | N:1 USER、PLAN_ITEM |
CHAT_SESSION / CHAT_MESSAGE |
会话与消息 | 1:N 嵌套;消息带 citations |
KNOWLEDGE_DOC / KNOWLEDGE_CHUNK |
知识文档与向量切片 | 1:N 切片 |
ACTION |
动作库字典 | M:N 关联 PLAN_ITEM |
TOOL_LOG |
工具调用日志 | N:1 CHAT_MESSAGE |
AGENT_CONFIG |
Agent 配置(单例) | 独立配置表 |
3.4 逻辑结构设计(关系数据模型)
命名约定:库表小写下划线,主键统一 bigint id,外键统一 表名_id。12 张表如下:
| # | 表 | 说明 | 关键字段 | 关键约束 |
|---|---|---|---|---|
| 1 | user |
账号 | username、password_hash、role、nickname、created_at |
UQ(username),role ∈ |
| 2 | health_profile |
健康档案 | user_id、age、gender、height_cm、weight_kg、goal、injury_notes、parq_result |
UQ(user_id) 保证 1:1 |
| 3 | exercise_plan |
处方头 | user_id、fitt_vp(jsonb)、status、generated_at |
status ∈ |
| 4 | plan_item |
处方条目 | plan_id、type、detail、intensity |
FK→exercise_plan,级联删除 |
| 5 | workout_log |
打卡记录 | user_id、plan_item_id、weight_kg、note、log_at |
数值非负检查;plan_item_id 可空 |
| 6 | chat_session |
会话 | user_id、title、created_at |
FK→user |
| 7 | chat_message |
消息 | session_id、role、content、citations |
role ∈ |
| 8 | knowledge_doc |
知识文档 | title、source、category |
title 非空 |
| 9 | knowledge_chunk |
知识切片 | doc_id、content、embedding(vector 1024) |
HNSW 索引,余弦距离 |
| 10 | action |
动作库 | name、muscle_group、contraindication |
禁忌与替代动作同表 |
| 11 | tool_log |
工具调用日志 | message_id、tool_name、args(jsonb)、result(jsonb) |
支撑审计与回放 |
| 12 | agent_config |
Agent 配置 | system_prompt、model、guardrails |
单例,变更留痕 |
关键表结构(示例:处方头与条目)
exercise_plan 字段 |
类型 | 约束 | 说明 |
|---|---|---|---|
id |
bigint | PK | 主键 |
user_id |
bigint | FK→user, NN | 所属用户 |
fitt_vp |
jsonb | NN | FITT-VP 结构化处方(频率/强度/时间/类型/总量/进阶) |
status |
varchar(20) | NN | draft / active / archived |
generated_at |
timestamp | NN | 生成时间 |
plan_item 字段 |
类型 | 约束 | 说明 |
|---|---|---|---|
id |
bigint | PK | 主键 |
plan_id |
bigint | FK→exercise_plan, NN | 所属处方 |
type |
varchar(20) | NN | 有氧 / 抗阻 / 柔韧 / 平衡 |
detail |
text | — | 动作、组次、时长 |
intensity |
varchar(50) | — | 心率区间或 RPE |
3.5 对象关系映射(ORM)
后端实体类字段用驼峰,库表用下划线,由 ORM 自动映射(示例以 JPA 注解表达,若采用 SQLAlchemy 则意义等价)。
| 实体类 | 库表 | 映射要点 |
|---|---|---|
User |
user |
passwordHash ↔ password_hash、createdAt ↔ created_at |
HealthProfile |
health_profile |
userId ↔ user_id(1:1,唯一约束)、parqResult ↔ parq_result |
ExercisePlan |
exercise_plan |
fittVpJson ↔ fitt_vp(jsonb)、generatedAt ↔ generated_at |
PlanItem |
plan_item |
planId ↔ plan_id,与 ExercisePlan 构成一对多 |
WorkoutLog |
workout_log |
planItemId ↔ plan_item_id(可空)、logAt ↔ log_at |
ChatSession / ChatMessage |
chat_session / chat_message |
sessionId ↔ session_id,citations 原样存储 |
KnowledgeDoc / KnowledgeChunk |
knowledge_doc / knowledge_chunk |
docId ↔ doc_id,embedding 映射为 vector(1024) |
Action / ToolLog / AgentConfig |
action / tool_log / agent_config |
toolName ↔ tool_name,args/result 映射为 jsonb |
@Entity
@Table(name = "exercise_plan")
public class ExercisePlan {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private User user;
@Column(name = "fitt_vp", columnDefinition = "jsonb")
private String fittVpJson; // FITT-VP 结构化处方
@Column(name = "status")
private String status; // draft / active / archived
@Column(name = "generated_at")
private LocalDateTime generatedAt;
@OneToMany(mappedBy = "plan")
private List<PlanItem> items;
}
3.6 领域知识、交互记录与任务结果的存储
| 数据类别 | 存储设计 | 为什么这样存 |
|---|---|---|
| 领域知识 | knowledge_doc(文档元数据 + 分类 + 来源)→ knowledge_chunk(切片 + 1024 维向量);检索命中写入 chat_message.citations |
文档与切片分离,既支持整份更新(换版本),也支持片段级召回与出处标注 |
| 用户交互记录 | chat_session + chat_message(含 role、content、citations)+ tool_log(工具名、入参、出参) |
会话用于上下文回放与体验优化;工具日志用于审计与「模型到底做了什么」的复盘 |
| 任务执行结果 | exercise_plan + plan_item(处方,JSONB 存 FITT-VP 全结构)+ workout_log(打卡与身体数据) |
处方头/条目分开,既能整份归档,也能按条目统计完成率;打卡数据形成时间序列,作为动态调整输入 |
规范化说明:实体关系达到 3NF;exercise_plan.fitt_vp 与 tool_log.args/result 采用 JSONB 属可控反规范化——处方结构随 FITT-VP 演进会变,工具参数天然异构,用 JSONB 换来的是「不改表结构就能迭代智能体」。
3.7 物理结构设计
| 表 | 索引 | 目的 |
|---|---|---|
user |
UQ(username) |
登录唯一性 |
health_profile |
UQ(user_id) |
1:1 快速定位 |
exercise_plan |
idx(user_id, generated_at) |
按用户 + 时间取历史处方 |
workout_log |
idx(user_id, log_at) |
进度曲线的时间序列查询 |
chat_message |
idx(session_id) |
会话内消息顺序读取 |
knowledge_chunk |
HNSW(embedding vector_cosine_ops) |
向量近似检索,平衡召回率与延迟 |
分区与归档:近 6 个月打卡与会话常驻热库,历史数据按月分区归档;knowledge_chunk 维度 1024,采用 HNSW;大文件不入库。
3.8 数据安全与备份
- 加密:密码仅存不可逆哈希;健康敏感字段加密存储,传输全程 TLS;
- 权限:数据库账号按角色授权,应用侧 JWT + 行级权限(用户只能读写自己的档案与处方);
- 备份:每日全量 + 增量,WAL 归档,保留 7 天,支持时间点恢复(PITR);
- 审计:
tool_log与操作日志保留,满足智能体行为的可追溯要求。
四、团队协作记录(20%)
4.1 协作平台与工作方式
| 维度 | 做法 |
|---|---|
| 项目管理 | GitHub Projects 看板:Backlog → Todo → In Progress → Review → Done,每个需求一张 Issue,带验收标准与负责人 |
| 代码管理 | main(可发布)/ dev(集成)/ feature-*(一人一分支);PR 至少 1 人 Review,CI 跑通才可合并 |
| 提交规范 | feat: / fix: / docs: / refactor: / test: + 一句话说明 + Issue 号 |
| 设计评审 | 设计图与文档走「先提 PR 再评」的流程,评审意见落在 Issue 里,可追溯 |
| 例会 | 每周一次 30 分钟站会:上周产出、本周计划、阻塞项 |
4.2 本轮交付与验收记录
| 编号 | 交付项 | 负责人 | 状态 | 证据(PR / 链接) | 验收人 · 阻塞 |
|---|---|---|---|---|---|
| 01 | 系统总体架构、功能模块分解与 UML 五图 | 01 | 已完成 | 【PR #N】design/01–07;.mmd 源文件可一键重渲染 |
01 验收;用例粒度经 10.28 评审收敛 |
| 02 | 用户端 5 页 + 管理端 5 页原型与交互规则 | 02 | 已完成 | 墨刀链接 + prototype/index.html;11.06 交互自测全链路通过、无脚本报错 |
03 验收;正式动效待联调 |
| 03 | 智能体五步任务流、提示词与护栏文案 | 03 | 已完成 | 原型五步遮罩截图;提示词与工具清单见 agent_config |
01 验收;医疗边界话术待补 3 类边界样例 |
| 04 | ER 图、12 张表模型与建表脚本 | 04 | 已完成 | 【PR #N】schema.sql;3NF 与索引方案评审通过 |
01 验收;分区归档策略待压测确认 |
| 05 | 《系统设计说明书》《数据库设计说明书》 | 01 / 05 | 已完成 | 两份 PDF(26 页 / 18 页),V1.0 评审定稿 | 全员交叉审阅;图表编号已统一 |
| 06 | 团队博客、协作记录与提交材料 | 05 | 已完成 | 本博客;GitHub Projects 看板与站会记录【截图】 | 01 验收 |
八、提交材料
- GitHub 团队仓库链接 https://github.com/jing-shu491/MoveMate
- 《跃动MoveMate_系统设计说明书.pdf》 https://github.com/jing-shu491/MoveMate/blob/main/docs/跃动MoveMate_数据库设计说明书.pdf
- 《跃动MoveMate_数据库设计说明书.pdf》 https://github.com/jing-shu491/MoveMate/blob/main/docs/跃动MoveMate_系统设计说明书.pdf

浙公网安备 33010602011771号