docs: 拆分网关与worker文档,按机器分别开发
- 新增 网关-开发任务书.md: 独立自包含的网关侧任务书(骨架/健康检查派发/ 鉴权转发/base64改URL/静态托管/部署/DoD),在外网机开发 - worker任务书 v1.5: 移除§16网关章节,顶部标注本机职责,DoD只留worker侧, 指向独立网关任务书 - 新增 docs/README.md: 文档索引,标清worker机/网关机/共享分别读哪些
This commit is contained in:
+12
-63
@@ -1,13 +1,14 @@
|
||||
# 接口 1:四庭七眼测量 — 开发任务书(AI Agent 执行版)
|
||||
# 接口 1:四庭七眼测量 — 开发任务书(worker 侧 · AI Agent 执行版)
|
||||
|
||||
> **在高性能 worker(GPU 机)上开发。** 本任务书只负责 worker 侧算法逻辑。
|
||||
> 配套技术方案:[`接口1-四庭七眼测量-技术实现方案.md`](接口1-四庭七眼测量-技术实现方案.md)
|
||||
> 系统架构:[`系统架构-网关与高性能后端.md`](系统架构-网关与高性能后端.md)
|
||||
> 系统架构(两端共享契约,先读):[`系统架构-网关与高性能后端.md`](系统架构-网关与高性能后端.md)
|
||||
> **网关侧在另一台机器开发,有独立任务书**:[`网关-开发任务书.md`](网关-开发任务书.md),本机不涉及。
|
||||
> 执行者:AI coding agent。请**严格按阶段顺序**执行,每个阶段完成后运行该阶段的「验证方法」,**通过后再进入下一阶段**。
|
||||
|
||||
> 📌 **架构拆分(务必先读架构文档)**:系统分为「外网网关」+「高性能 worker(GPU)」两层。
|
||||
> - **本任务书的阶段一~十(§2–§11)都在 worker 上实现**——worker 跑完整 `app.py` + `face_analysis`,用 GPU。
|
||||
> - **网关是独立工作流,见 §16**(薄代理:健康检查 / 派发 / 鉴权 / 标注图落盘改 URL)。
|
||||
> - 与单机版的两处关键差异:① torch 用 **GPU(CUDA)** 版;② 阶段八 handler **返回 `annotated_image_base64` 而非保存到 static + URL**(落盘改 URL 由网关做)。
|
||||
> 📌 **本机职责**:worker 跑完整 `app.py` + `face_analysis`,用 GPU。与单机版的两处关键差异:
|
||||
> - ① torch 用 **GPU(CUDA)** 版;
|
||||
> - ② 阶段八 handler **返回 `annotated_image_base64`,不保存到 static、不拼 URL**(落盘改 URL 由网关做)。
|
||||
> - 接口文档(对外契约)**完全不变**。
|
||||
|
||||
---
|
||||
@@ -258,7 +259,7 @@ curl -s -H "$H" -X POST $F -F image_file=@/tmp/oversize.bin # 1006
|
||||
curl -s -o /dev/null -w "%{http_code}\n" -X POST $F -F image_file=@tests/fixtures/frontal.jpg # 401
|
||||
# 1003) 侧脸:仓库无素材,用 mock 大 yaw 在单测中覆盖
|
||||
```
|
||||
- 正常用例 data 含 `annotated_image_base64`(**不是** URL——落盘改 URL 由网关做,见 §16);base64 解码后是合法 PNG。
|
||||
- 正常用例 data 含 `annotated_image_base64`(**不是** URL——落盘改 URL 由网关做,见网关任务书);base64 解码后是合法 PNG。
|
||||
- 不带 token 返回 401;`/health` 不需要 token。
|
||||
- `/docs` Swagger 正常加载,该接口 schema 未破坏。
|
||||
|
||||
@@ -314,13 +315,12 @@ nvidia-smi # 确认推理时 GPU 被占用
|
||||
|
||||
**完成标准**:worker 直连返回真实数据(base64 图)、鉴权生效、`/health` 就绪、GPU 在用。
|
||||
|
||||
> 端到端(经网关的 HTTPS 冒烟)见 §16 网关工作流的验证。
|
||||
> 端到端(经网关的 HTTPS 冒烟)见 [`网关-开发任务书.md`](网关-开发任务书.md) 的验证。
|
||||
|
||||
---
|
||||
|
||||
## 12. 总交付清单(Definition of Done)
|
||||
## 12. 总交付清单(worker 侧 Definition of Done)
|
||||
|
||||
**worker 侧(算法)**
|
||||
- [ ] `requirements.txt`(torch CUDA 版)/ `.gitignore` / `scripts/download_weights.sh`
|
||||
- [ ] `face_analysis/`:`detector.py`、`pose.py`、`calibration.py`、`hair_segmenter.py`、`measure.py`、`annotation.py`、`face_mesh_landmarks.py`、`fonts/`、`weights/`
|
||||
- [ ] `app.py` 中 `/api/v1/face/measure` 真实实现(移除该接口 Mock),**返回 `annotated_image_base64`**
|
||||
@@ -329,12 +329,7 @@ nvidia-smi # 确认推理时 GPU 被占用
|
||||
- [ ] worker(GPU 机 :28187)部署冒烟通过,GPU 在用
|
||||
- [ ] worker 返回 data 含 `annotated_image_base64`、`hairline_source`、`head_pose`,业务字段与 `docs/接口文档.md` 对齐
|
||||
|
||||
**网关侧(见 §16)**
|
||||
- [ ] 网关代理 5 个接口,对外契约/字段/URL 与接口文档**完全一致**
|
||||
- [ ] worker 池健康检查 + 空闲派发(并发=worker 数)+ 全忙排队/无后端→1007
|
||||
- [ ] 共享密码鉴权(配置文件,可轮换)
|
||||
- [ ] base64 → 落盘 `static/annotations/` → 改写 `annotated_image_url`
|
||||
- [ ] 端到端 HTTPS 冒烟:`https://hair.xiangsilian.com/...` 返回真实数据、`annotated_image_url` 可公网访问
|
||||
> 网关侧的交付清单在 [`网关-开发任务书.md`](网关-开发任务书.md)(另一台机器开发),本任务书不含。
|
||||
|
||||
---
|
||||
|
||||
@@ -500,50 +495,4 @@ def test_landmark_overlay():
|
||||
|
||||
---
|
||||
|
||||
## 16. 网关工作流(独立于上面 worker 阶段)
|
||||
|
||||
> 完整设计见 [`系统架构-网关与高性能后端.md`](系统架构-网关与高性能后端.md)。网关是**新建的薄代理应用**,与 worker 算法解耦,可并行开发。worker 至少完成阶段八(能直连返回 base64)后即可联调。
|
||||
|
||||
### 16.1 网关骨架与配置
|
||||
|
||||
**开发步骤**
|
||||
1. 新建 `gateway/`(独立 FastAPI/asgi 应用):`gateway/app.py`、`gateway/config.example.json`、`gateway/pool.py`(健康池+派发)、`gateway/forward.py`(转发+图片改写)。
|
||||
2. 加载 `config.json`(架构文档 §4 schema):worker 列表、密码、健康检查/派发参数。`config.json` 入 `.gitignore`,仓库只放 `config.example.json`。
|
||||
|
||||
**验证**:启动网关,加载配置无误,打印解析出的 worker 列表与参数。
|
||||
|
||||
### 16.2 健康检查 + 派发(并发=worker 数)
|
||||
|
||||
**开发步骤**
|
||||
1. 后台任务周期轮询每个 worker `/health`(带 token),按 `unhealthy/healthy_threshold` 维护在线池(架构 §5)。
|
||||
2. 每个 worker 维护忙/闲状态;新请求选一个**空闲健康** worker 派发,并发=1/worker;全忙则排队至 `queue_wait_seconds`,超时→1007;池空→1007(架构 §6/§10)。
|
||||
|
||||
**验证**
|
||||
- 配 2 个 worker,并发打 3 个请求:前 2 个并行、第 3 个排队;返回均正常。
|
||||
- 停掉 1 个 worker:健康检查在 `interval×threshold` 内将其下线,请求自动只走存活的。
|
||||
- 全停:请求返回 `code==1007`。
|
||||
|
||||
### 16.3 鉴权 + 转发 + 标注图改写
|
||||
|
||||
**开发步骤**
|
||||
1. 转发:原样透传客户端请求体,附加 `X-Internal-Token`(架构 §7/§8)。worker 的 1001–1008 原样透传给客户端。
|
||||
2. **图片改写**:worker 响应里的 `*_base64` 字段 → 解码落盘 `static/annotations/{uuid}.png` → 删除 base64、写入对应 `*_url`=`https://hair.xiangsilian.com/static/...`(架构 §9)。映射表以接口文档为准(接口1:`annotated_image`)。
|
||||
3. 网关托管 `/static/*`;加标注图定期清理任务。
|
||||
4. 转发失败按 `max_retries` 换 worker 重试;耗尽→1007。
|
||||
|
||||
**验证(端到端,最终冒烟)**
|
||||
```bash
|
||||
# 经网关 HTTPS(对外,无需 token——token 是网关→worker 内部的)
|
||||
curl -s -X POST https://hair.xiangsilian.com/api/v1/face/measure \
|
||||
-F image_file=@tests/fixtures/frontal.jpg | python -m json.tool
|
||||
# 期望:与接口文档完全一致——data 含 annotated_image_url(不是 base64)
|
||||
curl -sI https://hair.xiangsilian.com/static/annotations/<uuid>.png # 200
|
||||
```
|
||||
- **对外响应字段/URL 与接口文档逐一一致**(客户端无感知拆分)。
|
||||
- 直接打 worker 不带 token → 401;经网关正常。
|
||||
|
||||
**网关完成标准**:5 接口代理正常;多 worker 并发与排队符合预期;后端全挂→1007;标注图经网关落盘且公网可访问;**对外契约零变化**。
|
||||
|
||||
---
|
||||
|
||||
> **任务书版本**: v1.4 | **创建日期**: 2026-06-13(v1.4:适配网关+worker 拆分架构——worker 返 base64/GPU/鉴权,新增 §16 网关工作流)| 配套技术方案 v2.0 / 系统架构 v1.0
|
||||
> **任务书版本**: v1.5 | **创建日期**: 2026-06-13(v1.5:拆出网关任务书到独立文档,本书聚焦 worker 侧)| 配套技术方案 v2.0 / 系统架构 v1.0 / 网关任务书 v1.0
|
||||
|
||||
Reference in New Issue
Block a user