ai_member_xiaoyan/skills/interactive-component-json/project.md

12 KiB
Raw Blame History

互动组件配置JSON生成器 — 需求描述

项目概述

从飞书wiki剧本文档出发经过sheet数据解析、组件类型匹配、LLM驱动的jsonData生成 最终输出组件配置JSON并持久化到本地SQLite数据库。

数据来源

剧本文档表格的"组件配置"列。多维表格bitable是旧的数据流程 我们基于剧本文档进行自动化生产是新流程,目标是替换多维表格流程。 bitable数据可用于验证和参考。

已实现的互动类型

中互动27种v1-v3.1完成)

覆盖对话类(6)、信息类(6)、图片类(4)、其他(11)共27种中互动组件。 详见 scripts/match_component.pyMID_INTERACTION_TYPES

  • 每种类型使用独立的精确Prompt模板prompts/prompt_registry.py
  • 角色配置通过section-character映射解析
  • 教研配置文本拆解为结构化字段
  • 语音识别热词自动生成(表达类组件)

核心互动5种v4-v6完成

1. 合作阅读 core_reading_orderv4

  • 7步LLM调用流水线
  • 输出: taskInfo, materialInfo, flowInfo, studyInfo
  • bitable wiki: H6DJweNkpigCbak2Y5LcTZ8Vnfb

2. 看图选词 core_reading_imageDragv5

  • 5步LLM调用流水线
  • 输入: 教研-导览配置 + 教研-互动配置
  • 中间步骤: 学习流程配置, 互动描述
  • 最终JSON: taskInfo, questionGroup, studyInfo
  • bitable wiki: MVo7wugWfimJPIkxhJCcqppFnyf, table: tblKl9CGmARjpw1O
  • prompt模板: prompts/core_imagedrag_prompts.py

3. 口语快答 core_speaking_replyv5

  • 7步LLM调用流水线
  • 输入: 教研-用户视角任务信息 + 教研-任务规则与NPC设定
  • 中间步骤: 学习流程配置, promptInfo配置, 语音识别热词
  • 最终JSON: taskInfo, dialogSetting, dialogConfig, studyInfo
  • bitable wiki: TSwcw0nFmi21khkpUndchNMsn6f, table: tbl4Qg8d45O58Cqf
  • prompt模板: prompts/core_speaking_prompts.py

4. 口语妙问 core_speaking_inquiryv6

  • 7步LLM调用流水线
  • 输入: 教研-用户视角任务信息 + 教研-任务规则与NPC设定
  • 中间步骤: 学习流程配置, promptInfo配置(NPC角色扮演被动问答型), 语音识别热词
  • 最终JSON: taskInfo, dialogSetting, dialogConfig, studyInfo
  • 与口语快答的关键差异: Step2生成被动型NPC角色提示词(含知识库),而非主动提问型
  • bitable wiki: GJUVwNSEkis3EXkrVj0ccbqdn8c, table: tbl1Q68oopST9Mel
  • prompt模板: prompts/core_speaking_inquiry_prompts.py

5. 看图说话 core_speaking_imagev6

  • 8步LLM调用流水线
  • 输入: 教研-导览配置 + 教研-对话配置
  • 中间步骤: 学习流程配置, 语音识别热词
  • 最终JSON: taskInfo, dialogConfig, imageInfo, optionList, questionList, studyInfo
  • Step7(dialogConfig)依赖Step6(questionList), Step8(studyInfo)依赖Step1(学习流程配置)
  • bitable wiki: KBOXwzVHfin6ORkKbA3c3eWEnoh, table: tblvi5HF0uSU2GNo
  • prompt模板: prompts/core_speaking_image_prompts.py

通用机制resourceMapping

所有核心互动都使用统一的 resourceMapping 处理逻辑,不是某个类型的特有字段:

  1. 数据来源: parse_script.py 提取两级角色映射:
    • section_char_map: 从文档"角色-section对应"表解析按section分组
    • character_map: 从sheet数据全局提取作为fallback
  2. 解析流程: generate_json.pyresolve_resource_mapping() 解析section对应 → 格式化为 "NameID" 字符串 → 注入prompt的 {角色配置} 占位符
  3. LLM提取: prompt模板统一指示LLM从 {角色配置} 提取 {"name": int_id} JSON对象
  4. npcName#id规则: 部分类型(合作阅读、合作听力)在 textData/sequenceData 步骤中npcName字段追加 #id仅限npcName字段不适用于content等字段

已实现的核心互动类型(续)

v7 — 听力类3种已完成

详见 prd/v7.mdbitable 数据已验证

