--- 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 '!A1:H' \ --values '' \ --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 5 10 * * * /bin/bash /root/.openclaw/workspace-xiaokui/scripts/ai_summarize_feedback.sh >> /var/log/xiaokui_ai_summarize.log 2>&1 ``` ### 步骤 8:AI 问题归纳(新增) 脚本的规则匹配 `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 ` 重新生成文档内容,替换占位符为 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`