当你拿到一个项目需求,你该做什么?新手小白来时路!
前言
今天,让我们从最基本,最初始的地方开始,探讨一个完整,专业的项目到底该如何完成。
思维起手势
第一步:把需求还原成“人话故事”,而不是功能列表
用户给的需求往往是模糊的,比如“我想做一个能自动回答客户问题的系统”或者“我想用AI分析报表”。这个时候,你第一个要做的,不是想“我要用哪个模型”,而是把自己当成用户,走完一整条业务流程。问自己三个问题:
- 谁在用? 是内部员工、外部客户,还是系统管理员?
- 在什么场景下用? 是上班时查数据,还是购物时咨询售后?
- 他最终得到了什么? 是一段回答、一份表格,还是一个操作指令?
你会把这些答案,浓缩成一句极其通俗的“核心用户故事”。比如:
“我们公司的销售总监,每天早上想对着一个对话框说‘给我导出昨天华南区销量前三的产品’,系统就能跑出一份分析简报,并把原始数据留底。”
这句话,就是整个项目的北极星。你之后所有技术决策,都要回来问自己:我这么做,能让这个销售总监更爽吗?如果偏了,就拉回来。
第二步:给AI大模型“定角色”,别让它当万能的神
我们现在要做的是“Python + AI大模型”项目。很多新手最容易犯的错,就是把大模型当成一个全知全能的魔法盒子,什么东西都往里扔。
你要清醒地认识到:在我们这个以FastAPI为骨架的系统里,大模型只是一个“智商极高,但需要精确调度的特殊员工”。
拿到需求后,你必须明确大模型到底扮演哪个角色,这直接决定了你的架构。常见角色有这三种,你辨认一下你的需求属于哪种:

