# RAG 会话自动标题开发任务拆解与接口变更清单

> 最后整理：2026-05-19
> 对应方案：`docs/RAG/RAG会话自动标题生成与重命名实施方案.md`

## 1. 本期落地范围

本期目标不是做一个“前端点一下自动命名”的伪功能，而是完成第一版可稳定运行的后端自动标题链路：

1. 新会话首轮回答完成后，后端异步生成标题
2. 手动重命名后，不再被自动标题覆盖
3. 会话列表排序从“单纯 updated_at”收口到“最后消息时间优先”
4. 前端移除旧的假自动重命名逻辑

---

## 2. 任务拆解

## 2.1 后端数据层

任务：

1. 为 `rag_conversation` 增加标题状态字段
2. 增加 `last_message_at`
3. 增加相关索引

交付物：

1. `scripts/创建sql/schema_rag_chat_auto_title.sql`

验收点：

1. 老数据执行 SQL 不报错
2. 默认值正确
3. 索引存在

## 2.2 后端会话查询层

任务：

1. 会话列表返回 `titleSource`
2. 会话列表返回 `lastMessageAt`
3. 排序改为 `COALESCE(last_message_at, updated_at) DESC`

验收点：

1. 自动标题更新不会让会话无故跳到顶部
2. 真正发新消息的会话仍能上浮

## 2.3 后端消息完成链路

任务：

1. assistant 最终落库时同步更新 `last_message_at`
2. 首轮回答完成后调度自动标题任务

验收点：

1. 标题生成失败不影响主回答
2. 只在首轮完整回答后触发

## 2.4 后端自动标题生成器

任务：

1. 新增 `_maybe_schedule_auto_title(...)`
2. 新增 `_run_auto_title_task(...)`
3. 新增 `_generate_conversation_title(...)`
4. 新增 `_sanitize_generated_title(...)`
5. 新增 `_build_fallback_title(...)`

验收点：

1. 同一会话不会重复并发生成标题
2. 生成失败能记状态
3. 生成成功后能回写标题

## 2.5 后端手动重命名链路

任务：

1. `RenameConversation()` 改为写入 `title_source = 'manual'`
2. 清空最近一次标题生成错误

验收点：

1. 用户手动改名后，后续自动任务不再覆盖

## 2.6 前端聊天主链路

任务：

1. 移除 `generateConversationName(...)` 自动调用
2. 移除 `sidebarRef.autoRename(...)` 自动调用
3. 回答完成后轻量刷新会话列表，把后端自动标题同步回来

验收点：

1. 首轮问答完成后，会话名称自然更新
2. 前端不再双写标题

## 2.7 前端会话列表排序与本地更新

任务：

1. 会话排序优先用 `last_message_at`
2. 仅标题更新时不再强行覆盖 `updated_at`

验收点：

1. 手动重命名不会导致会话跳序
2. 自动重命名不会导致会话跳序

---

## 3. 接口变更清单

## 3.1 `GET /api/v3/rag/chat/conversations`

新增返回字段：

```json
{
  "id": "conversation_id",
  "name": "烟草专卖法中的烟草定义",
  "introduction": "",
  "titleSource": "auto",
  "createdAt": 1779078161,
  "updatedAt": 1779078200,
  "lastMessageAt": 1779078200
}
```

兼容性说明：

1. 前端旧代码即使不消费新增字段也不会炸
2. 新前端会使用 `last_message_at` 改善排序

## 3.2 `PATCH /api/v3/rag/chat/conversations/{ConversationId}`

本期请求体不变：

```json
{
  "name": "我手动改的标题"
}
```

但服务端语义变化为：

1. 更新标题
2. 将 `title_source` 切为 `manual`
3. 保护后续自动任务不覆盖

---

## 4. 数据字段说明

| 字段 | 说明 |
|---|---|
| `title_source` | `default / auto / manual` |
| `title_generation_status` | `idle / pending / running / succeeded / failed` |
| `title_generated_at` | 自动标题成功时间 |
| `first_question_message_id` | 预留，本期可暂不写 |
| `first_answer_message_id` | 记录首轮回答 message_id |
| `title_generation_error` | 最近一次失败原因 |
| `last_message_at` | 最后一次消息完成时间 |

---

## 5. 本期已知边界

1. 自动标题目前走与 follow-up 相同的在线 LLM 依赖
2. 如果 LLM 配置错误，主回答可能正常但标题生成失败
3. 本期还未增加专门的 `conversation_renamed` SSE 事件
4. 前端目前通过“回答完成后刷新列表”同步标题，优先保证正确性

---

## 6. 后续增强建议

1. 新增 `conversation_renamed` SSE 事件，减少列表刷新
2. 增加后台补偿任务，扫描 `failed` 会话再重试
3. 引入标题生成提示词版本号，便于回溯
4. 对 `first_question_message_id` 也做持久化，补齐审计链路
