Files
mcn-short-video/project/短视频脚本创作/V1.0/references/接口调用/WeKnora_极致事件检索.md
T

276 lines
18 KiB
Markdown
Raw Normal View History

# WeKnora 极致事件检索规范
> 维度:接口调用 | 定位:**极致事件库的调用契约(两个作用位共用)**
> 依赖 MCP 服务:`weknora`(工具 `hybrid_search`);**不可用时静默降级**(见 §5),不影响 S1-S11 核心创作流程
> 上游串联:`../知识库/05_极致事件/00_极致事件总纲.md`(类型层判定)→ `01_极致类型-素材标签映射表.md`(类型↔标签)→ `创作极致事件_通用_内容设计.md`(怎么用)→ **本文件(怎么取到)**
> 变更(2026-09-24):新建。素材层由「读 md 文件 + 四维标签筛条」切换为「WeKnora 语义检索(主)+ md 源文件(降级)」;实测依据见 §7。
> 变更(2026-09-29):**作用位由 1 个扩展为 2 个** —— 新增 **S9 事件素材召回(润色)**,见 §三之三;S7 填空侧补 **取条上限 1-2 个**。
---
## 〇、两个作用位(先看这张表,再决定怎么调)
| | 作用位① **填空** | 作用位② **润色** |
|:--|:--|:--|
| **用在** | **S7**:布位定完 → 事件展开前 | **S9**:格式选定 → 写台词前 |
| **解决** | 写不出具体桥段 → 要机制样本 | 台词概括 → 要表达质感样本 |
| **取什么** | 落差结构 + 手法类别 + 铺垫量级 | 原话 / 微反应 / 意外 的**写法** |
| **粒度** | 按 L1 节点(按需) | **按场次**(每场 1 条 query,固定执行) |
| **取条上限** | 🔴 **1-2 个/轮(全轮总条数)** | ≤2 条/场 |
| **触发** | 按需(自评"写不写得出") | **固定执行**,不靠自评 |
| **方法文件** | `创作极致事件` §二 | `创作极致事件` §三 |
> 🔴 **两者是上下游不是并列**:① 按需可能整轮不触发;② **必须独立执行**,否则润色环节恒空。
> 以下 §一~§五 的参数/降级/复筛对**两个作用位通用**;§三之三单独说 ② 的问法。
---
## 一、定位:本规范解决什么
| 层 | 文件 | 回答 |
|:--|:--|:--|
| 方法层 | `../知识库/05_极致事件/` 各创作体系 + `../知识库/03_框架节奏/02_冲突叙事套路.md` | 这场**用什么手法**制造极致感 |
| 判定层 | `00_总纲` / `01_映射表` / `02_赛道形态` / `03_评估标准` | 这**是什么**极致、定哪个库 |
| **检索层** | **本文件** | **怎么取到**可参考的事件素材 |
| 素材层 | WeKnora 容器(主)+ `../素材库/*.md`(源与降级) | 取到**什么材料** |
> 🔴 **调用方向自上而下**:方法 → 判定 → 素材。**不得反向**(先看有什么素材再想故事=素材驱动,会导致内容与账号人设脱节)。
---
## 二、调用:工具与参数
```
工具:hybrid_search(MCP 服务 weknora)
```
| 参数 | 取值 | 说明 |
|:--|:--|:--|
| `kb_id` | `MCN极致事件素材库` | **用库名**(服务自动解析),**禁写死 UUID** |
| `query` | 情境化事件陈述(见 §3) | **唯一召回杠杆** |
| `match_count` | **3** | ⚠️ **参数名必须是 `match_count`**;写成 `top_k`/`limit`/`size` 会被**静默忽略并恒返回 10 条**(实测,2026-09-28) |
| `vector_threshold` | **0.5**(**必须显式传**) | ⚠️ **省略该参数不等于 0.5**——实测省略时正常业务 query 会**直接返回 0 条**。另:0 会被当"未设置"处理,低阈值请写 `0.1` |
| `keyword_threshold` | ❌ **不传** | FAQ 库恒为**纯向量**召回,关键词不参与 |
> ⚠️ **禁用 `chat` / `agent_chat` 替代**:二者走 RAG+LLM 总结,会把卡片**摘要化**——而卡片的价值恰在不可概括的细节(原话、微反应、铺垫量级、镜头语言)。**必须用 `hybrid_search` 取卡片原文。**
> 🔴 **阈值不能提升召回质量(实测)**:同一 query 在 `thr=0.1~0.5` 区间命中数**完全相同**,阈值只做事后过滤(`≥0.65` 起才截断)。**想召回得准,唯一有效手段是把 `query` 写好**(见 §3)。
---
## 三、问法:情境化事件陈述
> **核心原则:把节点写成一件「具体可能发生的事」** —— 卡片正文描述的是**画面里发生了什么**,query 也应如此,而非"我要什么机制"的抽象请求。
> ⚠️ **本节的实测结论(2026-09-28,勿高估问法改写的收益)**:
> 用**反查法**(取库内确有的卡 → 两种问法分别表达同一事件 → 看能否召回自身)实测 35 张卡(覆盖 12 标签):
> **旧问法 R@1 = 34/35(97.1%)/新问法 R@1 = 35/35(100%)** —— **两者差异在噪声范围内**。
> **结论:当 query 信息足够(把事件讲清楚)时,两种写法都能召回;问法改写的真实收益是「降低编导写出低信息量 query 的概率」,不是「提升召回率」。**
> 真正带来确定性收益的是 §二 的两条**参数纠正**(`match_count` / 显式阈值),见 §7.1。
### 3.1 主写法:把节点翻译成一件具体的事
```
「{谁} 在 {什么处境} 下 {做了什么具体动作},结果 {发生了什么」}
```
| 要素 | 来源 | 说明 |
|:--:|:--|:--|
| 谁 | S6 场次事件的角色 | 用角色身份,不用人名 |
| 什么处境 | S7 布位节点 | 承接上文的压力/期待 |
| 做了什么 | **方法层**(`知识库/05_极致事件/` 各创作体系)+ 本账号具象锚点 | 必须是**可拍摄的动作** |
| 结果 | 落差结构 `[期待A]—被X打破→[结果B]` 的 B 端 | |
**示例对照**:
| 写法 A(抽象机制式,易造成信息不足) | 写法 B(情境化事件陈述,推荐) |
|:--|:--|
| `找一条 坚持用真材实料的人 被同行投诉举报 后厨 留人型 事件素材` | `坚持用真材实料的人被同行举报用死虾,检查的人来了他当场开箱捞活虾,反手把举报人堵回去` |
| `找一条 被当场刁难的人 用一连串专业细节把对方顶回去 厨房 留人型 事件素材` | `客人当众挑刺说食材不新鲜,她一句话不说直接端出后厨原箱让对方当场哑口` |
> ✅ **推荐 B 的理由(不是召回率,而是「信息量保障」)**:A 式把事件塞进「找一条…型事件素材」的壳里,**壳词会稀释事件本身的信息权重**,且编导容易只填空心机制词就提交;B 式强制写出「谁+动作+结果」,**从形式上杜绝低信息量 query**。
### 3.2 补充写法:结构词加成(仅有明确结构诉求时用)
若本节点明确要"反差/反转/冲突"这类结构,可在事件陈述**后追加结构词**:
```
{情境化事件陈述} + 反差 反转 冲突
```
> ⚠️ **不要只用结构词**(如仅 `反差 冲突 打脸`)—— 裸词串信息量过低。
### 3.3 五条禁忌(实测支撑)
| 禁忌 | 后果 | 实测 |
|:--|:--|:--|
| ❌ **纯抽象机制词**("制造反差""引起共鸣""制造极致感") | 零命中或落到泛化卡 | `data: null` |
| ❌ **赛道词当主检索词**("亲子""美妆") | 库内 72.6% 为剧情赛道,赛道词只会落到极少数条且分数低 | 赛道词只作为具象锚点的一部分 |
| ❌ **依赖 `CustomMetadata` 过滤** | **不参与过滤** | 想收敛范围只能靠 query 语义 + 检索后复筛 |
| ❌ **只堆关键词串** | 裸词串召回差 | 必须**成句** |
| ❌ **query 过短(<40 字)** | HTTP 400 报错 | 需最短长度保护 |
### 3.4 分数怎么读(重要认知修正)
> 🔴 **库内相似素材密集,top1~top10 分数带极窄**(实测同 query 首尾仅差 **0.047**,第 1-2 名间隔常在 **0.00~0.03**)。
> **→ 分数和间隔都不能用来判断"召回对不对"**;间隔小 ≠ 召回错,只是该主题素材本身多而相似。
> **→ 正确的动作是:取回后人工复筛「落差结构是否同构」**(§4.3),分数只用于粗筛。
### 3.5 作用位②(S9 润色)的问法:**复现该场事件**
> 与 ① 的区别:① 是"我写不出某个节点,帮我找机制"(**找**);② 是"这场事件已经定了,别人是怎么说、怎么演的"(**复现**)。
**写法**:用该场「**场次标题 + 事件概述**」拼成一件具体的事,≥40 字。
```
「{本场角色} 在 {本场空间/处境} 下 {本场核心动作链},{对方的反应/结果}」
```
**示例**(对照 `脚本07` 场3「看鳃拆穿」):
```
❌ 「小学生拆穿老板卖隔夜鱼」
✅ 「一个买鱼的孩子蹲在鱼摊前把鱼嘴掰开,指着鳃的颜色一条条数给老板听,围观的人越来越多,老板本来还在笑,手停在了半空」
```
**逐场次执行**:场1 → 场2 → … → 场N,每场 1 条 query。**调用次数 = 场次数**(典型 5-6 次)。
**复筛判据**(不同于 ①):① 看**落差结构同构**;② 看**是否含可借的表达质感** ——
即卡片里有没有 **原话**(语气词/方言/口误/半截话)、**微反应**(身体部位+幅度)、**意外**(计划外打断)。
三者有其一二即可留,**≤2 条/场**。
> ⚠️ **零命中同样不是错误**:该场留空、不重试、不报错,继续下一场(同 §4.1)。
---
## 四、返回值判据(三个必知行为)
### 4.1 零命中不是错误
```json
{ "data": null, "success": true } ← 零命中
```
> 判据:**`success == true 且 data == null` → 零命中**。
> ❌ 不得判为"调用失败";✅ 不重试、不报错,直接走 §5 降级。
### 4.2 同一张卡内容返回三份
| 字段 | 内容 | 处理 |
|:--|:--|:--|
| `chunk_metadata.answers[0]` | **卡片原文** | ✅ **只读这一份** |
| `content` | 标准问 + 相似问 + Answers 拼接 | ❌ 噪声 |
| `matched_content` | 又一份全文 | ❌ 噪声 |
| `chunk_metadata.standard_question` / `similar_questions` / `negative_questions` | 问法(生产信息) | ❌ 创作时无用 |
### 4.3 复筛与转译
| 步 | 动作 | 判据 |
|:--:|:--|:--|
| 1 | 读 `chunk_metadata.answers[0]` | 只读这一份 |
| 2 | **复筛** | 看卡片 `内容含义` 的落差结构 `[期待A]—被X打破→[结果B]` 是否与本节点**同构**;不同构直接弃。**分数不参与判断**(存在「泛化磁铁卡」会挤占 top1) |
| 3 | 保留 | **≤2 条/节点** |
| 4 | **转译** | 只取落差结构 / 手法类别 / 铺垫量级(短≤3s·中3-10s·长>10s)/ 镜头逻辑;**禁搬**人物·身份·台词·道具(取材不取形,硬规则见 `../创作流程规范.md` 六) |
> 🔴 卡片来自**他人账号**的具体桥段,直接搬用 = 抄袭且违反硬编码禁止规则。转译产物必须换成本账号的具象锚点(人设卡身份 + 本赛道物品),写入大纲时不留原卡痕迹。
---
## 五、降级矩阵(P0)
| 情形 | 判据 | 行为 |
|:--|:--|:--|
| 会话未挂载 weknora MCP | 工具不可用 | 静默回退读 `../素材库/*.md`(**md = 权威源,永不删除**) |
| 服务不可用(容器未启动 / 用户环境无服务) | 调用报错或超时 | 同上 |
| 库不存在 | 返回错误 | 视为未启用,全流程与原行为一致 |
| **零命中** | `success=true 且 data=null` | 退化为「仅用判定层类型子类」指引;**不编造素材**、不重试 |
> **能力探测式**:先试图检索 → 失败/零命中 → 降级。**既不假定可用,也不假定不可用。**
> 与 `SKILL.md`「MCP 不可用时不影响核心创作流程(步骤 1-11)」原则一致。
---
## 六、上下文成本控制
单条卡约 3.5–4KB(因 §4.2 的三份重复)× `match_count`:
| `match_count` | 单次返回 | 一视频 3 节点 | 一视频 5 节点 |
|:--:|:--:|:--:|:--:|
| 5(默认) | ~18KB ≈ 6K tokens | ~18K | ~30K |
| **3(本规范取值)** | **~11KB ≈ 3.5K tokens** | ~10K | ~18K |
**三条控制规则**:
1. **`match_count=3`**,复筛后留 ≤2 —— 不追求多召回(泛化磁铁卡会挤进前列);
2. **按需检索** —— 只对「规划时想不出具体桥段的节点」检索;**已有明确桥段的节点跳过**(通常一视频 1–3 次,而非每节点必检);
3. **串行、读后即弃** —— 一次只检索一个节点,读卡 → 转译 → 丢弃原文,不把多节点结果堆积在上下文里。
---
## 七、实测依据(2026-09-28)
| 项 | 结果 |
|:--|:--|
| MCP 可召回 FAQ 库 | ✅ `hybrid_search(kb_id="MCN极致事件素材库", query="被当场刁难的人,用一连串专业细节一步步把对方顶回去")` → 命中 `28325-3`,`score=0.6058205716953738` |
| 与 REST 路径等价 | ✅ 同 query 分数与 `POST /api/v1/knowledge-bases/{KB}/faq/search` **完全一致** |
| `kb_id` 支持库名 | ✅ 无需 UUID |
| 纯抽象问法 | ❌ `data: null`(零命中) |
| 具象机制问法 | ✅ 0.50–0.64 区间,最高 0.6696 |
| 库内库存 | **631 条事件卡**(旧记"450+"已过时);赛道:剧情 ≈72.6% / 生活vlog ≈27% / 美妆等 ≈0.7% |
| **标签覆盖(已补齐感官向缺口)** | 12 标签:`反差`175 / `反常识`119 / `价值观冲击`93 / `视觉冲击`67 / `自嘲反差`44 / `细节专业`32 / `感官沉浸`26 / `氛围沉浸`25 / `预见式服务`20 / `品质对比`19 / `食材极致`9 / `难度极限`2 —— **感官向 12 标签均有库存**(`难度极限`/`食材极致` 由 0 补齐为 2/9) |
### 7.1 检索机制实测(2026-09-28 新增,纠正既往认知)
#### A. 确定性收益 —— 参数纠正(**本次优化的主要价值**)
| 项 | 实测结果 | 结论 |
|:--|:--|:--|
| **数量参数名** | `top_k` / `limit` / `size` / `count` / `k` / `topK` = 3 → **一律返回 10 条**;`match_count` = 3 → **返回 3 条** | ⚠️ **必须用 `match_count`**,写错会被**静默忽略**(不报错) |
| **上下文成本收益** | 同 query:`top_k=3` 返回 **32122 字符** → `match_count=3` 返回 **10087 字符** | ✅ **省 69% 上下文**(此前设计意图从未生效) |
| **省略 `vector_threshold`** | 正常业务 query → **返回 0 条** | ⚠️ **必须显式传 0.5**,省略 ≠ 默认 0.5 |
#### B. 噪声级差异 —— 问法改写(**收益有限,勿高估**)
| 验证法 | 样本 | 结果 |
|:--|:--|:--|
| **反查法**(库内确有的卡 → 两种问法表达同一事件 → 看能否召回自身) | 35 卡 / 12 标签 | 旧问法 R@1 = **34/35(97.1%)**;新问法 R@1 = **35/35(100%)** → **差异在噪声范围内** |
| **需求法**(凭空编导需求) | 5 节点 | 两法 **3/5 节点均 0 命中** → 说明测的是「库内有无该素材」,不是「问法优劣」 |
> ✅ **问法改写的真实价值 = 「信息量保障」**:强制写出「谁+动作+结果」,从形式上杜绝低信息量 query。**不是**提升召回率。
> ⛔ **不要对外宣称「新问法把召回率从 97% 提升到 100%」** —— 那是噪声,且反查法的自然上限本就是 100%。
#### C. 认知修正(与检索无关,但会误导判断)
| 项 | 实测结果 | 结论 |
|:--|:--|:--|
| **阈值区间作用** | `thr=0.1/0.2/0.3/0.4/0.5` 命中数**相同**;`0.6`→3 条;`0.65`→0 条 | 阈值只做**事后过滤**,不能提升质量 |
| **分数带宽度** | 同一 query top1=0.6338 → top10=0.587(首尾差 **0.047**);第 1-2 名间隔常 **0.00~0.03** | ⚠️ **分数/间隔不能判优**,靠人工复筛落差结构 |
| **感官类(F1 型入库)召回** | 全量 101 卡,仅用事件名查询 → **R@1 = 97/97(100%)**,加不加意图/结构词**无差异** | F1 型问法本身即完整事件描述,查询已饱和 |
| **戏剧类(F3 型入库)召回** | 纯口语间隔仅 0.054;补结构词/画面词后 **×2.7** | 间隔指标(非召回率)有改善 |
> 🔴 **本节最重要的一条**:**召回能力的天花板由「入库存的是哪一型问法」决定**(F1 型 100% vs F3 型需补词),**不由 query 写法决定**。
> 库内现状:F3 需求壳句 318 条(50.4%)/ F4 白描陈述 202 条(32.0%)/ F1 编号+后缀 75 条(11.9%)/ F2 30 条(4.8%)/ F5 6 条(1.0%)。
> → **编导侧可控的只是「别把 query 写差」;要真正提升召回,须改入库模板(见 §8 待决策项)。**
### 7.2 已知限制
> ⚠️ **标签偏斜已缓解但结构性问题仍在**(P1):库内戏剧极致 ≈78%、感官极致 ≈22%(旧记 88%/12%),因早期队列按点赞降序导入,而感官类素材(美食/装修/手工)点赞普遍偏低;`难度极限` 仅 2 条。
> **影响**:检索「手工难度极限」这类极窄感官向 query 时仍可能零命中。
> **缓解**:降级矩阵已覆盖(零命中 → 仅用判定层类型子类指引,不编造);补采侧走 `tools/weknora-ingest/` 定向取批(`--target <标签> N`)。
>
> ⚠️ **真实瓶颈 = 素材覆盖,不是检索技术**:需求法实测显示,编导提出的 5 个真实节点需求中 **3 个在库内零命中**(顾客刁难反杀 / 品质验货 / 身份反差)。**问法再优化也召不回不存在的素材。**
> ⚠️ **已知限制:标签偏斜(P1)**。库内戏剧极致 ≈88%、感官极致 ≈12%,因队列按点赞降序导入,而感官类素材(美食/装修/手工)点赞普遍偏低。
> **影响**:检索「美食视觉冲击」「装修氛围沉浸」「手工难度极限」这类感官向 query 时会**零命中或召回不相关卡**。
> **缓解**:降级矩阵已覆盖(零命中 → 仅用判定层类型子类指引,不编造);补采侧走 `tools/weknora-ingest/` 的 `--sensory` 优先取批流程。
---
## 八、与其他接口的分工
| 路径 | 使用者 | 场景 |
|:--|:--|:--|
| **MCP `hybrid_search`** | AI 会话(S7 执行时) | 创作端单次检索,每视频 1–3 次 |
| REST `/faq/search` | `tools/weknora-ingest/*.py`(项目侧,**不入技能包**) | 生产端:批量导入 + 检索终验;导入通道独占(dry_run 须轮询 completed) |
> 🔴 MCP 服务地址与 API Key 属**环境配置**,只存在于 `~/.workbuddy/mcp.json`(项目侧 `tools/` 文档内),**不得写入本技能任何文件**。