怎么定角色?
很简单,你就看用户要达到目的,核心的“智力劳动”是谁干的。如果核心是需要理解千奇百怪的自然语言,那大模型是大脑;如果用户指令很明确,只是想让AI帮忙省掉打字和点菜单的麻烦,它就是翻译官。
第三步:画“数据河流图”,在纸上就跑通系统
你现在有了“北极星故事”和“大模型角色”,接下来就是用数据把这两个东西串起来。拿出一张白纸,横着画三道线,分别代表:
- 用户端(前端界面)
- 你的FastAPI服务(中间层)
- 数据与模型(MySQL + 大模型API/本地模型)
然后开始画一个完整的请求循环,比如“用户问:‘上个月哪些产品退货最多?’”:
- 用户端 → FastAPI:发了一个POST请求给 /chat 接口,带了这句话和用户I
- FastAPI内部(路由→服务层):服务层接到活儿,先想:“这事儿得查数据库,但我不知道该怎么查,需要翻译官”。
- FastAPI →大模型(翻译官):把用户的自然语言,连同你预设好的数据库表结构Prompt,一起发给大模型。大模型返回一个结构化的“查询计划”,比如
{“intent”: “top_returned_products”, “month”: “2026-04”} - FastAPI → MySQL:服务层拿到这个计划,组装出SQL,去MySQL里把退货最多的Top 5产品查出来。
- FastAPI →大模型(工匠):把查回来的冰冷数据,甩给大模型:“请把下面这堆数据,用友好的、给老板汇报的口吻写成一段话。数据:[……]”。
- FastAPI → 用户端:把大模型生成的分析报告,返回给用户。
落到具体行动上,你的第一个产出应该是一份“一页纸架构”
到现在为止,你没写一行代码,但思路比谁都清晰。把你的思考固化下来,形成一份只有一页纸的文档,它至少要包含:
- 项目一句话定义:就是上面那个“核心用户故事”。
- AI角色定义:一句话说清大模型在本项目里的角色(大脑/翻译官/工匠)。
- 核心API端点:先列最重要的,比如:
- POST /api/v1/chat (对话接口)
- GET /api/v1/reports/latest (获取最新报告)
- POST /api/v1/auth/login (登录)
- 核心数据表:只列最关键的,比如 users, conversations, sales_data。先不用画满所有的字段
- 关键流程草图:就是上面那种“数据河流图”的文字简版。
新手容易犯的错误
-
“我要用最牛的模型!” → 先跑通再优化。模型再牛,一个糟糕的Prompt就能让它变傻子。先用能调用的、成本最低的模型把整个链路跑起来。
-
“MySQL表我要设计得无比完美!” → 为时过早。根据上面设计的三四个核心表,直接用SQLAlchemy定义好Model,跑起来再说。数据结构的优化,源于真实数据的淬炼,不是凭空想出来的。
-
“我要学完所有FastAPI知识再动手” → 别。先会用 FastAPI(), @app.post, async def, Pydantic BaseModel 定义请求体和响应体,就足够你完成第一个MVP了。【Minimum Viable Product(最小可行产品)]
举例
我现在要做一个关于健康瘦身管理的网页端项目FitTrack,我们先确定他的的需求和业务流程为
① 用户注册/登录
↓
② 进入"健康概览"仪表盘
↓
③ 记录今日饮食(摄入多少卡路里)
④ 记录运动(消耗多少卡路里)
⑤ 记录体重
↓
⑥ AI自动生成每日健康评估(基于①②③的数据)
↓
⑦ 月底生成月度总结报告
↓
⑧ 根据报告定制下个月计划
↓
⑨ 循环往复,直到达到目标体重
定故事:给 FitTrack 一个一句话灵魂
“一个关心自己体重的普通人,每天花两分钟记录吃了什么、动了多久、体重多少,系统就自动帮他生成‘今日健康评价’和‘月度总结’,并且告诉他下个月怎么调整能更快达到目标体重。”
这个故事的潜台词是:用户不想懂营养学,不想自己算热量,更不想盯着Excel。所以你的系统,本质上是一个自动化的私人健康顾问。
定角色:AI大模型在这个故事里是谁?
我们对照之前的三角色表,来看 FitTrack 的每一步:
-
用户记录饮食/运动/体重:这是数据录入,不需要AI。
-
AI自动生成每日健康评估:基于今天的数据,给出评价和建议。比如“你今天碳水偏高,但运动消耗不错,继续保持,明天建议多吃点蔬菜”。这里需要理解营养学常识,并生成自然语言。
-
月底生成月度总结报告:需要分析一个月的数据趋势,发现规律,并用通俗的语言写出来。
-
定制下个月计划:基于月度总结和目标,生成一个可执行的饮食运动计划。
结论很明确:FitTrack里的AI大模型,扮演的是“资深营养师+健身教练”的角色。它是大脑,而且是“基于结构化数据进行推理和表达”的大脑。
更精确地说,它是一个 “架构师型大脑” :它的核心输入不是千奇百怪的开放问题,而是固定结构的用户健康数据。这比开放域聊天好做得多,也更容易控制质量。
因此,AI的角色定位一句话:“利用结构化健康数据,产出个性化评估、总结与计划的智能健康顾问。”
画流程:最重要的“数据河流图”
我们来画一条最核心的业务链路:用户请求生成“今日健康评估”。
在脑子里想像三个泳道:前端、FastAPI服务端、数据与模型层。
[前端]
│ 用户点击“生成今日评估”
│ POST /api/v1/assessments/daily
▼
[FastAPI 服务端]
│ 1. 鉴权中间件,拿到 user_id
│ 2. 路由 → 每日评估服务(DailyAssessmentService)
│
│ 3. 服务先问自己:我要拿哪些原始数据?
│ - 今日饮食记录 (从MySQL food_logs表)
│ - 今日运动记录 (从MySQL exercise_logs表)
│ - 最新体重记录 (从MySQL weight_logs表)
│ - 用户基础信息与目标 (从MySQL users/profiles表)
│
│ 4. 拿到四条数据后,组装成一个结构化的上下文对象
│ 例如:{ "user_name":"小明", "goal":"减重5kg", "calories_in":1800,
│ "calories_out":400, "weight_trend":"较昨日+0.3kg",
│ "food_detail":[{...}], "exercise_detail":[{...}] }
│
│ 5. 调用大模型服务(ModelService),把上面的上下文 + 精心设计的提示词模板
│ 发给大模型(这里大模型是“大脑”)
│
│ 6. 收到大模型生成的评估文本,做一层安全/质量过滤
│ 然后把评估结果存入数据库 assessment_reports 表
│
│ 7. 返回评估结果给前端
▼
[数据与模型层]
MySQL: 提供原始数据,存储生成的报告
大模型API: 执行自然语言生成任务
定架构:从数据流图画出一页纸架构
-
项目一句话定义
FitTrack 是一个帮助用户通过简单记录饮食、运动、体重,自动获得AI驱动的每日评估、月度总结和下月计划的健康管理平台。 -
AI角色定义
AI大模型是“基于用户结构化健康数据的个性化健康顾问大脑”。 -
核心API端点(初版)
POST /api/v1/auth/register 用户注册
POST /api/v1/auth/login 用户登录
GET /api/v1/dashboard 获取健康概览仪表盘数据
POST /api/v1/logs/food 记录饮食
POST /api/v1/logs/exercise 记录运动
POST /api/v1/logs/weight 记录体重
POST /api/v1/assessments/daily 生成今日评估
GET /api/v1/assessments/daily 查看历史评估
POST /api/v1/reports/monthly 生成月度总结报告
POST /api/v1/plans/monthly 生成下月计划
GET /api/v1/plans/current 查看当前计划
- 核心数据表(极其精简版,只列核心)
users : id, email, password_hash, created_at
profiles : user_id, height, target_weight, weekly_goal, …
food_logs : id, user_id, date, meal_type, food_name, calories, …
exercise_logs : id, user_id, date, exercise_type, duration, calories_burned, …
weight_logs : id, user_id, date, weight
assessments : id, user_id, date, content (AI生成的文本)
monthly_reports : id, user_id, year_month, content
monthly_plans : id, user_id, year_month, content
- 关键流程草图
见上方的“数据河流图”,重点就是:路由→服务层→数据聚合→Prompt组装→调用模型→存储结果→返回。
总结
你拿到需求后,第一个想的不应该是代码,而是:
定故事 → 定角色 → 画流程 → 写一页纸。
文件夹该怎么建
心法
项目结构不是银弹,是“分类收纳箱”。
我们的原则只有一个:当你想找一个东西时,3秒内能知道它大概在哪个文件里。 这就够了。
确认“地基” (.venv)和依赖
- 打开 PyCharm,右下角应该能看到 Python 3.11 (fittrack) … 之类,代表虚拟环境已激活。如果没有,手动点一下,选你项目里的 .venv 下的 python。
- 打开 PyCharm 底部的 Terminal 标签,你应该能看到命令行前面有 (fittrack) 字样。输入 pip list,确保 fastapi 和 uvicorn 已经躺在里面了。
一些常见文件名到底是装什么的

