Files
MediaCrawler/mac-agent-os-main/03_knowledge/99_system/architecture/trigger-matching-analysis.md
T
butubb 2112c1a870
Deploy VitePress site to Pages / build (push) Canceled after 0s
Deploy VitePress site to Pages / Deploy (push) Canceled after 0s
feat(monitor): 抖音 Web 接口客户端 —— 绕开爬虫子进程,直接发 HTTP
移植自 mac-agent-os 的 mediacrawler_adapter:不起子进程、不开页面,用浏览器里那份
登录态直接调抖音 Web 接口。产物键名照抄 store/douyin,所以 ingest 那条链路一个字不用改。

**目前能用的(真环境实测,非推断)**:

    profile/other : 200, 7075 字节  —— 博主主页指标(粉丝/获赞/作品数/昵称)
    aweme/detail  : 200, 45425 字节 —— 单条作品详情(含点赞/评论/收藏/分享)

**目前不能用的:作品列表 `aweme/post`。** 两个互相独立的原因:
  1. 这个接口被抖音单独升级成了真校验:不带 x-tt-argus 回 403「Uifid Not Found」,
     带上 dummy 值回 200 + **空 body**。也就是说「头在不在」骗得过,「真校验」过不了。
     同一套头打 profile/other 和 aweme/detail 都是通的 —— 抖音是挑着接口加保护的,
     挑中的恰好是「批量拉作品列表」这个最敏感的动作。
  2. 改走页面截获也不行:CDP 浏览器打开博主主页会落到「验证码中间页」(当天大量探测的
     代价,过几小时要重测)。

  所以现在的边界是:**已知作品的指标刷新能做,自动发现新作品做不了**。

**排查中控住变量后得到的两条事实**(都写进注释了):
  · `Accept` / `Accept-Language` / `Referer` 才是主页接口能返回真数据的原因 —— 只有
    UA+client hints+Cookie 时是 200 但仅 121 字节的空壳,补上这三个头变 7074 字节。
    (我先前猜的 sec-ch-ua 不是关键。)
  · 因此 UA 与 client hints 必须**成套地取自同一个浏览器**,所以 BrowserIdentity 一次
    从 CDP 取齐 cookie + UA + hints,而不是各自写死。

「200 + 空 body 必须当场报错」也是刻意写死的:放过去它会在下游变成「这个博主没作品」,
把一次失败伪装成一条正常结果 —— 爬虫那条路正是这么栽的,还被翻译成「账号被封」。

测试 +11:cookie 解析、请求头成套性(含 uifid 缺失/回退)、产物键名与 store 对齐、
以及 _get 的三条失败路径(空 body / 403 带网关原话 / 正常返回)。
2026-10-10 17:12:25 +08:00

