实验一——Python Vibe Coding 考核:Excel 报表生成与 FastAPI 记账接口
两道考题 + 一个网页演示版:从需求澄清、TDD 小步开发到独立核验的完整记录
一、项目背景
本次考核采用 Vibe Coding 方式完成:人与 AI 协作,通过「需求澄清 → 设计文档 → 实施计划 → TDD 小步实现 → 独立验证 → Git 全程留痕」的流程交付两个独立项目。两道考题均从零搭建,并额外产出一个 Streamlit 网页演示版,把两个项目合并到同一界面,方便展示。
考核按”结果 + 过程 + 验证 + 风险 + 复盘”五维评分,交付物包括:① 需求澄清清单;② 可运行源代码工程(目录结构清晰、含 README 运行说明);③ 测试用例(正常用例 + 至少 2 个边界/异常用例)及运行结果截图;④ AI 协作过程记录(关键对话摘要 + 代码修改 diff);⑤ 一段文字复盘。本文即围绕这五项展开。
二、环境与技术栈
操作系统:Windows;语言:Python 3.13
考题一:Pandas、openpyxl(Excel 读写)、pytest(测试)
考题二:FastAPI、Uvicorn、SQLite、Pydantic、pytest + httpx(接口测试)
网页演示版:Streamlit 1.65(双页面 + 文件上传)、Playwright(浏览器实测截图)
三、考题一:Excel 报表生成脚本
(一)需求与样例数据
读取含脏数据的销售明细 sales_raw.xlsx(六列:日期、销售员、产品、数量、单价、地区),完成清洗与统计,输出 report.xlsx。
样例数据由脚本生成(固定随机种子可复现),共 91 行,注入 5 类脏数据:
| 脏数据类型 | 数量 | 示例 |
|---|---|---|
| 关键字段缺失 | 4 行 | 缺日期 / 缺销售员等 |
| 重复行 | 3 行 | 整行完全相同 |
| 数量 ≤ 0 | 2 行 | 数量 0、-5 |
| 非法日期 | 1 行 | 2026-02-30(历法不存在) |
| 单价 ≤ 0 | 1 行 | 单价 -50 |
(二)清洗规则(5 类,逐类剔除)
删除关键字段缺失的行(
dropna)剔除数量 ≤ 0 的异常行
剔除日期非法(格式错误或历法不存在)的行(
pd.to_datetime校验)剔除单价 ≤ 0 的异常行
按全字段去重
清洗结果:91 → 80 行。开发过程中曾自查发现最初清洗只覆盖 3 类(缺失 / 数量≤0 / 重复),非法日期与负单价两行会流入统计并污染月度总额(负单价行销售额为 -250),已补全规则并同步更新口径。
(三)统计口径与输出
销售额 = 数量 × 单价;按销售员、按地区分别汇总
月度总额 = 841853.21 元(全部有效数据合计,四舍五入保留 2 位小数)
输出 4 个工作表:明细清洗后 / 按销售员 / 按地区 / 总览
约束:不得修改原始文件;异常输入(文件缺失、缺列、空文件、清洗后无有效数据)给出明确可读的报错提示
(四)测试与独立核验
pytest 9/9 全绿(清洗规则、异常输入、四表输出、新口径行数与总额)
verify_report.py独立重算:按销售员合计、按地区合计、独立重算总额三处与总览一致 → PASS


四、考题二:FastAPI 记账接口
(一)功能
提供记账接口(收入 / 支出流水):
POST /records:录入流水,合法返回 201;参数非法(金额≤0、非法类型、非法日期如 2026-02-30)返回 422 与校验详情GET /records:流水列表,支持按类型、分类、日期区间筛选并分页GET /summary:收入合计、支出合计、结余
(二)实现要点
SQLite 存储层:
_write_lock模块级锁串行化写事务,保证多线程并发写入不丢数据Pydantic 校验:金额
gt=0、类型枚举(收入 / 支出)、field_validator校验日期合法性,非法参数统一转 422(而非 500)
(三)测试与实测
pytest 19/19 全绿,含 20 线程 × 5 = 100 条并发写入无丢失 用例
Uvicorn 启动实测:合法录入 3×201、非法参数 3×422、筛选分页、summary 结余均符合预期

