# P5：AI 集成层 — miniapp-ai-integration

> 优先级：P5（依赖 P3 + P4）
> 预估工作量：大
> 详细应用需求：#[[file:docs/prd/AI需求2.md]]

---

## ⚠️ 两阶段交付策略（2026-03-07 评审决定）

P5 的 8 个 AI 应用中，应用 3/4/5/6/7 的首条 Prompt JSON 结构包含占位符字段（`consumption_records`、`service_history`、`objective_data` 等），这些字段的具体结构取决于对应页面 API 的数据格式。在页面 API 未开发前，Prompt 结构无法确定，强行实现会导致"先猜后改"的浪费。

因此 P5 拆分为两个阶段：

### P5-A（当前阶段，P4 之后立即执行）
交付"管道"：建表、百炼封装、缓存 API、SSE 框架，以及 Prompt 已完全确定的应用（应用 2、应用 8）。
应用 3/4/5/6/7 只实现触发机制和调用骨架（Prompt 拼接函数留接口，用 TODO 标记）。

### P5-B（Prompt 细化，随页面 API 同步完成）
各应用的 Prompt JSON 细化和拼接实现，分散到对应页面的开发任务中：
- P6（task-detail）→ 细化应用 4/5 的 Prompt（服务记录结构确定后）
- P9（customer-detail）→ 细化应用 3/6/7 的 Prompt（消费记录结构确定后）

详见各 spec 的对应任务。

---

## 需求（Requirements）

### 用户故事

1. 作为助教，我可以在任意页面点击 AI 按钮，跳转到对话页面与 AI 交流，AI 了解当前页面上下文。
2. 作为助教，我在任务详情页能看到 AI 生成的维客线索分析、关系分析、话术参考、客户分析。
3. 作为助教，我提交备注后，系统自动通过 AI 分析备注内容，提取维客线索并评分。
4. 作为管理者，我在财务看板能看到 AI 生成的财务洞察分析。
5. 作为系统，所有 AI 对话（含系统调用）都要持久化记录。
6. 作为系统，客户结账单出现后自动生成客户全量分析与运营建议。
7. 作为系统，应用 3/应用 6 产出新线索后，自动整合去重生成统一维客线索。

### 验收标准

- AC1：应用 1 通用对话支持流式返回（SSE），前端逐字展示
- AC2：应用 2 财务洞察每日自动更新，覆盖 8 个时间维度，返回结构化 JSON（序号+标题+正文）
- AC3：应用 3 维客线索在客户新增消费时自动更新，返回 JSON 维客线索（分类标签限 3 个枚举：客户基础/消费习惯/玩法偏好），提供者统一为"系统"
- AC4：应用 4 在助教参与新结算/优先召回任务分配/高优先召回任务分配时触发，读取应用 8 最新缓存
- AC5：应用 5 联动应用 4，提供沟通话术
- AC6：应用 6 在每个备注提交后自动分析，返回 JSON（评分 1-10 + 维客线索 0-N 条，分类标签 6 个枚举：客户基础/消费习惯/玩法偏好/促销接受/社交关系/重要反馈），提供者为当前备注提供人
- AC7：应用 7 在消费事件链中应用 8 完成后触发（串行），基于客户全量信息生成运营策略
- AC8：应用 8 在应用 3 或应用 6 有新内容产生后立即触发，整合去重维客线索
- AC9：所有 AI 调用记录持久化（conversation_id, message_id, app_id, user_id/系统, role, content, tokens_used, nickname, created_at, site_id）

---

## 设计要点

### 8 个 AI 应用

| 应用 | 用途 | 调用方式 | 触发条件 | 返回格式 |
|------|------|---------|---------|---------|
| 应用 1 | 通用对话 | 用户主动（流式） | 点击 AI 入口 | SSE 流式文本 |
| 应用 2 | 财务洞察 | 后台轮询 | 每日 | JSON（序号+标题+正文数组） |
| 应用 3 | 客户数据维客线索分析 | 后台事件 | 客户新增消费 | JSON（线索数组：详情+标签+摘要+Emoji） |
| 应用 4 | 关系分析/任务建议 | 后台事件 | 助教参与新结算 / 优先召回任务分配 / 高优先召回任务分配 | JSON（任务描述+行动建议数组+一句话总结） |
| 应用 5 | 话术参考 | 后台联动 | 应用 4 调用时 | JSON（话术内容数组） |
| 应用 6 | 备注分析 | 后台事件 | 每个备注提交时 | JSON（线索数组+评分） |
| 应用 7 | 客户分析 | 后台事件 | 消费事件链：应用 8 完成后 | JSON（策略数组：标题+正文 + 总结） |
| 应用 8 | 维客线索整理 | 后台联动 | 应用 3 或应用 6 有新内容时 | JSON（整合后线索数组：详情+标签+摘要+Emoji+提供者） |

