Files
yingqing/AGENTS.md
T
2026-07-20 11:55:19 +08:00

148 lines
11 KiB
Markdown

# Airshelf · 电商 AI 平台 · Codex 工程约定
> **本文件由 Codex 启动时自动加载。所有 AI 协作必须遵循以下规则。**
---
## 项目简介
**Airshelf** · AI 短视频带货生成平台 · 5 阶段流水线(商品 → 故事板 → 镜头 → 生成 → 投放)
- **设计代号:** Restraint · V2.1 · Firecrawl-aligned
- **实际开发目录:** [core/](core/) —— `core/frontend`(React 19 + Vite + TS,真网站前端)· `core/backend`(Django,后台)· `core/qa`(截图对比测试)
- **视觉标准答案(对照用,不是运行代码):** [电商AI平台/](电商AI平台/) —— UI 设计师手写的 HTML 设计稿 + `design.md` 设计规范。**开发改 `core/`,视觉照 `电商AI平台/`。**
- **历史归档:** [v1/](v1/) · [_archive/](_archive/)
---
## ★ 设计规范铁律(每次涉及页面 / CSS / UI 必读)
### 触发条件
**只要任务涉及以下任一种,必须先 Read [电商AI平台/design.md](电商AI平台/design.md)(设计规范),并对照 [电商AI平台/](电商AI平台/) 里对应的 `*.html` 设计稿(视觉标准答案):**
- 修改 `core/frontend` 里的页面(`.tsx`)或样式(`design-restraint.css` / `*-page.css`)
- 添加新页面 / 新组件
- 调整布局 / 间距 / 颜色 / 字号
- 用户提到"页面" "样式" "视觉" "组件" "色" "字" "圆角" "间距" 等关键词
> ⚠️ **现在不交付静态 HTML 了**:真代码在 `core/frontend/src`(React)。`电商AI平台/` 的 `.html` 只当**视觉对照标准**,别去改它来"做功能"。新页面/新组件的交付规范见 [design/CLAUDE.md](design/CLAUDE.md)。
### 必读章节
- [design.md §0 AI 协作铁律](电商AI平台/design.md#0--ai-协作铁律每次启动必读) — 必读
- [design.md §1 设计哲学](电商AI平台/design.md#1--设计哲学) — 价值观
- [design.md §3 组件清单](电商AI平台/design.md#4--组件清单restraintcss-已实现--不要重发明) — 用现成组件
- [design.md §8 Don't List](电商AI平台/design.md#8--dont-list绝对禁止--每次自检) — 自检
### 7 条铁律
1. **任何页面 / CSS 调整前必须 Read [电商AI平台/design.md](电商AI平台/design.md)** — 不读不动手
2. **检查 [core/frontend/src/design-restraint.css](core/frontend/src/design-restraint.css) 已有组件**(设计稿原版在 `电商AI平台/assets/restraint.css`)— `Grep ".btn|.pill|.input"` 等,别重发明
3. **禁止在某页 `*-page.css` 里重写共享类**(`.btn` `.pill` `.input` `.modal` `.drawer` `.toast` `.field` `.tabs` `.chip` `.stats` `.list-row` 等)— 要变体回 `design-restraint.css`
4. **禁止创建新色值** — 必须用 design.md §2.1 的 token,不写裸 hex
5. **禁止改动基础 token**(`--heat` `--background-base` `--border-faint` 等)— 改了破坏全站
6. **完成后对照 [design.md §8 Don't List](电商AI平台/design.md#8--dont-list绝对禁止--每次自检) 逐条自检**
7. **不确定就问用户**,不要凭感觉发挥 — 用户原话:"我都希望你能遵循我们的设计规范,而不是乱做"
---
## 设计核心速记(详见 design.md)
- **冷灰底** `#f9f9f9` · 主橙 `#fa5d19` · 主前景 `#262626`
- **全场 8 px 圆角**(Pill / dot 999 例外)· `>12 px` 直接判错
- **inside-border** 而非真 `border`(hover 不抖动)
- **单橙锚点** · 全场只有一个 accent · hover 用 alpha 不用换 hue
- **Mono 装饰必有** · `[ 200 OK ]` `// 05.14` `[ /v2 ]`(品牌签名)
- **主 CTA 唯一允许阴影** · 4 层橙色发光 · 其他场景禁阴影
- **Inter(英/数字/装饰)+ Alibaba PuHuiTi(中)** · 字符级 fallthrough
- **字重仅 3 档** · 400 / 500 / 600 · 700 仅给 Ctrl K 徽标
---
## Git 工作流
- **当前开发分支:** `dev`
- **主分支:** `main` (生产)
- **严禁直推 master/main** — 走 dev 分支 → PR → 合并触发 CI/CD
- **严禁 `--no-verify` 跳过 hook**
- **Push 规则:** 默认不 push,改完即停 · 用户明确说"push / 推一下"才执行
- **commit 前不要 amend** — 创建新 commit,避免破坏历史
- **Commit 格式:** 使用 `type: 中文简述`,例如 `feat: 接通模特三视图生成`;类型按改动选择 `feat``fix``docs``refactor``test``chore` 等,冒号后的备注必须是精简中文
---
## 认证 / 账号模型(产品定调 · 2026 中国市场)
- **登录 / 注册一律「用户名 + 密码」,不用邮箱** —— 登录页、注册页都**不要邮箱字段**(后端 `RegisterSerializer` / `LoginSerializer` 本就以 `username` 为主标识)。**这是有意偏离 V1 设计稿**(V1 login/register 画的是邮箱),别按 V1 把它改回邮箱。
- **注册 = 邀请制**:Invitation 邀请码;有码加入已有团队、无码开新团队当超管。成员也可由超管在团队页直接建账号 + 发凭据。
- **手机号注册:后续再做**,本期不做。
- 用户原话:「2026 年的中国没人用邮箱登录」。
---
## ★ AI 生成 Agent 化架构(后端核心 · 改 AI 链路前必读)
> 2026-06-17 落地:脚本从「散文+正则」升级为**结构化流式对话 agent**,并把 商品→脚本→图片→故事板→视频 用**可插拔 Provider** 打通。全流程已端到端验证(含 Seedance 出片)。详见仓库 `交接-AI生成Agent化-2026-06-17.md` 与 `AI生成-Agent化落地方案.md`。
### 可插拔 Provider(换中转站零改代码)
- 火山官方直连(豆包/SeeDream/Seedance)→ `VolcanoArkProvider`;其余(tokenssr 等中转站)→ 通用 `OpenAICompatibleProvider(base_url, api_key)`
- 分流在 [services.py](core/backend/apps/ai/services.py) `build_provider()`,按 `provider.name ∈ OFFICIAL_DIRECT_PROVIDERS`(含 `volcengine`)。**加/换中转站 = DB 加一行 `ModelProvider`**。凭证解析:`ModelProvider.api_key`(DB)→ `settings.PROVIDER_KEYS`(.env),密钥默认只在 .env。
- 默认模型 `get_default_model(capability)` = 最早创建的 active 模型;图像默认 = `tokenssr:gpt-image-2`(迁移 0006 停用其余图像模型,**别再激活火山 Seedream 否则会顶替默认**)。
### 脚本 Agent(流式 SSE)
- 端点 `POST /api/projects/{id}/script-agent-stream/``text/event-stream`,事件 `tool`/`delta`/`draft`/`saved`/`done`/`error`。**DRF 必须挂 `ServerSentEventRenderer` 否则 406**。
- 核心 [script_agent.py](core/backend/apps/ai/script_agent.py):加载 [core/backend/skills/ecommerce-video-script/](core/backend/skills/ecommerce-video-script/) 作系统提示词;3 模式(auto/theme/revise)+ **精准改一镜**(`target_index`,后端 `_merge_single_segment` 强制保留其余镜);多模型(`model_config_id`)。
- ⚠️ **skills 必须放在 `core/backend/` 内**(随后端打进 Docker 镜像)。镜像由 `./core/backend` 构建,skills 若放仓库根则不在构建上下文 → 镜像里没有 → 提示词加载为空 → 提取吐散文解析失败 / 脚本退化。提取的 skill 同理:[core/backend/skills/ecommerce-entity-extract/](core/backend/skills/ecommerce-entity-extract/)。
- **结构化 ScriptDraft 契约**:`narration`(口播/旁白,扁平兼容下游)+ `dialogue:[{speaker,line}]`(剧情对白,默认空,用户聊天提要求才补)+ `role/speaker/product_exposure/entity_refs`。落 `ScriptVersion.metadata`(hook/tone/entities)+ `ScriptSegment` 字段,并回填 `project.metadata`(cast/scenes/script_entities)给下游。
- **改稿用基准稿时长**(`effective_duration`),别用请求默认 60 否则截掉 90s 稿尾镜。**所有 `target_index` 判断用 `is None` 不用真值**(0 是合法镜号)。
### 图像 / 故事板 / 视频 / 模特库
- 故事板 @图1@图2@图3:`_storyboard_reference_images()``entity_refs` 取角色/场景/商品基础资产,`provider.image_edit(images=[...])` 多图合成(锁脸锁商品)。**走 image_edit 分支必须用 `build_storyboard_frame_prompt_refs`**(refs 版提示词,否则一致性约束失效)。
- 视频 Seedance:`create_video_task(generate_audio=True)` 直接出音(原写死 False)。慢:5-10 分钟/段。
- 模特库:`python manage.py seed_demo_models --count N`([model_library.py](core/backend/apps/ai/model_library.py),9:16氛围图→16:9白底三视图)。
### 测试 / 凭证
- 跑测试用 `DB_ENGINE=sqlite`(远程库无建库权限);测试 setUp 会停用 seed 的中转站文本模型保证命中可 mock 的 VolcanoArkProvider。
- **凭证安全:** 凭证只从本地安全配置、部署 Secret 或数据库配置读取;除非用户明确要求且任务确实需要,不得读取、输出或复制凭证内容。
- **火山人像素材库审核(绿/红盾)已接入并验证**:真人(person)基础资产生成后 `transaction.on_commit` 静默送审([assets/review.py](core/backend/apps/assets/review.py) + [assets_client.py](core/backend/apps/assets/assets_client.py),一团队一组 `AssetReviewGroup`);`Asset.review_status`(processing/active绿/failed红);端点 `poll-reviews` 前端基础资产趴每 8s 轮询刷新徽章。e2e 已拿到真绿盾。
## 文件操作
- **三视图 = 单张 16:9 图** · 不要拆成 3 张缩略 · 用 `aspect-ratio: 16/9` 单容器
- **设计稿优先** · 写页面前先读 [电商AI平台/](电商AI平台/) 对应页面的 `*.html` 设计稿(视觉标准答案)+ design.md
- **`.pen` 文件加密** · 只能用 pencil MCP 工具,不能 Read/Grep
## 本机连接备忘
- 火山 MySQL 公网域名 `mysql-8351f937d637-public.rds.volces.com` 在本机可能被 TUN / 代理解析到 `198.18.x.x` fake-ip,导致 MySQL 握手阶段断开。
- 本机开发连接测试 MySQL 时,优先使用真实公网 IP `14.103.27.192`,并加 `--bind-address=192.168.124.86`
- 部署到火山内网 / K8s 时,优先使用私网地址 `mysql8351f937d637.rds.ivolces.com`
- 账号、密码、ARK/TOS/Redis 等敏感信息应记录在本地安全文件 `account.md`(若存在),不要复制到本文件;仅在用户明确要求且任务确实需要时按最小范围读取。
- `192.168.124.86` 是本机历史地址;连接前先只读核对当前网卡地址,不要把它当成永久配置。
---
## 用户偏好
- **角色:** UI 设计师 · 不读代码报错,只看最终视觉结果
- **不需要的:** 终端报错截图、深奥的代码解释、过度的实施细节
- **需要的:** 简短状态更新、视觉结果对照、清晰的"对/错"反馈
---
## 关键路径速查
| 资产 | 路径 |
| ---- | ---- |
| **设计规范(SSoT)** | [电商AI平台/design.md](电商AI平台/design.md) |
| **视觉标准答案(HTML 设计稿)** | [电商AI平台/](电商AI平台/) 各 `*.html`(逐页对照还原) |
| **前端代码(真网站)** | [core/frontend/src/routes/](core/frontend/src/routes/) + 每页 `src/*-page.css` |
| **共享 CSS / token(实现)** | [core/frontend/src/design-restraint.css](core/frontend/src/design-restraint.css)(原版 `电商AI平台/assets/restraint.css`) |
| **公共外壳(侧栏/顶栏)** | [core/frontend/src/components/app-shell.tsx](core/frontend/src/components/app-shell.tsx)(原 `电商AI平台/assets/shell.js`) |
| **后端代码** | [core/backend/apps/](core/backend/apps/)(Django) |
| **截图对比测试** | [core/qa/visual-parity/compare-page.mjs](core/qa/visual-parity/compare-page.mjs) |
| **新页面交付规范** | [design/CLAUDE.md](design/CLAUDE.md) |
| **视觉样板间(归档)** | [电商AI平台/_archive/design-system.html](电商AI平台/_archive/design-system.html) |
---
**违反任何规范规则,用户有权要求重做,无需解释。**