类型 cType LLM步数 输出字段 bitable wiki
合作听力 core_listening_order 6 taskInfo, materialInfo, flowInfo, studyInfo FrxtwNRQDizqiikPkATcBzTCnYe
听力拖拽 core_listening_drag 7 taskInfo, preDialog, dialogList, questionList, studyInfo K3QrwQnWqiPBm1krhnNcWDTqnhe
听力选择 core_listening_choose 5 taskInfo, questionGroup, studyInfo Kwrcw6A4jip2sxkdLn4czd1knvf
  • 输入: 合作听力用 教研配置-任务 + 教研配置-材料;听力拖拽/选择用 教研配置-导览配置 + 教研配置-互动配置
  • 中间步骤: 学习过程配置(LLM生成) + 互动描述(LLM生成)
  • 合作听力的听音选意用2个中文含义选项听力拖拽/选择改为"对/错"判断题
  • 所有taskInfo均包含 resourceMapping通用机制
  • 专有名词对照暂不实现,后续单独处理
  • prompt模板: prompts/core_listening_order_prompts.py, prompts/core_listening_drag_prompts.py, prompts/core_listening_choose_prompts.py

待实现的核心互动类型

v8 — 写作类4种已完成

详见 prd/v8.mdbitable 数据已验证

类型 cType LLM步数 输出字段 bitable wiki
看图组句 core_writing_imgMakeSentence 6 taskInfo, textInfo, studyInfo, evalInfo BkmtwUBwMiHd5Ak7VS6ccE9SnHd
看图撰写 core_writing_imgWrite 6 taskInfo, textInfo, studyInfo, evalInfo KwPHwnaqdiWlvNkDm5fcFreDnQh
邮件组句 core_writing_questionMakeSentence 6 taskInfo, textInfo, studyInfo, evalInfo M5oTwUP6wiImC4kVJU8cRYnfnyf
邮件撰写 core_writing_questionWrite 6 taskInfo, textInfo, studyInfo, evalInfo Brn0wldKYizsLZkBqK6clp1tnKd
  • 输入: 教研配置-任务信息 + 教研配置-全文信息
  • 中间步骤: 学习流程配置(LLM生成) + 互动描述(LLM生成)
  • 4种类型共享通用6步流水线 _generate_core_writing()
  • 按输入源特征分为2个prompt文件: core_writing_img_prompts.py(看图类) + core_writing_question_prompts.py(邮件类)
  • 关键差异: 看图类stemDesc=图片列表+leadIn用image邮件类stemDesc=题干描述+leadIn用desc
  • 组句类inputType=sentence(optionList+answer)撰写类inputType=write(answerText+hint)
  • prompt模板: prompts/core_writing_img_prompts.py, prompts/core_writing_question_prompts.py

其他未实现类型

  • 口语独白、口语探讨
  • 写作互动

v9 — 中互动 cDesc 互动描述预生成(已完成)

详见 prd/v9.md

为 10 种中互动类型增加 cDesc互动描述LLM 预生成步骤:

  • 信息类(6种): mid_message_trace/spell/combine/fillin/word/sentence
  • 图片类(4种): mid_image_choose/multiple/sequence/drag

实现方式:

  • _generate_with_template()jsonData 生成前调用 LLM 预生成互动描述
  • 信息类使用 CDESC_PROMPT_MESSAGE 模板(输入: 互动名称 + 互动内容)
  • 图片类使用 CDESC_PROMPT_IMAGE 模板(输入: 互动名称 + 情境引入 + 互动内容 + 互动反馈 + 后置对话)
  • 生成结果注入 parsed_fields["互动描述"],由主 prompt 模板映射到 jsonData 的 cDesc 字段
  • 补全了 mid_image_sequence 模板中遗漏的 cDesc 字段定义
  • 始终使用 LLM 生成,覆盖教研配置中可能存在的值

v10 — 知识点匹配 + 触发命令 + HTML增强已完成

详见 prd/v10.md

知识点匹配功能

  • 新增 scripts/kp_matcher.py:连接 MySQL vala_test.vala_kp2613条有效记录
  • 两阶段匹配title 精确/模糊粗召回 → LLM 多候选精筛(用于同名不同释义消歧)
  • kpInfo 中 kpId 从数据库 kp_id 字段获取,kpTypetype 字段获取
  • kpSkill 使用默认值vocab→vocab_meaning, sentence→sentence_meaning
  • MySQL 不可达时 fallback 到 kpId=null