### 调用链与时序

```
消费事件（结账单）:
  └→ 应用 3（维客线索分析）→ 应用 8（线索整理）→ 应用 7（客户分析）
     （串行执行：应用 7 等待应用 8 完成后再启动，确保读到本次消费触发的最新线索）
     如果该结算单有助教参与:
       └→ 应用 4（关系分析，等待应用 8 完成后执行）→ 应用 5（话术参考）

备注提交事件:
  └→ 应用 6（备注分析）→ 应用 8（线索整理）

任务分配事件（优先召回/高优先召回）:
  └→ 应用 4（关系分析，读取应用 8 最新缓存）→ 应用 5（话术参考）
```

- 消费事件链为严格串行：应用 3 → 应用 8 → 应用 7，保证应用 7 的 reference 中包含本次消费产生的最新线索
- 应用 4 触发条件分两种场景：
  - 消费事件（有助教参与的新结算单）：等待应用 3 → 应用 8 完成后再执行，确保读到本次消费的最新线索
  - 任务分配事件（优先召回/高优先召回）：直接执行，读取应用 8 已有缓存
- 应用 8 在应用 3 或应用 6 每次产出后立即触发
- 应用 4 读取应用 8 缓存时，若缓存不存在（如新客户首次结算），reference 传空对象，Prompt 中标注"暂无历史线索"

### 应用分工说明

- 应用 3 vs 应用 6：应用 3 侧重客观数据分析（消费、到店频率等），应用 6 侧重主观备注分析（备注内容价值挖掘）
- 应用 3 vs 应用 7：应用 3 侧重单次消费触发的线索提取，应用 7 侧重客户全量信息的全局运营策略
- 应用 8：整合应用 3 + 应用 6 的线索，合并相似内容，保持最小改动原则

### 信息隔离

应用 1 通过 `biz_params.user_prompt_params` 传入：
- `User_ID`：当前用户 ID
- `Role`：身份（助教/管理者）
- `Nickname`：昵称

百炼平台侧根据参数做数据查询隔离。

### AI 入口汇总

所有入口统一使用应用 1，跳转 chat.html，第一条消息为页面上下文：

| 来源页面 | 触发方式 | 上下文内容 |
|---------|---------|-----------|
| task-list | 长按任务 → AI | 任务详情 + 客户-助教关系 |
| task-detail / coach-detail / customer-detail | "问问助手" | 页面完整内容 |
| board-* / performance-* / customer-service-records / my-profile | 右下角 AI 按钮 | 页面内容摘要 |

### 表结构

```
biz.ai_conversations
  - id, user_id, nickname, app_id, site_id
  - source_page, source_context (JSON)
  - created_at

biz.ai_messages
  - id, conversation_id, role (user/assistant/system)
  - content, tokens_used
  - created_at

biz.ai_cache
  - id, cache_type (app2_finance / app3_clue / app4_analysis / app5_tactics / app6_note_analysis / app7_customer_analysis / app8_clue_consolidated)
  - site_id, target_id (member_id 或 assistant_id 或 pair)
  - result_json, score (应用6专用)
  - triggered_by (trigger_job_id)
  - created_at, expires_at
```

### 应用 3 返回格式

应用 3 侧重客观数据，分类标签限 3 个枚举，提供者统一为"系统"：

```json
{
  "clues": [
    {
      "category": "消费习惯",
      "summary": "偏好周末下午时段消费",
      "detail": "近3个月周末消费占比72%，分析过程...",
      "emoji": "📅"
    }
  ]
}
```

- 分类标签枚举：客户基础 / 消费习惯 / 玩法偏好
- 输入：客户近 3 个月消费数据（DWD+DWS 订单明细全维度）、会员卡明细、余额合计、应到店日期、到店间隔
- 消费金额口径（已校准）：使用 `items_sum`（= table_charge_money + goods_money + assistant_pd_money + assistant_cx_money + electricity_money），不得使用 `consume_money`（三种历史口径混合，详见 DWD-DOC consume/consume-money-caliber.md）
- 参考信息：应用 6 的线索结果 + 最近 2 套应用 8 的历史信息（附生成时间）

### 应用 6 返回格式