134 lines
4.6 KiB
Markdown
Raw 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.
# 触发词匹配方案:关键词 vs 语义相似度
> 版本:v1.0 | 最后更新:2026-05-03
---
## 一、现状:关键词匹配
**工作原理**:SOUL.md 中列出触发词列表,检测用户输入中是否包含这些词。
| 类别 | 触发词 |
|------|--------|
| 升维审视 | 升维思考、第一性原理、前提挑战、深层原因、本质是什么、批判地看 |
| 跨域联想 | 跨界视角、换个角度、类比一下、新视角、别的领域、借鉴一下 |
| 知识操作 | 入库、记录这条、保存知识、知识审查 |
### 优点
- **零延迟**:字符串匹配,毫秒级
- **零依赖**:不需要调用任何模型
- **确定性**:100% 可预测,不会误触发
### 缺点
- **漏匹配**:用户说"换个思路"不会触发"换个角度";说"从别的学科看看"不会触发"跨界视角"
- **维护成本**:需要人工维护触发词列表,不断追加变体
- **僵化**:没法处理同义表达
---
## 二、升级方案:语义相似度匹配
**工作原理**:用现有 Qwen3-Embedding-0.6B 模型,把用户消息转为向量,与触发类别种子词的向量计算相似度。
### 架构
```
用户消息: "从这个角度看有点像生物学里的共生关系"
↓
调 Embedding API → 转为 1024 维向量
↓
与各触发类别的种子词向量做余弦相似度
↓
跨域联想类别: 相似度 0.89(阈值 0.8)→ 触发 ✅
升维审视类别: 相似度 0.45 → 不触发 ❌
```
### 种子词设计
| 类别 | 种子词(3-5 个示例,模型自动泛化) |
|------|-----------------------------------|
| 升维审视 | 升维、本质、第一性原理、前提挑战、深层原因 |
| 跨域联想 | 跨界、类比、换个角度、别的领域、借鉴 |
| 知识操作 | 入库、记录、保存、知识审查 |
不需要穷举,Embedding 模型会自动处理近义词。
### 优点
| 维度 | 关键词匹配 | 语义相似度 |
|------|-----------|-----------|
| 覆盖范围 | 仅精确匹配列表中的词 | 自动覆盖同义词、近义表达 |
| 维护成本 | 需手动追加变体 | 种子词固定,无需频繁维护 |
| 灵活性 | 僵化 | 自然 |
### 缺点
| 维度 | 影响 | 评估 |
|------|------|------|
| 延迟 | 每次调用 Embedding API | ~50-100ms,相对 LLM 响应时间(3-30s)可忽略 |
| 依赖 | 需要 oMLX 运行 Embedding 模型 | 各机器需确保 Embedding 模型已加载 |
| 误触发 | 语义相似但不相关的表达可能过阈值 | 可调整阈值(建议 0.8)+ 结合关键词兜底 |
| 实现复杂度 | 需维护种子词向量 + 相似度计算逻辑 | 约 50 行 Python 代码 |
---
## 三、速度影响实测
```
纯关键词匹配: 0ms
+ Embedding API 调用: 50-100ms
LLM 生成响应: 3,000-30,000ms
增加的比例: 约 0.3%-3% → 无感知
```
**结论:对用户体验无影响。**
---
## 四、建议方案:混合匹配
```
收到用户消息
↓
第一步:关键词快速匹配(0ms)
├─ 命中 → 直接触发 ✅(极速)
└─ 未命中 → 进入第二步
↓
第二步:语义相似度计算(50-100ms)
├─ 相似度 ≥ 0.8 → 触发 ✅
└─ 相似度 < 0.8 → 不触发 ❌
```
### 好处
- 常见触发词(用户明确说的)0ms 响应
- 边缘表达也能覆盖(语义泛化)
- 关键词作为第一道防线,减少 Embedding 调用频率
---
## 五、多机同步影响
| 项目 | 影响 | 说明 |
|------|------|------|
| **触发词列表** | ❌ 不需要修改 | 种子词写在 SOUL.md 中,Git 同步即可 |
| **种子词向量** | ⚠️ 需每台机器生成 | 各机器第一次使用时自动计算并缓存 |
| **Embedding 模型** | ✅ 各机器已有 | Qwen3-Embedding-0.6B 已在 oMLX 中加载 |
| **相似度计算代码** | ⚠️ 需写一个轻量脚本 | ~50 行 Python,Git 同步 |
| **向量库** | ❌ 不受影响 | 记忆向量和知识向量不变 |
| **知识库** | ❌ 不受影响 | 知识库内容不变 |
**综合评估**:升级成本很低,无破坏性影响,各机器各自运行 Embedding 模型即可。
---
## 六、最终建议
| 选项 | 做法 | 推荐程度 |
|------|------|---------|
| **A:保持关键词匹配** | 维持现状,手动维护触发词列表 | ⭐ 够用 |
| **B:纯语义相似度** | 完全依赖 Embedding | ⭐⭐ |
| **C:混合模式** | 关键词 + 语义兜底 | ⭐⭐⭐ **推荐** |
**推荐选 C**:关键词负责"快",语义负责"全"。先关键词匹配(0ms),未命中再调 Embedding(50-100ms)。大部分情况下用户会直接说触发词,关键词匹配就够了。