一、工作进展

本阶段主要完成了产品设计讨论、技术选型、后端项目初始化以及基础用户表设计。

主要产出:

  1. 确定「MetalCat」一站式 AI 健身助理的产品定位与核心交互
  2. 确定后端技术栈为 Python FastAPI + PostgreSQL + SQLAlchemy + JWT
  3. 完成 server/ 目录骨架搭建与开发规范制定
  4. 完成用户信息表(users)的初步设计

二、详细内容

1. 产品形态

产品定位为面向健身新手的 AI 健身助理,核心理念是降低健身入门门槛,让用户通过对话即可完成健身数据记录和训练规划,无需手动操作。

选择「健身新手」这个切入点是经过讨论的。健身人群可以大致分为两类:一类是已经有一定经验、知道自己要练什么的人,他们需要的是详细的计划管理和动作库;另一类是完全不知道从何开始的新手,他们最需要的其实是「有人告诉我现在该做什么」。前者需要的是工具,后者需要的是指导。我们选择了后者,因为 AI 天然适合做这件事——它可以对话,可以根据用户状态动态调整建议,不需要用户具备任何健身知识。

产品采用「展示区 + 对话区」的双区布局:

展示区包含四个独立组件,同一时间只显示一个:

  • 身体数据看板:身体指标的可视化图表
  • 训练规划和执行:健身计划日程表、每日训练记录
  • 营养实验室:饮食记录表、热量摄入环形图
  • 发现频道:AI 整理的健身信息日报

这四个板块的设计思路是:数据统一展示在左侧,用户不需要去各个地方找信息;右侧的对话窗口是统一的入口,用户做任何操作都通过对话完成。比如用户说「刚练完卧推」,AI 自动识别这是训练记录,应该更新训练数据;用户说「今天想吃火锅」,AI 识别这是饮食相关,自动调用营养模块计算热量。这种交互方式的好处是用户不需要学习「这个东西在哪里」,有什么需求直接说就行。

对话区的拟人化设计也是有意为之的。健身这件事本身是反人性的,坚持下来不容易。如果用户面对的是一个冷冰冰的系统,交流成本会很高。我们希望通过一个固定的「小八」形象和统一的语气风格,让用户感觉是在跟一个真人助手交流,而不是在使用一个工具。这对留存率可能会有影响。

四个子 Agent 之间需要状态同步,比如营养实验室需要知道用户的基础代谢率(来自身体数据看板),训练规划需要根据用户的体脂率调整强度。Agent 间的通讯协议和数据同步机制由 Agent 架构设计模块负责,这是个有意思的挑战,但不是本阶段的工作重点。

2. 技术选型

前端采用 React + TypeScript + Vite + Ant Design + Tailwind CSS。选择 React 是因为团队有人熟悉,生态成熟,组件库丰富。TypeScript 主要考虑的是减少运行时错误,接口定义清晰对多人协作有帮助。多端适配通过响应式布局解决,不做三套代码,用一套适配所有屏幕。

后端技术栈是本阶段最需要花心思的部分:

框架选择:FastAPI vs Django vs Flask

Django 是成熟的全家桶,ORM、后台管理、认证系统都自带,做传统 Web 应用很省心。但它的同步特性在 AI 场景下是个限制——AI 应用本质上是 IO 密集型的,大量的时间花在等待模型推理、等待数据库查询、等待外部 API 响应上。同步框架在这类场景下吞吐量不高。

Flask 足够灵活,但很多基础设施需要自己搭。认证、数据库连接池、参数校验、API 文档这些,Django 不用动脑子就能用,Flask 得自己选型自己集成。

FastAPI 是个折中的选择:异步支持原生,性能足够好,自带参数校验(Pydantic)和自动文档(Swagger UI),开发体验接近 Flask 但基础设施不用从零搭。缺点是生态没有 Django 丰富,有些场景需要自己动手。但对 AI 应用来说,这些都不是问题。

数据库选择:PostgreSQL vs MySQL

MySQL 轻量,部署简单,是很多创业公司的首选。但 PostgreSQL 在几个方面更适合这个项目:

一是 JSON 支持。健身数据的围度记录是典型的半结构化数据——不同用户可能记录不同的部位,今天加个「大腿围」,明天加个「臂围」,Schema 不好固定。MySQL 5.7 之前 JSON 支持很弱,5.7 之后有所改善但不如 PostgreSQL。PostgreSQL 的 JSONB 类型不仅存储方便,还能建索引查询,性能好很多。

二是向量索引。后面要做 RAG(检索增强生成),需要向量数据库支持。pgvector 扩展让 PostgreSQL 原生支持向量存储和相似度搜索,不需要额外搭一套 Milvus 或 Pinecone。

三是复杂查询。训练计划按日期范围查询、营养数据按时间段聚合统计,这些 SQL 在 PostgreSQL 里写起来更顺手。

ORM 选择:SQLAlchemy