应用 6 侧重主观备注分析，分类标签 6 个枚举，提供者为当前备注提供人：

```json
{
  "score": 7,
  "clues": [
    {
      "category": "社交关系",
      "summary": "常带朋友来消费",
      "detail": "备注提到经常约朋友周末来打球...",
      "emoji": "👥"
    }
  ]
}
```

- 分类标签枚举：客户基础 / 消费习惯 / 玩法偏好 / 促销接受 / 社交关系 / 重要反馈
- 评分规则：6 分为标准分，重复信息/低价值/时效性低酌情扣分，高价值信息酌情加分
- 输入：当前备注内容 + 客户消费数据 + 所有助教对该客户的全部备注
- 参考信息：应用 3 的线索结果 + 最近 2 套应用 8 的历史信息（附生成时间）

### 应用 7 返回格式

```json
{
  "strategies": [
    {
      "title": "高频消费但余额不足",
      "content": "客户近3个月消费12次但储值卡余额仅剩200元..."
    }
  ],
  "summary": "该客户为高频活跃用户，建议重点维护储值续费..."
}
```

- 输入：客户全量客观数据 + 所有备注（标注创建者）
- 消费金额口径（已校准）：同应用 3，使用 `items_sum` 而非 `consume_money`
- 参考信息：最新 + 最近 2 套应用 8 的历史信息（附生成时间）
- 主观信息需标注【来源：XXX，请甄别信息真实性】

### 应用 8 返回格式

```json
{
  "clues": [
    {
      "category": "消费习惯",
      "summary": "偏好周末下午时段消费",
      "detail": "近3个月周末消费占比72%...",
      "emoji": "📅",
      "providers": "系统,张助教"
    }
  ]
}
```

- 分类标签枚举：客户基础 / 消费习惯 / 玩法偏好 / 促销接受 / 社交关系 / 重要反馈
- 输入：当前最新应用 3 + 应用 6 的全部线索内容
- 原则：合并相似线索（多提供者逗号分隔），其余原文返回，最小改动

### 首条 Prompt 数据结构（后端调用时拼接）

> 以下定义每个应用调用百炼 API 时，后端需要拼接的首条用户消息（user message）JSON 结构。
> System Prompt 见 `docs/prd/ai-app-prompts.md`。
> ⚠️ 占位标记（两阶段策略）：各应用的 `consumption_records`、`assistant_info`、`service_history` 等字段当前为字符串占位符。
> P5-A 阶段只实现调用骨架，Prompt 拼接函数留接口。具体 JSON 子结构在以下阶段细化：
> - 应用 4/5 的 `service_history`、`assistant_info` → P6-T4（task-detail 页面 API 开发时）
> - 应用 3/6/7 的 `consumption_records`、`objective_data` → P9-T1（customer-detail 页面 API 开发时）

**通用规则（所有应用生效）：**
- 所有首条 Prompt JSON 中统一加入 `"current_time": "2026-03-08 14:30:25"` 字段（精确到秒），让 AI 知道当前时间上下文
- 所有 reference 中的参考资料必须标注生成时间（`generated_at` 字段），让 AI 判断信息时效性

#### 应用 1：通用对话

由前端发起，首条消息为页面上下文：

```json
{
  "current_time": "2026-03-08 14:30:25",
  "source_page": "来源页面标识（如 task-detail、board-finance）",
  "page_context": "页面上下文摘要（客户信息、任务信息等结构化文本）",
  "screen_content": "用户当前屏幕可见内容的文本化描述"
}
```

#### 应用 2：财务洞察

```json
{
  "current_time": "2026-03-08 08:05:00",
  "site_id": 12345,
  "time_dimension": "本月",
  "date_range": {"start": "2026-03-01 08:00:00", "end": "2026-04-01 08:00:00"},
  "current_period": {
    "income_structure": {"table_fee": 0, "assistant_pd": 0, "assistant_cx": 0, "goods": 0, "recharge": 0},
    "prepaid_assets": {"total_balance": 0, "recharge_amount": 0, "consumption_deduction": 0},
    "expense_summary": {"rent": 0, "utilities": 0, "supplies": 0, "salary": 0, "other": 0},
    "platform_settlement": {"groupbuy_income": 0, "platform_fee": 0, "net_income": 0}
  },
  "previous_period": {
    "time_dimension": "上月",
    "date_range": {"start": "2026-02-01 08:00:00", "end": "2026-03-01 08:00:00"},
    "income_structure": {},
    "prepaid_assets": {},
    "expense_summary": {},
    "platform_settlement": {}
  }
}
```

