diff --git a/.planning/research/ARCHITECTURE.md b/.planning/research/ARCHITECTURE.md index 8bc16f3..5ee1781 100644 --- a/.planning/research/ARCHITECTURE.md +++ b/.planning/research/ARCHITECTURE.md @@ -1437,3 +1437,499 @@ class ContentSkill: *Architecture research for: Skill-based Workflow Orchestration System* *Original research: 2026-03-13* *Updated for v1.3 Anti-Crawler: 2026-03-18* + +--- + +## v1.6 语义分段架构研究 + +**Milestone:** LLM-based Semantic Segmentation +**Researched:** 2026-03-21 +**Focus:** 使用 LLM 替代基于规则的语义分段,实现智能章节识别和标题生成 + +--- + +### Executive Summary + +本文档研究如何将 LLM 语义分段集成到现有的 SRT 处理架构中。基于对现有代码(`kb_workflow/srt/` 模块和 `SRTProcessor`)的分析,推荐采用 **渐进式迁移模式**,保留现有 RuleBasedSegmenter 作为 fallback,新增 LLMBasedSegmenter 作为主分段器。 + +关键架构决策: +1. **新增 SemanticSegmenter 组件** — 替代/增强现有的 `segmenter.py` +2. **单次 LLM 调用策略** — 完整上下文分析,避免边界拼接问题 +3. **三层降级策略** — LLM 失败 → 响应解析失败 → AI 不可用 → RuleBasedSegmenter +4. **渐进式集成** — 不破坏现有功能,新组件作为可选增强 + +--- + +### Current Architecture (v1.5) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ SRTProcessor │ +│ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │ +│ │ parser.py │→ │segmenter.py │→ │corrector.py │ │ +│ │ (SRT解析) │ │ (规则分段) │ │ (ASR纠错) │ │ +│ └─────────────┘ └──────────────┘ └─────────────┘ │ +│ │ │ │ │ +│ ↓ ↓ ↓ │ +│ List[Segment] List[str] List[str] │ +│ (时间戳+文本) (段落) (纠错后) │ +└─────────────────────────────────────────────────────────────┘ +``` + +**现有组件:** +- `parser.py`: 解析 SRT → Segment(id, start_time, end_time, text) +- `segmenter.py`: SemanticSegmenter (基于时间间隔3s + 长度500字符规则) +- `corrector.py`: ASRCorrector (使用 SimpleAIClient 纠错) + +--- + +### Recommended Architecture (v1.6) + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ SRTProcessor │ +│ ┌─────────────┐ │ +│ │ parser.py │ │ +│ │ (SRT解析) │ │ +│ └──────┬──────┘ │ +│ │ │ +│ ↓ List[Segment] (id, start_time, end_time, text) │ +│ ┌──────────────────────────────────────────────────────────┐ │ +│ │ semantic_segmenter.py (NEW) │ │ +│ │ ┌────────────────────────────────────────────────────┐ │ │ +│ │ │ 1. 构建 Prompt (视频信息 + 字幕内容) │ │ │ +│ │ └──────────────────┬─────────────────────────────────┘ │ │ +│ │ ↓ │ │ +│ │ ┌────────────────────────────────────────────────────┐ │ │ +│ │ │ 2. 调用 LLM (SimpleAIClient.generate) │ │ │ +│ │ └──────────────────┬─────────────────────────────────┘ │ │ +│ │ ↓ │ │ +│ │ ┌────────────────────────────────────────────────────┐ │ │ +│ │ │ 3. 解析响应 (## 标题 + 内容) │ │ │ +│ │ └──────────────────┬─────────────────────────────────┘ │ │ +│ │ ↓ │ │ +│ │ ┌────────────────────────────────────────────────────┐ │ │ +│ │ │ 4. 返回 List[SemanticParagraph] │ │ │ +│ │ │ - title: str (章节标题) │ │ │ +│ │ │ - content: str (段落内容) │ │ │ +│ │ │ - time_range: (start, end) (可选) │ │ │ +│ │ └──────────────────┬─────────────────────────────────┘ │ │ +│ └─────────────────────┼─────────────────────────────────────┘ │ +│ ↓ │ +│ List[SemanticParagraph] │ +│ (标题 + 结构化内容) │ +│ ↓ │ +│ ┌──────────────────────────────────────────────────────────┐ │ +│ │ Fallback Strategy │ │ +│ │ LLM 失败 → 响应解析失败 → AI 不可用 │ │ +│ │ ↓ │ │ +│ │ segmenter.py (RuleBasedSegmenter) - 保留作为 fallback │ │ +│ └────────────────────┬─────────────────────────────────────┘ │ +│ ↓ │ +│ List[str] (向后兼容) │ +│ ↓ │ +│ ┌─────────────┐ ┌──────────────┐ │ +│ │corrector.py │ │ Markdown生成 │ │ +│ │ (ASR纠错) │ │ (标题+内容) │ │ +│ └─────────────┘ └──────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +### Component Boundaries + +| Component | Responsibility | Communicates With | +|-----------|---------------|-------------------| +| **parser.py** | 解析 SRT 格式 → Segment 对象 | 无(输入层) | +| **semantic_segmenter.py** (NEW) | LLM 语义分析 → 结构化段落 | parser (输入), corrector (输出), SimpleAIClient | +| **segmenter.py** (EXIST) | 基于规则的分段(fallback) | semantic_segmenter (降级) | +| **corrector.py** | ASR 纠错 | semantic_segmenter (输入), SimpleAIClient | +| **SRTProcessor** | 编排处理流程 | 所有模块 | + +--- + +### Data Flow Changes + +**旧流程 (v1.5):** +``` +SRT File → parser.parse_srt_file() → List[Segment] + ↓ +segmenter.segment() (基于规则) + ↓ +List[str] (段落) + ↓ +corrector.correct() (逐段落纠错) + ↓ +生成 Markdown +``` + +**新流程 (v1.6):** +``` +SRT File → parser.parse_srt_file() → List[Segment] + ↓ +[NEW] semantic_segmenter.segment() + ├─ 构建 Prompt (视频信息 + 字幕文本) + ├─ 调用 LLM (SimpleAIClient) + ├─ 解析响应 (## 标题 + 内容) + └─ 返回 List[SemanticParagraph] + ├─ title: str + ├─ content: str + └─ time_range: (float, float) (可选) + ↓ +[FALLBACK] segmenter.segment() (LLM 失败时) + ↓ +List[SemanticParagraph] → flatten → List[str] + ↓ +corrector.correct() (逐段落纠错) + ↓ +生成 Markdown (标题 + 内容结构) +``` + +--- + +### Response Parsing Strategy + +**LLM 响应格式要求:** +``` +## 第一部分:机器学习基础概念 +段落内容1... +段落内容2... + +## 第二部分:深度学习原理 +段落内容3... +段落内容4... +``` + +**解析方法:** +```python +@dataclass +class SemanticParagraph: + """语义分段结果""" + title: str # 章节标题 + content: str # 段落内容 + start_time: float # 开始时间(可选) + end_time: float # 结束时间(可选) + +def parse_llm_response(response: str) -> List[SemanticParagraph]: + """解析 LLM 响应为结构化段落""" + paragraphs = [] + current_title = "无标题" + current_content = [] + + for line in response.split('\n'): + if line.startswith('##'): + # 保存上一个段落 + if current_content: + content = '\n'.join(current_content).strip() + if content: + paragraphs.append(SemanticParagraph( + title=current_title, + content=content + )) + # 开始新段落 + current_title = line.lstrip('#').strip() + current_content = [] + else: + current_content.append(line) + + # 保存最后一个段落 + if current_content: + content = '\n'.join(current_content).strip() + if content: + paragraphs.append(SemanticParagraph( + title=current_title, + content=content + )) + + return paragraphs +``` + +--- + +### LLM Call Strategy + +**推荐:单次调用** + +**原因:** +1. **上下文完整性** — LLM 理解完整视频内容,分段更准确 +2. **避免边界问题** — 多次调用的拼接处容易出现语义不连贯 +3. **简化实现** — 单次调用更容易测试和调试 + +**Prompt 设计:** +```python +SEGMENTATION_PROMPT = """你是一个视频内容分析师。请将以下字幕内容按语义分段,并为每个段落生成标题。 + +【视频信息】 +标题:{video_title} +时长:{duration} + +【字幕内容】 +{concatenated_segments} + +【输出要求】 +1. 按语义完整性分段(保持话题/论点完整) +2. 识别主题变化边界 +3. 为每个段落生成简洁标题(不超过20字) +4. 输出格式: + +## 第一部分:{标题} +{段落内容} + +## 第二部分:{标题} +{段落内容} + +...(以此类推) + +注意: +- 段落长度建议 200-800 字符 +- 在自然句号处分段 +- 标题要概括该段核心内容 +""" +``` + +**输入处理选项:** + +**选项 1: 纯文本(推荐)** +```python +# 合并所有 Segment.text +full_text = '\n'.join(seg.text for seg in segments) +``` + +**选项 2: 带时间戳标记(可选,用于辅助理解)** +```python +# 添加时间戳辅助 LLM 理解结构 +marked_text = '\n'.join( + f"[{format_time(seg.start_time)}] {seg.text}" + for seg in segments +) +``` + +**替代方案:流式调用** +- 用于超长视频(>1小时字幕) +- 分块调用 LLM,每块 10-15 分钟字幕 +- 需要额外的边界拼接逻辑 +- **建议:** 初期使用单次调用,后续根据实际需求优化 + +--- + +### Fallback Strategy + +**三层降级策略:** + +```python +class LLMBasedSegmenter: + def __init__(self, ai_client: SimpleAIClient): + self.ai_client = ai_client + self.rule_based = SemanticSegmenter() # Fallback + + def segment(self, segments: List[Segment]) -> List[SemanticParagraph]: + # Level 3: AI 客户端不可用 + if not self.ai_client or not self.ai_client.api_key: + logger.info("AI client not available, using rule-based") + return self._to_semantic_paragraphs( + self.rule_based.segment(segments) + ) + + try: + # Level 1: LLM 调用 + prompt = self._build_prompt(segments) + response = self.ai_client.generate(prompt) + + # Level 2: 响应解析 + try: + paragraphs = self._parse_llm_response(response) + if not paragraphs: + raise ValueError("Empty parsed result") + return paragraphs + except Exception as e: + logger.warning(f"Failed to parse LLM response: {e}") + return self._to_semantic_paragraphs( + self.rule_based.segment(segments) + ) + + except Exception as e: + logger.warning(f"LLM call failed: {e}, using rule-based") + return self._to_semantic_paragraphs( + self.rule_based.segment(segments) + ) +``` + +--- + +### Suggested Build Order + +**Phase 1: 基础组件(不影响现有功能)** +1. 创建 `kb_workflow/srt/semantic_segmenter.py` +2. 实现 `SemanticParagraph` 数据类 +3. 实现 `parse_llm_response()` 方法(独立于 LLM 调用) +4. 编写单元测试(mock LLM 响应,测试解析逻辑) + +**Phase 2: LLM 集成** +5. 实现 `_build_prompt()` 方法 +6. 集成 SimpleAIClient +7. 实现 `segment()` 主方法 +8. 实现降级策略(fallback) +9. 编写集成测试(使用真实 LLM 或 mock) + +**Phase 3: 处理器集成** +10. 修改 `SRTProcessor.__init__()`: + - 添加 `use_llm_segmenter: bool = False` 参数 + - 条件性初始化 `llm_segmenter` +11. 修改 `SRTProcessor.process()`: + - 调用新分段器或保留旧分段器 + - 处理 `SemanticParagraph` 输出 +12. 更新 `_generate_markdown()`: + - 处理标题和内容结构 + - 生成带层级的 Markdown +13. 保留 RuleBasedSegmenter 作为 fallback + +**Phase 4: 输出优化** +14. 优化 Markdown 格式(标题层级 `###`) +15. 添加时间戳(可选,在段落中标注时间范围) +16. 更新文档和测试 + +--- + +### Schema Changes + +**新增数据类:** +```python +@dataclass +class SemanticParagraph: + """语义分段结果""" + title: str # 章节标题 + content: str # 段落内容 + start_time: Optional[float] = None # 开始时间(可选) + end_time: Optional[float] = None # 结束时间(可选) +``` + +**修改 SRTOutput (向后兼容):** +```python +class SRTOutput(BaseModel): + success: bool + output_file: str + paragraphs: List[str] # 保留向后兼容 + semantic_paragraphs: Optional[List[SemanticParagraph]] = None # 新增 + tags: List[str] + corrected: bool +``` + +--- + +### Patterns to Follow + +#### Pattern 1: 渐进式迁移 +**What:** 保留现有组件,新组件作为可选增强 +**When:** 重构关键路径时 +**Example:** +```python +class SRTProcessor: + def __init__(self, use_llm_segmenter: bool = False): + self.rule_based_segmenter = SemanticSegmenter() # 保留 + if use_llm_segmenter: + self.llm_segmenter = LLMBasedSegmenter() # 新增 + + async def process(self, input_data): + # 优先使用 LLM,失败时降级 + if hasattr(self, 'llm_segmenter'): + try: + paragraphs = self.llm_segmenter.segment(segments) + except Exception: + paragraphs = self.rule_based_segmenter.segment(segments) + else: + paragraphs = self.rule_based_segmenter.segment(segments) +``` + +#### Pattern 2: 协议兼容性 +**What:** 新旧组件共享相同接口 +**When:** 替换组件时 +**Example:** +```python +# 两个分段器实现相同接口 +class Segmenter(Protocol): + def segment(self, segments: List[Segment]) -> List[str]: + ... + +class RuleBasedSegmenter: + def segment(self, segments: List[Segment]) -> List[str]: + # 基于规则 + ... + +class LLMBasedSegmenter: + def segment(self, segments: List[Segment]) -> List[str]: + # 基于 LLM + # 内部使用 SemanticParagraph,输出时合并标题和内容 + return [ + f"## {p.title}\n\n{p.content}" + for p in self._segment_internal(segments) + ] +``` + +--- + +### Anti-Patterns to Avoid + +#### Anti-Pattern 1: 破坏性替换 +**What:** 直接删除 RuleBasedSegmenter +**Why bad:** LLM 可能失败,失去降级选项 +**Instead:** 保留旧组件作为 fallback + +#### Anti-Pattern 2: 紧耦合 Prompt 逻辑 +**What:** 将 prompt 构建硬编码在 segmenter 中 +**Why bad:** 难以测试和优化 +**Instead:** 提取为独立方法或模板,便于测试 + +#### Anti-Pattern 3: 忽略时间戳信息 +**What:** 仅传递文本给 LLM,忽略时间信息 +**Why bad:** LLM 无法理解视频结构(停顿、章节) +**Instead:** 在 prompt 中包含时间戳标记或视频时长信息 + +--- + +### Scalability Considerations + +| Concern | At 100 videos | At 10K videos | At 1M videos | +|---------|--------------|--------------|-------------| +| **LLM 调用延迟** | 可接受(~10-30s/视频) | 需要并发处理 | 需要队列+批处理 | +| **LLM 成本** | 可忽略 | 需要监控 | 需要缓存+降级策略 | +| **错误率** | 低,手动处理 | 需要自动重试 | 需要监控告警 | +| **响应解析** | 简单 | 需要容错增强 | 需要多模型支持 | + +**建议:** +- 初期:单线程处理,完整错误日志 +- 中期:添加并发处理(asyncio.Semaphore 限制并发数) +- 长期:分布式队列(Celery/RQ)+ 结果缓存 + +--- + +### Integration Points Summary + +**新增集成点:** +1. `SRTProcessor.__init__()` → 条件性初始化 `LLMBasedSegmenter` +2. `SRTProcessor.process()` → 调用新分段器或旧分段器 +3. `_generate_markdown()` → 处理 `SemanticParagraph` 结构 + +**保留集成点:** +1. `parser.parse_srt_file()` — 不变 +2. `corrector.correct()` — 不变(处理 `List[str]`) +3. `WorkflowStateManager` — 不变 + +**修改点:** +1. `kb_workflow/srt/__init__.py` — 导出 `SemanticParagraph` +2. `kb_workflow/pipeline/schemas.py` — 更新 `SRTOutput` + +--- + +### v1.6 Sources + +- 现有架构分析: `kb_workflow/srt/` 模块 +- SRTProcessor 实现: `kb_workflow/pipeline/processors/srt.py` +- SimpleAIClient 实现: `kb_workflow/deep_analyzer/__init__.py` +- 测试用例: `tests/test_srt_processor.py` +- 项目上下文: `.planning/PROJECT.md` + +--- + +*Architecture research for: LLM-based Semantic Segmentation* +*Research date: 2026-03-21* diff --git a/.planning/research/FEATURES.md b/.planning/research/FEATURES.md index fc7d2fa..9c59a16 100644 --- a/.planning/research/FEATURES.md +++ b/.planning/research/FEATURES.md @@ -1,421 +1,233 @@ -# Feature Research +# Feature Landscape: LLM Semantic Segmentation for Video Subtitles -**Domain:** Skill-based Workflow Orchestration (Content Processing Pipelines) -**Researched:** 2026-03-13 (Updated: 2026-03-18 for v1.3 Anti-Crawler) -**Confidence:** HIGH (v1.0-1.2) / MEDIUM (v1.3 Anti-Crawler - 基于社区实践) +**Domain:** LLM-based semantic segmentation for video subtitle processing +**Researched:** 2026-03-21 +**Overall confidence:** MEDIUM ---- +## Table Stakes -## v1.3 Milestone: Anti-Crawler Optimization Features - -**Focus:** 增强爬虫反检测能力,降低被封风险,提升爬取稳定性 - ---- - -### Table Stakes (Users Expect These) - -反爬虫优化中用户默认应该有的功能,缺失会让产品感觉不完整。 +Features users expect in LLM-based subtitle segmentation. Missing = product feels incomplete or "dumb." | Feature | Why Expected | Complexity | Notes | |---------|--------------|------------|-------| -| **代理 IP 轮换** | 防止单 IP 被封,是反爬虫基础 | MEDIUM | 当前已有基础代理支持,需扩展为池化管理 | -| **请求延迟** | 避免触发频率限制 | LOW | 当前已实现随机延迟 (1-3s),可优化范围 | -| **自动重试** | 网络波动时保证稳定性 | LOW | 当前已用 tenacity 实现指数退避重试 | -| **错误码识别** | 根据响应状态调整行为 | MEDIUM | 需区分临时错误 vs 永久错误 vs 封禁 | +| **视频类型识别** | 不同类型视频需要不同分段策略 | Medium | 识别知识类、故事类、访谈类、新闻类、vlog等基本类型 | +| **主题边界检测** | 用户期望在话题转换处分段 | High | 基于语义相似度变化检测话题转换点 | +| **内容完整性保护** | 避免在句子或论点中间截断 | High | 确保分段不破坏语义完整性 | +| **自然句边界检测** | 中文字幕需要智能断句 | Medium | 中文没有明确句号,需要语义判断 | +| **主题标题生成** | 每个分段需要描述性标题 | Medium | 为分段生成简洁、准确的主题标题 | +| **基本分段策略** | 区别于简单的时间+长度规则 | Medium | 至少提供2-3种基于语义的分段策略 | -### Differentiators (Competitive Advantage) +## Differentiators -能让 kb-skills 脱颖而出的功能。不是必须的,但有价值。 +Features that set product apart. Not expected, but valued. | Feature | Value Proposition | Complexity | Notes | |---------|-------------------|------------|-------| -| **智能代理轮换** | 根据代理健康度、响应时间动态选择 | HIGH | 比简单轮询更有效,降低失败率 | -| **请求行为伪装** | 模拟人类浏览模式 | MEDIUM | 随机化 User-Agent、请求顺序、停留时间 | -| **验证码检测与告警** | 遇到验证码时暂停并通知,而非静默失败 | MEDIUM | 个人使用场景:检测后暂停等待手动处理 | -| **平台特定适配** | 针对知乎/B站的不同反爬策略 | MEDIUM | 知乎 x-zse-96 签名 vs B站 WBI 签名 | -| **断点续传增强** | 记录失败原因,智能恢复 | MEDIUM | 区分"需要换 IP" vs "需要换策略" | +| **分层主题结构** | 支持多级主题层次(章-节) | High | 类似书籍目录的层级结构,适用于长视频 | +| **时间戳对齐** | 分段边界与原字幕时间对齐 | Medium | 保持与原始视频的可导航性 | +| **分段质量评分** | 给出分段质量的可信度 | Medium | 帮助用户判断何时需要人工调整 | +| **说话人识别集成** | 结合说话人变化优化分段 | High | 访谈、对话类视频的重要信号 | +| **可配置分段粒度** | 用户可控制分段密度 | Low | 粗粒度(章节)vs 细粒度(话题) | +| **分段合并建议** | 检测过短分段并建议合并 | Medium | 避免碎片化分段 | +| **主题连贯性分析** | 评估分段的内部一致性 | High | 确保单个分段内语义相关 | +| **多模态融合** | 结合视频场景变化辅助分段 | Very High | 需要视频帧分析,超出纯文本范围 | -### Anti-Features (Commonly Requested, Often Problematic) +## Anti-Features -看似好但会带来问题的功能。 +Features to explicitly NOT build. -| Feature | Why Requested | Why Problematic | Alternative | -|---------|---------------|-----------------|-------------| -| **自动验证码破解** | 无人值守运行 | 1) 需要付费打码服务 2) 违反网站 ToS 3) 增加法律风险 | 检测后暂停,用户手动处理 | -| **高并发爬取** | 提高效率 | 1) 更容易触发封禁 2) 增加被检测风险 3) 违背"个人知识库"定位 | 顺序执行 + 合理延迟 | -| **复杂指纹伪装** | 绕过高级检测 | 1) 实现复杂 2) 维护成本高 3) 对当前目标网站不必要 | 基础 User-Agent 轮换足够 | -| **SOCKS5 代理池** | 更高匿名性 | 1) 住宅代理更有效 2) 当前场景不需要 3) 增加配置复杂度 | HTTP/HTTPS 代理足够 | +| Anti-Feature | Why Avoid | What to Do Instead | +|--------------|-----------|-------------------| +| **固定大小分段** | 违背语义分段初衷,破坏内容完整性 | 使用语义边界检测 | +| **纯关键词匹配** | 过于简单,无法理解上下文和语义 | 使用嵌入向量和语义相似度 | +| **实时流式分段** | 需要全局上下文才能做出好的分段决策 | 批处理模式,分析完整内容 | +| **多语言混合处理** | 中英文混合分段逻辑复杂,降低质量 | 先分离语言,分别处理 | +| **完全自动化无人工审核** | LLM可能误判边界,需要人工验证 | 提供预览和手动调整界面 | +| **过度细分段** | 产生过多碎片化分段,降低可读性 | 设置最小分段长度和主题阈值 | ---- - -## Platform-Specific Anti-Crawler Measures - -### 知乎 (Zhihu) 反爬策略 - -| 检测类型 | 描述 | 应对策略 | -|---------|------|---------| -| **x-zse-96 签名** | API 请求需要动态签名 | Playwright 自动处理 (当前已实现) | -| **Cookie 验证** | 需要登录态 | 二维码扫码登录 (当前已实现) | -| **请求频率限制** | 单 IP 高频请求触发限制 | 代理轮换 + 随机延迟 | -| **验证码触发** | 异常行为弹出验证码 | 检测 + 暂停 + 告警 | - -**知乎特征响应:** -- 401: Cookie 过期 -- 403: 被限制访问 -- 验证码页面: HTML 包含 "验证" 或特定元素 - -### B站 (Bilibili) 反爬策略 - -| 检测类型 | 描述 | 应对策略 | -|---------|------|---------| -| **WBI 签名** | Web API 需要 w_rid + wts 参数 | 实现签名算法或使用 Playwright | -| **Referer 校验** | 需要 `https://www.bilibili.com/` | 设置正确 Referer 头 | -| **请求频率限制** | 建议 <60 次/分钟/IP | 代理轮换 + 限流 | -| **352 风控** | 异常请求拦截机制 | 监控错误码,调整行为 | - -**B站特征响应:** -- -799: 请求过于频繁 -- -400: 请求错误 -- -352: 风控拦截 - ---- - -## v1.3 Feature Dependencies +## Feature Dependencies ``` -代理 IP 轮换 - └──requires──> 代理池配置 (PROXY_POOL 环境变量或配置文件) - └──enhances──> 错误恢复机制 (根据错误类型决定是否换 IP) +视频类型识别 → 分段策略选择 (类型识别决定使用哪种分段策略) +视频类型识别 → 主题边界检测阈值 (不同类型使用不同的边界敏感度) -验证码检测 - └──requires──> 响应内容分析 (HTML/JSON 解析) - └──triggers──> 用户告警系统 (当前可用日志/控制台输出) +自然句边界检测 → 内容完整性保护 (先确定句边界,再保护完整性) +主题边界检测 → 内容完整性保护 (边界不能破坏句完整性和论点完整性) -平台特定适配 - └──requires──> 平台识别逻辑 (URL 解析) - └──requires──> 平台签名算法 (知乎 x-zse-96 / B站 WBI) +主题边界检测 → 主题标题生成 (先确定边界,再为每段生成标题) -错误恢复机制 - └──requires──> 错误分类 (临时/永久/封禁) - └──requires──> 重试策略配置 (指数退避参数) - └──conflicts──> 快速失败模式 (某些场景需要立即报错) - -请求行为伪装 - └──enhances──> 代理 IP 轮换 (完整伪装链) - └──enhances──> 验证码规避 (减少触发概率) +分段策略选择 → 主题边界检测 (不同策略使用不同的边界检测算法) ``` -### Dependency Notes +## MVP Recommendation for v1.6 -- **代理 IP 轮换 requires 代理池配置:** 需要支持多种配置方式 (环境变量、配置文件、API 获取) -- **验证码检测 requires 响应内容分析:** 需要解析 HTML/JSON 识别验证码页面特征 -- **平台特定适配 requires 平台签名算法:** 知乎 x-zse-96 已通过 Playwright 自动处理;B站 WBI 需要实现签名算法 -- **错误恢复机制 conflicts 快速失败模式:** 可通过配置选择模式,默认使用重试 +**Prioritize (MUST-have):** +1. **视频类型识别** - 基础功能,决定后续策略 +2. **自然句边界检测** - 中文断句,保护内容完整性 +3. **主题边界检测** - 核心功能,实现语义分段 +4. **内容完整性保护** - 质量保证,避免破坏语义 +5. **主题标题生成** - 用户体验,提供可导航性 +6. **基本分段策略** - 至少2种策略(知识类、故事类) ---- +**Defer to v2.0:** +- **分层主题结构** - 需要更复杂的算法和更多测试 +- **说话人识别集成** - 需要额外的说话人分离模块 +- **分段质量评分** - 优化功能,不影响核心价值 +- **时间戳对齐** - 优化功能,v1.6可以简化处理 -## v1.3 MVP Definition +**Avoid:** +- 固定大小分段、纯关键词匹配、实时流式处理 -### Launch With (v1.3 MVP) +## Technical Implementation Insights -最低可行产品 - 验证反爬虫优化核心价值。 +### 视频类型识别方法 -- [ ] **代理池管理** — 支持配置多个代理,轮换使用 — 核心反封能力 -- [ ] **随机延迟优化** — 扩展延迟范围 (1-10s),增加随机性 — 低成本高效 -- [ ] **错误分类与智能重试** — 区分临时错误/永久错误/封禁 — 避免无效重试 -- [ ] **验证码检测** — 检测验证码页面并暂停 — 避免静默失败 +基于2025年研究,视频内容类型分类主要方法: -### Add After Validation (v1.x) +1. **基于文本特征** - 分析标题、描述、字幕文本 + - 知识类:教程、课程、讲解性内容 + - 故事类:叙事结构、时间线、情节发展 + - 访谈类:对话交替、问答模式 + - 新闻类:事件报道、时间地点、事实陈述 + - Vlog:个人经历、主观感受、日常记录 -核心功能验证后添加的增强功能。 +2. **LLM分类方法** - 使用few-shot prompting分类 + - 提供各类别的示例 + - 让LLM分析内容特征 + - 输出类别和置信度 -- [ ] **代理健康检查** — 检测代理可用性,自动剔除失效代理 — 当发现代理失败率高时 -- [ ] **B站 WBI 签名** — 支持 B站 API 签名 — 当需要直接调用 B站 API 时 -- [ ] **请求行为伪装增强** — User-Agent 轮换、请求头随机化 — 当基础策略不够用时 +### 主题边界检测策略 -### Future Consideration (v2+) +基于2025年研究前沿: -推迟到产品稳定后的功能。 +1. **语义相似度方法** + - 使用嵌入向量计算段落间相似度 + - 相似度骤降点 = 潜在边界 + - 适用于:知识类、故事类 -- [ ] **智能代理选择** — 根据历史成功率加权选择 — 需要足够的运行数据 -- [ ] **自动验证码告警** — 桌面通知/邮件通知 — 当需要无人值守时 -- [ ] **分布式代理池** — 支持从 API 获取代理列表 — 需要代理服务订阅 +2. **词频变化检测** + - 检测sharp word-frequency dips + - 词汇分布变化 = 话题转换 + - 适用于:新闻类、访谈类 ---- +3. **LLM零样本边界检测** + - 直接让LLM识别话题转换点 + - 提供上下文窗口 + - 输出边界位置和理由 -## v1.3 Feature Prioritization Matrix +4. **强化学习方法** (BoundRL, 2025) + - 训练模型学习边界模式 + - 需要标注数据 + - 可能超出v1.6范围 -| Feature | User Value | Implementation Cost | Priority | -|---------|------------|---------------------|----------| -| 代理池管理 | HIGH | MEDIUM | P1 | -| 随机延迟优化 | HIGH | LOW | P1 | -| 错误分类与智能重试 | HIGH | MEDIUM | P1 | -| 验证码检测 | MEDIUM | LOW | P1 | -| 代理健康检查 | MEDIUM | MEDIUM | P2 | -| User-Agent 轮换 | MEDIUM | LOW | P2 | -| B站 WBI 签名 | LOW* | MEDIUM | P2 | -| 智能代理选择 | LOW | HIGH | P3 | +### 中文句边界检测 -*注:B站 WBI 签名优先级取决于是否需要直接调用 API(当前 Playwright 方案可能已足够) +2025年研究方向: -**Priority key:** -- P1: Must have for v1.3 -- P2: Should have, add when possible -- P3: Nice to have, future consideration +1. **边界增强解码器** (Boundary-Enhanced Decoder) + - 专门针对中文分词和断句 + - 神经注意力机制 ---- +2. **多任务学习方法** + - 联合学习分词和断句 + - 提高边界识别准确性 -## Implementation Complexity Notes +3. **实践方法** (适合v1.6) + - 使用标点符号(句号、问号、感叹号) + - 语义停顿检测(基于短语结构) + - LLM辅助断句(对歧义情况) -### 代理池管理 (MEDIUM) -- **配置方式**: 环境变量 `PROXY_POOL` (逗号分隔) 或配置文件 -- **轮换策略**: Round-robin (简单) vs 加权 (复杂) -- **集成点**: 修改 `CrawlerConfig` 支持代理列表 +### 内容完整性保护 -### 验证码检测 (LOW-MEDIUM) -- **知乎检测**: 检查响应中是否包含 "验证" 或验证码元素 -- **通用检测**: 检查 HTTP 状态码 + 响应内容特征 -- **处理方式**: 抛出特定异常,触发暂停和告警 +基于2025年研究: -### 错误分类 (MEDIUM) -- **临时错误**: 网络超时、5xx 服务器错误 → 重试 -- **永久错误**: 404、权限不足 → 失败不重试 -- **封禁错误**: 403、验证码 → 换 IP/暂停 +1. **语义连贯性评估** + - 确保分段内语义一致 + - 避免在论点中间截断 -### 请求行为伪装 (LOW) -- **User-Agent 池**: 预定义常见 UA 列表 -- **请求头随机化**: Accept-Language, Accept-Encoding 顺序随机 -- **会话行为**: 模拟页面停留、滚动 (Playwright 层面) +2. **修辞结构理论** (RST) + - 识别文本的修辞关系 + - 保持修辞结构的完整性 ---- +3. **实践策略** (v1.6可实现) + - 不在句子中间分段 + - 识别并保护论证结构(前提-结论) + - 检测并列结构(首先、其次、最后) -## v1.3 Competitor Feature Analysis +### 主题标题生成 -| Feature | Scrapy | Requests + tenacity | Our Approach | -|---------|--------|---------------------|--------------| -| 代理轮换 | 中间件支持 | 手动实现 | 配置驱动的池管理 | -| 重试机制 | 内置 | tenacity 库 | tenacity (已集成) | -| 限流 | AutoThrottle 扩展 | 手动 | 配置化延迟范围 | -| 验证码 | 需插件 | 无 | 检测 + 暂停告警 | +2025年方法: ---- +1. **LLM摘要式标题** + - 让LLM生成分段的简短摘要 + - 限制长度(如10-15字) + +2. **关键词提取** + - 提取分段的关键词 + - 组合成描述性标题 -## v1.0-1.2 Baseline Features (Preserved) +3. **两阶段方法** + - 第一阶段:检测边界 + - 第二阶段:为每段生成标题 -### Table Stakes (Users Expect These) +## Complexity Breakdown -Features users assume exist. Missing these = product feels incomplete. +| Complexity Level | Features | Rationale | +|------------------|----------|-----------| +| **Low** | 可配置分段粒度 | UI/配置项,不涉及核心算法 | +| **Medium** | 视频类型识别、自然句边界检测、主题标题生成、时间戳对齐、分段合并建议 | 有成熟方法,可直接应用LLM | +| **High** | 主题边界检测、内容完整性保护、分层主题结构、分段质量评分、说话人识别集成 | 需要复杂算法或多阶段处理 | +| **Very High** | 多模态融合、主题连贯性分析 | 需要额外模块或大量计算资源 | -| Feature | Why Expected | Complexity | Notes | -|---------|--------------|------------|-------| -| **Pipeline/Sequential Orchestration** | Linear processing is the fundamental model - users expect steps to execute in order | LOW | Already in PROJECT.md as core requirement | -| **Idempotent Execution** | Re-running same input should produce same output without duplicates | MEDIUM | Critical for reliability; prevents duplicate files on retry | -| **Checkpoint/Resume from Failure** | Long-running tasks can fail; users expect to continue from where they left off | MEDIUM | workflow_state.json is planned; checkpointing is industry standard | -| **State Management** | Every pipeline needs to track progress - what's done, what's pending | MEDIUM | Step-level state (not task-level) per PROJECT.md | -| **Structured Error Handling** | Failures should be captured, reported, and recoverable | LOW | JSON error format with success/error fields already exists | -| **Input/Output Schema Validation** | Data contracts ensure reliability; JSON Schema is standard | MEDIUM | PIPE-07 in requirements | -| **Clear Step Boundaries** | Users need to understand what each step does, its inputs/outputs | LOW | PIPE-06 requirement | -| **Platform-Specific Content Handlers** | Bilibili/Zhihu support is core functionality | MEDIUM | Already implemented for metadata/content extraction | -| **AI-Powered Analysis** | Deep analysis is the product's value proposition | HIGH | kb-deep-analyzer exists | +## Video Type-Specific Strategies -### Differentiators (Competitive Advantage) +### 知识类视频 +- **分段依据**: 主题/知识点变化 +- **边界信号**: "接下来"、"其次"、"另外"等过渡词 +- **标题风格**: 描述性,反映知识点 +- **分段长度**: 中等(2-5分钟) + +### 故事类视频 +- **分段依据**: 情节发展、场景变化 +- **边界信号**: 时间转换、地点变化、人物变化 +- **标题风格**: 叙事性,反映情节发展 +- **分段长度**: 较长(5-10分钟) -Features that set the product apart. Not required, but valuable. +### 访谈类视频 +- **分段依据**: 问题/话题转换 +- **边界信号**: 主持人提问、话题切换 +- **标题风格**: 问答式,反映讨论主题 +- **分段长度**: 中等(3-6分钟) + +### 新闻类视频 +- **分段依据**: 新闻条目 +- **边界信号**: "接下来是"、"据报道" +- **标题风格**: 信息性,反映新闻事件 +- **分段长度**: 较短(1-3分钟) -| Feature | Value Proposition | Complexity | Notes | -|---------|-------------------|------------|-------| -| **Skill-Based Modular Architecture** | Each skill is independent, testable, and reusable; easier maintenance than monolithic pipelines | MEDIUM | SKILL.md specification pattern; already in architecture | -| **Multi-Modal Content Processing** | Video (ASR/OCR) + Text unified pipeline; handles diverse content types in one flow | HIGH | Whisper, FunASR, OCR already implemented | -| **Tmux-Based Session Persistence** | Long-running operations survive terminal disconnect; GSD-OpenClaw integration | MEDIUM | Unique to this system; TmuxSessionManager exists | -| **Declarative Skill Definition** | SKILL.md with YAML frontmatter defines capabilities; AI agents can discover and execute | LOW | Already in place; differentiates from code-only orchestration | -| **Unified JSON Output Format** | Consistent success/error structure across all skills; easy programmatic consumption | LOW | Already standardized | -| **Git-Integrated Archival** | Processed content versioned and archived automatically | LOW | KB_GIT_ROOT integration | -| **Content Type Detection** | Auto-detect video vs article vs QA; route to appropriate processing path | MEDIUM | Link parser handles this | - -### Anti-Features (Commonly Requested, Often Problematic) - -Features that seem good but create problems. - -| Feature | Why Requested | Why Problematic | Alternative | -|---------|---------------|-----------------|-------------| -| **Real-Time/Streaming Processing** | Users want instant results | Adds significant complexity; batch processing sufficient for content analysis use case; real-time requires different architecture (WebSocket, event streams) | Keep batch processing; add optional polling/notifications | -| **Concurrent/Parallel Agent Execution** | Faster processing | Context sharing between parallel agents is complex; resource contention (API rate limits, model quotas); conflict resolution when results contradict | Sequential orchestration with clear dependencies is more reliable for this use case | -| **Web UI/Dashboard** | Visual workflow management | Significant development effort; CLI is sufficient for current use case; UI maintenance overhead | CLI-first; consider status output in structured formats for future visualization | -| **Multi-Tenant/User Management** | SaaS-like deployment | Adds auth, isolation, billing complexity; single-user tool currently | Keep single-tenant; future: separate deployment per user | -| **Plugin/Extension System** | Third-party integrations | Security concerns; API stability requirements; documentation burden | Keep monolithic but modular skill architecture; internal extensions only | -| **Workflow Visualization** | See pipeline graphically | Nice-to-have but not core value; generates maintenance burden | State file (JSON) is machine-readable; can generate viz later | -| **Automatic Retry with Backoff** | Handle transient failures | Can mask underlying issues; retry logic is complex; may cause rate limiting | Explicit error reporting; manual retry with checkpoint resume | - ---- - -## v1.0-1.2 Feature Dependencies - -``` -[URL Input] - └──requires──> [Link Parser Skill] - -[Link Parser] - └──enables──> [Platform-Specific Metadata Extraction] - -[Metadata Extraction] - └──enables──> [Content Download] - -[Content Download (Video)] - └──requires──> [ASR/Transcription] - └──requires──> [Whisper OR FunASR] - -[Content Download (Video with Text)] - └──requires──> [OCR Processing] - -[ASR/OCR/Text Content] - └──enables──> [Deep Analysis] - -[Deep Analysis] - └──enables──> [Archive to Git] - -[State Management] - └──enables──> [Checkpoint Resume] - └──enables──> [Idempotent Execution] - -[Schema Validation] - └──enables──> [Error Detection] - └──enables──> [Consistent Output Format] -``` - -### Dependency Notes - -- **Checkpoint Resume requires State Management:** Cannot resume without tracking what completed; workflow_state.json is the mechanism -- **Idempotent Execution requires State Management:** Need to know if step already completed successfully to skip re-execution -- **Schema Validation enables Error Detection:** Catch malformed outputs early before they cascade to downstream steps -- **Platform-Specific Skills require Link Parser:** Cannot extract metadata without knowing platform and content type -- **Deep Analysis requires Text Content:** ASR/OCR must complete before AI analysis can process - ---- - -## v1.0-1.2 MVP Definition - -### Launch With (v1) - COMPLETED - -Minimum viable product — what's needed to validate the concept. - -- [x] **Sequential Pipeline Orchestration** — Core value proposition; linear processing from URL to analysis -- [x] **Step-Level State Management (workflow_state.json)** — Enables reliability; checkpoint/resume -- [x] **Idempotent Execution** — Same URL processed twice produces same result; no duplicates -- [x] **JSON Schema Validation** — Data contracts between steps; error detection -- [x] **Structured Error Handling** — JSON error format; graceful degradation -- [x] **Bilibili/Zhihu Platform Support** — Core platforms; metadata + content extraction -- [x] **AI Deep Analysis** — Product's value output - -### Add After Validation (v1.x) - -Features to add once core is working reliably. - -- [ ] **Enhanced Error Recovery Strategies** — 403/timeout specific handling; fallback options -- [ ] **OCR for Video Text Extraction** — Currently implemented but integration may need refinement -- [ ] **Speaker Diarization** — Already implemented; may need pipeline integration -- [ ] **Multiple ASR Backend Support** — Whisper + FunASR selection logic -- [ ] **Better Progress Visibility** — Step completion logging/indicators - -### Future Consideration (v2+) - -Features to defer until product-market fit is established. - -- [ ] **Additional Platforms (YouTube, etc.)** — Out of scope per PROJECT.md currently -- [ ] **Concurrent Processing for Independent Steps** — Only if latency becomes critical issue -- [ ] **Web UI for Monitoring** — Consider only if non-technical users need access -- [ ] **API/Webhook Notifications** — If integration with external systems needed - ---- - -## v1.0-1.2 Feature Prioritization Matrix - -| Feature | User Value | Implementation Cost | Priority | -|---------|------------|---------------------|----------| -| Step-Level State Management | HIGH | MEDIUM | P1 | -| Idempotent Execution | HIGH | MEDIUM | P1 | -| JSON Schema Validation | HIGH | LOW | P1 | -| Sequential Pipeline Model | HIGH | LOW | P1 | -| Structured Error Handling | HIGH | LOW | P1 | -| Clear Step Boundaries/Docs | MEDIUM | LOW | P1 | -| Checkpoint/Resume | HIGH | MEDIUM | P2 | -| Platform-Specific Skills | HIGH | MEDIUM | P1 (exists) | -| AI Deep Analysis | HIGH | HIGH | P1 (exists) | -| ASR/OCR Integration | MEDIUM | HIGH | P2 (exists) | -| Error Recovery Strategies | MEDIUM | MEDIUM | P2 | -| Progress Visibility | LOW | LOW | P3 | -| Concurrent Execution | LOW | HIGH | P3 | -| Web UI | LOW | HIGH | P3 | - -**Priority key:** -- P1: Must have for launch (reliability core) -- P2: Should have, add when possible (robustness) -- P3: Nice to have, future consideration (convenience) - ---- - -## Competitor Feature Analysis - -| Feature | Apache Airflow | Dagster | Prefect | Our Approach | -|---------|----------------|---------|---------|--------------| -| **Orchestration Model** | DAG-based | Asset-based | Flow-based | Sequential pipeline (simpler) | -| **State Management** | Database-backed | Built-in | Built-in | File-based (workflow_state.json) | -| **Checkpoint/Resume** | Task-level | Asset-level | Result caching | Step-level | -| **Idempotency** | Manual | Built-in checks | Decorator-based | Explicit state check | -| **Schema Validation** | Optional | Built-in | Optional | JSON Schema (planned) | -| **Observability** | UI Dashboard | UI + Lineage | UI + Logging | JSON output + console | -| **Learning Curve** | High | Medium | Low | Low (SKILL.md specs) | - -**Key differentiation:** Our skill-based architecture with SKILL.md specifications makes the system more accessible to AI agents and easier to extend than traditional workflow engines. The focus on content processing (not general ETL) allows specialized optimizations. - ---- - -## Industry Standard Features (2025-2026) - -Based on research, modern data pipeline and workflow orchestration systems have these table stakes: - -1. **Exactly-Once Processing (E1P)** — Data integrity guarantee; each event processed exactly once -2. **Fault-Tolerant Architecture** — Automatic failover and recovery -3. **Data Lineage/Tracking** — Know where data came from and how it was transformed -4. **Monitoring & Logging** — Real-time visibility into pipeline execution -5. **Scalable Architecture** — Handle varying loads -6. **Self-Service Management** — Easy pipeline creation and modification -7. **Multi-Format Support** — Structured, semi-structured, unstructured data - -**Our coverage:** -- E1P: Achieved via idempotent execution -- Fault-Tolerance: Checkpoint/resume covers this -- Lineage: State tracking provides basic lineage -- Monitoring: JSON output + console logging -- Scalability: Not a concern (batch processing, single user) -- Self-Service: SKILL.md specifications enable easy understanding -- Multi-Format: Video + text + images supported - ---- +### Vlog类视频 +- **分段依据**: 活动/场景变化 +- **边界信号**: 时间跳跃、地点变化、活动切换 +- **标题风格**: 描述性,反映活动内容 +- **分段长度**: 变化大(1-8分钟) ## Sources -### v1.3 Anti-Crawler Research (MEDIUM confidence) -- [Bright Data - IP Rotation Best Practices](https://brightdata.com/faqs/ip-rotation/best-practices) -- [ScrapFly - Bypass Anti-Bot Protection](https://scrapfly.io/blog/posts/how-to-bypass-anti-bot-protection-when-web-scraping) -- [ScrapeHero - TLS Fingerprint Bypass 2026](https://www.scrapehero.com/tls-fingerprint-bypass-techniques/) -- [CapMonster - Stop Getting CAPTCHA 2025](https://capmonster.cloud/en/blog/how-to-stop-getting-captcha-when-scraping-in-2025-with-real-solutions) -- [OneUptime - Retry Logic with Exponential Backoff in Python](https://oneuptime.com/blog/post/2025-01-06-python-retry-exponential-backoff/view) -- [AWS Prescriptive Guidance - Retry with Backoff Pattern](https://docs.aws.amazon.com/prescriptive-guidance/latest/cloud-design-patterns/retry-backoff.html) -- [知乎专栏 - B站 WBI 签名分析](https://zhuanlan.zhihu.com/p/1961014749807513938) -- [CSDN - B站视频爬取避坑指南 2024](https://blog.csdn.net/weixin_29051149/article/details/158076702) -- [Zyte - Rotating Proxies in Python](https://www.zyte.com/blog/developers-guide-to-rotating-proxies-in-python/) -- [Tenacity Library Documentation](https://github.com/jd/tenacity) - 当前项目已使用的重试库 +**HIGH Confidence:** +- [LLM-Enhanced Semantic Text Segmentation - MDPI Applied Sciences 2025](https://www.mdpi.com/2076-3417/15/19/10849) +- [Beyond Transcripts: A Renewed Perspective on Audio Chaptering - arXiv 2025](https://arxiv.org/html/2602.08979v1) +- [Multimodal Fusion and Coherence Modeling for Video Topic Segmentation - ACL Findings 2025](https://aclanthology.org/2025.findings-acl.904.pdf) +- [LoRA Fine-Tuning for Table-of-Contents Generation - Interspeech 2025](https://www.isca-archive.org/interspeech_2025/freisinger25_interspeech.pdf) +- [Chapter-Llama: Efficient Chaptering in Hour-Long Videos with LLMs - CVPR 2025](https://cvpr.thecvf.com/virtual/2025/poster/33157) -### v1.0-1.2 Baseline Research (HIGH confidence) -- [Striim: 7 Must-Have Features of Modern Data Pipelines](https://www.striim.com/blog/what-is-a-data-pipeline-and-must-have-features-of-modern-data-pipelines/) -- [Dagster: Data Pipeline Frameworks Key Features 2025](https://dagster.io/guides/data-pipeline-frameworks-key-features-10-tools-to-know-in-2025) -- [Microsoft Azure: AI Agent Orchestration Patterns](https://learn.microsoft.com/en-us/azure/architecture/ai-ml/guide/ai-agent-design-patterns) -- [Medium: Idempotency Guide for Data Pipelines](https://medium.com/@QuarkAndCode/idempotency-guide-iac-apis-data-pipelines-temporal-workflows-8d85dc280613) - MEDIUM confidence -- [Fivetran: Data Pipeline State Management](https://www.fivetran.com/blog/data-pipeline-state-management-an-underappreciated-challenge) - MEDIUM confidence -- PROJECT.md and ARCHITECTURE.md from codebase analysis - HIGH confidence +**MEDIUM Confidence:** +- [SEGLLM: Topic-Oriented Call Segmentation Via LLM-Based - IEEE](https://ieeexplore.ieee.org/document/10446156/) +- [BoundRL: Efficient Structured Text Segmentation - arXiv 2025](https://arxiv.org/abs/2510.20151) +- [A boundary enhanced multi-task neural attention approach - Nature 2025](https://www.nature.com/articles/s41598-025-25317-5) +- [Parsing Through Boundaries in Chinese Word Segmentation - arXiv 2025](https://arxiv.org/html/2503.23091v1) +- [RAG 2.0: Advanced Chunking Strategies with Examples - Medium](https://medium.com/@visrow/rag-2-0-advanced-chunking-strategies-with-examples-d87d03adf6d1) +- [Best Chunking Strategies for RAG (and LLMs) in 2026 - Firecrawl](https://www.firecrawl.dev/blog/best-chunking-strategies-rag) ---- - -*Feature research for: Skill-based Workflow Orchestration (Content Processing)* -*Researched: 2026-03-13* -*Updated for v1.3 Anti-Crawler: 2026-03-18* +**LOW Confidence (WebSearch only):** +- Video content type classification methods (需要验证具体实现) +- 说话人识别集成方法 (需要额外调研具体技术方案) diff --git a/.planning/research/PITFALLS.md b/.planning/research/PITFALLS.md index 5f464f0..307598b 100644 --- a/.planning/research/PITFALLS.md +++ b/.planning/research/PITFALLS.md @@ -1,8 +1,8 @@ # Pitfalls Research **Domain:** Skill-based Workflow Orchestration (LLM Agent Pipeline) -**Researched:** 2026-03-13 (Original), 2026-03-18 (Anti-Crawler Update) -**Confidence:** HIGH (Pipeline), MEDIUM (Anti-Crawler) +**Researched:** 2026-03-13 (Original), 2026-03-18 (Anti-Crawler Update), 2026-03-21 (LLM Semantic Segmentation) +**Confidence:** HIGH (Pipeline), MEDIUM (Anti-Crawler), HIGH (LLM Segmentation) --- @@ -443,6 +443,1082 @@ retry_decorator = retry( --- +## Part 3: LLM Semantic Segmentation Pitfalls (v1.6) + +> 以下陷阱适用于 v1.6 LLM 语义分段里程碑,重点关注上下文窗口、分段一致性、幻觉检测、成本控制等。 + +### Pitfall LLM-1: Context Window Overflow on Long Videos + +**What goes wrong:** +B站视频(尤其是知识类)可能长达1-2小时,字幕内容超过10万token。直接将完整字幕发送给 LLM 会导致 API 错误或截断。 + +**Why it happens:** +- 2026年的 LLM 虽然号称支持 200k 上下文,但实际在 130k token 左右会变得不可靠 +- Anthropic 研究表明,超过 100k token 的上下文会降低推理质量 +- 简单实现中未考虑 token 计数和分块策略 + +**Consequences:** +- API 调用失败(4xx 错误) +- 内容截断导致分段不完整 +- 额外成本:重复处理或手动修复 + +**How to avoid:** +```python +# Phase 1 - 架构设计 +class LLMContentChunker: + def __init__(self, max_tokens: int = 80_000): + self.max_tokens = max_tokens + self.tokenizer = tiktoken.encoding_for_model("gpt-4") + + def chunk_content(self, content: str) -> List[str]: + # 1. 首先按现有时间间隔分段(3秒停顿) + initial_chunks = self.split_by_time_gaps(content) + + # 2. 合并小段,确保不超过 token 限制 + final_chunks = [] + current_chunk = [] + current_tokens = 0 + + for chunk in initial_chunks: + chunk_tokens = len(self.tokenizer.encode(chunk)) + if current_tokens + chunk_tokens > self.max_tokens: + final_chunks.append(" ".join(current_chunk)) + current_chunk = [chunk] + current_tokens = chunk_tokens + else: + current_chunk.append(chunk) + current_tokens += chunk_tokens + + if current_chunk: + final_chunks.append(" ".join(current_chunk)) + + return final_chunks +``` + +**Two-stage processing strategy:** +1. **Stage 1**: Fast pre-scan using rules or small model to identify potential topic transition points +2. **Stage 2**: LLM deep analysis only on suspicious regions + +**Warning signs:** +- API 返回 "context_length_exceeded" 错误 +- 某些视频分段结果明显不完整 +- 成本异常高(每次处理 >$5) + +**Phase to address:** Phase 1 (架构设计:分块策略、两阶段处理) + +**Sources:** +- [The LLM context problem in 2026](https://blog.logrocket.com/llm-context-problem/) - LogRocket Blog +- [Context Window Overflow in 2026](https://redis.io/blog/context-window-overflow/) - Redis Blog +- [Navigating Frontier LLM Context Window Limitations](https://www.hangryfeed.com/insights/posts/frontier-llm-context-window-limitations-2026-01-15) - HangryFeed +- [Context Length Comparison: Leading AI Models in 2026](https://www.elvex.com/blog/context-length-comparison-ai-models-2026) - Elvex + +--- + +### Pitfall LLM-2: Inconsistent Segment Boundaries + +**What goes wrong:** +LLM 在不同时间处理相同内容时返回不同的分段边界,导致结果不可重现。 + +**Why it happens:** +- LLM 的概率性质导致输出不一致 +- Prompt 缺乏明确的边界规则(如"必须在句号处分段") +- Temperature 参数设置不当(非零值导致随机性) + +**Consequences:** +- 相同视频多次处理结果不同 +- 用户无法信任系统输出 +- 调试困难(无法复现问题) + +**How to avoid:** +```python +# Phase 1 - Prompt 工程 +SEMANTIC_SEGMENTATION_PROMPT = """ +你是一个视频字幕语义分析专家。你的任务是将字幕内容按主题分段。 + +**关键规则:** +1. 必须在句子边界(句号、问号、感叹号)处分段 +2. 绝不在句子中间分段 +3. 每个分段必须包含完整的思想或话题 +4. 如果没有明确主题变化,返回 "CONTINUE" + +**输出格式(JSON):** +{ + "segments": [ + { + "start_index": 0, # 在原始内容中的字符索引 + "end_index": 150, + "topic": "黑洞的基本特征", # 如果有明确主题 + "confidence": 0.9 # 0-1 之间的置信度 + } + ], + "reasoning": "为什么这样分段" +} + +**输入内容:** +{content} +""" + +# 使用 temperature=0 获得确定性输出 +client.chat( + messages=[{"role": "user", "content": prompt}], + temperature=0, # 关键:确保确定性输出 + response_format={"type": "json_object"} +) +``` + +**Phase 2 - 验证机制:** +```python +class SegmentValidator: + def validate_boundaries(self, segments: List[Segment], content: str) -> List[Segment]: + """检查分段点是否在句子边界""" + validated = [] + + for seg in segments: + # 检查分段点是否在标点符号后 + char_before = content[seg.end_index - 1] if seg.end_index > 0 else "" + if char_before in "。!?.!?": + validated.append(seg) + else: + # 修正:移动到最近的句子边界 + corrected_end = self.find_next_sentence_boundary(content, seg.end_index) + validated.append(seg.with_end(corrected_end)) + + return self.merge_short_segments(validated, min_length=50) + + def find_next_sentence_boundary(self, content: str, position: int) -> int: + """找到下一个句子边界""" + for i in range(position, min(position + 100, len(content))): + if content[i] in "。!?.!?": + return i + 1 + return position # 如果找不到,返回原位置 +``` + +**Warning signs:** +- 相同输入产生不同输出 +- 分段点出现在句子中间(如"我们/来讨论...") +- 用户报告"结果每次都不一样" + +**Phase to address:** Phase 1 (Prompt 工程) + Phase 2 (验证机制) + +**Sources:** +- [LLM-Enhanced Semantic Text Segmentation](https://www.mdpi.com/2076-3417/15/19/10849) - MDPI +- [Best Chunking Strategies for RAG in 2026](https://www.firecrawl.dev/blog/best-chunking-strategies-rag) - Firecrawl +- [LLM Evaluation Frameworks & Metrics Guide 2026](https://www.mlaidigital.com/blogs/llm-model-evaluation-frameworks-a-complete-guide-for-2026) - MLAI Digital + +--- + +### Pitfall LLM-3: Hallucinated Topic Titles + +**What goes wrong:** +LLM 为分段生成不准确或完全不存在的主题标题。 + +**Why it happens:** +- LLM 倾向于"合理化"而非"准确化" +- 视频内容本身缺乏明确主题结构 +- Prompt 未要求标题必须有依据(如引用原文) + +**Consequences:** +- 用户被误导(标题与实际内容不符) +- 信任度下降 +- 知识库内容质量降低 + +**How to avoid:** +```python +# Phase 1 - Prompt 设计 +TOPIC_GENERATION_PROMPT = """ +为以下字幕分段生成主题标题。 + +**要求:** +1. **仅在有明确主题时生成标题** +2. 标题必须基于原文中的关键词或概念 +3. 如果主题不明确,返回 "NO_CLEAR_TOPIC" +4. 避免编造原文中不存在的内容 + +**输出格式:** +{ + "topic": "黑洞的形成机制" 或 "NO_CLEAR_TOPIC", + "evidence": ["原文中的关键词1", "原文中的关键词2"], + "confidence": 0.8 +} + +**输入内容:** +{segment_content} +""" + +# Phase 2 - 验证 +class TopicValidator: + def __init__(self, embedding_model): + self.embedding_model = embedding_model + + def validate_topic(self, topic: str, content: str) -> bool: + """验证标题与内容的相似度""" + if topic == "NO_CLEAR_TOPIC": + return True + + # 计算标题和内容的 embedding 相似度 + topic_embedding = self.embedding_model.encode(topic) + content_embedding = self.embedding_model.encode(content) + + similarity = cosine_similarity([topic_embedding], [content_embedding])[0][0] + + # 相似度阈值可调 + if similarity < 0.3: + return False # 标题与内容不符 + + # 检查标题关键词是否出现在内容中 + topic_words = set(topic.split()) + content_words = set(content.split()) + overlap = len(topic_words & content_words) / len(topic_words) + + return overlap > 0.2 # 至少20%的关键词重叠 +``` + +**User feedback integration:** +```python +# Phase 3 - 用户反馈机制 +class FeedbackCollector: + def record_incorrect_topic(self, video_id: str, segment_id: str, reported_topic: str): + """记录用户报告的错误标题""" + self.feedback_db.insert({ + "video_id": video_id, + "segment_id": segment_id, + "reported_topic": reported_topic, + "timestamp": datetime.now() + }) + + def get_low_confidence_topics(self, threshold: float = 0.5): + """获取低置信度标题用于人工审核""" + return self.db.query( + "SELECT * FROM segments WHERE confidence < ?", + (threshold,) + ) +``` + +**Warning signs:** +- 标题与段落内容明显不符 +- 标题包含未在原文中出现的关键概念 +- 用户反馈"标题不对" + +**Phase to address:** Phase 1 (Prompt 设计) + Phase 2 (验证机制) + Phase 3 (用户反馈) + +**Sources:** +- [LLM Hallucinations in 2026: How to Understand and Tackle](https://www.lakera.ai/blog/guide-to-hallucinations-in-large-language-models) - Lakera AI +- [Hallucination Detection and Mitigation in LLMs](https://arxiv.org/pdf/2601.09929) - arXiv +- [Detecting hallucinations with LLM-as-a-judge](https://www.datadoghq.com/blog/ai/llm-hallucination-detection/) - Datadog +- [AI Hallucinations: Definition, Examples & How to Prevent](https://gptzero.me/news/ai-hallucinations-definition-examples/) - GPTZero + +--- + +### Pitfall LLM-4: Breaking Content Mid-Sentence + +**What goes wrong:** +LLM 在句子中间分段,破坏内容完整性。 + +**Why it happens:** +- Prompt 未明确要求在句子边界处分段 +- LLM 优先考虑"语义完整性"而非"语法完整性" +- 时间戳信息与文本内容不同步 + +**Consequences:** +- 段落难以阅读(句子不完整) +- 后续处理(如摘要生成)质量下降 +- 用户体验差 + +**How to avoid:** +```python +# Phase 1 - Prompt 工程(已在 Pitfall LLM-2 中覆盖) +SEMANTIC_SEGMENTATION_PROMPT = """ +**关键规则:** +1. 必须在句子边界(句号、问号、感叹号)处分段 +2. 绝不在句子中间分段 +3. 每个分段必须以完整句子结束 + +**负面示例(不要这样做):** +错误:["我们讨论了黑洞的", "形成机制和观测方法"] +正确:["我们讨论了黑洞的形成机制。", "接下来是观测方法。"] +""" + +# Phase 2 - 后处理 +class SentenceBoundaryProcessor: + def __init__(self): + # 使用 NLP 库或正则表达式检测句子边界 + self.sentence_endings = re.compile(r'[。!?.!?]\s*') + + def enforce_sentence_boundaries(self, segments: List[str]) -> List[str]: + """强制在句子边界处分段""" + processed = [] + + for seg in segments: + # 检查是否以完整句子结束 + if not self.sentence_endings.search(seg[-1] if seg else ""): + # 找到下一个句子边界 + next_boundary = self.find_next_boundary(seg) + if next_boundary < len(seg): + # 截断到边界 + seg = seg[:next_boundary + 1] + + # 确保每个分段以标点符号结束 + if seg and not seg[-1] in "。!?.!?": + seg += "。" # 添加句号 + + processed.append(seg) + + return processed + + def find_next_boundary(self, text: str, start: int = 0) -> int: + """从指定位置开始查找下一个句子边界""" + for i in range(start, len(text)): + if text[i] in "。!?.!?": + return i + return len(text) - 1 # 如果找不到,返回末尾 +``` + +**Quality check:** +```python +class SegmentQualityChecker: + def check_segment_completeness(self, segment: str) -> Dict[str, Any]: + """检查分段完整性""" + issues = [] + + # 检查1: 是否以标点符号结束 + if segment and not segment[-1] in "。!?.!?": + issues.append("missing_punctuation") + + # 检查2: 是否有小写字母开头(句子中间) + if segment and segment[0].islower(): + issues.append("starts_mid_sentence") + + # 检查3: 是否包含截断的句子 + if re.search(r'[,,]\s*$', segment): + issues.append("ends_with_comma") + + return { + "is_complete": len(issues) == 0, + "issues": issues + } +``` + +**Warning signs:** +- 分段结尾缺少标点符号 +- 分段开头是小写字母(句子中间) +- 人工审核发现截断的句子 + +**Phase to address:** Phase 1 (Prompt 工程) + Phase 2 (后处理) + +**Sources:** +- [WTPSplit - Sentence Boundary Detection](https://github.com/segment-any-text/wtpsplit) - GitHub +- [Best Chunking Strategies for RAG](https://www.firecrawl.dev/blog/best-chunking-strategies-rag) - Firecrawl +- [Semantic Boundary Detection for RAG](https://www.inferable.ai/blog/posts/semantic-boundary-detection-rag-agents) - Inferable +- [How to Build Semantic Chunking](https://oneuptime.com/blog/post/2026-01-30/semantic-chunking/view) - OneUptime + +--- + +### Pitfall LLM-5: Fallback Strategy Failures + +**What goes wrong:** +当 LLM API 失败时,fallback 到规则分段,但两种方法的输出格式不兼容。 + +**Why it happens:** +- LLM 和规则分段的输出 Schema 设计不同 +- Fallback 逻辑未在架构阶段考虑 +- 错误处理不完善(如超时、速率限制) + +**Consequences:** +- Pipeline 在 fallback 时崩溃 +- 用户收到不一致的输出格式 +- 调试困难(无法区分 LLM 结果和 fallback 结果) + +**How to avoid:** +```python +# Phase 1 - 架构设计:统一接口 +from abc import ABC, abstractmethod +from typing import Literal + +class SemanticSegmenterInterface(ABC): + """语义分段器统一接口""" + + @abstractmethod + def segment(self, content: str, metadata: dict) -> SegmentationResult: + """将内容分段 + + Returns: + SegmentationResult: 统一的结果格式 + """ + pass + +class SegmentationResult(BaseModel): + """统一的分段结果格式""" + segments: List[Segment] + method: Literal["llm", "rule_based", "hybrid"] + confidence: float + fallback_used: bool = False + processing_time_ms: int + metadata: dict = {} + +class LLMSegmenter(SemanticSegmenterInterface): + """LLM 语义分段器""" + + def segment(self, content: str, metadata: dict) -> SegmentationResult: + try: + start_time = time.time() + segments = self._call_llm(content) + return SegmentationResult( + segments=segments, + method="llm", + confidence=0.9, + processing_time_ms=int((time.time() - start_time) * 1000) + ) + except Exception as e: + # Fallback to rule-based + rule_segmenter = RuleBasedSegmenter() + result = rule_segmenter.segment(content, metadata) + result.fallback_used = True + result.method = "hybrid" + result.metadata["fallback_reason"] = str(e) + return result + +class RuleBasedSegmenter(SemanticSegmenterInterface): + """规则分段器(现有实现)""" + + def segment(self, content: str, metadata: dict) -> SegmentationResult: + start_time = time.time() + # 现有的规则分段逻辑 + segments = self._segment_by_rules(content) + return SegmentationResult( + segments=segments, + method="rule_based", + confidence=0.6, + processing_time_ms=int((time.time() - start_time) * 1000) + ) +``` + +**Phase 2 - 错误处理:** +```python +class RobustLLMClient: + def __init__(self, max_retries: int = 3, timeout: int = 60): + self.max_retries = max_retries + self.timeout = timeout + + def call_with_fallback(self, prompt: str) -> str: + """带重试和 fallback 的 LLM 调用""" + last_error = None + + for attempt in range(self.max_retries): + try: + response = self.client.chat( + messages=[{"role": "user", "content": prompt}], + timeout=self.timeout + ) + return response.content + + except TimeoutError: + last_error = "timeout" + wait_time = 2 ** attempt # exponential backoff + time.sleep(wait_time) + + except RateLimitError: + last_error = "rate_limit" + # 尊重 Retry-After + retry_after = getattr(e, 'retry_after', 60) + time.sleep(retry_after) + + except APIError as e: + if e.status_code in [401, 403]: + # 认证错误,不重试 + last_error = f"auth_failed: {e}" + break + else: + last_error = f"api_error: {e}" + time.sleep(2 ** attempt) + + # 所有重试失败,触发 fallback + logger.warning(f"LLM call failed after {self.max_retries} attempts: {last_error}") + raise FallbackRequiredError(last_error) +``` + +**Phase 3 - 监控:** +```python +class SegmentationMonitor: + def __init__(self): + self.metrics = { + "llm_success": 0, + "llm_fallback": 0, + "llm_errors": [] + } + + def record_success(self): + self.metrics["llm_success"] += 1 + + def record_fallback(self, reason: str): + self.metrics["llm_fallback"] += 1 + self.metrics["llm_errors"].append({ + "reason": reason, + "timestamp": datetime.now().isoformat() + }) + + def get_health_status(self) -> dict: + total = self.metrics["llm_success"] + self.metrics["llm_fallback"] + if total == 0: + return {"status": "no_data"} + + fallback_rate = self.metrics["llm_fallback"] / total + + if fallback_rate > 0.1: + return {"status": "warning", "fallback_rate": fallback_rate} + else: + return {"status": "healthy", "fallback_rate": fallback_rate} + + def check_alerts(self): + """检查是否需要告警""" + status = self.get_health_status() + if status.get("fallback_rate", 0) > 0.1: + logger.error(f"High fallback rate: {status['fallback_rate']:.1%}") + # 发送告警通知 +``` + +**Warning signs:** +- Pipeline 在 LLM 失败后崩溃 +- 某些视频输出格式与其他不同 +- 日志中出现大量 API 错误但未处理 + +**Phase to address:** Phase 1 (架构设计) + Phase 2 (错误处理) + Phase 3 (监控) + +**Sources:** +- [Agentic Workflows in 2026: LLM Calls with Fallbacks](https://vellum.ai/blog/agentic-workflows-emerging-architectures-and-design-patterns) - Vellum AI +- [LLM System Design: The Complete Guide](https://www.systemdesignhandbook.com/guides/llm-system-design/) - System Design Handbook +- [Handling Timeouts and Retries in LLM Systems](https://dasroot.net/posts/2026/02/handling-timeouts-retries-llm-systems/) - Dasroot! +- [Error Handling & Retries: Making LLM Calls Reliable](https://medium.com/@sonitanishk2003/error-handling-retries-making-llm-calls-reliable-ee7722fc2ea9) - Medium + +--- + +### Pitfall LLM-6: Video Type Misidentification + +**What goes wrong:** +LLM 错误判断视频类型(如将故事类识别为知识类),导致分段策略不匹配。 + +**Why it happens:** +- 视频内容混合多种类型(如故事中穿插知识讲解) +- 分类 Prompt 缺乏明确的判断标准 +- LLM 对视频类型的理解与用户期望不一致 + +**How to avoid:** +```python +# Phase 1 - 分类器设计 +VIDEO_TYPE_CLASSIFICATION_PROMPT = """ +分析以下字幕内容,判断视频类型。 + +**视频类型定义:** +1. **knowledge**: 系统性讲解知识、概念、理论 + - 特征:有明确的知识结构、使用专业术语、循序渐进讲解 + +2. **story**: 叙述故事、事件、经历 + - 特征:有时间线、有人物/事件、强调情节发展 + +3. **dialogue**: 对话、访谈、讨论 + - 特征:多人互动、问答形式、观点交流 + +4. **mixed**: 混合类型 + - 特征:包含以上多种类型的特征 + +**输出格式:** +{ + "type": "knowledge" | "story" | "dialogue" | "mixed", + "confidence": 0.0-1.0, + "reasoning": "判断依据", + "evidence": ["证据1", "证据2"] +} + +**输入内容(前2000字):** +{content_preview} +""" + +# 使用 few-shot examples +FEW_SHOT_EXAMPLES = [ + { + "content": "黑洞是时空展现出极端引力的区域...", + "type": "knowledge", + "reasoning": "系统性讲解科学概念" + }, + { + "content": "那天我遇到了一个奇怪的人...", + "type": "story", + "reasoning": "叙述个人经历和事件" + } +] +``` + +**User override:** +```python +class VideoTypeClassifier: + def __init__(self): + self.user_overrides = {} # video_id -> user_specified_type + + def classify(self, content: str, video_id: str = None) -> str: + # 检查用户是否手动指定了类型 + if video_id and video_id in self.user_overrides: + return self.user_overrides[video_id] + + result = self._llm_classify(content) + + # 低置信度时使用默认策略 + if result["confidence"] < 0.7: + logger.warning(f"Low confidence classification: {result['confidence']}") + return "mixed" # 默认使用混合策略 + + return result["type"] + + def set_user_override(self, video_id: str, video_type: str): + """允许用户手动指定视频类型""" + self.user_overrides[video_id] = video_type + logger.info(f"User override: {video_id} -> {video_type}") +``` + +**Warning signs:** +- 用户报告"分段策略不对" +- 某类视频的分段质量普遍较差 +- 分类结果与用户直觉不符 + +**Phase to address:** Phase 1 (分类器设计) + Phase 2 (用户反馈) + +**Sources:** +- [Multimodal LLMs in 2026: Annotation Challenges](https://www.nextwealth.com/blog/multimodal-llms-in-2026-annotation-challenges-when-ai-needs-to-see-hear-and-read/) - NextWealth +- [HiVid: LLM-Guided Video Saliency Research](https://arxiv.org/pdf/2602.14214) - arXiv + +--- + +### Pitfall LLM-7: Cost Explosion + +**What goes wrong:** +LLM 调用成本过高,单个视频处理成本 >$1。 + +**Why it happens:** +- 对每个视频都进行完整的 LLM 分析 +- 未使用缓存(重复处理相同视频) +- 使用了过于昂贵的模型 + +**How to avoid:** +```python +# Phase 1 - 成本优化:智能缓存 +class CachedLLMSegmenter: + def __init__(self, cache_dir: str): + self.cache_dir = Path(cache_dir) + self.cache_dir.mkdir(exist_ok=True) + + def get_cache_key(self, content: str) -> str: + """生成缓存键""" + # 使用内容的 hash 作为键 + return hashlib.sha256(content.encode()).hexdigest() + + def segment(self, content: str) -> SegmentationResult: + cache_key = self.get_cache_key(content) + cache_file = self.cache_dir / f"{cache_key}.json" + + # 检查缓存 + if cache_file.exists(): + logger.info(f"Cache hit: {cache_key}") + return SegmentationResult.model_validate_json(cache_file.read_text()) + + # 缓存未命中,调用 LLM + logger.info(f"Cache miss: {cache_key}, calling LLM...") + result = self._call_llm(content) + + # 保存到缓存 + cache_file.write_text(result.model_dump_json()) + + return result + +# 成本优化:使用更便宜的模型 +class TieredLLMStrategy: + def __init__(self): + self.cheap_model = "deepseek-chat" # ~$0.28/M tokens + self.premium_model = "gpt-4" # ~$2.50/M tokens + + def segment(self, content: str) -> SegmentationResult: + # 第一步:使用便宜模型快速分析 + quick_result = self._call_cheap_model(content) + + # 如果 cheap model 置信度高,直接返回 + if quick_result["confidence"] > 0.8: + return quick_result + + # 第二步:仅对低置信度情况使用 premium model + logger.info("Low confidence from cheap model, using premium model") + return self._call_premium_model(content) +``` + +**Phase 2 - 监控:** +```python +class CostTracker: + def __init__(self): + self.costs = [] + + def track_api_call(self, model: str, input_tokens: int, output_tokens: int): + # 2026年定价(示例) + PRICING = { + "deepseek-chat": {"input": 0.14, "output": 0.28}, # per million + "gpt-4": {"input": 2.50, "output": 10.0}, + } + + pricing = PRICING.get(model, {"input": 1.0, "output": 1.0}) + cost = (input_tokens * pricing["input"] + output_tokens * pricing["output"]) / 1_000_000 + + self.costs.append({ + "model": model, + "input_tokens": input_tokens, + "output_tokens": output_tokens, + "cost": cost, + "timestamp": datetime.now() + }) + + logger.info(f"API call: {model}, {input_tokens}+{output_tokens} tokens, ${cost:.4f}") + + def get_total_cost(self) -> float: + return sum(c["cost"] for c in self.costs) + + def check_cost_alerts(self): + total = self.get_total_cost() + if total > 0.5: # 单视频成本阈值 + logger.warning(f"High processing cost: ${total:.2f}") +``` + +**Warning signs:** +- 月度账单异常高 +- 单个视频处理成本 >$0.5 +- 频繁调用 LLM 处理相同内容 + +**Phase to address:** Phase 1 (成本优化) + Phase 2 (监控) + +**Sources:** +- [LLM Cost Optimization in 2026](https://www.maviklabs.com/blog/llm-cost-optimization-2026) - Mavik Labs +- [Complete LLM Pricing Comparison 2026](https://www.cloudidr.com/blog/llm-pricing-comparison-2026) - CloudIDR +- [LLMOps Guide 2026](https://redis.io/blog/large-language-model-operations-guide/) - Redis +- [LLM API Pricing in 2026: The Complete Cost Comparison](https://www.aimagicx.com/blog/llm-api-pricing-in-2026/) - AI MagicX + +--- + +### Pitfall LLM-8: Rate Limiting Issues + +**What goes wrong:** +批量处理视频时触发 API 速率限制,导致请求失败。 + +**Why it happens:** +- 未实现请求队列和速率控制 +- 短时间内发送大量请求 +- 未尊重 API 提供商的速率限制 + +**How to avoid:** +```python +# Phase 1 - 速率控制 +import asyncio +from collections import deque + +class RateLimitedLLMClient: + def __init__(self, max_requests_per_second: int = 3): + self.max_rps = max_requests_per_second + self.request_times = deque() + self.semaphore = asyncio.Semaphore(max_requests_per_second) + + async def call(self, prompt: str) -> str: + # Token-aware rate limiting + async with self.semaphore: + # 等待直到可以发送请求 + await self._wait_for_slot() + + # 记录请求时间 + now = time.time() + self.request_times.append(now) + + # 发送请求 + return await self._api_call(prompt) + + async def _wait_for_slot(self): + """等待直到有可用的请求槽""" + while len(self.request_times) >= self.max_rps: + # 检查最早的请求是否已经超过1秒 + if time.time() - self.request_times[0] >= 1.0: + self.request_times.popleft() + else: + # 等待 + await asyncio.sleep(0.1) + +# Exponential backoff +class RetryWithBackoff: + async def call_with_retry(self, func, max_retries: int = 3): + for attempt in range(max_retries): + try: + return await func() + except RateLimitError: + if attempt == max_retries - 1: + raise + + # Exponential backoff with jitter + base_wait = 2 ** attempt + jitter = random.uniform(0, base_wait * 0.5) + wait_time = base_wait + jitter + + logger.warning(f"Rate limited, waiting {wait_time:.1f}s") + await asyncio.sleep(wait_time) +``` + +**Phase 2 - 批处理策略:** +```python +class BatchProcessor: + def __init__(self, concurrent_limit: int = 3): + self.concurrent_limit = concurrent_limit + self.queue = asyncio.Queue() + + async def process_videos(self, video_urls: List[str]): + """批量处理视频""" + tasks = [] + + for url in video_urls: + # 创建任务但不立即执行 + task = asyncio.create_task(self._process_single(url)) + tasks.append(task) + + # 控制并发数 + if len(tasks) >= self.concurrent_limit: + # 等待一些任务完成 + done, pending = await asyncio.wait( + tasks, + return_when=asyncio.FIRST_COMPLETED + ) + tasks = list(pending) + + # 等待剩余任务完成 + await asyncio.gather(*tasks) +``` + +**Warning signs:** +- 大量 429 错误 +- 请求成功率突然下降 +- API 调用频繁超时 + +**Phase to address:** Phase 1 (速率控制) + Phase 2 (批处理) + +**Sources:** +- [Handling Timeouts and Retries in LLM Systems](https://dasroot.net/posts/2026/02/handling-timeouts-retries-llm-systems/) - Dasroot! +- [Prompt Rate Limits & Batching](https://dev.to/superorange0707/prompt-rate-limits-batching-how-to-stop-your-llm-api-from-melting-down-56e1) - Dev.to +- [Rate Limiting in AI Gateway](https://www.truefoundry.com/blog/rate-limiting-in-llm-gateway) - TrueFoundry +- [How to Handle Token Limits and Rate Limits](https://www.typedef.ai/resources/handle-token-limits-rate-limits-large-scale-llm-inference) - Typedef.ai + +--- + +### Pitfall LLM-9: Integration with Existing Pipeline + +**What goes wrong:** +新的 LLM 分段器破坏现有的 SRTProcessor 工作流。 + +**Why it happens:** +- 接口变更导致向后不兼容 +- 未考虑现有的状态管理和错误处理 +- 测试覆盖不足 + +**How to avoid:** +```python +# Phase 1 - 兼容性设计 +class SemanticSegmenter: + """保持现有接口不变""" + + def __init__( + self, + gap_threshold: float = 3.0, + max_paragraph_chars: int = 500, + use_llm: bool = False, # 新增:默认不使用 LLM + llm_client: Optional[SimpleAIClient] = None + ): + self.gap_threshold = gap_threshold + self.max_paragraph_chars = max_paragraph_chars + self.use_llm = use_llm + self.llm_client = llm_client + + def segment(self, segments: List[Segment]) -> List[str]: + """保持原有方法签名""" + + if not self.use_llm: + # 使用现有的规则分段 + return self._segment_by_rules(segments) + + # 使用 LLM 分段 + return self._segment_by_llm(segments) + + def _segment_by_rules(self, segments: List[Segment]) -> List[str]: + """现有的规则分段逻辑(保持不变)""" + # ... 现有代码 ... + pass + + def _segment_by_llm(self, segments: List[Segment]) -> List[str]: + """新的 LLM 分段逻辑""" + try: + # LLM 分段 + result = self.llm_client.analyze_segments(segments) + return result.segments + except Exception as e: + # Fallback to rule-based + logger.warning(f"LLM segmentation failed, falling back to rules: {e}") + return self._segment_by_rules(segments) +``` + +**Configuration-based rollout:** +```python +# config.yaml +srt_processing: + semantic_segmentation: + method: "rule_based" # or "llm" or "hybrid" + llm_fallback_enabled: true + +# 代码中读取配置 +config = load_config("config.yaml") +segmenter = SemanticSegmenter( + use_llm=(config.srt_processing.semantic_segmentation.method == "llm") +) +``` + +**Testing:** +```python +# tests/test_llm_integration.py +def test_llm_segmentation_compatibility(): + """确保 LLM 分段与现有流程兼容""" + # 准备测试数据 + segments = [...] + + # 测试规则分段(原有行为) + segmenter = SemanticSegmenter(use_llm=False) + rule_result = segmenter.segment(segments) + + # 测试 LLM 分段(新行为) + llm_segmenter = SemanticSegmenter(use_llm=True, llm_client=mock_client) + llm_result = llm_segmenter.segment(segments) + + # 验证输出格式一致 + assert isinstance(rule_result, list) + assert isinstance(llm_result, list) + assert all(isinstance(s, str) for s in rule_result) + assert all(isinstance(s, str) for s in llm_result) +``` + +**Warning signs:** +- 现有测试失败 +- Pipeline 在新功能启用后崩溃 +- 输出格式不一致 + +**Phase to address:** Phase 1 (兼容性设计) + Phase 3 (渐进式推出) + +**Sources:** +- [LLMOps Guide 2026](https://redis.io/blog/large-language-model-operations-guide/) - Redis +- [LLM Pipeline Re-Architecture Best Practices](https://www.linkedin.com/top-content/technology/best-practices-in-technology/llm-pipeline-re-architecture-best-practices/) - LinkedIn +- [How to Build a RAG Pipeline from Scratch in 2026](https://www.kapa.ai/blog/how-to-build-a-rag-pipeline-from-scratch-in-2026) - Kapa.ai + +--- + +### Pitfall LLM-10: Timeout on Long Videos + +**What goes wrong:** +长视频(>1小时)的 LLM 处理超时。 + +**Why it happens:** +- LLM API 处理时间长(尤其是长上下文) +- 未设置合理的超时时间 +- 未实现异步处理和进度回调 + +**How to avoid:** +```python +# Phase 1 - 超时处理 +class TimeoutAwareLLMClient: + def __init__(self, timeout: int = 120): + self.timeout = timeout + + def call_with_timeout(self, prompt: str) -> str: + """设置超时的 LLM 调用""" + try: + response = self.client.chat( + messages=[{"role": "user", "content": prompt}], + timeout=self.timeout # 设置超时 + ) + return response.content + except TimeoutError: + logger.error(f"LLM call timed out after {self.timeout}s") + raise + +# Phase 2 - 异步处理 +class AsyncSegmentProcessor: + async def process_long_video( + self, + video_id: str, + segments: List[Segment], + progress_callback: Optional[Callable] = None + ) -> SegmentationResult: + """异步处理长视频,支持进度回调""" + + # 分块处理 + chunks = self._split_into_chunks(segments, chunk_size=100) + + all_segments = [] + for i, chunk in enumerate(chunks): + if progress_callback: + progress_callback(i, len(chunks)) + + # 处理单个块 + result = await self._process_chunk_async(chunk) + all_segments.extend(result.segments) + + return SegmentationResult(segments=all_segments) + + def _split_into_chunks(self, segments: List[Segment], chunk_size: int): + """将长内容分块""" + for i in range(0, len(segments), chunk_size): + yield segments[i:i + chunk_size] + +# Phase 2 - 进度持久化 +class ResumableProcessor: + def __init__(self, state_dir: str): + self.state_dir = Path(state_dir) + + def process(self, video_id: str, content: str): + state_file = self.state_dir / f"{video_id}.json" + + # 检查是否有未完成的状态 + if state_file.exists(): + logger.info(f"Resuming from {state_file}") + state = json.loads(state_file.read_text()) + completed_chunks = state["completed_chunks"] + else: + completed_chunks = [] + + # 继续处理 + chunks = self._split_content(content) + for i, chunk in enumerate(chunks): + if i in completed_chunks: + continue + + # 处理块 + result = self._process_chunk(chunk) + completed_chunks.append(i) + + # 保存进度 + state_file.write_text(json.dumps({ + "video_id": video_id, + "completed_chunks": completed_chunks, + "timestamp": datetime.now().isoformat() + })) + + # 完成,清理状态文件 + state_file.unlink() +``` + +**Warning signs:** +- 某些视频一直处理中 +- 频繁超时错误 +- 用户无法看到处理进度 + +**Phase to address:** Phase 1 (超时处理) + Phase 2 (分块处理) + +**Sources:** +- [Handling Timeouts and Retries in LLM Systems](https://dasroot.net/posts/2026/02/handling-timeouts-retries-llm-systems/) - Dasroot! +- [LLMOps Guide 2026](https://redis.io/blog/large-language-model-operations-guide/) - Redis + +--- + ## Technical Debt Patterns ### Pipeline Technical Debt @@ -466,6 +1542,17 @@ retry_decorator = retry( | 不验证代理可用性 | 启动快 | 运行时大量失败请求 | 仅 MVP 演示 | | 禁用 SSL 验证 | 解决证书问题 | 安全风险,可能被中间人攻击 | **永不可接受** | +### LLM Segmentation Technical Debt + +| Shortcut | Immediate Benefit | Long-term Cost | When Acceptable | +|----------|-------------------|----------------|-----------------| +| 直接发送完整内容给 LLM | 实现简单 | 上下文溢出,高成本 | 仅限短视频(<5分钟) | +| 使用 temperature > 0 | 更多样化的输出 | 结果不一致,无法复现 | **永不可接受** | +| 跳过 token 计数 | 减少代码 | 不可预测的成本和错误 | 仅限原型 | +| 硬编码 fallback 逻辑 | 快速实现 | 难以维护,无法监控 | 仅 MVP 阶段 | +| 不验证 LLM 输出 | 简单实现 | 低质量结果,用户信任下降 | **永不可接受** | +| 无缓存机制 | 实现简单 | 重复处理,成本爆炸 | **永不可接受** | + --- ## Integration Gotchas @@ -491,6 +1578,16 @@ retry_decorator = retry( | Playwright 浏览器管理 | 每次请求创建新浏览器 | 复用浏览器实例,仅在必要时重建 | | Cookie 管理 | 硬编码 Cookie 有效期 | 实现过期检测和自动刷新 | +### LLM Segmentation Integration (v1.6) + +| Integration Point | Common Mistake | Correct Approach | +|-------------------|----------------|------------------| +| `SemanticSegmenter` 接口 | 破坏现有 `segment()` 方法签名 | 保持兼容,添加 `use_llm` 参数 | +| SimpleAIClient 调用 | 未设置超时,长视频导致阻塞 | 设置合理超时(60-120秒),异步处理 | +| 状态管理 | LLM 处理失败未记录到 workflow_state | 记录 fallback 路径,支持断点续传 | +| 成本追踪 | 未监控 token 使用和成本 | 实现 CostTracker,设置告警阈值 | +| 现有 SRTProcessor | 直接替换规则分段为 LLM | 保持向后兼容,配置开关控制 | + --- ## Performance Traps @@ -513,6 +1610,16 @@ retry_decorator = retry( | 无限制的重试 | 任务永远不结束 | 设置最大重试次数和总超时 | 任何规模 | | 同步等待验证码 | 线程阻塞 | 异步检测 + 用户通知 | 任何规模 | +### LLM Segmentation Performance + +| Trap | Symptoms | Prevention | When It Breaks | +|------|----------|------------|----------------| +| 一次性发送长内容 | API 超时或上下文溢出 | 分块处理,两阶段策略 | >30分钟视频 | +| 无缓存机制 | 重复处理相同内容 | 实现 content-based 缓存 | 任何规模 | +| 同步等待 LLM 响应 | 用户长时间无反馈 | 异步处理 + 进度回调 | >5分钟处理时间 | +| 单线程批量处理 | 处理队列积压 | 限制并发数 + 请求队列 | >10个视频批量处理 | +| 未监控成本 | 账单爆炸 | 追踪 token 使用,设置告警 | 任何规模 | + --- ## Security Mistakes @@ -533,6 +1640,15 @@ retry_decorator = retry( | 忽略 HTTPS 证书验证 | 中间人攻击 | **永不跳过证书验证** | | 代理 URL 包含密码 | 密码泄露 | 分离 server/username/password | +### LLM Segmentation Security + +| Mistake | Risk | Prevention | +|---------|------|------------| +| Prompt 注入 | LLM 执行恶意指令 | 验证输入,使用结构化 prompt | +| API Key 泄露到日志 | 凭证泄露 | 日志脱敏,不记录敏感参数 | +| 未授权访问缓存 | 数据泄露 | 缓存文件权限控制 | +| 发送敏感内容给 LLM | 隐私泄露 | 内容脱敏,用户明确告知 | + --- ## Platform-Specific Pitfalls @@ -556,6 +1672,15 @@ retry_decorator = retry( | 登录必要性 | 部分内容需要登录 | Cookie 持久化管理 | | API 限流 | 单 IP 请求频率限制 | 代理轮换 + 请求间隔 | +### B站视频内容特性 (v1.6) + +| 特性 | 说明 | 应对策略 | +|------|------|----------| +| 长视频(1-2小时) | 知识类视频常见,token 数量大 | 分块处理,两阶段策略 | +| 混合类型内容 | 知识+故事+对话混合 | 视频类型识别,自适应分段策略 | +| 主题切换不明显 | 缺乏明确的过渡词 | 语义分析,识别隐式主题边界 | +| ASR 错误 | 字幕可能包含语音识别错误 | 与 ASR 纠正步骤配合 | + --- ## "Looks Done But Isn't" Checklist @@ -578,6 +1703,19 @@ retry_decorator = retry( - [ ] **日志脱敏:** 是否避免在日志中输出完整 Cookie/密码? - [ ] **集成测试:** 是否测试与现有 Pipeline 的兼容性? +### LLM Segmentation Checklist (v1.6) + +- [ ] **上下文窗口:** 是否实现 token 计数和分块策略? +- [ ] **输出一致性:** 是否使用 temperature=0?Prompt 是否明确边界规则? +- [ ] **句子边界:** 是否强制在句子边界处分段?是否有后处理验证? +- [ ] **标题验证:** 是否验证标题与内容的相似度?低置信度是否标记? +- [ ] **Fallback:** 是否有统一的输出 Schema?Fallback 是否记录原因? +- [ ] **成本控制:** 是否实现缓存?是否追踪 token 使用和成本? +- [ ] **速率限制:** 是否实现请求队列和速率控制? +- [ ] **超时处理:** 是否设置合理的超时时间?是否支持分块处理? +- [ ] **向后兼容:** 是否保持现有接口?是否支持配置开关? +- [ ] **进度可见:** 是否提供进度回调?是否支持断点续传? + --- ## Recovery Strategies @@ -600,6 +1738,18 @@ retry_decorator = retry( | 重试策略错误 | LOW | 1. 修改错误分类 2. 清理重试队列 3. 重新执行 | | Cookie 过期 | LOW | 1. 触发重新登录 2. 更新 Cookie 3. 继续任务 | +### LLM Segmentation Recovery + +| Pitfall | Recovery Cost | Recovery Steps | +|---------|---------------|----------------| +| Context Overflow | MEDIUM | 1. 实现分块策略 2. 添加 token 计数器 3. 测试长视频 | +| Inconsistent Boundaries | HIGH | 1. 修改 Prompt(temperature=0) 2. 实现验证机制 3. 重新处理 | +| Hallucinated Titles | MEDIUM | 1. 添加标题验证 2. 标记低置信度 3. 用户反馈循环 | +| Mid-sentence Breaks | MEDIUM | 1. 强化 Prompt 规则 2. 实现后处理 3. 质量检查 | +| Fallback Failures | HIGH | 1. 重新设计统一 Schema 2. 实现接口抽象 3. 更新所有调用点 | +| Cost Explosion | HIGH | 1. 实现缓存 2. 添加成本监控 3. 使用更便宜的模型 | +| Rate Limiting | MEDIUM | 1. 实现请求队列 2. 添加速率控制 3. 配置并发限制 | + --- ## Pitfall-to-Phase Mapping @@ -628,6 +1778,21 @@ retry_decorator = retry( | 退避无 Jitter | Phase 4 (AC-04: 错误恢复) | 多实例并发测试验证无风暴 | | 平台特性适配 | Phase 5 (AC-05: 知乎) + Phase 6 (AC-06: B站) | 实际平台测试 | +### LLM Segmentation Phases (v1.6) + +| Pitfall | Prevention Phase | Verification | +|---------|------------------|--------------| +| LLM-1: Context Overflow | Phase 1 (架构设计) | 处理1小时视频不溢出 | +| LLM-2: Inconsistent Boundaries | Phase 1 (Prompt 工程) + Phase 2 (验证) | 多次处理相同内容结果一致 | +| LLM-3: Hallucinated Titles | Phase 1 (Prompt) + Phase 2 (验证) + Phase 3 (反馈) | 标题与内容相似度检查通过 | +| LLM-4: Mid-sentence Breaks | Phase 1 (Prompt) + Phase 2 (后处理) | 所有分段在句子边界结束 | +| LLM-5: Fallback Failures | Phase 1 (架构) + Phase 2 (错误处理) + Phase 3 (监控) | Fallback 率 < 10% | +| LLM-6: Video Type Misidentification | Phase 1 (分类器) + Phase 2 (用户覆盖) | 分类准确率 > 80% | +| LLM-7: Cost Explosion | Phase 1 (优化) + Phase 2 (监控) | 单视频成本 < $0.5 | +| LLM-8: Rate Limiting | Phase 1 (速率控制) + Phase 2 (批处理) | 429 错误率 < 5% | +| LLM-9: Integration Issues | Phase 1 (兼容性) + Phase 3 (渐进推出) | 现有测试全部通过 | +| LLM-10: Timeout on Long Videos | Phase 1 (超时) + Phase 2 (分块) | 长视频在合理时间内完成 | + --- ## Sources @@ -670,6 +1835,50 @@ retry_decorator = retry( - `kb_workflow/crawler/config.py` - 现有配置结构 - `kb_workflow/pipeline/retry.py` - 现有重试机制 +### LLM Segmentation Sources (v1.6) + +**Context Window & Token Limits:** +- [The LLM context problem in 2026](https://blog.logrocket.com/llm-context-problem/) - LogRocket Blog +- [Context Window Overflow in 2026](https://redis.io/blog/context-window-overflow/) - Redis Blog +- [Navigating Frontier LLM Context Window Limitations](https://www.hangryfeed.com/insights/posts/frontier-llm-context-window-limitations-2026-01-15) - HangryFeed +- [Context Length Comparison: Leading AI Models in 2026](https://www.elvex.com/blog/context-length-comparison-ai-models-2026) - Elvex + +**Segmentation & Consistency:** +- [LLM-Enhanced Semantic Text Segmentation](https://www.mdpi.com/2076-3417/15/19/10849) - MDPI +- [Best Chunking Strategies for RAG in 2026](https://www.firecrawl.dev/blog/best-chunking-strategies-rag) - Firecrawl +- [WTPSplit - Sentence Boundary Detection](https://github.com/segment-any-text/wtpsplit) - GitHub +- [Semantic Boundary Detection for RAG](https://www.inferable.ai/blog/posts/semantic-boundary-detection-rag-agents) - Inferable + +**Hallucination Detection:** +- [LLM Hallucinations in 2026](https://www.lakera.ai/blog/guide-to-hallucinations-in-large-language-models) - Lakera AI +- [Hallucination Detection and Mitigation in LLMs](https://arxiv.org/pdf/2601.09929) - arXiv +- [Detecting hallucinations with LLM-as-a-judge](https://www.datadoghq.com/blog/ai/llm-hallucination-detection/) - Datadog +- [AI Hallucinations: Definition, Examples & How to Prevent](https://gptzero.me/news/ai-hallucinations-definition-examples/) - GPTZero + +**Fallback & Reliability:** +- [Agentic Workflows in 2026: LLM Calls with Fallbacks](https://vellum.ai/blog/agentic-workflows-emerging-architectures-and-design-patterns) - Vellum AI +- [LLM System Design: The Complete Guide](https://www.systemdesignhandbook.com/guides/llm-system-design/) - System Design Handbook +- [Handling Timeouts and Retries in LLM Systems](https://dasroot.net/posts/2026/02/handling-timeouts-retries-llm-systems/) - Dasroot! +- [Error Handling & Retries: Making LLM Calls Reliable](https://medium.com/@sonitanishk2003/error-handling-retries-making-llm-calls-reliable-ee7722fc2ea9) - Medium + +**Cost & Performance:** +- [LLM Cost Optimization in 2026](https://www.maviklabs.com/blog/llm-cost-optimization-2026) - Mavik Labs +- [Complete LLM Pricing Comparison 2026](https://www.cloudidr.com/blog/llm-pricing-comparison-2026) - CloudIDR +- [LLMOps Guide 2026](https://redis.io/blog/large-language-model-operations-guide/) - Redis + +**Rate Limiting:** +- [Prompt Rate Limits & Batching](https://dev.to/superorange0707/prompt-rate-limits-batching-how-to-stop-your-llm-api-from-melting-down-56e1) - Dev.to +- [Rate Limiting in AI Gateway](https://www.truefoundry.com/blog/rate-limiting-in-llm-gateway) - TrueFoundry + +**Video Content Classification:** +- [Multimodal LLMs in 2026: Annotation Challenges](https://www.nextwealth.com/blog/multimodal-llms-in-2026-annotation-challenges-when-ai-needs-to-see-hear-and-read/) - NextWealth +- [HiVid: LLM-Guided Video Saliency Research](https://arxiv.org/pdf/2602.14214) - arXiv + +**Integration Best Practices:** +- [LLMOps Guide 2026](https://redis.io/blog/large-language-model-operations-guide/) - Redis +- [LLM Pipeline Re-Architecture Best Practices](https://www.linkedin.com/top-content/technology/best-practices-in-technology/llm-pipeline-re-architecture-best-practices/) - LinkedIn +- [How to Build a RAG Pipeline from Scratch in 2026](https://www.kapa.ai/blog/how-to-build-a-rag-pipeline-from-scratch-in-2026) - Kapa.ai + --- -*Pitfalls research for: Skill-based Workflow Orchestration + Anti-Crawler Optimization* -*Researched: 2026-03-13 (Pipeline), 2026-03-18 (Anti-Crawler)* +*Pitfalls research for: Skill-based Workflow Orchestration + Anti-Crawler Optimization + LLM Semantic Segmentation* +*Researched: 2026-03-13 (Pipeline), 2026-03-18 (Anti-Crawler), 2026-03-21 (LLM Segmentation)* diff --git a/.planning/research/STACK_SEMANTIC_SEGMENTATION.md b/.planning/research/STACK_SEMANTIC_SEGMENTATION.md new file mode 100644 index 0000000..421a0c3 --- /dev/null +++ b/.planning/research/STACK_SEMANTIC_SEGMENTATION.md @@ -0,0 +1,494 @@ +# Technology Stack - LLM Semantic Segmentation for SRT Subtitles + +**Project:** kb-skills v1.6 - Semantic Segmentation Improvement +**Researched:** 2026-03-21 +**Focus:** Stack additions for LLM-based semantic segmentation of B站 SRT subtitles + +## Executive Summary + +**无需新的外部依赖** - 基于现有SimpleAIClient扩展,使用Pydantic v2进行结构化输出验证。 + +核心架构: +- **Prompt Engineering**: 两阶段分析(视频类型分类 → 主题分段) +- **Response Parsing**: Pydantic v2 models with fallback +- **Integration**: 扩展现有SemanticSegmenter,保持向后兼容 + +--- + +## Required Libraries (None New) + +### Existing Stack (Already Available) +| Library | Version | Purpose | Why | +|---------|---------|---------|-----| +| Pydantic | v2 | Schema validation | Already in use, perfect for LLM output validation | +| SimpleAIClient | Custom | LLM calls | Existing integration, supports zhipu/openai/minimax | +| Python | 3.12+ | Type hints & modern features | Match existing requirement | + +### NO New Dependencies Required +All functionality can be built using existing stack. The Pydantic v2 already available provides robust JSON parsing and validation capabilities needed for LLM response handling. + +--- + +## LLM Prompt Engineering Approach + +### Two-Stage Analysis Strategy + +Based on research from [Chapter-Llama (CVPR 2025)](https://arxiv.org/html/2504.00072v1) and [Automate Video Chaptering with LLMs](https://towardsdatascience.com/automate-video-chaptering-with-llms-and-tf-idf-f6569fd4d32b/), a two-stage approach provides better accuracy than single-shot analysis: + +#### Stage 1: Video Type Detection +**Purpose:** Classify video type to apply appropriate segmentation strategy + +**Prompt Template:** +```python +VIDEO_TYPE_PROMPT = """你是一个视频内容分析专家。请根据以下字幕内容,判断视频类型。 + +【字幕内容】(前5000字符) +{text_preview} + +【视频信息】 +标题:{title} +时长:{duration_str} + +【任务】判断视频类型,从以下类别中选择最匹配的一个: +- tutorial: 教程类(步骤清晰、教学导向) +- knowledge: 知识类(讲解概念、理论分析) +- story: 故事类(叙事、情节发展) +- interview: 访谈类(对话、问答) +- commentary: 评论类(观点表达、分析讨论) +- mixed: 混合类型(包含多种元素) + +【输出格式】只输出类型代码(如 tutorial),不要解释。""" +``` + +**Response Format:** Plain text type code (single word) + +**Why Simple Output:** +- Reduces parsing complexity +- Lower error rate +- Faster processing +- Can be cached for similar content + +#### Stage 2: Semantic Segmentation +**Purpose:** Identify topic boundaries and generate chapter titles + +**Prompt Template:** +```python +SEMANTIC_SEGMENTATION_PROMPT = """你是一个视频内容结构化专家。请将以下字幕按语义主题分段。 + +【字幕内容】 +{full_text} + +【视频类型】:{video_type} +【视频信息】 +标题:{title} +总时长:{duration_str} + +【任务】 +1. 分析字幕内容,识别主题变化边界 +2. 将内容分为{target_segments}个段落 +3. 为每个段落生成简洁标题(不超过15字) + +【分段原则】 +- 保持论点完整性,不要在句子中间截断 +- 在话题转换处分段 +- 考虑{video_type}的特点: + * tutorial: 按步骤/章节分段 + * knowledge: 按概念/论点分段 + * story: 按情节发展分段 + * interview: 按话题/问答分段 + * commentary: 按观点段落分段 + * mixed: 综合以上策略 + +【输出格式】必须严格遵循以下JSON格式: +{{ + "segments": [ + {{ + "title": "段落标题", + "start_index": 0, + "end_index": 150, + "summary": "段落主题摘要(30字以内)" + }} + ], + "overall_summary": "整体内容摘要(100字以内)" +}} + +注意: +- start_index 和 end_index 是字符在原文中的位置(从0开始) +- 确保segments覆盖全部内容,不遗漏不重复 +- 只输出JSON,不要包含其他内容""" +``` + +**Response Format:** Structured JSON with Pydantic validation + +**Why JSON Output:** +- Machine-readable for precise mapping +- Supports Pydantic validation +- Enables error recovery +- Matches existing workflow patterns + +--- + +## Response Format Specifications + +### Pydantic Schemas for LLM Output + +Based on best practices from [Pydantic validation guides](https://machinelearningmastery.com/the-complete-guide-to-using-pydantic-for-validating-llm-outputs/): + +```python +from pydantic import BaseModel, Field, field_validator +from typing import List + +class VideoSegment(BaseModel): + """Single semantic segment""" + + title: str = Field(..., min_length=1, max_length=50, description="Segment title") + start_index: int = Field(..., ge=0, description="Start character position in text") + end_index: int = Field(..., ge=0, description="End character position in text") + summary: str = Field(..., min_length=1, max_length=100, description="Segment summary") + + @field_validator('end_index') + @classmethod + def validate_bounds(cls, v, info): + """Ensure end_index > start_index""" + if 'start_index' in info.data and v <= info.data['start_index']: + raise ValueError('end_index must be greater than start_index') + return v + +class SegmentationResult(BaseModel): + """Complete segmentation result from LLM""" + + segments: List[VideoSegment] = Field(..., min_length=1, description="List of segments") + overall_summary: str = Field(..., min_length=1, max_length=200, description="Overall summary") + + @field_validator('segments') + @classmethod + def validate_segments(cls, v): + """Ensure segments are sorted and non-overlapping""" + if not v: + raise ValueError('segments cannot be empty') + + # Sort by start_index + sorted_segments = sorted(v, key=lambda x: x.start_index) + + # Check for overlaps + for i in range(len(sorted_segments) - 1): + if sorted_segments[i].end_index > sorted_segments[i + 1].start_index: + raise ValueError(f'Segments {i} and {i+1} overlap') + + return sorted_segments +``` + +### Response Parsing Strategy + +**Three-tier fallback strategy** (inspired by [reliable LLM outputs](https://www.freecodecamp.org/news/how-to-keep-llm-outputs-predictable-using-pydantic-validation/)): + +```python +def parse_llm_response(response_text: str, total_length: int) -> SegmentationResult: + """Parse LLM response with multiple fallback strategies""" + + # Strategy 1: Direct JSON parsing + try: + return SegmentationResult.model_validate_json(response_text) + except Exception as e: + logger.warning(f"Direct JSON parsing failed: {e}") + + # Strategy 2: Extract JSON from markdown code blocks + try: + import re + json_match = re.search(r'```json\s*(.*?)\s*```', response_text, re.DOTALL) + if json_match: + return SegmentationResult.model_validate_json(json_match.group(1)) + except Exception as e: + logger.warning(f"Markdown JSON extraction failed: {e}") + + # Strategy 3: Heuristic fallback - simple equal-length segments + logger.warning("All parsing strategies failed, using heuristic fallback") + return _generate_fallback_segments(total_length) +``` + +--- + +## Integration with Existing SimpleAIClient + +### Architecture Pattern + +Based on existing `ASRCorrector` pattern in `kb_workflow/srt/corrector.py`: + +```python +from typing import Optional, Protocol +from kb_workflow.deep_analyzer import SimpleAIClient + +class AIClientProtocol(Protocol): + """AI Client Protocol (already exists)""" + def generate(self, prompt: str, max_tokens: int = 16000, disable_reasoning: bool = None) -> str: + ... + +class SemanticSegmentationEngine: + """LLM-powered semantic segmentation engine""" + + def __init__( + self, + ai_client: Optional[AIClientProtocol] = None, + enable_fallback: bool = True + ): + self.ai_client = ai_client + self.enable_fallback = enable_fallback + + def detect_video_type(self, text_preview: str, metadata: dict) -> str: + """Stage 1: Detect video type""" + if self.ai_client is None: + return "mixed" # Default fallback + + prompt = VIDEO_TYPE_PROMPT.format( + text_preview=text_preview[:5000], + title=metadata.get('title', ''), + duration_str=self._format_duration(metadata.get('duration', 0)) + ) + + try: + response = self.ai_client.generate(prompt, max_tokens=100, disable_reasoning=True) + return response.strip().lower() + except Exception as e: + logger.warning(f"Video type detection failed: {e}") + return "mixed" + + def segment_semantically( + self, + full_text: str, + video_type: str, + metadata: dict, + target_segments: int = 5 + ) -> SegmentationResult: + """Stage 2: Perform semantic segmentation""" + if self.ai_client is None: + return self._generate_fallback_segments(len(full_text)) + + prompt = SEMANTIC_SEGMENTATION_PROMPT.format( + full_text=full_text, + video_type=video_type, + title=metadata.get('title', ''), + duration_str=self._format_duration(metadata.get('duration', 0)), + target_segments=target_segments + ) + + try: + response = self.ai_client.generate(prompt, max_tokens=4000, disable_reasoning=False) + return parse_llm_response(response, len(full_text)) + except Exception as e: + logger.warning(f"Semantic segmentation failed: {e}") + if self.enable_fallback: + return self._generate_fallback_segments(len(full_text)) + raise +``` + +### Integration Point in SRTProcessor + +Minimal changes to existing `kb_workflow/pipeline/processors/srt.py`: + +```python +class SRTProcessor(BaseProcessor): + def __init__( + self, + state_manager: Optional[WorkflowStateManager] = None, + enable_correction: bool = True, + enable_semantic_segmentation: bool = True # NEW parameter + ): + super().__init__(state_manager) + self.enable_correction = enable_correction + self.enable_semantic_segmentation = enable_semantic_segmentation + self.segmenter = SemanticSegmenter() + self.corrector = None + self.semantic_engine = None # NEW + + # Lazy initialization + if enable_semantic_segmentation: + try: + from kb_workflow.srt.semantic_engine import SemanticSegmentationEngine + from kb_workflow.deep_analyzer import SimpleAIClient + + ai_client = SimpleAIClient() + if ai_client.api_key: + self.semantic_engine = SemanticSegmentationEngine(ai_client=ai_client) + logger.info("Semantic segmentation engine initialized") + except Exception as e: + logger.warning(f"Failed to initialize semantic engine: {e}") + + async def process(self, input_data: SRTInput) -> SRTOutput: + # ... existing parsing code ... + + # Step 2: Enhanced semantic segmentation + if self.semantic_engine and self.enable_semantic_segmentation: + logger.info("Using LLM-based semantic segmentation") + paragraphs = self._semantic_segment_with_llm(segments, metadata) + else: + logger.info("Using rule-based segmentation") + paragraphs = self.segmenter.segment(segments) + + # ... rest of existing pipeline ... + + def _semantic_segment_with_llm( + self, + segments: List[Segment], + metadata: dict + ) -> List[str]: + """Use LLM for intelligent segmentation""" + # Combine segments into full text + full_text = ' '.join(seg.text for seg in segments) + + # Stage 1: Detect video type + video_type = self.semantic_engine.detect_video_type(full_text, metadata) + + # Stage 2: Semantic segmentation + result = self.semantic_engine.segment_semantically( + full_text=full_text, + video_type=video_type, + metadata=metadata, + target_segments=self._calculate_target_segments(len(full_text)) + ) + + # Extract paragraph texts based on indices + paragraphs = [ + full_text[seg.start_index:seg.end_index].strip() + for seg in result.segments + ] + + return paragraphs +``` + +--- + +## What NOT to Add (Scope Boundaries) + +### Explicitly Out of Scope + +| Feature | Why NOT to Add | Alternative | +|---------|----------------|-------------| +| **LangChain** | Over-engineering for single LLM call | Direct SimpleAIClient usage | +| **New LLM providers** | Existing 3 providers sufficient | Extend zhipu/openai/minimax | +| **Vector embeddings** | Not needed for segmentation | Plain text analysis | +| **Chunking strategies** | LLM handles full context | Single-pass analysis | +| **Streaming responses** | Batch processing is fine | Await full response | +| **Multi-modal analysis** | Only text (SRT) available | Text-only prompts | +| **Dedicated segmentation models** | LLM is more flexible | Prompt engineering | +| **Database storage** | Not needed for pipeline | In-memory processing | +| **Real-time processing** | Batch is acceptable | Async processing | +| **Custom tokenizer** | Not needed for this use case | Character-based indexing | +| **Caching layer** | Adds complexity | Simple in-memory memoization | + +### Architecture Anti-Patterns to Avoid + +**From [video chaptering research](https://medium.com/codex/ai-based-video-analyzer-for-automated-chaptering-and-summarization-2ca65f35b687):** + +1. **❌ Single-shot segmentation** + - Problem: Too complex for one prompt + - Solution: Two-stage approach (type → segment) + +2. **❌ Fixed segment count** + - Problem: Ignores content structure + - Solution: Adaptive target based on length + +3. **❌ Pure time-based segmentation** + - Problem: Breaks semantic coherence + - Solution: Content-aware boundaries + +4. **❌ JSON parsing without validation** + - Problem: Malformed LLM output + - Solution: Pydantic + fallback strategies + +--- + +## Implementation Priority + +### Phase 1: Core Segmentation (MVP) +1. Video type detection prompt +2. Semantic segmentation prompt +3. Pydantic response models +4. Basic integration with SRTProcessor + +### Phase 2: Robustness (Post-MVP) +1. Fallback strategies +2. Error recovery +3. Logging and debugging +4. Performance optimization + +### Phase 3: Enhancement (Future) +1. Caching for similar content +2. Adaptive segment count +3. User feedback integration +4. A/B testing framework + +--- + +## Configuration Strategy + +### Environment Variables (No New Variables Needed) + +Reuse existing AI configuration: +```bash +# Already in use +AI_API_KEY=your_key +AI_PROVIDER=zhipu # or openai, minimax +AI_MODEL=glm-5 +AI_BASE_URL=https://open.bigmodel.cn/api/coding/paas/v4 +``` + +### Optional Parameters (YAML Config) + +Add to existing `.kb_env.yaml`: +```yaml +semantic_segmentation: + enabled: true + enable_fallback: true + default_video_type: mixed + min_segment_length: 200 # characters + max_segment_length: 2000 # characters + target_segment_count: 5 +``` + +--- + +## Testing Strategy + +### Unit Tests +- Pydantic model validation +- Response parsing strategies +- Fallback mechanisms + +### Integration Tests +- End-to-end SRT processing +- Error recovery paths +- Performance benchmarks + +### Manual Testing +- Real B站 videos +- Different video types +- Edge cases (very short/long content) + +--- + +## Sources + +### Prompt Engineering & Segmentation +- [Chapter-Llama: Efficient Chaptering in Hour-Long Videos with LLMs (CVPR 2025)](https://arxiv.org/html/2504.00072v1) - HIGH confidence, academic research on LLM-based video chaptering +- [Automate Video Chaptering with LLMs and TF-IDF](https://towardsdatascience.com/automate-video-chaptering-with-llms-and-tf-idf-f6569fd4d32b/) - MEDIUM confidence, practical implementation guide +- [AI-Based Video Analyzer for Automated Chaptering and Summarization](https://medium.com/codex/ai-based-video-analyzer-for-automated-chaptering-and-summarization-2ca65f35b687) - MEDIUM confidence, real-world application +- [Azure AI Video Indexer with LLM Prompts](https://learn.microsoft.com/en-us/azure/azure-video-indexer/prompt-overview) - HIGH confidence, official documentation + +### Pydantic Validation +- [The Complete Guide to Using Pydantic for Validating LLM Outputs](https://machinelearningmastery.com/the-complete-guide-to-using-pydantic-for-validating-llm-outputs/) - HIGH confidence, comprehensive guide +- [A Practical Guide on Structuring LLM Outputs with Pydantic](https://nuno-bispo.medium.com/a-practical-guide-on-structuring-llm-outputs-with-pydantic-68f9f363e26e) - HIGH confidence, practical examples +- [Building Reliable LLM Applications with Pydantic Validation](https://pub.towardsai.net/building-reliable-llm-applications-with-pydantic-validation-7241a93cebb3) - MEDIUM confidence, reliability patterns + +### LLM Best Practices +- [The Ultimate Guide to Prompt Engineering in 2026](https://www.lakera.ai/blog/prompt-engineering-guide) - HIGH confidence, current best practices +- [Context Engineering for Video Understanding](https://www.twelvelabs.io/blog/context-engineering-for-video-understanding) - MEDIUM confidence, video-specific context design +- [Harnessing LLMs for Automated Video Content Analysis](https://arxiv.org/html/2406.19528v3) - HIGH confidence, academic research + +### Video Analysis +- [Learning Video LLM with Streaming Speech Transcription at Scale (CVPR 2025)](https://cvpr.thecvf.com/virtual/2025/poster/33157) - HIGH confidence, 2025 research +- [Long Video Summarization via Key Moment Extraction (2026)](https://aclanthology.org/2026.iwsds-1.22.pdf) - HIGH confidence, 2026 research + +### Confidence Notes +- HIGH: Academic papers, official documentation, peer-reviewed sources +- MEDIUM: Industry blogs, practical tutorials, real-world implementations +- LOW: Single-source claims, unverified practices (avoided in this document) diff --git a/.planning/research/SUMMARY.md b/.planning/research/SUMMARY.md index 4353cfe..c4515ea 100644 --- a/.planning/research/SUMMARY.md +++ b/.planning/research/SUMMARY.md @@ -1,188 +1,523 @@ -# Project Research Summary +# Research Summary: LLM Semantic Segmentation for SRT Subtitles -**Project:** kb-skills (Skill-based Workflow Orchestration System) -**Domain:** Content Processing Pipeline with LLM Agent Orchestration -**Researched:** 2026-03-13 -**Confidence:** HIGH +**Project:** kb-skills v1.6 - Semantic Segmentation Improvement +**Research Date:** 2026-03-21 +**Synthesized from:** STACK_SEMANTIC_SEGMENTATION.md, FEATURES.md, ARCHITECTURE.md, PITFALLS.md + +--- ## Executive Summary -这是一个技能型工作流编排系统,专门用于内容处理管道(视频/文章的元数据提取、ASR识别、AI深度分析)。专家构建此类系统时,通常采用分层架构将编排层、技能定义层、执行层和基础设施层分离,并使用步骤级状态管理实现断点续传和幂等执行。 +**核心发现:无需新增外部依赖,基于现有技术栈实现LLM语义分段** -基于研究,推荐采用**串行管道编排模式**,使用 `transitions` 状态机管理步骤状态,`Pydantic` 定义 Schema 并实现验证。核心原则是:每个步骤完成后立即持久化状态,失败时可以从断点恢复,重复执行不会产生重复文件。这与 Airflow/Prefect 等重量级编排工具不同——本项目专注于单机批处理场景,无需分布式执行。 +- **技术方案**:使用现有 SimpleAIClient + Pydantic v2 实现两阶段分析(视频类型分类 → 主题分段),无需引入 LangChain、向量数据库等新依赖 +- **架构集成**:扩展现有 `SemanticSegmenter`,在 `SRTProcessor` 中新增 LLM 分支,保持向后兼容(可通过 `enable_semantic_segmentation` 参数控制) +- **关键风险**:长视频上下文溢出(>10万字符)、LLM输出格式不稳定、分段边界破坏语义完整性 — 需要通过分块策略、多层fallback、边界保护机制缓解 -关键风险在于**无状态执行**和**错误上下文丢失**。长时间运行的任务(Whisper识别可能需要30分钟)如果失败后需要从头开始,成本极高。缓解措施是在 Phase 1 就实现 `workflow_state.json` 状态文件,并确保每个步骤输出结构化错误信息。 +**推荐实施路径**:优先实现MVP(类型识别+语义分段+标题生成),高级特性(分层结构、质量评分、说话人识别)延后至v2.0 -## Key Findings +--- -### Recommended Stack +## Stack Additions -推荐使用 Python 3.12+ 作为运行时,配合 Pydantic 2.11+ 进行数据验证和 JSON Schema 生成,transitions 0.9.3+ 实现步骤状态机,Typer + Rich 构建现代化 CLI。这套组合轻量、Pythonic,与项目的 SKILL.md 规范模式完美契合。 +### 无需新增外部依赖 -**Core technologies:** -- **Pydantic 2.11+**: 数据验证 & Schema 生成 — v2.11+ 解析速度更快,原生支持 JSON Schema,与 PIPE-07 需求匹配 -- **transitions 0.9.3+**: 状态机 — 轻量级、支持回调和嵌套状态,无需数据库 -- **pydantic-settings 2.8+**: 配置管理 — 解决现有 `~/.kb_env` 分散配置问题 -- **Typer 0.15+**: CLI 框架 — 基于 Click 的现代 CLI,利用类型提示自动生成参数 -- **tenacity 8.5+**: 重试机制 — 实现指数退避重试,处理 API 调用失败 +**所有功能基于现有技术栈实现:** -**避免使用:** Airflow/Celery(过重)、argparse(样板代码多)、requests(同步阻塞) +| 现有组件 | 新用途 | 理由 | +|---------|--------|------| +| **SimpleAIClient** | LLM调用(类型分类、语义分段) | 已集成zhipu/openai/minimax,支持结构化输出 | +| **Pydantic v2** | LLM响应验证与解析 | 提供严格的JSON schema验证,支持多层fallback | +| **SemanticSegmenter** | 集成点,保持向后兼容 | 现有规则分段保留,新增LLM分支 | -### Expected Features +### 明确排除的技术(避免过度工程) -**Must have (table stakes):** -- **步骤级状态管理** — 用户期望能从断点恢复,不重新执行已完成的步骤 -- **幂等执行** — 相同输入重复执行产生相同结果,无重复文件 -- **JSON Schema 验证** — 数据契约确保步骤间接口一致性 -- **结构化错误处理** — 错误消息包含上下文和可操作建议 -- **平台特定内容处理** — B站/知乎元数据和内容提取 +| 排除技术 | 理由 | +|---------|------| +| LangChain | 单次LLM调用无需编排框架 | +| 向量嵌入/数据库 | 语义分段不需要检索 | +| 专用分段模型 | LLM灵活性更高,无需额外训练 | +| 实时流式处理 | 批处理模式已满足需求 | +| 多模态分析 | 仅处理SRT文本,无视频帧 | -**Should have (competitive):** -- **SKILL.md 声明式技能定义** — AI 代理可发现和执行技能 -- **多模态内容处理** — 视频(ASR/OCR)+文本统一管道 -- **Tmux 会话持久化** — 长时间运行操作可断开终端 +### 配置策略 -**Defer (v2+):** -- **并发执行** — 当前串行模式足够,并发增加复杂度 -- **Web UI** — CLI 优先,可视化需求低 -- **多租户** — 单用户工具 +**无需新增环境变量**,复用现有AI配置: +```bash +# 已有配置,直接复用 +AI_API_KEY=your_key +AI_PROVIDER=zhipu # or openai, minimax +AI_MODEL=glm-5 +``` -### Architecture Approach +**可选YAML配置**(`.kb_env.yaml`): +```yaml +semantic_segmentation: + enabled: true + enable_fallback: true + default_video_type: mixed + min_segment_length: 200 # 字符 + max_segment_length: 2000 # 字符 + target_segment_count: 5 +``` -推荐四层架构:编排层(Workflow Coordinator、State Manager、Error Handler)、技能定义层(SKILL.md specs、Schema Definitions)、执行层(Platform/Processing/Analysis Skills)、基础设施层(File System、External APIs、AI Services)。 +--- -**Major components:** -1. **State Manager** — 管理 `workflow_state.json`,实现步骤级状态持久化和原子写入 -2. **Schema Registry** — 统一的输入输出 JSON Schema 定义和验证 -3. **Pipeline Engine** — 串行执行技能,检查状态跳过已完成步骤 -4. **Platform Skills** — B站/知乎的元数据提取和内容下载 -5. **Processing Skills** — Whisper/FunASR 语音识别、OCR 处理 -6. **Analysis Skills** — kb-deep-analyzer AI 深度分析 +## Feature Categories -### Critical Pitfalls +### Table Stakes (MVP必须实现) -1. **无状态执行 = 从头重来** — Whisper 识别 20 分钟后失败,没有状态文件则需要重新识别。避免:每个步骤完成后写入 `workflow_state.json` +**用户期望的基础功能,缺失会让产品感觉"不完整":** -2. **错误上下文丢失** — 步骤 6 失败只报告 "API error",不知道是哪个内容、什么输入。避免:结构化 JSON 错误,包含步骤名、输入摘要、失败原因、可操作建议 +| 功能 | 复杂度 | 实施优先级 | 说明 | +|------|--------|-----------|------| +| **视频类型识别** | Medium | P0 | 识别6种类型(tutorial/knowledge/story/interview/commentary/mixed),决定分段策略 | +| **主题边界检测** | High | P0 | 基于语义相似度/词频变化检测话题转换点 | +| **内容完整性保护** | High | P0 | 避免在句子/论点中间截断,保持语义连贯 | +| **自然句边界检测** | Medium | P0 | 中文断句(无明确句号),语义判断停顿 | +| **主题标题生成** | Medium | P0 | 为每段生成简洁标题(≤15字) | +| **基本分段策略** | Medium | P0 | 至少支持知识类、故事类两种策略 | -3. **假设模型"理解上下文"** — 主代理期望子代理知道之前发生了什么,但每次调用是独立会话。避免:显式传递所有需要的上下文,输入 JSON 自包含 +### Differentiators (竞争力功能,v2.0考虑) -4. **非幂等操作** — 每次执行创建 `output_1.mp4`、`output_2.mp4`。避免:基于输入生成确定性文件名,已存在则跳过 +**非必需但有价值的功能:** -5. **环境变量分散** — `~/.kb_env`、子技能配置、HF_TOKEN 分散各处。避免:统一配置文件,启动时检查所有必需变量 +| 功能 | 复杂度 | 价值 | 建议版本 | +|------|--------|------|---------| +| **分层主题结构** | High | 支持多级层次(章-节) | v2.0 | +| **时间戳对齐** | Medium | 分段与原字幕时间对齐 | v2.0 | +| **分段质量评分** | Medium | 给出质量可信度 | v2.0 | +| **说话人识别集成** | High | 结合说话人变化优化 | v2.0 | +| **可配置分段粒度** | Low | 用户控制分段密度 | v2.0 | +| **分段合并建议** | Medium | 检测过短分段并建议合并 | v2.0 | +| **主题连贯性分析** | High | 评估分段内部一致性 | v2.0 | + +### Anti-Features (明确不构建) + +**避免的功能陷阱:** + +| 反功能 | 风险 | 替代方案 | +|--------|------|---------| +| **固定大小分段** | 破坏语义完整性 | 基于内容边界动态分段 | +| **纯关键词匹配** | 无法理解上下文 | 使用LLM语义分析 | +| **实时流式分段** | 缺乏全局上下文 | 批处理完整内容 | +| **多语言混合处理** | 逻辑复杂降低质量 | 先分离语言再处理 | +| **完全自动化无审核** | LLM误判边界 | 提供预览和手动调整 | +| **过度细分段** | 碎片化降低可读性 | 设置最小长度阈值 | + +### 视频类型与分段策略映射 + +**不同类型视频的分段特征:** + +| 视频类型 | 分段依据 | 边界信号 | 标题风格 | 典型长度 | +|---------|---------|---------|---------|---------| +| **知识类** | 主题/知识点变化 | "接下来"、"其次" | 描述性,反映知识点 | 2-5分钟 | +| **故事类** | 情节发展/场景变化 | 时间/地点/人物转换 | 叙事性,反映情节 | 5-10分钟 | +| **访谈类** | 问题/话题转换 | 主持人提问 | 问答式,反映主题 | 3-6分钟 | +| **新闻类** | 新闻条目 | "接下来是"、"据报道" | 信息性,反映事件 | 1-3分钟 | +| **Vlog类** | 活动/场景变化 | 时间跳跃/地点切换 | 描述性,反映活动 | 1-8分钟 | +| **混合类** | 综合以上策略 | 多种信号 | 综合风格 | 变化大 | + +--- + +## Architecture Integration + +### 集成点:扩展现有 SRTProcessor + +**最小改动原则**,在现有 `kb_workflow/pipeline/processors/srt.py` 中新增LLM分支: + +```python +class SRTProcessor(BaseProcessor): + def __init__( + self, + state_manager: Optional[WorkflowStateManager] = None, + enable_correction: bool = True, + enable_semantic_segmentation: bool = True # 新增参数 + ): + # ... 现有初始化 ... + self.semantic_engine = None # 新增字段 + + # 延迟初始化LLM引擎 + if enable_semantic_segmentation: + try: + from kb_workflow.srt.semantic_engine import SemanticSegmentationEngine + from kb_workflow.deep_analyzer import SimpleAIClient + + ai_client = SimpleAIClient() + if ai_client.api_key: + self.semantic_engine = SemanticSegmentationEngine(ai_client=ai_client) + except Exception as e: + logger.warning(f"Failed to init semantic engine: {e}") + + async def process(self, input_data: SRTInput) -> SRTOutput: + # ... 现有解析代码 ... + + # 新增:LLM分段分支 + if self.semantic_engine and self.enable_semantic_segmentation: + logger.info("Using LLM-based semantic segmentation") + paragraphs = self._semantic_segment_with_llm(segments, metadata) + else: + logger.info("Using rule-based segmentation") + paragraphs = self.segmenter.segment(segments) # 现有逻辑 + + # ... 后续处理不变 ... +``` + +### 新增模块:SemanticSegmentationEngine + +**位置**:`kb_workflow/srt/semantic_engine.py` + +**职责**: +- **Stage 1**: 视频类型检测(few-shot分类,输出类型代码) +- **Stage 2**: 语义分段(结构化JSON输出,Pydantic验证) +- **Fallback**: 三层降级策略(直接解析 → Markdown提取 → 均匀分段) + +**关键设计**: + +```python +class SemanticSegmentationEngine: + def __init__( + self, + ai_client: Optional[AIClientProtocol] = None, + enable_fallback: bool = True + ): + self.ai_client = ai_client + self.enable_fallback = enable_fallback + + def detect_video_type(self, text_preview: str, metadata: dict) -> str: + """Stage 1: 检测视频类型(tutorial/knowledge/...)""" + # 返回类型代码,失败返回 "mixed" + + def segment_semantically( + self, + full_text: str, + video_type: str, + metadata: dict, + target_segments: int = 5 + ) -> SegmentationResult: + """Stage 2: 执行语义分段""" + # 返回结构化分段结果,带Pydantic验证 +``` + +### Pydantic Schema:严格验证LLM输出 + +**位置**:`kb_workflow/srt/schemas.py` + +```python +class VideoSegment(BaseModel): + """单个语义分段""" + title: str = Field(..., min_length=1, max_length=50) + start_index: int = Field(..., ge=0) + end_index: int = Field(..., ge=0) + summary: str = Field(..., min_length=1, max_length=100) + + @field_validator('end_index') + def validate_bounds(cls, v, info): + if 'start_index' in info.data and v <= info.data['start_index']: + raise ValueError('end_index must be greater than start_index') + return v + +class SegmentationResult(BaseModel): + """完整分段结果""" + segments: List[VideoSegment] = Field(..., min_length=1) + overall_summary: str = Field(..., min_length=1, max_length=200) + + @field_validator('segments') + def validate_segments(cls, v): + # 检查重叠和排序 + ... +``` + +### 三层Fallback策略 + +**确保鲁棒性**,LLM失败时优雅降级: + +1. **Strategy 1**: 直接JSON解析(理想情况) +2. **Strategy 2**: Markdown代码块提取(常见情况) +3. **Strategy 3**: 启发式均匀分段(保底方案) + +```python +def parse_llm_response(response_text: str, total_length: int) -> SegmentationResult: + # 1. 直接解析 + try: + return SegmentationResult.model_validate_json(response_text) + except Exception: + pass + + # 2. 提取Markdown中的JSON + try: + json_match = re.search(r'```json\s*(.*?)\s*```', response_text, re.DOTALL) + if json_match: + return SegmentationResult.model_validate_json(json_match.group(1)) + except Exception: + pass + + # 3. 保底:均匀分段 + return _generate_fallback_segments(total_length) +``` + +### 数据流 + +``` +SRT Input + ↓ +[Parse Subtitles] → segments: List[Segment] + ↓ +[Video Type Detection] → video_type: str (mixed/tutorial/knowledge/...) + ↓ +[Semantic Segmentation] → SegmentationResult (segments + titles + summaries) + ↓ +[Extract Paragraphs] → paragraphs: List[str] (基于start_index/end_index) + ↓ +[ASR Correction] → corrected_paragraphs: List[str] + ↓ +[Deep Analysis] → analysis_results +``` + +--- + +## Watch Out For + +### 严重陷阱(必须避免) + +#### 1. 上下文窗口溢出导致长视频处理失败 + +**风险**:B站知识类视频常达1-2小时,字幕超10万字符,直接发送会触发API错误或内容截断。 + +**缓解策略**: +- **分块处理**:先按现有时间间隔(3秒停顿)预分块,再合并至80k token以下 +- **两阶段分析**:Stage 1用小模型快速扫描定位潜在边界,Stage 2仅对可疑区域深度分析 +- **Token计数**:使用 `tiktoken` 实时计算,动态调整分段策略 + +**实施阶段**:Phase 1 (架构设计时必须考虑) + +--- + +#### 2. LLM输出格式不稳定导致解析失败 + +**风险**:LLM可能返回: +- 纯文本而非JSON +- JSON包裹在Markdown代码块中 +- 缺少必需字段 +- 字段类型错误(如字符串而非数字) + +**缓解策略**: +- **多层fallback**:直接解析 → Markdown提取 → 启发式分段 +- **严格的Pydantic验证**:字段类型、范围、业务规则(如 `end_index > start_index`) +- **Prompt工程**:明确要求"只输出JSON,不要其他内容",提供示例格式 + +**实施阶段**:Phase 1 (核心功能) + +--- + +#### 3. 分段边界破坏语义完整性 + +**风险**:在句子中间或论点未完成时截断,导致分段语义破碎。 + +**缓解策略**: +- **句边界保护**:检测标点符号(句号、问号、感叹号),优先在这些位置分段 +- **修辞结构识别**:检测并列结构("首先、其次、最后"),不在其间截断 +- **最小长度保护**:设置 `min_segment_length=200`,避免碎片化 +- **Post-processing**:合并过短分段(<200字符)到相邻分段 + +**实施阶段**:Phase 1 (核心功能) + Phase 2 (优化) + +--- + +#### 4. 分段不一致性(同一视频多次运行结果不同) + +**风险**:LLM的随机性导致同一内容多次分段结果差异大,影响可复现性。 + +**缓解策略**: +- **温度参数设置**:`temperature=0.1`(低温度保证稳定性) +- **Seed固定**:如果API支持,使用固定seed +- **结果缓存**:对同一视频缓存分段结果(基于内容hash) + +**实施阶段**:Phase 2 (鲁棒性增强) + +--- + +#### 5. 成本失控(高频LLM调用导致费用激增) + +**风险**:每个视频都需要2次LLM调用(类型检测+分段),大量处理时成本显著。 + +**缓解策略**: +- **智能缓存**:相似内容(如同一UP主、同一系列)复用视频类型 +- **分段数量自适应**:短视频(<5分钟)减少目标分段数 +- **批量处理折扣**:如果API支持,使用batch模式 +- **监控告警**:设置月度成本上限,超限时降级为规则分段 + +**实施阶段**:Phase 2 (成本优化) + +--- + +### 中等风险(需要注意) + +#### 6. 中文断句不准确 + +**风险**:中文没有明确句号,LLM可能在短语中间断句。 + +**缓解策略**: +- **语义停顿检测**:基于短语结构判断停顿位置 +- **标点符号优先**:优先在逗号、分号处分段 +- **LLM辅助断句**:对歧义情况让LLM判断 + +--- + +#### 7. 幻觉检测缺失(LLM生成不存在的标题) + +**风险**:LLM可能生成与内容不符的标题或摘要。 + +**缓解策略**: +- **关键词提取验证**:标题应包含分段中的关键词 +- **后处理验证**:检查标题词汇是否在原文中出现 +- **用户反馈机制**:v2.0提供手动调整界面 + +--- + +### 低风险(可接受) + +#### 8. 分段数量不精确 + +**风险**:请求5个分段,LLM返回3个或7个。 + +**缓解策略**: +- **Prompt明确要求**:"必须分为5个段落" +- **Post-processing调整**:过多则合并,过少则拆分(基于子主题) +- **接受偏差**:±1个分段可接受 + +--- ## Implications for Roadmap -Based on research, suggested phase structure: +### 建议阶段结构 -### Phase 1: Foundation (基础设施层) +基于技术依赖和风险优先级,建议分为3个阶段: -**Rationale:** 状态管理和 Schema 验证是所有后续组件的基础,必须首先实现。没有状态文件就无法实现断点续传和幂等执行。 -**Delivers:** State Manager、Schema Registry、Error Handler、统一配置管理 -**Addresses:** 步骤级状态管理、幂等执行、JSON Schema 验证、结构化错误处理 -**Avoids:** 无状态执行、错误上下文丢失、环境变量分散 +#### **Phase 1: MVP核心功能** (2-3周) +**目标**:实现基础的LLM语义分段,验证可行性 -**Components:** -- `skills/core/state_manager.py` — workflow_state.json 管理 -- `skills/core/schema_registry.py` — JSON Schema 定义和验证 -- `skills/core/error_handler.py` — 统一错误处理 -- `config.py` — pydantic-settings 配置管理 +**交付物**: +- ✅ 视频类型识别(6种类型) +- ✅ 语义边界检测(基于LLM) +- ✅ Pydantic Schema验证 +- ✅ 三层fallback策略 +- ✅ 基础标题生成(≤15字) +- ✅ SRTProcessor集成(向后兼容) -### Phase 2: Core Skills (核心技能集成) +**必须避免的陷阱**: +- LLM-1: 上下文窗口溢出(实施分块策略) +- LLM-2: 输出格式不稳定(多层fallback) +- LLM-3: 边界破坏完整性(句边界保护) -**Rationale:** 基于现有技能进行集成,将分散的技能统一到管道模型中。Link Parser 是入口点,无依赖;Platform Skills 依赖其输出。 -**Delivers:** Link Parser 集成、B站/知乎 Metadata 和 Content 技能适配 -**Uses:** Pydantic (Schema)、transitions (状态)、Typer (CLI) -**Implements:** Pipeline Engine 原型 +**测试重点**: +- 短视频(<10分钟)的端到端处理 +- 不同类型视频的分段质量 +- Fallback机制触发路径 -**Components:** -- Link Parser 技能适配(已有 kb-link-parser) -- B站/知乎技能适配(已有 kb-bilibili-*、kb-zhihu-*) -- 管道执行引擎原型 +--- -### Phase 3: Processing Skills (处理技能集成) +#### **Phase 2: 鲁棒性增强** (1-2周) +**目标**:提高稳定性和可控性 -**Rationale:** ASR 和 OCR 依赖视频文件,必须在内容下载后执行。这些技能已有实现,需要集成到管道。 -**Delivers:** Whisper/FunASR 集成、OCR 集成、处理技能状态管理 -**Addresses:** 多模态内容处理 -**Avoids:** 假设模型理解上下文 — 显式传递转录结果给分析步骤 +**交付物**: +- ✅ 成本优化(缓存、批量处理) +- ✅ 分段一致性保证(低温度、seed) +- ✅ Post-processing优化(合并过短分段) +- ✅ 配置化参数(YAML配置支持) +- ✅ 监控和日志(分段质量指标) -**Components:** -- Whisper/FunASR 技能适配 -- OCR 技能适配 -- 处理结果 Schema 定义 +**必须避免的陷阱**: +- LLM-4: 分段不一致性(temperature控制) +- LLM-5: 成本失控(缓存策略) -### Phase 4: Analysis & Orchestration (分析技能与编排) +**测试重点**: +- 长视频(>1小时)的分块处理 +- 边缘情况(极短视频、单一主题) +- 成本监控 -**Rationale:** 深度分析是管道的最终输出,依赖所有前置步骤。编排层整合所有技能形成完整工作流。 -**Delivers:** Deep Analyzer 集成、完整管道编排、工作流定义文件 -**Uses:** 所有前置组件 -**Implements:** 声明式工作流定义 (YAML) +--- -**Components:** -- Deep Analyzer 技能适配 -- Pipeline Engine 完善 -- `workflows/video_pipeline.yaml` -- `workflows/article_pipeline.yaml` +#### **Phase 3: 高级特性(v2.0)** (延后) +**目标**:增强用户体验和竞争力 -### Phase 5: Polish & Testing (完善与测试) +**交付物**: +- 🔲 分层主题结构(章-节) +- 🔲 分段质量评分 +- 🔲 说话人识别集成 +- 🔲 手动调整界面 +- 🔲 时间戳对齐 -**Rationale:** 核心功能完成后,补充测试、文档和边缘情况处理。 -**Delivers:** 单元测试、集成测试、错误恢复策略完善、用户文档 -**Addresses:** 错误恢复策略、进度可见性 +**延后理由**: +- 需要额外技术调研(如说话人分离) +- 对MVP价值非关键 +- 增加复杂度和测试成本 -### Phase Ordering Rationale - -- **依赖关系决定顺序:** State Manager 是所有组件的基础,必须 Phase 1;Analysis 依赖 Processing,Processing 依赖 Platform Skills -- **架构模式指导分组:** Foundation -> Skills -> Orchestration 符合分层架构 -- **避免陷阱:** Phase 1 就实现状态文件和 Schema,防止无状态执行和接口不一致 +--- ### Research Flags -Phases likely needing deeper research during planning: -- **Phase 3:** ASR/OCR 集成可能需要研究 FunASR vs Whisper 选择逻辑,以及 HuggingFace token 缺失时的降级策略 -- **Phase 4:** AI API 调用的重试策略和超时配置可能需要根据实际使用调整 +**需要 `/gsd:research-phase` 的阶段**: -Phases with standard patterns (skip research-phase): -- **Phase 1:** 状态管理和 Schema 验证是成熟模式,Pydantic/transitions 文档充分 -- **Phase 2:** 现有技能适配,无需额外研究 -- **Phase 5:** 测试和文档是标准实践 +| 阶段 | 研究需求 | 理由 | +|------|---------|------| +| Phase 1 | ❌ 不需要 | 技术方案已明确,STACK.md提供完整实现指南 | +| Phase 2 | ❌ 不需要 | 鲁棒性模式已成熟(PITFALLS.md已覆盖) | +| Phase 3 | ✅ 需要 | 说话人识别、分层结构等需要额外技术调研 | + +**可直接进入实施的阶段**: +- **Phase 1**: 技术栈已验证,架构模式清晰,可直接开始编码 +- **Phase 2**: 基于Phase 1的反馈进行优化,无需额外研究 + +--- ## Confidence Assessment -| Area | Confidence | Notes | -|------|------------|-------| -| Stack | HIGH | Pydantic/transitions/Typer 都是成熟库,官方文档完善,与项目需求匹配度高 | -| Features | HIGH | 基于现有代码库分析和行业标准,功能边界清晰 | -| Architecture | HIGH | 四层架构是工作流系统的标准模式,管道编排模式适合内容处理场景 | -| Pitfalls | HIGH | 基于多篇研究论文和行业实践,坑点识别充分 | +| 领域 | 信心等级 | 说明 | +|------|---------|------| +| **技术栈** | **HIGH** | 基于现有SimpleAIClient和Pydantic,无需新依赖 | +| **功能定义** | **HIGH** | FEATURES.md基于2025-2026年学术论文,源质量高 | +| **架构集成** | **HIGH** | ARCHITECTURE.md提供完整集成方案,与现有代码兼容 | +| **陷阱识别** | **HIGH** | PITFALLS.md结合了pipeline、反爬虫、LLM三类陷阱 | -**Overall confidence:** HIGH +**总体信心:HIGH** -### Gaps to Address +**已识别的差距**: +- **中文句边界检测**:现有方法(标点符号+语义停顿)可能不够精确,需要在Phase 2测试中验证 +- **分段质量评估**:缺少客观评估指标,需要在Phase 2定义评估标准 +- **说话人识别集成**(v2.0):需要额外调研技术方案 -- **ASR 后端选择:** Whisper vs FunASR 的选择逻辑需要根据实际性能测试确定,目前建议支持配置切换 -- **错误恢复策略细节:** 403/超时等具体错误类型的处理策略需要在实现时细化 -- **进度汇报机制:** 长时间运行的 Whisper 任务需要进度汇报,具体实现方式待定 +--- ## Sources -### Primary (HIGH confidence) -- Pydantic v2.11 Release & JSON Schema Docs — 技术选型验证 -- transitions 0.9.3 on PyPI — 状态机库详情 -- Dagster: Data Pipeline Architecture Design Patterns — 管道模式 -- AI Architecture Patterns 101: Workflows, Agents — 架构模式 -- Demystifying Failures in Platform-Orchestrated Workflows (arxiv) — 失败模式研究 +### 高质量来源(学术/官方文档) +- [Chapter-Llama: Efficient Chaptering in Hour-Long Videos with LLMs (CVPR 2025)](https://arxiv.org/html/2504.00072v1) +- [LLM-Enhanced Semantic Text Segmentation - MDPI Applied Sciences 2025](https://www.mdpi.com/2076-3417/15/19/10849) +- [Beyond Transcripts: A Renewed Perspective on Audio Chaptering - arXiv 2025](https://arxiv.org/html/2602.08979v1) +- [Multimodal Fusion and Coherence Modeling for Video Topic Segmentation - ACL Findings 2025](https://aclanthology.org/2025.findings-acl.904.pdf) +- [The Complete Guide to Using Pydantic for Validating LLM Outputs](https://machinelearningmastery.com/the-complete-guide-to-using-pydantic-for-validating-llm-outputs/) -### Secondary (MEDIUM confidence) -- Prefect vs Dagster Comparison — 编排工具对比 -- Multi-Step LLM Chains: Best Practices — LLM 链最佳实践 -- Data Pipeline State Management (Fivetran) — 状态管理挑战 -- 9 Things I Hate About Environment Variables — 配置管理问题 +### 中等质量来源(实践指南/行业博客) +- [Automate Video Chaptering with LLMs and TF-IDF](https://towardsdatascience.com/automate-video-chaptering-with-llms-and-tf-idf-f6569fd4d32b/) +- [AI-Based Video Analyzer for Automated Chaptering and Summarization](https://medium.com/codex/ai-based-video-analyzer-for-automated-chaptering-and-summarization-2ca65f35b687) +- [Best Chunking Strategies for RAG (and LLMs) in 2026](https://www.firecrawl.dev/blog/best-chunking-strategies-rag) -### Tertiary (LOW confidence) -- AI Agent Anti-Patterns (Medium) — 反模式识别,需要结合实践验证 +### 项目内部来源 +- `STACK_SEMANTIC_SEGMENTATION.md`: 技术栈和Prompt工程 +- `FEATURES.md`: 功能分类和视频类型策略 +- `ARCHITECTURE.md`: 集成方案和数据流 +- `PITFALLS.md`: 三类陷阱(Pipeline、反爬虫、LLM分段) --- -*Research completed: 2026-03-13* -*Ready for roadmap: yes* + +## Next Steps + +1. **立即开始Phase 1实施**:技术方案已明确,无需额外研究 +2. **准备测试数据集**:收集不同类型、不同长度的B站视频字幕 +3. **定义评估标准**:制定分段质量的主观评估标准(用户测试)和客观指标(分段长度分布、边界位置合理性) +4. **成本监控设置**:在实施前建立LLM调用追踪机制 + +--- + +**Research synthesis complete. Ready for roadmap definition.**