SQLAlchemy 是 Python 生态最成熟的 ORM,有 Core 和 ORM 两套 API。Core 偏 SQL 层面,更灵活;ORM 偏对象层面,更直观。SQLAlchemy 2.0 统一了两者的 API,设计更合理。

选 SQLAlchemy 而不是直接用 psycopg2 或 asyncpg 的原因是:业务代码不应该跟原始 SQL 耦合太紧,换数据库代价太大。ORM 薄薄一层抽象,性能损失在 AI 场景下不是瓶颈,收益是代码可维护性和可测试性。

鉴权选择:JWT vs Session

Session 的好处是服务端可以随时让会话失效,用户改个密码就能踢掉所有活跃会话。但 session 需要存储,Flask 默认存 cookie(不安全),生产环境通常要搭 Redis。引入 Redis 增加部署复杂度,多实例部署时还要考虑 session 共享。

JWT 的本质是一个加密令牌,服务端不需要存储,会话状态全在 token 本身。这让它天然适合分布式场景——任何实例都能验证 token,不需要共享存储。

代价是「无状态」带来的问题:token 一旦签发,服务端没有办法让它失效。用户被盗号了,想踢掉所有活跃会话?做不到,只能等 token 过期(通常是 24 小时)。

这个代价是可以接受的。短期 token 策略(24 小时)已经将风险控制在可接受范围内。如果将来真的需要「强制登出」,可以在用户表加一个 token_version 字段,每次改密码就递增,验证时检查版本号。这个改动成本不高。

3. 后端项目初始化

server/ 目录采用分层架构:

server/
├── api/           # API 路由层,参数校验、调用 service
├── infra/        # 基础设施层,数据库连接等
├── config/       # 配置管理
├── middleware/   # 中间件层,JWT 鉴权、CORS
├── agents/       # Agent 逻辑层
├── modules/      # 业务模块层
├── tools/        # MCP 工具实现
├── jobs/         # 定时任务
└── tests/        # 测试用例

分层的出发点是分离关注点和降低耦合。API 层应该只负责接收请求、参数校验、调用下层、返回响应,不应该有业务逻辑。业务逻辑放在 modules 层,基础设施封装在 infra 层。这样做的好处是:

第一,方便测试。API 层测请求响应,modules 层测业务规则,infra 层测基础设施,各自独立。Mock 的层级也很清晰。

第二,方便替换。数据库要从 PostgreSQL 换到 MySQL,只需要改 infra 层;认证逻辑要改,只改 modules 层。不会牵一发动全身。

第三,方便协作。分层清晰了,大家就可以分模块开发,不会出现三个人改同一个文件的情况。

依赖方向是单向的:api → modules → infra,下层不依赖上层,同层不相互依赖。这个约束在项目初期就要定下来并执行,否则时间一长必然会乱。

开发规范通过 server/AGENTS.md 约束。规范这件事在团队项目中很重要,但不是越细越好——太细了没人愿意遵守,等于没写。我只定了几个关键点:Git 提交格式(Conventional Commits)、类型注解(公共函数必须有)、docstring(公共 API 必须有)、API 设计原则(统一响应体)。这些都是实际项目中容易出问题的地方,定清楚能减少很多沟通成本。

4. 用户信息表设计

本阶段仅设计了一张表:用户信息表(users),用于支持注册和登录。

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

密码用 bcrypt 哈希存是常识,就不多说了。这里想说的是表设计的时机问题。

很多人做项目喜欢一开始就设计完整的 ER 图,把所有表都画出来。我觉得这对信息管理系统这类需求稳定的项目是合适的,但对探索型的产品项目不合适——你还不知道这个功能要不要做、做成什么样子,过早设计出来的表大概率要改。

这个阶段只设计账号相关的表就够了。用户要注册登录,这是确定的,必须做。身体数据怎么存、训练计划什么结构,现在讨论太早了。等业务逻辑明确之后再设计,数据模型会更准确。

业务相关的表在后续阶段根据开发进度逐步设计。比如身体数据看板的功能范围定了之后,再设计 body_profile;训练规划的具体需求明确了,再设计 train_plan。这种渐进式的表设计与敏捷开发的思想是一致的:不要提前设计你不确定的东西。

三、总结

本阶段完成了产品设计到技术方案的转化,核心是做出了一系列「在当前阶段最合理」的选择。

几个关键决策:

  1. 健身新手切入:差异化定位,AI 适合做这件事,不是大而全的工具而是真正能引导新手的助手

  2. JWT 无状态鉴权:用「无法主动失效」的代价换取水平扩展能力,短期 token 策略控制风险,后续可通过 token_version 解决强制登出

  3. 分层架构的项目组织:分离关注点,降低耦合,方便测试、维护和多人协作。规范不要定太细,抓关键问题

  4. 渐进式数据库设计:只设计确定要做的部分,不提前设计尚不确定的业务表

这些决策背后有一个共同的原则:不要过度设计当前阶段不需要的东西。架构是为业务服务的,业务还没明确的时候,过早的抽象反而会成为负担。

下一阶段将完善数据库设计,实现完整的鉴权系统和业务 API。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