- 8 个时间维度：本月/上月/本周/上周/前3月不含本月/本季/上季/近6月不含本月
- 营业日分界点 08:00
- 收入结构字段映射（已校准，数据源：DWD-DOC 03-财务全景）：`table_fee` = `table_charge_money`（56.6%）、`assistant_pd` = `assistant_pd_money`（30.6%）、`assistant_cx` = `assistant_cx_money`（0.9%）、`goods` = `goods_money`（10.1%）、`recharge` = 充值 pay_amount（settle_type=5）
- `electricity_money` 全为 0（门店未启用灯控），不纳入收入结构

#### 应用 3：客户数据维客线索分析

```json
{
  "current_time": "2026-03-08 14:30:25",
  "member_nickname": "客户昵称",
  "main_data": {
    "consumption_records": "近3个月消费数据（DWD+DWS 订单明细：台费、充值、助教消费等全维度）",
    "member_cards": "名下会员卡明细",
    "card_balance_total": 0,
    "stored_value_balance_total": 0,
    "expected_visit_date": "2026-03-10",
    "days_since_last_visit": 15
  },
  "reference": {
    "app6_clues": "应用6的线索结果（如有）",
    "app8_history": [
      {"generated_at": "2026-03-01", "clues": "最近第1套应用8结果"},
      {"generated_at": "2026-02-15", "clues": "最近第2套应用8结果"}
    ]
  }
}
```

#### 应用 4：关系分析 / 任务建议

```json
{
  "current_time": "2026-03-08 14:30:25",
  "assistant_info": "助教基本信息（花名、级别、工龄等）",
  "service_history": "助教服务该客户的历史记录",
  "task_assignment_basis": "任务分配的依据（新结算/优先召回/高优先召回）",
  "customer_data": {
    "system_data": "客户近3个月消费数据（同应用3的 main_data 结构）",
    "notes": [
      {"recorded_by": "备注创建者", "content": "备注全文", "created_at": "时间"}
    ]
  },
  "reference": {
    "app8_current": "当前最新维客线索（应用8结果）",
    "app8_history": [
      {"generated_at": "2026-03-01", "clues": "最近第1套应用8结果"},
      {"generated_at": "2026-02-15", "clues": "最近第2套应用8结果"}
    ]
  }
}
```

#### 应用 5：话术参考

```json
{
  "current_time": "2026-03-08 14:30:25",
  "assistant_info": "助教基本信息",
  "service_history": "助教服务该客户的历史记录",
  "task_assignment_basis": "任务分配的依据",
  "customer_data": {
    "system_data": "客户近3个月消费数据（同应用3的 main_data 结构）",
    "notes": [
      {"recorded_by": "备注创建者", "content": "备注全文", "created_at": "时间"}
    ]
  },
  "task_suggestion": "本次任务建议（应用4返回的完整结果）",
  "reference": {
    "app8_history": [
      {"generated_at": "2026-03-01", "clues": "最近第1套应用8结果"},
      {"generated_at": "2026-02-15", "clues": "最近第2套应用8结果"}
    ]
  }
}
```

#### 应用 6：备注分析

```json
{
  "current_time": "2026-03-08 14:30:25",
  "current_note": {
    "content": "本次提交的备注内容",
    "recorded_by": "备注创建者",
    "created_at": "提交时间"
  },
  "reference": {
    "member_nickname": "客户昵称",
    "consumption_data": "客户近3个月消费数据（同应用3的 main_data 结构）",
    "all_notes": [
      {"recorded_by": "创建者", "content": "备注全文", "created_at": "时间"}
    ],
    "app3_clues": "应用3的线索结果（如有）",
    "app8_history": [
      {"generated_at": "2026-03-01", "clues": "最近第1套应用8结果"},
      {"generated_at": "2026-02-15", "clues": "最近第2套应用8结果"}
    ]
  }
}
```

#### 应用 7：客户分析

```json
{
  "current_time": "2026-03-08 14:30:25",
  "member_id": 12345,
  "member_nickname": "客户昵称",
  "objective_data": "客户近3个月消费数据（同应用3的 main_data 结构）",
  "subjective_data": {
    "notes": [
      {"recorded_by": "创建者", "content": "备注全文", "created_at": "时间"}
    ]
  },
  "reference": {
    "app8_current": "最新维客线索（应用8结果）",
    "app8_history": [
      {"generated_at": "2026-03-01", "clues": "最近第1套应用8结果"},
      {"generated_at": "2026-02-15", "clues": "最近第2套应用8结果"}
    ]
  }
}
```