集成改动

  • generate_json.py:所有 _try_rule_based_kp 调用替换为 generate_kp_info()kp_matcher.match_knowledge_points()
  • 所有核心互动生成器12个和中互动入口统一使用新接口
  • 新增 level 参数贯穿 pipeline → generate_component → 各生成器 → kp_matcher

触发命令

  • SKILL.md 添加触发场景:*组件配置-json* {飞书剧本文档链接}
  • 触发后执行完整 pipeline返回 HTML 报告

HTML 增强

  • 中互动组件在 HTML 报告中也展示 kpInfo section之前仅核心互动展示

v11 — 字段重命名 + 交互式HTML + 推送功能(已完成)

详见 prd/v11.md

字段重命名方案B全量重命名为推送接口字段名

  • 所有核心互动输出字段统一改名为推送接口字段名
  • 映射: taskData→taskInfo, textData→materialInfo, sequenceData→flowInfo, learningData→studyInfo, settingData→dialogSetting, configData→dialogConfig, questionGroupData→questionGroup, studyData→studyInfo, preDialogData→preDialog, dialogListData→dialogList, questionListData→questionList
  • 涉及文件: generate_json.py, pipeline.py, db_manager.py, html_report.py, validate_core_v5.py

交互式HTML报告v2

  • 每个JSON section使用 textarea 可直接编辑
  • kpId 使用下拉选择(显示粗筛 top10 候选)
  • 每个组件 header 内嵌两个推送按钮:[配置↑] [知识↑]
  • 顶部固定操作栏:一键推送全部 + 进度条 + 成功/失败统计
  • 推送状态实时指示loading/ok/fail

推送接口

kp_matcher增强

  • 粗召回加 LIMIT 10
  • 每条知识点匹配结果附带 candidates 字段top10候选供HTML下拉展示

参考文档

  • v11需求详细文档: prd/v11.md
  • v10需求详细文档: prd/v10.md
  • v9需求详细文档: prd/v9.md
  • v8需求详细文档: prd/v8.md
  • v7需求详细文档: prd/v7.md
  • v6需求详细文档: prd/v6.md
  • v5需求详细文档: prd/v5.md
  • v4需求详细文档: prd/v4.md
  • 组件类型注册表: references/component_registry.md

v12 — 解析增强 + pipeline 自动 HTML + 进度输出(已完成)

组件行识别增强parse_script.py

  • 支持单行空格分隔格式: "合作阅读 0000800" → type_name + cId
  • 支持多行带前缀格式: "核心互动- 囗语\n听力选择\n0000810" → 跳过前缀取实际类型
  • LLM 兜底: 正则无法提取时,如果 cell 含中文+5位以上数字调 LLM 解析(带缓存)
  • 测试文档识别率: 15 → 42 组件

pipeline 自动生成交互式 HTML

  • 无需 --dry-run --html 参数,执行完自动生成 v2 交互式 HTML 报告
  • 非 dry-run 模式也保留完整 jsonData/kpInfo 到 report results
  • report 返回 html_path 字段供外部调用者使用

进度输出

  • 每个组件完成后打印 ✓/✗ 状态行
  • 每 5 个组件输出进度摘要(成功/失败/跳过计数)
  • 末尾输出最终统计

cType=None 优雅跳过

  • 未实现类型(口语独白、口语探讨、写作互动)标记为 skipped不触发异常

v13 — CORS 代理服务(已完成)

问题背景

用户直接打开本地HTML文件file://协议)点击推送按钮时,浏览器发送 Origin: null 目标API服务端校验 Origin 返回 403。curl 直接测试正常但浏览器无法绕过。

解决方案:轻量代理中转服务

  • 新增 scripts/proxy_server.py:基于 http.server + requests 的转发代理
  • 新增 config.json代理配置外网IP、端口、速率限制、目标URL
  • 代理只转发到固定目标地址,加上正确的 Origin 头
  • HTML 报告中 API 地址改为代理地址

安全措施

  • 硬编码单一目标URL不可被滥用为开放代理
  • body 结构校验(必须含 componentData/pushRelationKp/pushType
  • 可配置速率限制(默认 60 req/min/IP
  • 专用端口 18080用户在安全组中精确控制

集成方式

  • pipeline 执行时自动检测代理运行状态GET /health
  • 未运行则 subprocess 自动后台启动
  • 代理 URL 传入 html_report 生成到 HTML 的默认 API 地址中

配置文件 config.json

{
  "proxy": {
    "external_ip": "115.190.225.235",
    "port": 18080,
    "rate_limit_per_minute": 60,
    "target_url": "https://api-test.valavala.com/content/feishu/notify",
    "target_origin": "https://flow-test.valavala.com"
  }
}