五、网页演示版(Streamlit 双页面)
把两个考题合并为一个 Streamlit 应用(端口 8505),复用两个考题的同一份代码与口径,不复制实现:
| 页面 | 演示内容 |
|---|---|
| 📊 报表演示 | 数据来源可切换(内置样例 / 上传文件):91 行 → 5 类脏数据卡片 → 清洗 91→80 行 → 按销售员 / 按地区统计 → 月度总额 841853.21 → 下载 report.xlsx(附样例下载按钮) |
| 💰 记账演示 | 表单录单 → 201/422 校验语义 → 流水列表(类型 / 分类 / 日期区间筛选 + 分页)→ 收支汇总 → 并发写入 100 条无丢失 |
上传文件模式支持任意符合六列结构的 Excel(含我额外生成的 127 行多脏数据样例 原数据.xlsx:缺失 12 / 重复 6 / 数量≤0 5 / 非法日期 4 / 单价≤0 4,清洗后 100 行)。





六、工作流:Vibe Coding + Superpowers
两个项目全程按 Superpowers 流程执行:
头脑风暴(HARD-GATE):先书面写清需求澄清清单——目标(两个可独立运行的 Python 工程)、输入输出(考题一读
sales_raw.xlsx出report.xlsx;考题二为 HTTP 记账服务)、边界(不修改原始文件、异常可读报错、非法参数返回 4xx)、验收标准(一键运行 + 数值人工核对一致 + pytest 覆盖核心用例);关键决策拍板:样例数据由 AI 生成(固定种子可复现)、单工程双子目录组织、过程记录由 AI 草拟用户审改设计文档与实施计划:两份 spec + 两份 plan(考核 9 任务 + 网页版 5 任务),均获用户批准后动工
TDD 小步实现:每个功能先写失败测试(RED)→ 最小实现(GREEN)→ 提交;过程中 RED 暴露并修复了 3 类真实缺陷(测试数据缺陷、422 语义、并发事务冲突)
独立核验:
verify_report.py三处比对、接口实测、浏览器实测截图Git 全程留痕:15+ 次提交,每步可追溯
七、运行与复现
1 | # 考题一:生成样例 → 一键运行 → 独立核验 |
八、测试统计汇总
| 模块 | 测试数 | 说明 |
|---|---|---|
| 考题一 | 9 | 清洗规则 / 异常输入 / 四表输出 / 新口径 |
| 考题二 | 19 | 校验边界 / 筛选分页 / 并发 100 条无丢失 |
| 网页演示 | 19 | 报表 / 记账逻辑(含分类筛选)/ 上传模式 |
| 合计 | 47 全绿 | 独立核验 PASS(841853.21) |
各模块均含正常用例与 ≥2 个边界/异常用例:非法日期 422、全为脏数据报错、缺列/损坏文件上传、并发 100 条无丢失等。
九、复盘:哪些环节交给 AI、哪些自己拍板、哪些人工审查
| 环节 | 主导方 | 说明 |
|---|---|---|
| 需求澄清与验收口径 | 用户拍板 | 样例数据 AI 生成(固定种子)、单工程双子目录、过程记录 AI 草拟用户审改、上传文件固定六列结构 |
| 技术选型与实现 | AI 主导 | 清洗/统计规则、SQLite + 模块锁、Pydantic 校验、Streamlit 双页面方案 |
| 测试与独立核验 | 双方协作 | AI 按 TDD 写用例并跑绿;关键数值由 verify_report.py 独立重算,人工复核一致 |
| 风险人工审查 | 人工接管 | 拦截 3 类真实缺陷:测试数据日期笔误(去重测不到点)、GET 非法日期 500 应转 422、多线程并发写共享连接事务冲突 |
十、结语
这次考核最大的收获是完整走了一遍「人与 AI 协作开发」的正规流程:先想清楚再动手、每个功能有测试兜底、每个结论有独立核验、每一步都留在 Git 里。两道考题本身并不复杂,但流程带来的确定性让「看起来能跑」变成了「可验证地正确」—— 这也是 Vibe Coding 和随手写脚本的区别。