#### 应用 8：维客线索整理

```json
{
  "current_time": "2026-03-08 14:30:25",
  "app3_clues": {
    "generated_at": "2026-03-05 14:30:00",
    "clues": [
      {"detail": "...", "category": "消费习惯", "summary": "...", "emoji": "📅"}
    ]
  },
  "app6_clues": {
    "generated_at": "2026-03-05 14:25:00",
    "clues": [
      {"category": "社交关系", "emoji": "👥", "detail": "...", "summary": "..."}
    ]
  }
}
```

### 数据写入规则

- 应用 1：流式返回完成后，将完整的 assistant 回复写入 `ai_messages`（role=assistant），用户消息在发送时即写入（role=user）
- 应用 3/6 的线索产出后，先写入 `ai_cache`，再触发应用 8
- 应用 8 整合后的线索**全量替换**该客户在 `member_retention_clue` 中的所有 AI 来源线索（`source IN ('ai_consumption', 'ai_note')`），人工线索（`source='manual'`）不受影响。全量替换合理性：应用 8 输入包含应用 3 + 应用 6 的全部线索，AI 整合时会保留重要内容，输出即为该客户的完整 AI 线索集
- 应用 2/4/5/7 的结果写入 `ai_cache`，供前端读取
- 所有 AI 调用记录写入 `ai_conversations` + `ai_messages`（含 tokens_used 统计）

### 应用 8 → member_retention_clue 字段映射

应用 8 返回的每条线索写入 `member_retention_clue` 时，字段映射如下：

| 应用 8 返回字段 | member_retention_clue 列 | 说明 |
|----------------|-------------------------|------|
| `category` | `category` | 直接映射，枚举值必须与 DDL CHECK 约束一致（6 个值） |
| `emoji` + `summary` | `summary` | emoji 拼接在 summary 前面存储，如 `📅 偏好周末下午时段消费`，前端直接读取展示 |
| `detail` | `detail` | 直接映射 |
| `providers` | `recorded_by_name` | 多提供者逗号分隔，如 `系统,张助教` |
| — | `recorded_by_assistant_id` | 系统触发时填 NULL |
| — | `source` | 根据线索来源判断：纯应用 3 产出 → `ai_consumption`，纯应用 6 产出 → `ai_note`，混合来源 → `ai_consumption`（以客观数据为主） |
| — | `member_id` | 从触发上下文获取 |
| — | `site_id` | 从触发上下文获取 |
| — | `recorded_at` | 写入时间 NOW() |

### ai_cache 数据保留策略

- 应用 1（通用对话）：对话记录保留在 `ai_conversations` + `ai_messages` 中，无条数限制（按需清理）
- 应用 2-8：每个 `(cache_type, site_id, target_id)` 组合保留最近 500 条记录，超过时删除最旧的
- 清理时机：每次写入新记录后，异步检查并清理超限记录

### ai_cache target_id 约定

| 应用 | cache_type | target_id 含义 | 示例 |
|------|-----------|---------------|------|
| 应用 2 | app2_finance | 时间维度编码 | `this_month`、`last_week`、`last_3_months` 等 |
| 应用 3 | app3_clue | member_id | `12345` |
| 应用 4 | app4_analysis | `{assistant_id}_{member_id}` | `100_12345` |
| 应用 5 | app5_tactics | `{assistant_id}_{member_id}` | `100_12345` |
| 应用 6 | app6_note_analysis | member_id | `12345` |
| 应用 7 | app7_customer_analysis | member_id | `12345` |
| 应用 8 | app8_clue_consolidated | member_id | `12345` |

应用 2 的 8 个时间维度编码：`this_month` / `last_month` / `this_week` / `last_week` / `last_3_months` / `this_quarter` / `last_quarter` / `last_6_months`

### 应用 2 调度机制

- 调度方式：ETL 调度器中的调度任务，在每日 08:00（营业日切点）后的首次任务执行时触发
- 执行逻辑：DWS 日更数据更新完成后，依次对 8 个时间维度发起独立调用（共 8 次百炼 API 调用）
- 每次调用生成一条 `ai_cache` 记录，`target_id` 为时间维度编码
- 如果 ETL 调度器中尚无此调度逻辑，需在 P5-A 阶段补充

### 应用 1 对话历史管理

- 每次从任意页面进入 chat 页面时，始终新建对话（`ai_conversations` 新增一行），不复用已有对话
- 历史对话列表按时间倒序展示，20 条/页懒加载
- 暂不支持删除对话