作者友情(血泪)提示:一定要学好英语
架构心法
一切架构的本质,是“分层”和“边界”
一个合格健康的项目,不管是后端还是前端,其核心思想只有一个:把不同职责的代码,物理隔离在不同的文件和文件夹里。修改一个功能时,改动的范围尽可能小。 这就是“高内聚,低耦合”的人话解释。
我们分为两个独立王国:后端帝国 和 前端帝国。它们通过 HTTP 协议(JSON 格式)互相派遣使者。
前后端分离 + SPA (单页应用)
fittrack-fullstack/ (你的总项目名)
├── backend/ ← 纯 API,不碰任何 HTML
└── frontend/ ← 纯前端 Vue/React 项目,用 npm run dev 跑
它的特征是:
前端和后端跑在不同的端口(比如前端 localhost:5173,后端 localhost:8000)。
前端通过 fetch/axios 跨域调用后端 API。
前端负责所有的页面渲染和路由跳转,后端只管 JSON 数据。
这也是现代互联网公司99%的项目形态。
第一帝国:FastAPI 后端(纯 API 服务)
它的唯一使命:接收 HTTP 请求,经过一系列处理,返回 JSON 数据。绝不直接碰 HTML 模板。
下面这个结构,是我们从今以后新建任何 FastAPI 项目的万金油模板。只要遵循心法,就能“随心所欲,而不逾矩”。
backend/
├── .env # 环境变量,存密钥,永不提交Git
├── requirements.txt # Python依赖
├── alembic.ini # 数据库迁移工具配置
├── alembic/ # 迁移脚本
│ └── versions/
│
└── app/ # 主应用包
├── main.py # 总入口:创建FastAPI实例,挂载路由,注册中间件
│
├── core/ # [地基层] 与业务无关的全局基础设施
│ ├── config.py # Pydantic Settings类,从.env读取所有配置
│ ├── security.py # 与安全相关:JWT生成校验、密码哈希
│ └── database.py # 异步引擎、会话工厂、get_db依赖
│
├── models/ # [数据层] SQLAlchemy 模型,纯表结构定义
│ ├── base.py # Base = declarative_base()
│ ├── user.py
│ └── ... # 其他表:product.py, order.py 等
│
├── schemas/ # [接口层] Pydantic 模型,定义进出数据的形状
│ ├── user.py # UserCreate, UserResponse, Token
│ └── ... # 其他:product.py, order.py
│
├── api/ # [路由层] 接待员,只做参数提取和调用下层,不写业务逻辑
│ ├── v1/
│ │ ├── __init__.py
│ │ ├── router.py # 聚合所有子路由,统一加 /api/v1 前缀
│ │ └── endpoints/
│ │ ├── auth.py # 登录注册
│ │ ├── users.py # 用户CRUD
│ │ └── ...
│ └── deps.py # 共享依赖项:如 get_current_user
│
├── crud/ # [数据访问层] 只与数据库交互,不关心HTTP
│ ├── user.py
│ └── ...
│
├── services/ # [业务逻辑层] 核心业务、算法、第三方API调用
│ ├── ai_service.py
│ └── ...
│
└── utils/ # [工具层] 与业务无关的通用函数
├── pagination.py
└── exceptions.py
后端帝国的铁律:数据流向是单向的
这是依赖倒置原则(Dependency Inversion Principle)的体现:高层模块不依赖低层模块,都依赖抽象
Controller → Service → DAO/CRUD → Database
作者小常识:
什么是"高层"和"底层"?
不是指代码的物理位置,而是指"业务抽象程度"
高层模块 = 接近业务逻辑的代码
底层模块 = 接近基础设施的代码
一个请求的生命周期,必须严格遵循这个链条:
api/endpoints (取参数)
→ 需要鉴权时,调用 api/deps.py 的依赖注入
→ 参数校验后,交给 services/ (处理业务逻辑)
→ 需要数据库时,services/ 调用 crud/
→ crud/ 操作 models/ 定义的表
→ 结果一层层返回到 api/endpoints,用 schemas/ 模型格式化后返回
数据流向:
api/endpoints → deps.py → services → crud → models
铁律:
- api 绝不直接操作数据库,必须通过 crud。
【关注点分离(Separation of Concerns)原则】 - crud 绝不包含业务逻辑,只做增删改查。
- services 是唯一可以调用多个crud 和外部的服务的地方。
第二帝国:Vue3 前端(纯客户端应用)
它的唯一使命:从后端拿 JSON 数据,经过一系列处理,渲染成用户可以交互的网页。
当你用 npm create vue@latest 创建项目后,把它放在后端旁边,形成我之前说的总项目文件夹:
fittrack-fullstack/ (或用你的项目名)
├── backend/
└── frontend/
以下是frontend/ 里的万金油结构,不管你走到哪一步,谨记心法:
frontend/
├── index.html # 单页面应用的HTML挂载点
├── vite.config.js # Vite 构建配置
├── package.json # 项目依赖
│
└── src/
├── main.js # 应用入口:创建Vue实例,挂载路由、状态管理
├── App.vue # 根组件
│
├── router/ # [路由] 控制URL与页面组件的映射
│ └── index.js
│
├── api/ # [通信层] 对所有后端接口的封装,前端其他部分只能通过这里与后端交互
│ ├── client.js # Axios实例,配置 baseURL、拦截器、自动带JWT令牌
│ ├── auth.js # 调用 /auth/register, /auth/login 等
│ ├── users.js
│ └── ...
│
├── stores/ # [状态层] Pinia/Vuex 全局状态管理
│ ├── auth.js # 用户登录状态、JWT令牌
│ └── ...
│
├── views/ # [页面层] 与路由一一对应的页面级组件
│ ├── LoginView.vue
│ ├── HomeView.vue
│ ├── UserProfileView.vue
│ └── ...
│
├── components/ # [组件层] 可复用的UI组件,不包含页面级逻辑
│ ├── common/ # 通用组件:Navbar.vue, Footer.vue, Loading.vue
│ └── ...
│
├── composables/ # [逻辑复用] Vue3 组合式函数的封装 (自定义hooks)
│ └── useAuth.js # 封装登入登出逻辑
│
└── assets/ # [静态资源] 图片、字体、全局样式
├── styles/
└── images/
前端帝国的铁律:数据是单向向下流动的
views/ 页面组件通过调用 stores/ 里的 action 获取数据,或直接调用 api/。
api/ 通过 client.js 里配置好的 axios 实例与后端通信。
获取到的数据在 stores/ 中存储,或直接在组件本地存储。
components/ 只通过 props 接收数据,通过 emits 事件通知父组件,自己不直接操作全局状态或发起 API 请求。
composables/ 将可复用的有状态逻辑抽取出来,让 views 和 components 保持简洁。
需要注意的小tips
一、Git 是什么(通俗版)
Git 是目前全球最主流的代码版本管理工具,简单理解:
给你的代码做「时光机 + 多人协作盘」。
核心两大作用
- 版本回溯(时光机)
每一次代码改动都会记录快照,改错了、功能崩了,可以一键切回之前正常的版本;也能查看每一行代码是谁、什么时候改的。 - 多人协作
团队多人开发同一个项目,所有人基于同一套代码拉取、修改、合并,不会互相覆盖文件。
配套平台(你常听到的)
- GitHub / Gitee / GitLab:云端代码仓库(线上服务器)
本地代码 → 推送(Push)到云端仓库 → 队友拉取(Pull)代码。
日常说「把代码传上去」,就是指推送到云端 Git 仓库。
二、核心问题:为什么密码、密钥、.env 绝对不能提交到 Git?
先看你项目里的敏感内容:
数据库账号密码、JWT 签名密钥、API Key(DeepSeek/OpenAI 密钥)、内网地址等。
一旦提交到 Git(尤其是公开仓库),风险极大。
1. 一旦上传,永久留痕,删不掉
Git 不是普通网盘:
- 普通文件:删掉 → 网盘里就没了;
- Git:所有历史提交记录永久保存。
哪怕你后来在代码里删掉密码、重新提交,历史提交快照里依然能完整查到原始密码。
任何人拿到你的代码仓库,翻历史记录就能扒出所有明文密钥。
2. 仓库分「公开/私有」,风险等级不同
① 公开仓库(GitHub 公开项目)
任何人都能搜索、下载、查看你的代码。
密码、密钥泄露后:
- 别人用你的数据库账号登录,篡改/盗取数据;
- 盗用你的 AI API Key 疯狂调用接口,产生高额账单;
- 接管你的 JWT 密钥,伪造登录 Token,入侵后台。
② 私有仓库(仅团队可见)
哪怕仓库设为私密,也不建议传:
- 团队人员流动、账号泄露、仓库意外外泄,都会导致敏感信息流出;
- 违反安全规范,正规企业开发一律禁止硬编码/提交密钥。
3. 多环境冲突
你的本地数据库密码、测试库密码、线上库密码完全不一样。
如果把本地 .env 提交上去,队友拉取代码后,配置和自己本地环境冲突,直接项目启动失败。
三、标准避坑做法
1. 第一步:新建 .gitignore 文件(关键)
在项目根目录创建文件,文件名就叫 .gitignore(无后缀)。
作用:告诉 Git:这些文件/文件夹,一律忽略,不要提交、不要上传。
你的项目 .gitignore 标准内容
# 忽略环境变量文件(核心!禁止上传 .env)
.env
.env.local
.env.dev
.env.prod
# Python 缓存、虚拟环境、日志、编译文件
__pycache__/
*.pyc
venv/
logs/
*.log
# 编辑器配置(可选)
.idea/
.vscode/
只要写了 /.env,Git 就会彻底无视这个文件,永远不会把它传到云端仓库。
2. 第二步:提供示例模板(队友怎么用?)
因为 .env 被忽略了,队友拉完代码是空的,启动会报错。
解决方案:
新建一份 .env.example 示例文件,这个可以正常提交到 Git。
示例文件 .env.example
# 数据库配置
DB_HOST=127.0.0.1
DB_USER=root
DB_PASSWORD=你的数据库密码
# JWT 配置
SECRET_KEY=你的JWT密钥
# AI 接口
DEEPSEEK_API_KEY=你的API密钥
3. 使用流程(团队统一规范)
- 代码仓库里只保留:
.env.example(模板,可上传) - 每个人本地:复制一份
cp .env.example .env - 自己修改本地
.env填入自己的真实密码/密钥 - 本地
.env被.gitignore忽略,不会上传
四、区分 3 个容易混淆的文件(你项目必记)
| 文件 | 作用 | 能不能提交到 Git |
|---|---|---|
.env |
存放真实密码、密钥、本地配置 | ❌ 绝对不能提交(.gitignore 忽略) |
.env.example |
配置模板、字段说明、占位符 | ✅ 必须提交,给队友参考 |
config.py |
配置加载代码(BaseSettings) |
✅ 正常提交(只是代码,无明文密码) |
五、补充:再回头串你整套流程(完整闭环)
- 本地开发:
写.env→ 存放数据库密码、JWT密钥 config.py:
用pydantic-settings自动读取.env,业务代码导入使用- Git 控制:
配置.gitignore忽略.env - 协作/上传:
只上传代码 +.env.example,真实密码留在每个人本地
六、一句话总结
- Git = 代码版本管理工具,用来存代码、回溯版本、团队协作;
- 密码/密钥不能传 Git:因为 Git 历史记录删不掉,一旦泄露会被盗用、拖垮服务;
- 标准解决方案:
真实配置放.env+ 用.gitignore禁止上传 + 提交.env.example模板给他人使用。
更多推荐




所有评论(0)