文档:完善后端协作与AI秘书基线
This commit is contained in:
@@ -1 +1,914 @@
|
||||
# 01_老板 AI 秘书与 AI 草稿
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
本模块负责把老板在飞书私聊或平台入口输入的一句话,交给 `AiSecretaryAgent` 理解、归类、补上下文,并生成可确认的 AI 草稿或直接回复。
|
||||
|
||||
这个模块是老板秘书的大脑,不直接创建任务、提醒或发送通知。所有执行动作都必须走人工确认后的任务、提醒和通知模块。
|
||||
|
||||
说明:整体方案中的“事项、需求、安排”在第一版统一归入 `task`。如果后续单独拆出 requirement 类型,需要先更新本 spec 和数据对象约定。
|
||||
|
||||
## 2. 第一版做什么
|
||||
|
||||
第一版核心定位:
|
||||
|
||||
```text
|
||||
老板一句话
|
||||
-> AiSecretaryAgent 判断意图和上下文
|
||||
-> 意图归类为 task / reminder / qa / realtime_qa / note / need_more_info / unsupported
|
||||
-> 稳定 AiSecretaryResponse JSON
|
||||
-> 生成 AI 草稿 / 追问 / 直接回复
|
||||
-> 老板确认、补充、取消或转程经理
|
||||
```
|
||||
|
||||
- 支持老板通过飞书私聊或平台入口输入文本。
|
||||
- 统一走 `POST /api/secretary/handle-message`。
|
||||
- 判断 `task/reminder/qa/realtime_qa/note/need_more_info/unsupported`。
|
||||
- 生成稳定的 `AiSecretaryResponse` JSON。
|
||||
- 对任务和提醒只生成可确认草稿,不直接执行。
|
||||
- 对普通聊天、实时问答兜底、普通记录直接回复或记录。
|
||||
- 支持 30 分钟内补充、重说、确认、取消和转程经理。
|
||||
- 支持低置信度追问和最多 3 轮追问收敛。
|
||||
- 使用 PostgreSQL 持久化老板秘书当前会话记忆、消息记录和 `BotContext`。
|
||||
- 记录模型调用、提示词版本、操作日志和失败记录。
|
||||
|
||||
## 3. 第一版不做
|
||||
|
||||
- 不做员工通用 AI 工作台。
|
||||
- 不让程经理或普通员工通过机器人派活。
|
||||
- 不让 AI 自动创建任务、提醒、通知或外部系统操作。
|
||||
- 不做复杂多轮通用聊天记忆、跨账号记忆或长期画像;第一阶段只持久化老板秘书当前会话所需的对话记忆和草稿上下文。
|
||||
- 不把公司背景库全文每次塞进模型,只使用 `PromptContext` 中的压缩摘要和版本。
|
||||
- 不做实时行情、交易、数据库、后台系统自动查询和自动判断。
|
||||
- 不把普通记录做成独立知识库、向量库或长期记忆,只保留当前演示闭环需要的消息记录。
|
||||
|
||||
## 4. 核心流程
|
||||
|
||||
### 4.1 统一入口
|
||||
|
||||
所有老板消息统一走:
|
||||
|
||||
```http
|
||||
POST /api/secretary/handle-message
|
||||
```
|
||||
|
||||
飞书回调、`/api/demo/boss-message`、未来平台入口都转发到该入口。
|
||||
|
||||
处理顺序:
|
||||
|
||||
```text
|
||||
记录原始消息
|
||||
-> 按 source + message_id 做幂等检查
|
||||
-> 校验发送人角色
|
||||
-> 非老板直接固定回复并记录
|
||||
-> 读取 BotContext,外部 context 只作为参考
|
||||
-> 判断本次消息是 follow_up / new_request / qa / realtime_qa / note / unsupported / command
|
||||
-> 组装 PromptContext
|
||||
-> 调用模型
|
||||
-> 校验 AiSecretaryResponse
|
||||
-> 写 ModelCallLog
|
||||
-> 生成草稿 / 追问 / 直接回复
|
||||
-> 写 OperationLog 和必要 FailureRecord
|
||||
```
|
||||
|
||||
幂等规则:
|
||||
|
||||
- 同一个 `source + message_id` 重复进入时,不重复调用模型、不重复创建草稿、不重复写业务对象。
|
||||
- 幂等命中时,不重复追加 PostgreSQL `secretary_messages`,不重复写 `SecretaryMessage`,只返回既有处理结果。
|
||||
- 飞书或外部入口的原始回调可以写 `FeishuEventLog` 并标记为 duplicate,但不能污染老板对话记忆。
|
||||
- 如果上一轮已经处理成功,直接返回上一轮处理结果或可重放的 `reply_type/answer/draft_id`。
|
||||
- 如果上一轮处理失败,允许按失败类型进入人工重试或后台重试,但必须继续复用同一个幂等键。
|
||||
|
||||
### 4.2 上下文规则
|
||||
|
||||
`BotContext / Conversation` 记录老板当前可补充的草稿。
|
||||
|
||||
`BotContext.status` 建议取值:
|
||||
|
||||
```text
|
||||
empty
|
||||
awaiting_more_info
|
||||
awaiting_confirm
|
||||
expired
|
||||
cleared
|
||||
```
|
||||
|
||||
状态含义:
|
||||
|
||||
- `empty`:当前没有可补充或可确认的草稿。
|
||||
- `awaiting_more_info`:AI 已追问,等待老板补充。
|
||||
- `awaiting_confirm`:草稿已整理完成,等待老板确认、修改、取消或转经理。
|
||||
- `expired`:超过 30 分钟,旧上下文只可用于回顾,不再默认参与修改。
|
||||
- `cleared`:草稿已确认、取消或转换完成,当前上下文已清空。
|
||||
|
||||
规则:
|
||||
|
||||
- 每次进入 `awaiting_more_info` 或 `awaiting_confirm` 状态时重置 `expires_at = now + 30 分钟`。
|
||||
- 点击或说出“补充/重说”后,30 分钟内下一条消息优先尝试作为上一条草稿的修正。
|
||||
- 30 分钟内不能无条件吞掉所有消息,必须先判断为 `follow_up / new_request / qa / realtime_qa / note / unsupported / command`。
|
||||
- 老板说“换成东东”“改到明天”“刚才那个不要了”,优先修正当前草稿。
|
||||
- 老板说“另外再安排一个”“新建一个”“再帮我记一个”,创建新草稿。
|
||||
- 老板说“确认”“就这样”“发给他”,确认当前草稿。
|
||||
- 老板说“算了”“取消”“不要了”,取消当前草稿并清空上下文。
|
||||
- 老板问“刚才我说了什么”“总结一下”,做上下文回顾,不修改草稿。
|
||||
- 超过 30 分钟,上下文标记 `expired`,下一条默认按新输入处理;如果老板明显仍在说上一条草稿,可先提示“上一条草稿已过期,我按新请求处理”。
|
||||
- 老板确认、取消或草稿转换为任务/提醒后立即清空上下文,不受 30 分钟窗口约束。
|
||||
- 30 分钟窗口只绑定未确认草稿;草稿进入 `CONFIRMED / CONVERTED / CANCELLED` 后,后续“改一下刚才那个”不能再修改原草稿,只能作为已发布任务/提醒变更请求或第一阶段能力外请求处理。
|
||||
- 多次 `follow_up` 必须合并到同一个 `pending_draft`,直到老板确认、取消、过期或明确新建,不得每次补充都新建草稿。
|
||||
- `BotContext` 只提供上下文候选,不强制绑定消息。当本地规则或模型无法判断是修改当前草稿、新建请求、普通聊天还是取消当前草稿时,必须走 `need_more_info` 追问,不允许默认修改当前草稿。
|
||||
- 老板可以通过“另外、重新来、换个事、先别管这个、取消、重新安排”等自然语言随时跳出当前上下文。
|
||||
|
||||
`command` 不是模型最终 `intent`,而是进入模型前后的消息预分类,用于处理“确认、取消、转经理、补充/重说、上下文回顾”等对当前 `BotContext` 的操作。命中明确 command 时,后端优先处理当前上下文;需要模型理解时,再把 command 结果作为上下文提示传给模型。
|
||||
|
||||
命中确认、取消、补充、转经理等 command,但当前没有待处理草稿时,不抛异常、不创建新草稿,按 `qa`/`plain_answer` 回复“目前没有待确认的草稿”。
|
||||
|
||||
自然语言指令最小关键词集合:
|
||||
|
||||
| 类型 | 关键词 |
|
||||
| --- | --- |
|
||||
| 新建信号 | 另外、新建、再来一个、再安排、再记一个 |
|
||||
| 跳出信号 | 重新来、换个事、先别管这个、说另一个、重新安排 |
|
||||
| 补充信号 | 改成、改为、换成、改到、补充、加上 |
|
||||
| 确认信号 | 确认、就这样、发给他、可以了 |
|
||||
| 取消信号 | 取消、算了、不要了、作废、刚才那个不要 |
|
||||
|
||||
关键词只是第一层判断,最终仍要结合 BotContext、当前草稿和模型结构化结果确认。
|
||||
|
||||
### 4.3 追问收敛
|
||||
|
||||
- 缺少关键字段时先追问。
|
||||
- 每次最多 3 个问题。
|
||||
- 累计最多 3 轮追问。
|
||||
- 老板说“就这样”“差不多”“先这样”时,停止追问,生成带 `missing_fields` 的草稿。
|
||||
- 3 轮仍补不全,也生成带 `missing_fields` 的草稿,不继续拉扯。
|
||||
- 每次追问都必须保存一条 `SecretaryMessage`,`intent_type=need_more_info`,内容为本次给老板的问题。
|
||||
- 追问轮次写入 `BotContext.follow_up_count`,并记录 `OperationLog(action=ask_follow_up)`。
|
||||
- `follow_up_count` 在以下情况重置为 0:草稿被确认、取消、过期、进入 `PENDING_CONFIRM`,或生成带 `missing_fields` 的终态草稿后收到下一条新消息。
|
||||
|
||||
## 5. 数据对象
|
||||
|
||||
本模块主要涉及:
|
||||
|
||||
- `AiSecretaryResponse`
|
||||
- `BotContext / Conversation`
|
||||
- `SecretaryDraft / ai_drafts`
|
||||
- `SecretaryMessage / note`
|
||||
- `PromptContext`
|
||||
- `ModelCallLog`
|
||||
- `OperationLog`
|
||||
- `FailureRecord`
|
||||
- `FeishuEventLog`
|
||||
|
||||
字段事实源以 `docs/contracts/数据对象约定.md` 为准。本 spec 只强调模块规则。
|
||||
|
||||
`BotContext` 归本模块维护;`05_权限日志失败记录.md` 只消费它做调试展示、过期记录和操作审计。
|
||||
|
||||
`BotContext` 第一阶段建议字段:
|
||||
|
||||
| 字段 | 说明 |
|
||||
| --- | --- |
|
||||
| `conversation_id` | 当前老板秘书会话 ID,第一阶段可固定为 `boss_secretary_default` |
|
||||
| `boss_id` | PostgreSQL 中的老板用户 ID |
|
||||
| `status` | `empty/awaiting_more_info/awaiting_confirm/expired/cleared` |
|
||||
| `pending_draft_id` | 当前待补充或待确认的 PostgreSQL 草稿 ID |
|
||||
| `pending_draft_type` | `task/reminder/none` |
|
||||
| `last_intent` | 上一条有效意图 |
|
||||
| `expires_at` | 当前上下文过期时间,进入待补充或待确认时重置为 30 分钟后 |
|
||||
| `follow_up_count` | 当前草稿累计追问轮次 |
|
||||
| `last_message_id` | 最近一次参与上下文判断的消息 ID |
|
||||
| `extracted_facts` | 从多轮对话提取的候选事实,只用于草稿修订,不作为业务事实源 |
|
||||
| `updated_at` | 上下文最近更新时间 |
|
||||
|
||||
`SecretaryMessage` 是老板消息、AI 追问、普通记录和上下文回顾的统一保存对象。`note` 不新建独立业务表,第一版复用 `SecretaryMessage`,至少保存 `message_id/source/sender_id/requester_open_id/requester_name/text/answer/intent_type/raw_payload/created_at`,并在回顾时按时间倒序读取默认最近 10 条消息、当前待确认草稿和最近 3 条已确认/已转换草稿摘要。`note` 类型可以没有 `answer`,或 `answer=""`,回顾时主要展示原始 `text`。
|
||||
|
||||
`PromptContext` 至少包含:
|
||||
|
||||
| 字段 | 说明 |
|
||||
| --- | --- |
|
||||
| `company_background_summary` | 公司背景库压缩摘要,不塞全文 |
|
||||
| `boss_communication_style` | 老板大白话风格和回复口吻规则 |
|
||||
| `ai_secretary_rules` | 本 spec 中的第一阶段业务规则摘要 |
|
||||
| `role_and_alias_rules` | 角色、人员称呼和别名规则摘要 |
|
||||
| `current_bot_context` | 当前 `BotContext` 摘要 |
|
||||
| `pending_draft_summary` | 当前待确认草稿摘要,没有则为空 |
|
||||
| `recent_messages_summary` | 最近对话摘要,用于判断补充、新建、普通聊天 |
|
||||
| `prompt_version` | 提示词版本号,必须写入 `ModelCallLog` |
|
||||
|
||||
第一阶段不再依赖纯内存保存对话上下文,也不再拆多套数据库。PostgreSQL 是唯一数据源:角色、人员映射、草稿确认、任务、提醒、通知、反馈、失败记录、操作日志,以及老板秘书当前会话的 AI 对话记忆、消息记录和 `BotContext` 快照都落 PostgreSQL。
|
||||
|
||||
### 5.1 第一阶段对话记忆持久化(PostgreSQL 最小版)
|
||||
|
||||
第一阶段只做一个老板秘书入口的对话记忆持久化,不做多账号、多租户、跨老板记忆合并、长期画像、embedding 召回或复杂记忆策略。
|
||||
|
||||
PostgreSQL 最小保存三类 AI 记忆数据:
|
||||
|
||||
- `secretary_conversations`:当前老板秘书会话,可先使用固定 `conversation_id=boss_secretary_default`,并关联 PostgreSQL 中的 `boss_id`。
|
||||
- `secretary_messages`:老板输入、AI 回复、追问、上下文回顾、普通记录等对话消息。
|
||||
- `bot_contexts`:当前待确认草稿、`pending_draft_id`、上一条意图、30 分钟过期时间、`follow_up_count`、是否等待补充等上下文状态。
|
||||
|
||||
读写规则:
|
||||
|
||||
- `secretary_messages` 只追加,不修改,用于对话回放、上下文回顾和问题复盘。
|
||||
- `bot_contexts` 表示当前最新上下文,可覆盖更新。
|
||||
- `secretary_messages.bot_context_snapshot` 使用 `jsonb` 保存消息发生时的快照,不代表当前最新状态。
|
||||
- `bot_contexts.extracted_facts` 使用 `jsonb` 保存从多轮对话里提取出的结构化事实,例如 `receiver_text/task_content/schedule_text/requires_feedback`;这些事实只能用于草稿修订,不能替代正式业务表。
|
||||
- 对 `conversation_id + created_at`、`source + message_id`、`bot_contexts.conversation_id` 建索引;`jsonb` 字段第一阶段只做读取展示和调试,不作为复杂查询主路径。
|
||||
|
||||
最小字段建议:
|
||||
|
||||
```json
|
||||
{
|
||||
"conversation_id": "boss_secretary_default",
|
||||
"boss_id": "postgres_user_id",
|
||||
"source": "feishu|web|debug",
|
||||
"message_id": "外部消息ID或内部生成ID",
|
||||
"role": "boss|assistant|system",
|
||||
"text": "原始输入或AI回复",
|
||||
"intent": "task|reminder|qa|realtime_qa|note|need_more_info|unsupported|context_summary",
|
||||
"draft_id": "postgres_ai_draft_id",
|
||||
"bot_context_snapshot": {},
|
||||
"created_at": "2026-06-22T10:00:00+08:00"
|
||||
}
|
||||
```
|
||||
|
||||
边界规则:
|
||||
|
||||
- PostgreSQL 是唯一事实源;AI 对话记忆表也在 PostgreSQL 内,但不能替代正式业务表。
|
||||
- `secretary_messages`、`bot_contexts` 中的 `draft_id/task_id/reminder_id/notification_id` 只能引用正式业务表记录,不能替代对应业务状态。
|
||||
- 创建草稿、确认草稿、创建任务、创建提醒、发送通知、员工反馈,必须以 PostgreSQL 事务和正式业务表状态为准。
|
||||
- 服务重启后必须能从 PostgreSQL 恢复最近有效 `BotContext`,避免 30 分钟内的补充/确认丢失。
|
||||
- 如果 PostgreSQL 的 AI 记忆表或上下文读写失败,不能继续依赖内存悄悄处理确认类命令;必须降级回复“暂时没处理好,请稍后再试”,并写入 `FailureRecord(memory_store_failed)`。如果 PostgreSQL 整体不可用导致 `FailureRecord` 也无法写入,至少写应用日志/告警,恢复后补偿记录。
|
||||
- 后续如果要做多账号、多会话、长期记忆或向量召回,优先在 PostgreSQL 中扩展 schema、`jsonb`、全文索引或 pgvector;只有 PostgreSQL 明确无法满足时,再另行评估外部存储。
|
||||
|
||||
### 5.2 AiSecretaryResponse
|
||||
|
||||
模型必须返回稳定 JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"intent": "task|reminder|qa|realtime_qa|note|need_more_info|unsupported",
|
||||
"draft_type": "task|reminder|none",
|
||||
"should_create_draft": true,
|
||||
"route_type": "none|direct_after_boss_confirm|manager_confirm_required",
|
||||
"answer": "给老板看的自然语言回复",
|
||||
"draft": {
|
||||
"title": "草稿标题",
|
||||
"content": "整理后内容",
|
||||
"receiver_candidates": ["东东"],
|
||||
"receiver_text": "东东",
|
||||
"scheduled_at": "2026-06-23T09:00:00+08:00",
|
||||
"schedule_text": "明天上午 9 点",
|
||||
"recurrence_type": "none|daily|weekly|monthly",
|
||||
"requires_feedback": true,
|
||||
"need_manager_confirm": false,
|
||||
"missing_fields": [
|
||||
{
|
||||
"field": "receiver",
|
||||
"reason": "missing_person_mapping",
|
||||
"raw_value": "小王",
|
||||
"message": "无法识别接收人"
|
||||
}
|
||||
]
|
||||
},
|
||||
"questions": ["最多3个追问"],
|
||||
"reason": "简要说明判断原因"
|
||||
}
|
||||
```
|
||||
|
||||
校验规则:
|
||||
|
||||
- `task/reminder` 必须 `should_create_draft=true`,`draft_type` 必须对应为 `task` 或 `reminder`。
|
||||
- `qa/realtime_qa/note/need_more_info/unsupported` 必须 `should_create_draft=false`,`draft_type=none`。
|
||||
- `task` 时 `route_type` 必填,只能是 `direct_after_boss_confirm` 或 `manager_confirm_required`。
|
||||
- `reminder/qa/realtime_qa/note/need_more_info/unsupported` 时 `route_type=none`。
|
||||
- `route_type=manager_confirm_required` 时,`draft.need_manager_confirm=true`;老板主动说“给程经理看看”“让经理确认”时,也必须置为 true。
|
||||
- `route_type=direct_after_boss_confirm` 时,`draft.need_manager_confirm=false`。
|
||||
- `task` 必须有事项内容;时间不是必填项。
|
||||
- `reminder` 必须有提醒内容和可解析时间;缺时间必须追问或进入 `missing_fields`。
|
||||
- `missing_fields` 必须是对象数组;`field` 和 `reason` 必填,`raw_value` 和 `message` 可选。常用 `reason` 包括 `missing_person_mapping`、`time_not_parsed`、`receiver_missing`、`content_missing`、`scheduled_at_missing`。
|
||||
- `questions` 最多 3 个;`intent=need_more_info` 时至少 1 个、最多 3 个,其他 intent 必须为空数组。
|
||||
- `reason` 必填,用于调试和复盘;写入 `ModelCallLog.parsed_result`,不返回给老板,但可通过调试接口查看。
|
||||
- `answer` 不能出现“已通知”“已创建”“已发送”“已经安排”等执行语义;出现时视为校验失败或强制改写为“我整理成草稿,等你确认”。
|
||||
- `answer` 是给老板看的口语回复,`draft.content` 是正式草稿正文;二者可以表达方式不同,但不能语义矛盾。
|
||||
- `title/content/receiver/schedule` 不能编造老板没说过的具体业务结论,只能整理、压缩和明确表达。
|
||||
- `receiver_candidates` 无法解析到 open_id 时,不直接失败;保留 `receiver_text`,把 `missing_person_mapping` 写入 `missing_fields`,草稿仍可生成,但确认前必须由后端、调试页或人员映射补齐。
|
||||
- 草稿确认前必须检查 `missing_fields`;阻塞字段未补齐时不允许正常确认,回复老板补齐关键信息。调试页如果强制确认,必须写对应 `FailureRecord` 和操作日志。
|
||||
- 非法 JSON 不允许进入任务、提醒、通知流程。
|
||||
|
||||
确认阻塞规则:
|
||||
|
||||
| draft_type | 阻止确认的 missing_fields.reason | 不阻止确认 |
|
||||
| --- | --- | --- |
|
||||
| task | `content_missing`、`receiver_missing`、`missing_person_mapping` | `time_not_parsed`、`scheduled_at_missing` |
|
||||
| reminder | `content_missing`、`scheduled_at_missing`、`time_not_parsed`、`receiver_missing`、`missing_person_mapping` | 无 |
|
||||
|
||||
如果模型无法判断本次输入应归为 `follow_up / new_request / qa / cancel`,必须返回 `need_more_info` 并追问,例如“你是想修改刚才那条草稿,还是新建一条?”。
|
||||
|
||||
### 5.3 意图区分
|
||||
|
||||
| intent | 处理 |
|
||||
| --- | --- |
|
||||
| task | 生成任务草稿,等待老板确认 |
|
||||
| reminder | 生成提醒草稿,等待老板确认 |
|
||||
| qa | 直接回答,不生成草稿、不通知 |
|
||||
| realtime_qa | 固定提示需要实时数据查询,第一版暂不作为正式能力 |
|
||||
| note | 只保存消息记录,不生成草稿、不通知,可用于“刚才说了什么”回顾 |
|
||||
| need_more_info | 信息不足但属于可处理范围,主动追问 |
|
||||
| unsupported | 超出第一版能力,解释为什么不能做,不追问执行字段 |
|
||||
|
||||
优先级和兜底规则:
|
||||
|
||||
- 天气、新闻、股价、行情、今日走势、实时政策等需要实时数据的输入,固定归为 `realtime_qa`。
|
||||
- `realtime_qa.answer` 固定使用模板:“这个需要实时数据查询,第一版暂不作为正式能力;我不会把它生成任务或提醒。”
|
||||
- 超出第一版能力但不属于实时数据类的输入,归为 `unsupported`。
|
||||
- `unsupported.answer` 应说明当前入口只处理老板事项草稿、提醒草稿、普通问答和普通记录,不追问执行字段。
|
||||
|
||||
示例:
|
||||
|
||||
- “安排一下” -> `need_more_info`,追问安排谁、做什么。
|
||||
- “帮我分析今天的股票走势” -> `realtime_qa`,提示第一版不做正式实时数据查询或投资判断。
|
||||
- “帮我写一份完整年报” -> `unsupported`,说明超出第一版老板秘书入口能力。
|
||||
- “记一下,今天先别催东东” -> `note`,只保存记录。
|
||||
|
||||
### 5.4 草稿状态
|
||||
|
||||
`ai_drafts.status` 只表示已经落 PostgreSQL 草稿表的草稿状态。非草稿意图(`qa/realtime_qa/note/unsupported`)和纯追问结果(`need_more_info`)不落 `ai_drafts`,只保存 `SecretaryMessage`、`BotContext` 和处理结果。
|
||||
|
||||
`ai_drafts.status` 建议状态:
|
||||
|
||||
```text
|
||||
PENDING_CONFIRM
|
||||
NEED_MANAGER_CONFIRM
|
||||
CONFIRMED
|
||||
CANCELLED
|
||||
FAILED
|
||||
CONVERTED
|
||||
```
|
||||
|
||||
对老板可见时可以简化为:待确认、待程经理确认、已确认、已取消、已失败。
|
||||
|
||||
状态含义:
|
||||
|
||||
- `PENDING_CONFIRM`:草稿可确认,等待老板确认。
|
||||
- `NEED_MANAGER_CONFIRM`:老板已确认,但该任务仍需要程经理确认,不能直接转换任务。
|
||||
- `CONFIRMED`:确认链路已完成,可以交给任务或提醒模块转换。
|
||||
- `CANCELLED`:老板取消草稿。
|
||||
- `FAILED`:草稿或 AI 解析过程失败的草稿状态;失败原因写入 `FailureRecord.failure_type`,例如 `ai_parse_failed`,两者不能混用。
|
||||
- `CONVERTED`:草稿已经成功转换为任务或提醒。
|
||||
|
||||
非草稿处理状态:
|
||||
|
||||
- `need_more_info`:本轮只追问老板,不创建 `ai_drafts`;追问内容保存为 `SecretaryMessage(intent_type=need_more_info)`,上下文状态为 `BotContext.status=awaiting_more_info`。
|
||||
- `answered`:`qa/realtime_qa/note/context_summary/unsupported` 的处理结果,不转换为任务或提醒,不影响当前有效 `BotContext`。
|
||||
- 追问 3 轮仍补不全、但系统决定生成带 `missing_fields` 的草稿时,模型输出必须从 `need_more_info` 转为 `task` 或 `reminder`,创建 `PENDING_CONFIRM` 草稿,并由确认阻塞规则控制能否确认。
|
||||
|
||||
`DRAFTING` 不作为第一版 `ai_drafts.status` 持久化枚举。实现中如需表达“AI 已决定生成草稿但还在校验/解析”的过程态,只能作为方法内的内存标记或局部变量;落库状态必须从 `PENDING_CONFIRM`、`NEED_MANAGER_CONFIRM` 或 `FAILED` 开始。
|
||||
|
||||
### 5.5 Prompt 硬规则
|
||||
|
||||
- AI 只整理草稿,不直接执行动作。
|
||||
- AI 不得在回复里声称“已创建、已通知、已发送、已安排完成”。
|
||||
- AI 不得编造老板没有给出的业务事实、责任结论、交易判断或研究结论。
|
||||
- 结构化字段必须正式清晰,不能出现游戏化表达。
|
||||
- 实时问答、行情、股价、新闻、天气等输入,第一版默认不作为正式能力,走 `realtime_qa` 兜底。
|
||||
- note 只作为消息记录,不升级成任务、提醒或通知。
|
||||
|
||||
模型调用失败策略:
|
||||
|
||||
- 百炼或模型网关超时、网络失败、服务异常时,最多自动重试 1 次。
|
||||
- 重试仍失败时,不创建草稿、不继续修改 `BotContext`,返回 `reply_type=error`。
|
||||
- 失败回复固定为:“暂时没处理好,请稍后再试。”
|
||||
- 写 `ModelCallLog`,并写 `FailureRecord(ai_model_failed)`。
|
||||
- 模型返回非法 JSON、schema 校验失败或字段不匹配,走 `ai_parse_failed`,不使用 `ai_model_failed`。
|
||||
|
||||
## 6. 接口需求
|
||||
|
||||
### 6.1 统一消息入口
|
||||
|
||||
```http
|
||||
POST /api/secretary/handle-message
|
||||
```
|
||||
|
||||
输入包括:
|
||||
|
||||
- `source`
|
||||
- `message_id`
|
||||
- `sender.open_id`
|
||||
- `sender.name`
|
||||
- `sender.role`
|
||||
- `text`
|
||||
- `context.has_pending_draft`
|
||||
- `context.pending_draft_id`
|
||||
|
||||
`context` 是外部调用方可选提示。后端必须以本地 `BotContext` 为准:
|
||||
|
||||
- 调用方没传 context 时,后端自己查询 BotContext。
|
||||
- 调用方传了 context 但和 BotContext 不一致时,以 BotContext 为准。
|
||||
- 外部 context 不能绕过草稿归属、过期时间和权限校验。
|
||||
|
||||
返回包括:
|
||||
|
||||
- `intent`
|
||||
- `reply_type`
|
||||
- `answer`
|
||||
- `draft`
|
||||
- `questions`
|
||||
- `context_summary`
|
||||
- `failure`
|
||||
|
||||
`failure` 只在不可恢复错误或降级时返回。结构建议:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ai_parse_failed|ai_model_failed|bot_message_failed|follow_up_expired|bot_unauthorized|missing_person_mapping|memory_store_failed|draft_convert_failed|permission_error|system_error",
|
||||
"message": "给前端或调试页看的失败说明",
|
||||
"record_id": "failure record id,可为空"
|
||||
}
|
||||
```
|
||||
|
||||
当发生 `ai_parse_failed`、`ai_model_failed`、`memory_store_failed`、`system_error` 等不可恢复错误时,`reply_type=error`,`answer` 使用固定兜底话术:“暂时没处理好,请稍后再试。”,并写 `FailureRecord`。
|
||||
|
||||
`reply_type` 建议取值:
|
||||
|
||||
- `draft_preview`:返回草稿预览,等待老板确认。
|
||||
- `follow_up_question`:返回追问问题。
|
||||
- `plain_answer`:普通问答回复。
|
||||
- `context_summary`:上下文回顾回复。
|
||||
- `unsupported`:能力外兜底回复。
|
||||
- `error`:降级或失败回复。
|
||||
|
||||
当老板问“刚才我说了什么”“总结一下”时,返回 `reply_type=context_summary`,并返回 `context_summary` 字段,默认包含最近 10 条 `messages`、当前待确认草稿、最近 3 条已确认/已转换草稿摘要;该回复不创建草稿、不覆盖当前待确认草稿。
|
||||
|
||||
### 6.2 兼容接口
|
||||
|
||||
现有 Demo 接口保留,但内部转发:
|
||||
|
||||
- `/api/demo/boss-message`
|
||||
- `/api/feishu/callback`
|
||||
- `/api/demo/drafts/{id}/confirm`
|
||||
- `/api/demo/drafts/{id}/cancel`
|
||||
|
||||
`/api/feishu/callback` 的验签、去重、鉴权和原始事件记录归 `03_飞书通知与反馈.md`、`05_权限日志失败记录.md` 负责;本模块只消费解析后的老板消息或草稿操作命令。
|
||||
|
||||
## 7. 权限规则
|
||||
|
||||
- 飞书机器人私聊入口第一版只允许老板使用。
|
||||
- 非老板消息不调用 AI,不生成草稿,不创建业务对象。
|
||||
- 草稿确认、取消、补充和转经理必须是草稿发起老板本人。
|
||||
- 程经理不能通过机器人对话派活,只通过 Web 或通知跳转确认复杂任务。
|
||||
- AI 不得绕过人工确认。
|
||||
|
||||
## 8. 状态流转
|
||||
|
||||
```text
|
||||
老板输入
|
||||
-> AI 解析成功
|
||||
-> draft_preview / follow_up_question / plain_answer
|
||||
-> 老板补充
|
||||
-> 新草稿或修订草稿
|
||||
-> 老板确认
|
||||
-> direct_after_boss_confirm: CONFIRMED -> TaskAdapter / ReminderService 转换 -> CONVERTED
|
||||
-> manager_confirm_required: NEED_MANAGER_CONFIRM -> 程经理确认 -> CONFIRMED -> TaskAdapter 转换 -> CONVERTED
|
||||
```
|
||||
|
||||
草稿确认后的边界:
|
||||
|
||||
- `direct_after_boss_confirm`:老板确认成功后,草稿进入 `CONFIRMED`。
|
||||
- `manager_confirm_required`:老板确认成功后,草稿进入 `NEED_MANAGER_CONFIRM`,通知或展示给程经理确认;程经理确认后才进入 `CONFIRMED`。
|
||||
- 任务/提醒转换成功后,草稿进入 `CONVERTED`,并清空 `BotContext`。
|
||||
- 任务/提醒转换失败时,不回滚老板确认;草稿保持 `CONFIRMED`,写 `FailureRecord(draft_convert_failed)`,支持后台重试或人工处理。
|
||||
- 老板确认后,无论进入 `CONFIRMED` 还是 `NEED_MANAGER_CONFIRM`,都要清空老板侧 `BotContext`;后续经理确认不再依赖老板 30 分钟上下文。
|
||||
- `NEED_MANAGER_CONFIRM / CONFIRMED / CONVERTED` 后,01 不再直接修改原草稿;老板后续说“把刚才发出去那个改一下”,应识别为任务/提醒变更请求,第一阶段未接入变更能力时回复暂不支持或引导到任务模块。
|
||||
|
||||
直接回复流转:
|
||||
|
||||
```text
|
||||
qa / realtime_qa / note / context_summary
|
||||
-> answered 处理结果
|
||||
-> 不落 ai_drafts,不转换,不清空当前有效 BotContext
|
||||
```
|
||||
|
||||
`context_summary` 也必须保存为一条 `SecretaryMessage(intent_type=context_summary)`,便于调试页回看“老板什么时候要求回顾、系统回了什么”。
|
||||
|
||||
失败流转:
|
||||
|
||||
```text
|
||||
模型调用失败
|
||||
-> 重试 1 次
|
||||
-> 仍失败则不创建可确认草稿
|
||||
-> FailureRecord(ai_model_failed)
|
||||
|
||||
JSON 非法 / schema 校验失败
|
||||
-> 不创建可确认草稿
|
||||
-> 可选创建 FAILED 草稿仅用于调试
|
||||
-> FailureRecord(ai_parse_failed)
|
||||
```
|
||||
|
||||
`FAILED` 草稿不能确认、不能转换为任务/提醒、不能发送通知,只能用于调试追踪。
|
||||
|
||||
取消流转:
|
||||
|
||||
```text
|
||||
PENDING_CONFIRM
|
||||
-> CANCELLED
|
||||
-> 清空 BotContext
|
||||
|
||||
awaiting_more_info 且还没有 ai_drafts
|
||||
-> 清空 BotContext
|
||||
-> 记录 OperationLog(cancel_context)
|
||||
```
|
||||
|
||||
`NEED_MANAGER_CONFIRM` 阶段如需取消或退回,归程经理确认模块或任务模块处理;01 只负责展示状态和记录操作,不再把它当作可补充草稿处理。
|
||||
|
||||
## 9. 失败和日志
|
||||
|
||||
必须记录:
|
||||
|
||||
- 老板原始输入。
|
||||
- BotContext 命中或过期。
|
||||
- PromptContext 使用版本。
|
||||
- 模型请求、响应、耗时和解析结果。
|
||||
- `AiSecretaryResponse.reason`,写入 `ModelCallLog.parsed_result`,只用于调试和复盘。
|
||||
- AI JSON 校验失败。
|
||||
- 草稿创建、修订、确认、取消、转经理。
|
||||
- AI 追问消息,保存为 `SecretaryMessage(intent_type=need_more_info)`。
|
||||
- 追问轮次变化,保存到 `BotContext.follow_up_count`。
|
||||
- 追问动作,记录 `OperationLog(action=ask_follow_up)`。
|
||||
- 非老板访问。
|
||||
- note 消息保存。
|
||||
- context_summary 上下文回顾,保存为 `SecretaryMessage(intent_type=context_summary)`。
|
||||
- receiver_candidates 解析失败和人工补映射。
|
||||
|
||||
`failure.type` 和 `FailureRecord.failure_type` 使用同一组枚举:
|
||||
|
||||
| failure_type | 触发条件 |
|
||||
| --- | --- |
|
||||
| `ai_parse_failed` | 模型返回非法 JSON、schema 校验失败、字段组合不符合 `AiSecretaryResponse` |
|
||||
| `ai_model_failed` | 百炼或模型网关超时、网络失败、服务异常,重试 1 次后仍失败 |
|
||||
| `bot_message_failed` | 入口消息结构缺失、无法解析文本或 sender 信息,导致无法进入正常处理 |
|
||||
| `follow_up_expired` | 存在旧 `BotContext` 但已超过 30 分钟,老板仍尝试修改上一条草稿 |
|
||||
| `bot_unauthorized` | 非老板访问老板秘书入口 |
|
||||
| `missing_person_mapping` | 接收人候选无法映射真实人员;生成草稿时可记录低严重度,确认被阻止或调试页强制确认时必须记录 |
|
||||
| `memory_store_failed` | PostgreSQL AI 记忆表、上下文或快照保存/读取失败 |
|
||||
| `draft_convert_failed` | 老板或程经理确认后,转换任务/提醒失败 |
|
||||
| `permission_error` | 非草稿发起老板尝试确认、取消、补充或转程经理 |
|
||||
| `system_error` | 未归类系统异常 |
|
||||
|
||||
## 10. 给 AI 的测试样例
|
||||
|
||||
### 10.1 任务草稿
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
让东东跟进一下合同
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 生成 `task` 草稿。
|
||||
- 不因为没有时间反复追问。
|
||||
- 接收人候选包含东东。
|
||||
- `should_create_draft=true`。
|
||||
|
||||
### 10.2 提醒草稿
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
明天上午 9 点提醒东东准备咖啡
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 生成 `reminder` 草稿。
|
||||
- `scheduled_at` 使用 `Asia/Shanghai`。
|
||||
- recurrence 为 `none`。
|
||||
|
||||
### 10.3 补充上一条
|
||||
|
||||
前置:存在一条待确认 `task` 草稿,内容为“让东东跟进合同”,没有明确 `due_at` 或 `schedule_text`;该草稿不是提醒草稿。
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
改成明天下午
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 判断为 `follow_up`。
|
||||
- 修订上一条草稿,不新建任务。
|
||||
- 更新该任务草稿的 `due_at` 或 `schedule_text`,不修改 `reminder.scheduled_at`。
|
||||
|
||||
### 10.4 新建例外
|
||||
|
||||
前置:存在待确认草稿。
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
另外再安排一个,让行政订会议室
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 判断为 `new_request`。
|
||||
- 新建草稿。
|
||||
|
||||
### 10.5 取消
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
算了,刚才那个不要了
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 取消当前草稿。
|
||||
- 清空上下文。
|
||||
|
||||
### 10.6 非老板访问
|
||||
|
||||
输入:普通员工私聊机器人。
|
||||
|
||||
期望:
|
||||
|
||||
- 固定回复“当前入口是老板秘书,如需处理事项请进入平台。”
|
||||
- 不调用 AI。
|
||||
- 写失败和操作日志。
|
||||
|
||||
### 10.7 追问信息不足
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
安排一下
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 判断为 `need_more_info`。
|
||||
- 不生成任务或提醒。
|
||||
- 追问“安排谁、做什么”等关键问题。
|
||||
|
||||
### 10.8 实时问答兜底
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
帮我分析今天的股票走势
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 判断为 `realtime_qa`。
|
||||
- 不生成草稿。
|
||||
- 回复固定模板:“这个需要实时数据查询,第一版暂不作为正式能力;我不会把它生成任务或提醒。”
|
||||
|
||||
### 10.9 普通记录
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
记一下,今天先别催东东
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 判断为 `note`。
|
||||
- 只保存消息记录。
|
||||
- 不创建草稿、不通知任何人。
|
||||
|
||||
### 10.10 接收人解析失败
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
让小王处理一下合同
|
||||
```
|
||||
|
||||
前置:`PersonResolver` 无法识别“小王”。
|
||||
|
||||
期望:
|
||||
|
||||
- 草稿可以生成。
|
||||
- `receiver_text=小王`。
|
||||
- `missing_fields` 包含 `{ "field": "receiver", "reason": "missing_person_mapping", "raw_value": "小王" }`。
|
||||
- 正常确认被阻止,回复老板需要先补齐人员映射。
|
||||
|
||||
### 10.11 能力外请求
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
帮我写一份完整年报
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 判断为 `unsupported`。
|
||||
- 不生成草稿。
|
||||
- 不追问执行人、时间等任务字段。
|
||||
- 说明当前入口只处理老板事项草稿、提醒草稿、普通问答和普通记录。
|
||||
|
||||
### 10.12 上下文回顾
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
我刚才说了什么
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 返回 `reply_type=context_summary`。
|
||||
- 返回 `context_summary`,默认摘要最近 10 条消息、当前待确认草稿和最近 3 条已确认/已转换草稿。
|
||||
- 不创建新草稿,不覆盖当前待确认草稿。
|
||||
- 保存 `SecretaryMessage(intent_type=context_summary)`。
|
||||
|
||||
### 10.13 无草稿 command
|
||||
|
||||
前置:当前没有待确认草稿。
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
确认
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 命中 command,但不抛异常。
|
||||
- 不创建草稿。
|
||||
- 返回 `reply_type=plain_answer`。
|
||||
- 回复“目前没有待确认的草稿”。
|
||||
|
||||
### 10.14 错误降级
|
||||
|
||||
前置:模型返回非法 JSON。
|
||||
|
||||
期望:
|
||||
|
||||
- 不进入任务、提醒、通知流程。
|
||||
- 写 `ModelCallLog` 和 `FailureRecord(ai_parse_failed)`。
|
||||
- 返回 `reply_type=error`。
|
||||
- `answer=暂时没处理好,请稍后再试。`
|
||||
- `failure.type=ai_parse_failed`。
|
||||
- 如落 `FAILED` 草稿,仅用于调试,不能确认或转换。
|
||||
|
||||
### 10.15 低置信度追问
|
||||
|
||||
前置:存在一条待确认任务草稿。
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
这个换一下
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 如果无法判断是修改接收人、时间、措辞,还是切换到新事项,不默认修改当前草稿。
|
||||
- 返回 `intent=need_more_info`。
|
||||
- 追问“你是想修改刚才那条草稿,还是新建一条?具体想换什么?”。
|
||||
|
||||
### 10.16 已发布后修改
|
||||
|
||||
前置:上一条草稿已经 `CONVERTED`,`BotContext` 已清空。
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
把刚才那个改成明天下午
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 不修改已转换草稿。
|
||||
- 识别为任务/提醒变更请求或第一阶段能力外请求。
|
||||
- 第一阶段未接入变更能力时,回复“刚才的事项已经发布,第一阶段暂不支持直接修改已发布任务;我可以帮你重新整理一条补充说明。”。
|
||||
|
||||
### 10.17 消息幂等
|
||||
|
||||
前置:同一个 `source + message_id` 已处理成功并生成草稿。
|
||||
|
||||
输入:同一消息再次进入。
|
||||
|
||||
期望:
|
||||
|
||||
- 不重复调用模型。
|
||||
- 不重复创建草稿。
|
||||
- 不重复追加 PostgreSQL `secretary_messages` 或 `SecretaryMessage`。
|
||||
- 返回上一轮处理结果或已存在草稿引用。
|
||||
|
||||
### 10.18 待确认草稿中的普通聊天
|
||||
|
||||
前置:存在一条待确认任务草稿。
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
这个措辞是不是太硬了?
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 判断为 `qa` 或低置信度追问,不默认修改当前草稿。
|
||||
- 不创建新草稿。
|
||||
- 不清空当前有效 `BotContext`。
|
||||
|
||||
### 10.19 30 分钟过期
|
||||
|
||||
前置:存在一条 `awaiting_confirm` 草稿,但 `expires_at` 已过期。
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
改成明天下午
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 不直接修改旧草稿。
|
||||
- 写 `FailureRecord(follow_up_expired)` 或 OperationLog 过期记录。
|
||||
- 按新输入处理,或追问老板“上一条草稿已过期,你是想修改刚才那条还是新建一条?”。
|
||||
|
||||
### 10.20 PostgreSQL AI 记忆读写失败
|
||||
|
||||
前置:PostgreSQL 保存 `secretary_messages` 或 `BotContext` 失败。
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
确认
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 不继续依赖内存确认草稿。
|
||||
- 不转换任务或提醒。
|
||||
- 返回 `reply_type=error`。
|
||||
- 写 `FailureRecord(memory_store_failed)`。
|
||||
|
||||
### 10.21 程经理确认流转
|
||||
|
||||
前置:草稿 `route_type=manager_confirm_required`,`draft.need_manager_confirm=true`。
|
||||
|
||||
输入:
|
||||
|
||||
```text
|
||||
确认
|
||||
```
|
||||
|
||||
期望:
|
||||
|
||||
- 老板确认后草稿进入 `NEED_MANAGER_CONFIRM`。
|
||||
- 清空老板侧 `BotContext`。
|
||||
- 不直接调用 `TaskAdapter` 转换任务。
|
||||
- 程经理确认后草稿进入 `CONFIRMED`,再转换为任务并进入 `CONVERTED`。
|
||||
|
||||
## 11. Review 重点
|
||||
|
||||
- 是否所有入口都走 `POST /api/secretary/handle-message`。
|
||||
- 是否用 `source + message_id` 做幂等,避免重复调用模型和重复创建草稿。
|
||||
- 是否幂等命中时不会重复追加 PostgreSQL `secretary_messages` 或 `SecretaryMessage`。
|
||||
- 是否实现 30 分钟上下文,但没有无脑吞掉所有消息。
|
||||
- 是否 `BotContext.status` 使用明确状态,并且只绑定未确认草稿。
|
||||
- 是否 `BotContext` 字段按本 spec 集中字段表实现。
|
||||
- 是否低置信度时追问老板,而不是默认修改当前草稿。
|
||||
- 是否 `ai_drafts.status` 和非草稿处理状态已经拆清,`need_more_info/answered` 不误落草稿表。
|
||||
- 是否所有 AI 输出都做 JSON 校验。
|
||||
- 是否 `qa/realtime_qa/note/need_more_info/unsupported` 没有误生成草稿。
|
||||
- 是否普通任务不强制时间。
|
||||
- 是否提醒缺时间会追问。
|
||||
- 是否 AI 只生成草稿,不直接执行。
|
||||
- 是否禁止“已通知、已创建、已发送”等执行语义。
|
||||
- 是否禁止编造老板没说过的业务结论。
|
||||
- 是否 receiver 解析失败时保留草稿并标记 `missing_person_mapping`。
|
||||
- 是否记录 PromptContext 和 ModelCallLog。
|
||||
- 是否 PromptContext 包含公司背景摘要、老板风格、业务规则、角色别名、当前上下文、待确认草稿摘要、最近消息摘要和版本号。
|
||||
- 是否模型超时/百炼失败最多重试 1 次,仍失败写 `FailureRecord(ai_model_failed)`。
|
||||
- 是否非老板入口完全绕开 AI。
|
||||
- 是否为任务、提醒、通知留下 adapter 边界。
|
||||
- 是否明确区分 `realtime_qa` 和 `unsupported`,实时数据类固定走 `realtime_qa`。
|
||||
- 是否把 `command` 作为消息预分类而不是最终 `intent`。
|
||||
- 是否追问消息也保存为 `SecretaryMessage`。
|
||||
- 是否 `missing_person_mapping` 会阻止正常确认。
|
||||
- 是否不同 `draft_type` 的确认阻塞字段已明确。
|
||||
- 是否 `reason` 必填且只进入日志/调试,不直接展示给老板。
|
||||
- 是否 `DRAFTING` 没有作为持久化草稿状态使用。
|
||||
- 是否 `missing_fields` 使用对象数组,并能区分字段和失败原因。
|
||||
- 是否 command 命中但无草稿时返回普通说明,不抛异常。
|
||||
- 是否 `failure` 返回结构只在错误降级时出现。
|
||||
- 是否 `failure.type` 和 `FailureRecord.failure_type` 使用同一枚举,并有明确触发条件。
|
||||
- 是否对话消息、上下文回顾和 `BotContext` 快照已落 PostgreSQL,而不是只放内存。
|
||||
- 是否 `secretary_messages` 只追加、`bot_contexts` 可覆盖、`bot_context_snapshot` 不作为最新状态。
|
||||
- 是否 PostgreSQL 作为唯一事实源,AI 记忆表不替代正式草稿、任务、提醒、通知和反馈表状态。
|
||||
- 是否 PostgreSQL AI 记忆读写异常时会降级并写 `FailureRecord(memory_store_failed)` 或应用日志/告警。
|
||||
- 是否草稿 `CONFIRMED / CONVERTED / CANCELLED` 后立即清空上下文,后续修改不再直接改原草稿。
|
||||
- 是否 `manager_confirm_required` 走 `NEED_MANAGER_CONFIRM -> 程经理确认 -> CONFIRMED -> CONVERTED`,不会绕过程经理确认。
|
||||
- 是否转换失败写 `FailureRecord(draft_convert_failed)`,且不回滚老板确认。
|
||||
- 是否上下文回顾默认范围为最近 10 条消息、当前待确认草稿和最近 3 条已确认/已转换草稿。
|
||||
- 是否 `/api/feishu/callback` 的验签、去重和鉴权没有写进本模块。
|
||||
|
||||
@@ -1 +1,135 @@
|
||||
# 02_事项任务
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
事项任务模块承接老板 AI 秘书草稿、程经理确认和手动创建事项,负责通知接收人、记录反馈、展示状态和沉淀失败原因。第一版只做轻量事项闭环,不做完整项目管理。
|
||||
|
||||
## 2. 第一版做什么
|
||||
|
||||
1. 事项可以来自 AI 草稿 `CONFIRMED` 后转换。
|
||||
2. 事项可以由程经理确认复杂草稿后生成,复杂草稿来自 `route_type=manager_confirm_required`。
|
||||
3. 事项可以由老板或程经理手动创建。
|
||||
4. 普通员工第一版不默认给别人创建事项。
|
||||
5. 事项必须有发起人、接收人、事项内容、反馈要求和状态。
|
||||
6. 事项生成前必须经过人工确认。
|
||||
7. 事项生成后可以创建飞书通知。
|
||||
8. 接收人可以反馈:已收到、处理中、已完成、有问题。
|
||||
9. 有问题反馈必须填写一句原因。
|
||||
10. 发起人、程经理或有权限人员可以查看处理进度。
|
||||
11. 通知失败或无人反馈的事项需要可见,但不单独做看板。
|
||||
|
||||
## 3. 第一版不做
|
||||
|
||||
1. 不做复杂项目管理系统。
|
||||
2. 不做多级子任务。
|
||||
3. 不做复杂审批流。
|
||||
4. 不做绩效排名。
|
||||
5. 不做任务依赖和甘特图。
|
||||
6. 不做项目级看板。
|
||||
7. 不做独立反馈看板。
|
||||
8. 不从 AI 工作台结果生成事项。
|
||||
|
||||
## 4. 核心流程
|
||||
|
||||
简单事项:
|
||||
|
||||
```text
|
||||
AI 草稿或手动输入
|
||||
-> 人工确认
|
||||
-> AI 草稿进入 CONFIRMED
|
||||
-> 创建 tasks
|
||||
-> 创建 notifications
|
||||
-> 飞书通知接收人
|
||||
-> 接收人反馈
|
||||
-> 更新事项状态
|
||||
-> 写入 operation_logs
|
||||
```
|
||||
|
||||
复杂事项:
|
||||
|
||||
```text
|
||||
老板确认转程经理
|
||||
-> AI 草稿进入 NEED_MANAGER_CONFIRM
|
||||
-> 创建 pending_manager_confirm 事项或待确认记录
|
||||
-> 给程经理发飞书提醒
|
||||
-> 程经理进入平台确认、修改和分发
|
||||
-> 草稿进入 CONFIRMED 后转换任务
|
||||
-> 通知接收人
|
||||
-> 接收反馈
|
||||
```
|
||||
|
||||
## 5. 数据对象
|
||||
|
||||
本模块主要使用:
|
||||
|
||||
1. `ai_drafts`
|
||||
2. `tasks`
|
||||
3. `notifications`
|
||||
4. `feedbacks`
|
||||
5. `failure_records`
|
||||
6. `operation_logs`
|
||||
|
||||
字段以 `docs/contracts/数据对象约定.md` 为准。
|
||||
|
||||
## 6. 接口需求
|
||||
|
||||
主要接口:
|
||||
|
||||
1. `GET /api/tasks`
|
||||
2. `POST /api/tasks`
|
||||
3. `GET /api/tasks/{id}`
|
||||
4. `PATCH /api/tasks/{id}`
|
||||
5. `POST /api/tasks/{id}/manager-confirm`
|
||||
6. `POST /api/tasks/{id}/cancel`
|
||||
7. `POST /api/tasks/{id}/notify`
|
||||
8. `POST /api/tasks/{id}/feedback`
|
||||
|
||||
接口格式以 `docs/contracts/API接口约定.md` 为准。
|
||||
|
||||
## 7. 权限规则
|
||||
|
||||
1. 老板可以创建事项。
|
||||
2. 程经理可以创建和分发事项。
|
||||
3. 普通员工不能给别人创建事项。
|
||||
4. 接收人只能反馈自己相关事项。
|
||||
5. 程经理只能确认待自己处理的复杂事项。
|
||||
6. 管理员 / AI 团队可以为排查查看必要记录,但不处理业务分歧。
|
||||
|
||||
## 8. 状态流转
|
||||
|
||||
事项状态以 `docs/contracts/状态流转约定.md` 为准。核心约束:
|
||||
|
||||
1. 未确认事项不得通知接收人。
|
||||
2. `pending_manager_confirm` 必须由程经理确认后才能进入通知流程。
|
||||
3. 01 模块中的 `NEED_MANAGER_CONFIRM` 不能绕过程经理直接创建正式任务。
|
||||
4. 通知失败进入 `notify_failed`,不得假装已通知。
|
||||
5. 已取消事项不能反馈、通知或补发。
|
||||
6. 有问题反馈会将事项标记为 `problem`,并记录原因。
|
||||
|
||||
## 9. 失败和日志
|
||||
|
||||
必须记录:
|
||||
|
||||
1. 事项创建来源:AI 草稿、手动创建或程经理确认。
|
||||
2. 创建、修改、取消、通知、补发、反馈操作。
|
||||
3. 权限拒绝。
|
||||
4. 通知失败。
|
||||
5. 有问题反馈原因。
|
||||
6. 人员映射缺失或接收人不明确。
|
||||
|
||||
## 10. 给 AI 的测试样例
|
||||
|
||||
1. 普通员工请求给同事创建事项,应返回权限错误。
|
||||
2. 老板确认简单事项后,事项进入待通知或已通知状态。
|
||||
3. 研究类事项应进入程经理确认路径。
|
||||
4. 接收人反馈“有问题”但不填原因,应返回校验错误。
|
||||
5. 通知失败时,事项状态不得变成已通知。
|
||||
6. 已取消事项不得再次通知。
|
||||
|
||||
## 11. Review 重点
|
||||
|
||||
1. 后端是否做了权限校验,而不是只靠前端隐藏按钮。
|
||||
2. 状态流转是否只走允许路径。
|
||||
3. 通知失败是否留下失败记录。
|
||||
4. 有问题反馈是否强制原因。
|
||||
5. 是否避免把复杂项目管理能力混入第一版。
|
||||
|
||||
@@ -1 +1,148 @@
|
||||
# 03_飞书通知与反馈
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
飞书模块负责平台登录身份、老板机器人私聊入口、个人消息通知、交互卡片确认和反馈回调。第一版飞书是闭环主入口之一,所有回调必须验签、幂等、可追溯。
|
||||
|
||||
## 2. 第一版做什么
|
||||
|
||||
1. 飞书扫码登录 / 身份登录。
|
||||
2. 根据飞书身份匹配平台用户和角色。
|
||||
3. 接收老板机器人私聊消息。
|
||||
4. 非老板私聊机器人时提示进入平台并记录未授权访问。
|
||||
5. 发送 AI 草稿确认卡片给老板。
|
||||
6. 发送复杂事项待确认提醒给程经理,按钮只跳转平台。
|
||||
7. 发送事项或提醒通知给接收人。
|
||||
8. 接收卡片按钮回调。
|
||||
9. 支持接收人反馈已收到、处理中、已完成、有问题。
|
||||
10. 记录飞书事件、通知发送结果和回调处理结果。
|
||||
|
||||
## 3. 第一版不做
|
||||
|
||||
1. 不把机器人开放成程经理或普通员工通用派活入口。
|
||||
2. 不让程经理在机器人里对话分发事项。
|
||||
3. 不在飞书消息里展开敏感全文。
|
||||
4. 不做飞书卡片内复杂字段编辑表单。
|
||||
5. 不绕过平台角色权限。
|
||||
|
||||
## 4. 核心流程
|
||||
|
||||
飞书登录:
|
||||
|
||||
```text
|
||||
用户点击飞书登录
|
||||
-> 跳转飞书授权
|
||||
-> 飞书回调 auth callback
|
||||
-> 校验 state 和 code
|
||||
-> 换取飞书身份
|
||||
-> 匹配平台用户
|
||||
-> 写入 feishu_auth_sessions
|
||||
-> 建立平台登录态
|
||||
```
|
||||
|
||||
机器人私聊:
|
||||
|
||||
```text
|
||||
飞书推送消息事件
|
||||
-> 验签
|
||||
-> 记录 feishu_events
|
||||
-> 匹配平台用户
|
||||
-> 校验 boss 角色
|
||||
-> 转发到 POST /api/secretary/handle-message
|
||||
-> 根据 reply_type 发送确认卡片、追问或普通回复
|
||||
```
|
||||
|
||||
卡片回调:
|
||||
|
||||
```text
|
||||
飞书卡片按钮点击
|
||||
-> 验签
|
||||
-> 记录 feishu_events
|
||||
-> 查找 notification / draft / task / reminder
|
||||
-> 校验操作人权限
|
||||
-> 执行业务动作
|
||||
-> 写 operation_logs
|
||||
-> 返回飞书处理结果
|
||||
```
|
||||
|
||||
## 5. 数据对象
|
||||
|
||||
本模块主要使用:
|
||||
|
||||
1. `users`
|
||||
2. `person_mappings`
|
||||
3. `feishu_auth_sessions`
|
||||
4. `feishu_events`
|
||||
5. `notifications`
|
||||
6. `feedbacks`
|
||||
7. `bot_contexts`
|
||||
8. `secretary_messages`
|
||||
9. `failure_records`
|
||||
10. `operation_logs`
|
||||
|
||||
字段以 `docs/contracts/数据对象约定.md` 为准。
|
||||
|
||||
## 6. 接口需求
|
||||
|
||||
主要接口:
|
||||
|
||||
1. `GET /api/auth/feishu/login`
|
||||
2. `GET /api/auth/feishu/callback`
|
||||
3. `POST /api/feishu/events`
|
||||
4. `POST /api/feishu/bot/messages`
|
||||
5. `POST /api/feishu/card-callback`
|
||||
6. `POST /api/notifications/{id}/retry`
|
||||
|
||||
接口格式以 `docs/contracts/API接口约定.md` 为准。
|
||||
|
||||
## 7. 权限规则
|
||||
|
||||
1. 飞书身份只用于认证和操作人追溯,业务权限仍以平台角色为准。
|
||||
2. 机器人私聊入口第一版只允许老板使用。
|
||||
3. 老板只能确认、取消、补充自己发起的草稿。
|
||||
4. 程经理待办提醒只能跳转平台确认。
|
||||
5. 反馈人必须是事项或提醒接收人。
|
||||
6. 管理员 / AI 团队可以处理系统失败和补发,但不能代替业务反馈。
|
||||
|
||||
## 8. 状态与幂等
|
||||
|
||||
状态以 `docs/contracts/状态流转约定.md` 为准。幂等约束:
|
||||
|
||||
1. 同一个飞书 `event_id` 只处理一次。
|
||||
2. 同一个通知只允许一个有效发送结果。
|
||||
3. 同一个卡片按钮重复点击不得重复创建事项、提醒或反馈。
|
||||
4. 同一个机器人消息还必须按 `source + message_id` 在老板秘书入口二次幂等,不重复追加 `secretary_messages`。
|
||||
5. 回调处理失败必须标记 `feishu_events.process_status = failed` 并写失败记录。
|
||||
|
||||
## 9. 失败和日志
|
||||
|
||||
必须记录:
|
||||
|
||||
1. 飞书登录成功或失败。
|
||||
2. 飞书事件原始 payload。
|
||||
3. 机器人消息处理结果。
|
||||
4. 卡片回调处理结果。
|
||||
5. 通知发送成功或失败。
|
||||
6. 验签失败。
|
||||
7. 找不到关联对象。
|
||||
8. 操作人无权操作。
|
||||
9. 有问题反馈缺少原因。
|
||||
|
||||
普通日志不得打印飞书 token、App Secret、完整手机号或完整邮箱。
|
||||
|
||||
## 10. 给 AI 的测试样例
|
||||
|
||||
1. 验签失败的回调应返回拒绝并写失败记录。
|
||||
2. 同一 `event_id` 重放应幂等,不重复创建反馈。
|
||||
3. 非接收人点击反馈按钮应返回权限错误。
|
||||
4. 老板点击取消草稿后,草稿不能再转换。
|
||||
5. 非老板私聊机器人不应调用 AI。
|
||||
6. 飞书通知失败时,应写 `failure_records` 并保留通知失败状态。
|
||||
|
||||
## 11. Review 重点
|
||||
|
||||
1. 回调是否验签。
|
||||
2. 回调是否幂等。
|
||||
3. 飞书身份是否没有直接绕过平台权限。
|
||||
4. 通知内容是否只发摘要和链接。
|
||||
5. 失败是否可复盘。
|
||||
|
||||
@@ -1 +1,141 @@
|
||||
# 04_定时提醒
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
定时提醒模块负责创建一次性或固定周期提醒,到点生成通知、发送飞书消息、按需接收反馈,并记录触发结果和失败原因。
|
||||
|
||||
## 2. 第一版做什么
|
||||
|
||||
1. 支持一次性提醒。
|
||||
2. 支持每天、每周、每月固定周期提醒。
|
||||
3. 支持提醒来自手动创建。
|
||||
4. 支持提醒来自老板 AI 草稿 `CONFIRMED` 后转换。
|
||||
5. 支持提醒与事项关联。
|
||||
6. 到点后通知接收人。
|
||||
7. 通知成功或失败都要记录。
|
||||
8. 支持查看自己相关提醒状态。
|
||||
9. 创建人、发起人、管理员可以修改、暂停或取消提醒。
|
||||
10. 提醒可以设置是否需要接收人反馈。
|
||||
|
||||
## 3. 第一版不做
|
||||
|
||||
1. 不做 cron 表达式。
|
||||
2. 不做自定义复杂周期规则。
|
||||
3. 不做日历系统。
|
||||
4. 不做复杂自动化流程。
|
||||
5. 不自动操作外部系统。
|
||||
6. 不从 AI 工作台结果生成提醒。
|
||||
|
||||
## 4. 核心流程
|
||||
|
||||
创建提醒:
|
||||
|
||||
```text
|
||||
手动创建或草稿确认
|
||||
-> 后端校验创建权限
|
||||
-> AI 提醒草稿必须有明确 scheduled_at
|
||||
-> 写入 reminders
|
||||
-> 计算 next_trigger_at
|
||||
-> 写 operation_logs
|
||||
```
|
||||
|
||||
触发提醒:
|
||||
|
||||
```text
|
||||
scheduler 扫描 due reminders
|
||||
-> 校验提醒状态
|
||||
-> 生成幂等键
|
||||
-> 创建 notifications
|
||||
-> 调用飞书发送
|
||||
-> 更新 last_triggered_at 和 next_trigger_at
|
||||
-> 成功或失败都写记录
|
||||
```
|
||||
|
||||
反馈:
|
||||
|
||||
```text
|
||||
接收人点击卡片反馈
|
||||
-> 飞书回调验签
|
||||
-> 校验接收人权限
|
||||
-> 写 feedbacks
|
||||
-> 保留 reminders 调度状态,反馈结果通过 feedbacks 展示
|
||||
```
|
||||
|
||||
## 5. 数据对象
|
||||
|
||||
本模块主要使用:
|
||||
|
||||
1. `ai_drafts`
|
||||
2. `tasks`
|
||||
3. `reminders`
|
||||
4. `notifications`
|
||||
5. `feedbacks`
|
||||
6. `failure_records`
|
||||
7. `operation_logs`
|
||||
|
||||
字段以 `docs/contracts/数据对象约定.md` 为准。
|
||||
|
||||
## 6. 接口需求
|
||||
|
||||
主要接口:
|
||||
|
||||
1. `GET /api/reminders`
|
||||
2. `POST /api/reminders`
|
||||
3. `GET /api/reminders/{id}`
|
||||
4. `PATCH /api/reminders/{id}`
|
||||
5. `POST /api/reminders/{id}/pause`
|
||||
6. `POST /api/reminders/{id}/resume`
|
||||
7. `POST /api/reminders/{id}/cancel`
|
||||
8. `POST /api/reminders/{id}/notify`
|
||||
9. `POST /api/reminders/{id}/feedback`
|
||||
|
||||
接口格式以 `docs/contracts/API接口约定.md` 为准。
|
||||
|
||||
## 7. 权限规则
|
||||
|
||||
1. 所有人可以创建自己的提醒。
|
||||
2. 老板和程经理可以给别人创建提醒。
|
||||
3. 普通员工不能给同事创建提醒。
|
||||
4. 创建人、发起人、管理员可以修改、暂停或取消提醒。
|
||||
5. 接收人只能反馈自己相关提醒。
|
||||
|
||||
## 8. 状态流转
|
||||
|
||||
提醒状态以 `docs/contracts/状态流转约定.md` 为准。核心约束:
|
||||
|
||||
1. `active` 提醒才允许 scheduler 触发。
|
||||
2. `paused` 不触发,但可以恢复。
|
||||
3. `cancelled` 不触发、不可恢复。
|
||||
4. `trigger_failed` 必须写失败记录。
|
||||
5. 同一个提醒同一触发时间同一接收人只能生成一条有效通知。
|
||||
6. 一次性提醒成功触发后进入 `triggered`;周期提醒成功触发后保持 `active` 并计算下一次 `next_trigger_at`。
|
||||
7. 提醒反馈不改变提醒调度状态,反馈结果通过 `feedbacks` 展示。
|
||||
8. AI 提醒草稿缺少明确时间时不得创建 active 提醒,应由 01 模块追问或标记 `missing_fields`。
|
||||
|
||||
## 9. 失败和日志
|
||||
|
||||
必须记录:
|
||||
|
||||
1. 提醒创建、修改、暂停、恢复、取消。
|
||||
2. scheduler 触发成功或失败。
|
||||
3. 飞书通知发送成功或失败。
|
||||
4. 幂等冲突或重复触发跳过。
|
||||
5. 权限拒绝。
|
||||
6. 有问题反馈原因。
|
||||
|
||||
## 10. 给 AI 的测试样例
|
||||
|
||||
1. 普通员工给同事创建提醒,应返回权限错误。
|
||||
2. `paused` 提醒到点不应触发通知。
|
||||
3. 同一提醒同一触发时间重复扫描,不应重复创建通知。
|
||||
4. 每周提醒触发后,应计算下一次提醒时间。
|
||||
5. 通知失败应写失败记录。
|
||||
6. 自己提醒自己默认不需要反馈,老板或程经理给别人提醒默认需要反馈。
|
||||
|
||||
## 11. Review 重点
|
||||
|
||||
1. 是否防止重复触发。
|
||||
2. 是否限制普通员工给别人创建提醒。
|
||||
3. 是否不支持 cron 等第一版不做内容。
|
||||
4. scheduler 是否走 service 层而不是直接改业务表。
|
||||
5. 失败是否可复盘。
|
||||
|
||||
@@ -1 +1,139 @@
|
||||
# 05_权限日志失败记录
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
权限、日志和失败记录模块负责保证第一版闭环可控、可追溯、可复盘。权限必须在后端校验,关键操作必须写日志,AI、飞书、调度和业务失败必须形成失败记录。
|
||||
|
||||
## 2. 第一版做什么
|
||||
|
||||
1. 定义老板、程经理、普通员工、管理员 / AI 团队四类角色。
|
||||
2. 控制事项、提醒、草稿、反馈、失败记录的可见范围和操作范围。
|
||||
3. 记录关键操作日志。
|
||||
4. 记录 AI 解析失败、模型调用失败、AI 记忆读写失败、草稿转换失败、人员映射缺失、飞书通知失败、回调失败、定时触发失败、用户反馈有问题等失败。
|
||||
5. 支持管理员 / AI 团队查看和处理失败记录。
|
||||
6. 对敏感信息做日志边界约束。
|
||||
|
||||
## 3. 第一版不做
|
||||
|
||||
1. 不做复杂组织架构。
|
||||
2. 不做细粒度多级权限。
|
||||
3. 不做复杂审批流。
|
||||
4. 不做独立失败看板或复杂 BI。
|
||||
5. 不把飞书身份直接等同于业务权限。
|
||||
6. 不把密钥、token、完整手机号、完整邮箱写入普通日志。
|
||||
|
||||
## 4. 核心流程
|
||||
|
||||
权限校验:
|
||||
|
||||
```text
|
||||
请求进入 DRF view
|
||||
-> permission class 做入口校验
|
||||
-> serializer 做参数校验
|
||||
-> service 做业务权限和状态校验
|
||||
-> 通过后执行业务动作
|
||||
```
|
||||
|
||||
失败记录:
|
||||
|
||||
```text
|
||||
业务或外部调用失败
|
||||
-> 写 failure_records
|
||||
-> 保留关联对象和失败类型
|
||||
-> 管理员 / AI 团队处理
|
||||
-> 填写处理结果
|
||||
-> 写 operation_logs
|
||||
```
|
||||
|
||||
操作日志:
|
||||
|
||||
```text
|
||||
关键动作发生
|
||||
-> 记录 actor、action、target_type、target_id
|
||||
-> 记录操作渠道和结果摘要
|
||||
-> 避免记录敏感明文
|
||||
```
|
||||
|
||||
## 5. 数据对象
|
||||
|
||||
本模块主要使用:
|
||||
|
||||
1. `users`
|
||||
2. `failure_records`
|
||||
3. `operation_logs`
|
||||
4. `model_call_logs`
|
||||
5. `feishu_events`
|
||||
6. `secretary_messages`
|
||||
7. `bot_contexts`
|
||||
|
||||
字段以 `docs/contracts/数据对象约定.md` 为准。
|
||||
|
||||
## 6. 接口需求
|
||||
|
||||
主要接口:
|
||||
|
||||
1. `GET /api/users/me`
|
||||
2. `GET /api/failure-records`
|
||||
3. `GET /api/failure-records/{id}`
|
||||
4. `PATCH /api/failure-records/{id}`
|
||||
5. `POST /api/failure-records/{id}/resolve`
|
||||
6. `GET /api/notifications`
|
||||
7. `GET /api/notifications/{id}`
|
||||
8. `GET /api/feedbacks`
|
||||
|
||||
接口格式以 `docs/contracts/API接口约定.md` 为准。
|
||||
|
||||
## 7. 权限规则
|
||||
|
||||
1. 普通员工只能看自己作为接收人、创建人或反馈人的记录。
|
||||
2. 老板能看自己发起、创建或接收的记录。
|
||||
3. 程经理能看自己发起、负责、待确认,以及第一批试用管理范围内的记录。
|
||||
4. 管理员 / AI 团队能看失败记录、通知记录、人员映射和必要操作日志。
|
||||
5. 普通员工不能给别人创建事项或提醒。
|
||||
6. 反馈人必须是事项或提醒接收人。
|
||||
7. 飞书登录用户必须匹配到启用状态的平台用户后才能进入平台。
|
||||
|
||||
## 8. 状态流转
|
||||
|
||||
失败记录状态以 `docs/contracts/状态流转约定.md` 为准。核心约束:
|
||||
|
||||
1. 新失败进入 `pending`。
|
||||
2. 处理中进入 `processing`。
|
||||
3. 填写处理结果后进入 `resolved`。
|
||||
4. 确认不处理可进入 `cancelled`。
|
||||
5. 失败记录状态变化必须写操作日志。
|
||||
|
||||
## 9. 必须写日志的动作
|
||||
|
||||
1. 飞书登录成功或失败。
|
||||
2. 机器人收到老板消息。
|
||||
3. 非老板私聊机器人。
|
||||
4. AI 生成草稿、解析失败。
|
||||
5. AI 追问、普通记录、上下文回顾和 BotContext 变化。
|
||||
6. 人工确认、修改、取消草稿。
|
||||
7. 老板点击补充/重说。
|
||||
8. 程经理确认复杂事项。
|
||||
9. 创建事项、创建提醒。
|
||||
10. 发送通知、补发通知、通知失败。
|
||||
11. 接收反馈,尤其是有问题反馈。
|
||||
12. 定时提醒触发成功或失败。
|
||||
13. AI 记忆读写失败、草稿转换失败和失败记录处理。
|
||||
14. 背景摘要或老板风格提示词版本启用。
|
||||
|
||||
## 10. 给 AI 的测试样例
|
||||
|
||||
1. 普通员工创建给别人的事项,应被拒绝并写权限失败日志。
|
||||
2. 普通员工创建给别人的提醒,应被拒绝。
|
||||
3. 非接收人提交反馈,应被拒绝。
|
||||
4. 管理员处理失败记录时,必须留下处理结果。
|
||||
5. 日志中不得包含完整手机号、完整邮箱、飞书 token 或密钥。
|
||||
6. 未匹配平台用户的飞书登录应失败并写失败记录。
|
||||
7. PostgreSQL AI 记忆读写失败时,应写 `memory_store_failed`,不得继续依赖内存确认草稿。
|
||||
|
||||
## 11. Review 重点
|
||||
|
||||
1. 后端权限是否完整。
|
||||
2. 状态流转是否可追踪。
|
||||
3. 失败记录是否包含关联对象、失败类型和处理结果。
|
||||
4. 日志是否记录操作人和渠道。
|
||||
5. 敏感信息是否被脱敏。
|
||||
|
||||
Reference in New Issue
Block a user