ai_member_xiaokui/skills/feishu-feedback-sync/SKILL.md
2026-05-12 08:10:01 +08:00

479 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: feishu-feedback-sync
description: 同步飞书「内容测试问题反馈」群消息到知识库电子表格并执行对话链排序。用于:(1) 刘新玉说"同步飞书反馈"、"更新飞书问题反馈表格"、"整理反馈对话链"时触发;(2) 定时任务每日自动同步。数据源为 MySQL vala_test.lark_group_message,目标为知识库内容测试问题反馈表格。含七步完整流程:数据同步 → 写入表格 → 对话链排序 → 问题归纳 → 优先级判定排序 → 问题分类 → 问题分发。
---
# 飞书问题反馈同步(七步完整流程)
## 概述
从 MySQL `vala_test.lark_group_message` 读取飞书群消息,执行七步完整处理流程。
### 七步流程总览
| 步骤 | 名称 | 目标文档/群 | 产出 |
|------|------|---------|------|
| 步骤 1 | 查询数据库 | — | 原始消息数据 |
| 步骤 2 | 写入飞书表格 | `AHtnsehwShUVyDtjasSciIvgn7b` | 按天分 sheet 的原始数据 |
| 步骤 3 | 反馈对话链排序 | `AHtnsehwShUVyDtjasSciIvgn7b` | 已排序的问题簇 |
| 步骤 4 | 问题归纳 | `RaL6whoYMijyYHkSlWrc7OLLnBy`(子文档) | 结构化问题描述+对话表格+结论 |
| 步骤 5 | 优先级判定与排序 | `RaL6whoYMijyYHkSlWrc7OLLnBy`(子文档) | 按 P0>P1>P2>P3 排序的问题列表 |
| 步骤 6 | 问题分类 | `RaL6whoYMijyYHkSlWrc7OLLnBy`(子文档) | 按优先级+分类展示的问题列表 |
| 步骤 7 | 问题分发 | 「小葵小葵」群 `oc_4171a2188f2554522a4309f2d7c27753` | P0问题@通知到群 |
| 步骤 8 | AI 问题归纳 | `RaL6whoYMijyYHkSlWrc7OLLnBy`(子文档) | AI 生成精炼问题描述,替换占位符 |
## 关键标识
| 项目 | 值 |
|------|-----|
| 数据库 | MySQL `bj-cdb-8frbdwju.sql.tencentcdb.com:25413`,user `chatbot`,密码 `xhuBx7d@uT2gUVv`,database `vala_test` |
| 源表 | `lark_group_message` |
| 目标表格 token | `AHtnsehwShUVyDtjasSciIvgn7b`(步骤1-3:原始数据整理) |
| 目标归纳文档 token | `RaL6whoYMijyYHkSlWrc7OLLnBy`(步骤4:问题归纳输出) |
| 目标知识库节点 | `TVivwmzqXiW3YakDUzucFMRenvf` |
| 知识空间 space_id | `7612229802338045122` |
| 群 chat_id | `oc_fabff7672e62a9ced7b326ee4a286c26` |
| Bot App ID | `cli_a9311791083adcc1` |
| Bot App Secret | `ThhLL1I0F2AIKnSbpozKnhm40LTPfyap` |
## 表格字段(与数据库一致)
| 列 | 数据库字段 |
|----|-----------|
| 消息ID | `message_id` |
| 发送者 | `sender_name` |
| 消息类型 | `msg_type` |
| 内容 | `content` |
| 媒体URL | `media_url` |
| 引用消息ID | `quote_message_id` |
| 消息时间 | `msg_time` |
| 消息时间戳 | `msg_timestamp` |
## 执行流程
### 步骤 1:查询数据库
```sql
SELECT message_id, sender_name, msg_type, content, media_url, quote_message_id,
DATE_FORMAT(msg_time, '%Y-%m-%d %H:%i:%s') as msg_time, msg_timestamp
FROM lark_group_message
WHERE msg_time >= '{date} 00:00:00' AND msg_time < '{next_date} 00:00:00'
ORDER BY msg_time ASC
```
默认同步最近 3 天的数据。如果表格已有当天 sheet,则追加新数据(去重写入,按 message_id 去重);如无则创建新 sheet。
### 步骤 2:写入飞书表格
使用 `lark-cli sheets +write`(Bot 身份)批量写入:
- 按天分 sheet(sheet 名为日期,如 `2026-04-28`)
- 表头固定为 8 列
- 每 sheet 最多一次写入(或分批,不超过 500 行/批)
**凭证环境:**
```bash
export PATH=/root/.nvm/versions/node/v24.14.0/bin:$PATH
export LARKSUITE_CLI_CONFIG_DIR=/root/.openclaw/credentials/xiaokui
export HOME=/root
```
**写入命令格式:**
```bash
lark-cli sheets +write \
--spreadsheet-token AHtnsehwShUVyDtjasSciIvgn7b \
--range '<sheet_id>!A1:H<n>' \
--values '<json_2d_array>' \
--as bot
```
### 步骤 3:反馈对话链排序
对每个 sheet 中的数据执行引用链排序(详见下文排序逻辑),使每个问题的完整讨论过程在表格中连续呈现。
## 反馈对话链排序逻辑
### 两阶段排序
#### 阶段 A:推断缺失引用(策略2)
由于飞书群消息同步时仅采集了 `quote_message_id`(显式引用),大量通过飞书「直接回复」功能产生的消息没有引用关系。策略2通过启发式规则补全:
1. **@提及匹配**(最高优先级):消息中 `@某人` → 关联到被@者最近一条消息
2. **同发送者聚类**:同一发送者在 2 分钟窗口内连续发多条消息 → 认为是对同一目标的回复
3. **最近不同发送者**(fallback):关联到最近一条不同发送者的消息(需在 30 分钟内,防止跨话题误关联)
```
示例:
12:18 徐思清: NPC HUD 报告 (无引用)
12:19 王胤鑫: o3 分支? (无引用 → 推断关联12:18,因为12:18是最近不同发送者)
12:19 王胤鑫: 有固定关卡吗 (无引用 → 推断关联12:18,因为同发送者2分钟窗口内)
```
#### 阶段 B:引用链排序
1. **Union-Find 聚类**:将有引用关系的消息(含推断引用)合并为同一「问题簇」
2. **簇内递归展开**:从根消息开始,子回复紧跟父消息(子节点按时间排序)
3. **簇间排序**:按每个簇最早消息的时间排序
### 排序效果对比
排序前(时间平铺):
```
12:18 徐思清: NPC HUD 报告
12:19 王胤鑫: o3 分支?
12:19 王胤鑫: 有固定关卡出现吗
12:20 庞鸿潇: @王胤鑫 11-2 (引用"有固定关卡")
12:22 梁晨: @王胤鑫 没啥规律 (引用"有固定关卡")
12:28 王胤鑫: 是否只在移动端 (引用NPC HUD)
```
排序后(问题链聚合):
```
12:18 徐思清: NPC HUD 报告
12:19 王胤鑫: o3 分支? (推断引用12:18)
12:19 王胤鑫: 有固定关卡吗 (推断引用12:18)
12:20 庞鸿潇: 11-2 (引用"有固定关卡")
12:22 梁晨: 没啥规律 (引用"有固定关卡")
12:28 王胤鑫: 是否只在移动端 (引用12:18)
12:26 孙时敏: Playtesting有数据 (推断引用12:22)
```
> 缩进行为对该根消息的直接或间接回复,形成完整的「问题 → 追问 → 诊断 → 结论」链路。
### 步骤 4:问题归纳
对每个问题簇生成结构化归纳,分两个部分:
1. **问题描述**:按固定格式描述问题
2. **当前问题排查结论**:从对话最后几条消息中提取排查状态
#### 4.1 问题描述格式
```
> **在{端}端{环节}内({课程}),{角色/组件}出现了{现象}**
```
#### 位置要素提取维度
| 维度 | 可能的值 | 来源 |
|------|---------|------|
| 端 | 移动端、iOS、iPad、pad端、Android | 消息内容关键词 |
| 环节 | 关卡内、关卡外、知识巩固、巩固题、单元挑战、挑战、听力挑战、阅读挑战、口语挑战、写作挑战、单元强化、瓦拉学院、报告 | 消息内容关键词 |
| 课程 | 数字如 11-2、L1 3-2 | 消息内容中的数字/字母编号 |
| 角色/组件 | NPC、HUD、音频、组件等 | 消息内容关键词 |
| 现象 | 一句话概括发生了什么 | 综合理解 |
#### 4.2 归纳输出格式
每个问题簇输出一个结构化块(结论在表格上方,表格放原始对话):
```markdown
### 问题 N
**问题描述:** {AI 归纳后的精炼描述}
**当前问题排查结论:** {结论}
| 发言人 | 对话信息 |
|--------|---------|
| 报告人 | 🚩 报告:原始对话内容 |
| ... | 原始对话内容(含媒体 URL) |
| 最终人 | ✅ 原始对话内容 |
```
```
#### 4.3 排查结论提取规则
脚本从**全部消息**(而非仅最后 1-2 条)中提取结论。优先匹配以下模式:
| 优先级 | 匹配模式 | 结论 |
|--------|---------|------|
| 1 | 已修复/已解决/修好了 | 已修复 |
| 2 | 确认是bug/确实是问题 | 已确认,待修复 |
| 3 | 不是bug/设计如此/非问题 | 非问题,设计如此 |
| 4 | 有解释性分析 + 日志已上传 + 排查中 | 疑似{原因},已上传日志,排查中 |
| 5 | 日志已上传 + 排查中 | 已上传日志,排查中 |
| 6 | 暂未/没复现/未复现 | 暂未排查到问题 |
| 7 | 其他(无明确结论) | 暂未排查到问题 |
**解释性分析** 的来源:消息中匹配 "因为/原因是/应该是/改为了/导致/预下载/上云/首次/正常情况" 等关键词,提取对应发言人的判断句作为疑似原因。
> 注意:脚本的规则匹配是辅助手段。运行时的 AI 可以根据完整对话上下文,修正或补全结论。
#### 4.4 归纳示例
```markdown
### 问题一
> **在移动端关卡内(11-2 等),NPC 头上的 HUD 偶尔变成一小条**
| 发言人 | 要点 |
|--------|------|
| 徐思清 | 🚩 报告:最近经常出现,无明显规律 |
| 王胤鑫 | 追问:o3 分支?只在手机包出现,unity 里正常? |
| 庞鸿潇 | 确认:11-2 出现了 |
| 梁晨 | 补充:只在 APP 里发现过 |
| 徐思清 | ✅ 确认:确实只在移动端出现 |
**当前问题排查结论:** 暂未排查到问题
```
```markdown
### 问题二
> **在 iOS 端关卡内(L1 3-2),组件数据丢失,无音频,Loading 耗时约 10 秒**
| 发言人 | 要点 |
|--------|------|
| 胡陈辰 | 🚩 报告:iOS 线上 L1 3-2 组件无音频 |
| 安君仪 | 询问:哪个组件? |
| 胡陈辰 | 复现:Loading 约 10 秒,组件数据丢失,杀 APP 重进恢复正常 |
| 毋益飞 | 解释:Loading 慢因内容上云加载;要求上传日志 |
| 胡陈辰 | ✅ 日志已上传,待明天排查 |
**当前问题排查结论:** 日志已上传,排查中
```
### 步骤 5:优先级判定与排序
基于《用户反馈问题优先级判断文档》,对步骤4归纳的问题自动评定优先级(P0-P3),并按优先级从高到低排序输出。
#### 5.1 判定维度
| 维度 | 说明 | 来源 |
|------|------|------|
| 基础优先级 | 根据问题严重程度(崩溃/功能异常/体验瑕疵/细节优化) | 关键词规则匹配 |
| 出现概率 | 必现/高概率/中概率/低概率/偶现 | 消息内容关键词 |
| 影响范围 | 全部用户/大部分用户/部分用户/极少数用户 | 消息内容关键词 |
#### 5.2 动态调整规则
| 规则 | 条件 | 效果 |
|------|------|------|
| 必现升级 | 出现概率为必现/高概率 | 原有优先级 +1 级(P1→P0, P2→P1) |
| 偶现降级 | 出现概率为低概率/偶现 | 原有优先级 -1 级(最多降一级,P1→P2) |
| 范围升级 | 影响全部用户 | 原有优先级 +1 级 |
| 范围降级 | 仅影响极少数用户 | 原有优先级 -1 级 |
#### 5.3 优先级等级定义
| 级别 | 定义 | 修复时限 | 典型关键词 |
|------|------|----------|-----------|
| 🔴 **P0** | 孩子完全上不了课 / 核心功能崩溃 | 2小时内处理,当天解决 | 闪退、崩溃、进不去、数据丢失、服务器宕机 |
| 🟠 **P1** | 功能能用但不对劲 / 学习效果打折扣 | 3天内修复上线 | 音频异常、判分错误、进度保存失败、奖励未发放 |
| 🟡 **P2** | 偶尔小毛病 / 界面瑕疵 / 刷新就好 | 当周修复 | UI显示异常、偶尔不显示、拖拽不流畅、刷新恢复 |
| 🟢 **P3** | 几乎不影响使用 / 追求完美细节 | 不单独排期 | 分辨率略低、错别字、背景音不统一 |
#### 5.4 输出格式
在步骤4归纳结果的基础上,每个问题标题追加优先级标签,并新增优先级信息行:
```markdown
### 问题 1 🔴 P0
**优先级:** 🔴 P0 | 基础优先级: P1(匹配P1规则:learning_func);出现频率: 必现;动态调整: 升级 1 级
**修复时限:** 2小时内处理,当天解决
> **[AI归纳: 问题描述]**
...
```
问题在文档中按 **P0 → P1 → P2 → P3** 排列,同优先级内按最早消息时间排序。
在归纳开头先输出优先级分布汇总:
```markdown
**优先级分布:** P0:1个 | P1:3个 | P2:5个 | P3:2个
```
#### 5.5 执行方式
```bash
# 默认启用步骤5
python3 sync_feishu_feedback.py --days 3
# 跳过步骤5(仅执行步骤1-4)
python3 sync_feishu_feedback.py --days 3 --skip-priority
```
优先级判定函数位于独立模块 `scripts/priority_classifier.py`,可单独测试:
```bash
python3 priority_classifier.py
```
### 步骤 6:问题分类
对每个问题簇自动判定问题类别,在"今日问题归纳"部分按 **优先级 + 分类** 分组展示。
#### 6.1 问题分类规则
按匹配优先级从上到下执行,命中第一个即返回:
| 分类名称 | 匹配关键词场景 |
|---------|----------------|
| 启动/运行异常 | 闪退、崩溃、卡死、无法启动、进不去、服务器宕机 |
| 版本/更新类 | 更新失败、版本异常、升级后无法使用 |
| Loading/加载类 | 加载慢、加载超时、转星星、Loading 耗时异常 |
| 数据/进度类 | 数据丢失、进度不对、白学、保存失败 |
| 声音/音频类 | 无声、音频异常、播放问题、听不到 |
| 语音识别/判分类 | 判分不对、识别错误、评测异常 |
| 关卡/内容类 | 关卡异常、课程问题、层级问题、题目错误 |
| UI显示类 | 界面异常、HUD显示、动画、错位、截断 |
| 用户反馈问题 | 反馈、建议 |
| 其他问题 | 默认兆底 |
#### 6.2 "今日问题归纳"输出格式
```markdown
## 今日问题归纳
**⚠️ P0级核心问题(需优先处理)**
1. **Loading/加载类**
- 在iOS 端关卡内(3-2),Loading 耗时约 10 秒...
**⚡ P1级重要问题**
1. **关卡/内容类**
- 【偶现】在移动端关卡内,NPC 头上的 HUD 偶尔变成一小条
**📌 P2级一般问题**
1. **UI显示类**
- ...
**📝 P3级低优先级**
1. **其他问题**
- ...
```
#### 6.3 优先级标题映射
| 优先级 | 标题格式 |
|--------|----------|
| P0 | ⚠️ P0级核心问题(需优先处理) |
| P1 | ⚡ P1级重要问题 |
| P2 | 📌 P2级一般问题 |
| P3 | 📝 P3级低优先级 |
#### 6.4 分类函数
位于 `sync_feishu_feedback.py` 中的 `classify_problem(cluster_msgs)` 函数,基于 `CATEGORY_PATTERNS` 列表顺序匹配。
### 文档输出结构(子文档模式)
「用户反馈问题汇总」采用子文档模式,每个日期独立一个子文档:
```
📂 用户反馈问题汇总 (node: RaL6whoYMijyYHkSlWrc7OLLnBy)
├── 2026-05-06 问题反馈
├── 2026-04-28 问题反馈
└── ...更多日期
```
**规则:**
- 每天只新增一个对应日期的子文档,绝不重复创建
- 子文档标题格式:`YYYY-MM-DD 问题反馈`
- 已有同日期子文档则覆盖更新内容
- 实现函数:`update_summary_doc_as_children(day_sections)`
- 依赖:`list_child_nodes()` 查询已有子文档,`create_child_doc()` 创建新节点
### 步骤 7:问题分发
将每日问题归纳同步到「小葵小葵」问题反馈群(chat_id: `oc_4171a2188f2554522a4309f2d7c27753`),P0问题 @相关负责人及时跟进
#### 7.1 分发规则
| 规则 | 说明 |
|------|------|
| 内容 | 仅发送"今日问题归纳"部分(不含"今日问题拆解"详细表格) |
| 格式 | 富文本 post 消息,含标题 + 归纳正文 + 文档链接 |
| P0 @通知 | 自动 @配置列表中的负责人(当前:毋益飞 eggbg21g) |
| 身份 | 使用小葵Bot(凭证目录 `DIS PATCH_CRED_DIR`)直接调用 API |
| 频率 | 每天每条汇总发送一次 |
#### 7.2 消息格式示例
```
📋 2026-04-28 用户反馈问题归纳
⚠️ P0级核心问题(需优先处理) @毋益飞
1. Loading/加载类
- 在iOS 端关卡内(3-2),Loading 耗时约 10 秒...
⚡ P1级重要问题
1. 关卡/内容类
- 【偶现】在移动端关卡内(11-2),NPC 头上的 HUD 偶尔变成一小条
📄 详细文档:2026-04-28 问题反馈 [链接]
```
#### 7.3 配置
位于 `sync_feishu_feedback.py`:
| 配置项 | 值 | 说明 |
|--------|-----|------|
| DISPATCH_CHAT_ID | `oc_4171a2188f2554522a4309f2d7c27753` | 目标群 |
| P0_NOTIFY_USERS | `["eggbg21g"]` | P0问题 @列表 |
| DISPATCH_CRED_DIR | `/root/.openclaw/credentials/xiaokui` | Bot身份凭证 |
#### 7.4 执行方式
```bash
# 默认执行步骤7
python3 sync_feishu_feedback.py --days 3
# 跳过步骤7
python3 sync_feishu_feedback.py --days 3 --skip-dispatch
```
## 定时任务
建议每日执行一次,在飞书群消息同步完毕后(`feishu-group-msg-sync` 之后)运行。
### 两阶段执行(含 AI 归纳)
```bash
# 阶段一:每天 10:00 执行(生成占位符 + 保存上下文 JSON
0 10 * * * /bin/bash /root/.openclaw/workspace-xiaokui/scripts/sync_feishu_feedback_wrapper.sh --ai-placeholders >> /var/log/xiaokui_feedback_sync.log 2>&1
# 阶段二:每天 10:05 AI 归纳(读取上下文 JSON → AI 生成描述 → 回写文档)
# 由心跳任务或手动触发python3 sync_feishu_feedback.py --apply-ai <descriptions.json>
5 10 * * * /bin/bash /root/.openclaw/workspace-xiaokui/scripts/ai_summarize_feedback.sh >> /var/log/xiaokui_ai_summarize.log 2>&1
```
### 步骤 8AI 问题归纳(新增)
脚本的规则匹配 `generate_problem_description()` 只能处理预定义的症状模式,无法理解对话语义。当问题类型不在关键词列表内时会退化为原文拼贴。
**AI 归纳流程:**
1. **脚本阶段**`--ai-placeholders` 模式下,问题描述使用 `[待AI归纳:#N]` 占位符,同时保存 `cluster_context_{date}.json``output/daily_feedback/`
2. **AI 阶段**AI 读取上下文 JSON理解完整对话语义生成精炼的问题描述写入 `ai_descriptions_{date}.json`
3. **回写阶段**`--apply-ai <descriptions.json>` 重新生成文档内容,替换占位符为 AI 描述,覆盖写入知识库
**上下文 JSON 结构:**
```json
{
"date": "2026-05-11",
"clusters": [{
"index": 1,
"location": {"端": "", "环节": "", "课程": "", "角色/组件": ""},
"priority": "P2",
"category": "其他问题",
"conclusion": "**当前问题排查结论:** ...",
"messages": [{"sender": "...", "content": "...", "time": "..."}]
}]
}
```
**AI 描述 JSON 格式:**
```json
{
"date": "2026-05-11",
"descriptions": [{"index": 1, "description": "AI 生成的问题描述"}]
}
```
## 权限说明
- Bot 有 `sheets:read/write` 和 wiki API 读取权限
- Bot 缺少 `wiki:node:create`、`drive`、`bitable` 权限
- 所有操作均使用 Bot 身份 + `lark-cli` 命令
- 创建新 sheet 使用 `lark-cli api POST sheets_batch_update`