### 前端消费方式

| 应用 | 前端展示位置 | 数据来源 | 展示说明 |
|------|-------------|---------|---------|
| 应用 1 | chat 页面 | SSE 流式 + `ai_messages` | 实时对话，历史记录从 ai_messages 读取 |
| 应用 2 | board-finance 财务看板 | `ai_cache`（cache_type=app2_finance） | JSON 数组渲染为洞察卡片（序号+标题+正文） |
| 应用 3 | 不直接展示 | `ai_cache`（cache_type=app3_clue） | 作为基础资料供应用 8 整合，不在页面显示 |
| 应用 4 | task-detail 任务详情页 | `ai_cache`（cache_type=app4_analysis） | 展示任务描述+行动建议+一句话总结；`summary` 摘要同时在 task-list 任务卡片中显示 |
| 应用 5 | task-detail 任务详情页 | `ai_cache`（cache_type=app5_tactics） | 展示话术参考列表 |
| 应用 6 | task-detail 备注卡片 | `ai_cache`（cache_type=app6_note_analysis） | `score` 以打星方式呈现在备注卡片上；线索部分不直接展示，作为基础资料供应用 8 整合 |
| 应用 7 | customer-detail 客户详情页 | `ai_cache`（cache_type=app7_customer_analysis） | 展示运营策略数组+总结 |
| 应用 8 | customer-detail + task-detail | `member_retention_clue` 表 | 展示整合后的维客线索（Emoji+标签+摘要+详情）；task-detail 中提供者显示为"By:系统"或"By:备注"（不显示具体人名） |

---

## 任务清单

### P5-A 阶段（当前执行，Prompt 已确定 + 调用骨架）

- [ ] T1：创建 `biz.ai_conversations` + `biz.ai_messages` + `biz.ai_cache` 表（cache_type 扩展 app7/app8）
- [ ] T2：实现百炼 API 统一封装层（流式/非流式、重试、日志、JSON 输出模式）
- [ ] T3：实现应用 1 通用对话 API（SSE 流式返回，上下文注入框架先搭建，页面文本化工具留接口）
- [ ] T5：实现应用 2 财务洞察轮询任务（Prompt 已完全确定，JSON 输出：序号+标题+正文）
- [ ] T6-骨架：实现应用 3 触发机制 + 调用框架（Prompt 拼接函数留接口，`consumption_records` 等字段待 P9-T1 细化）
- [ ] T7-骨架：实现应用 4 触发机制 + 调用框架（Prompt 拼接函数留接口，`service_history` 等字段待 P6-T4 细化）
- [ ] T8-骨架：实现应用 5 联动框架（Prompt 拼接函数留接口，随应用 4 同步细化）
- [ ] T9-骨架：实现应用 6 触发机制 + 调用框架（Prompt 拼接函数留接口，`consumption_data` 等字段待 P9-T1 细化）
- [ ] T10-骨架：实现应用 7 触发机制 + 调用框架（Prompt 拼接函数留接口，`objective_data` 等字段待 P9-T1 细化）
- [ ] T11：实现应用 8 维客线索整理（Prompt 已完全确定，应用 3/6 产出后触发，合并去重→写入 member_retention_clue）
- [ ] T12：实现 AI 缓存读写 API（前端读取缓存结果）
- [ ] T13：查阅百炼文档确认流式返回技术方案（SSE vs WebSocket）及 JSON 输出最佳实践

### P5-B 阶段（Prompt 细化，分散到对应页面 spec）

以下任务不在 P5 中独立执行，而是嵌入对应页面的开发任务：

- [ ] T4：实现页面内容文本化工具（各页面数据 → AI 可读文本）→ 随 P6-P9 各页面逐步实现
- [ ] T6-完整：应用 3 Prompt JSON 细化 + 拼接实现 → 在 P9-T1（customer-detail API）中完成
- [ ] T7-完整：应用 4 Prompt JSON 细化 + 拼接实现 → 在 P6-T4（task-detail API）中完成
- [ ] T8-完整：应用 5 Prompt JSON 细化 + 拼接实现 → 在 P6-T4（task-detail API）中完成
- [ ] T9-完整：应用 6 Prompt JSON 细化 + 拼接实现 → 在 P9-T1（customer-detail API）中完成
- [ ] T10-完整：应用 7 Prompt JSON 细化 + 拼接实现 → 在 P9-T1（customer-detail API）中完成
