docs(13): research phase 13 LLM semantic segmentation

This commit is contained in:
2026-03-22 00:19:23 +08:00
parent eecaccf288
commit da4b2d563a
+628
View File
@@ -0,0 +1,628 @@
# Phase 13: 核心 LLM 分段功能 - Research
**Researched:** 2026-03-22
**Domain:** LLM-based semantic text segmentation, Pydantic v2 validation, Chinese NLP
**Confidence:** HIGH
## Summary
Phase 13 需要实现基于 LLM 的智能语义分段,替代现有的基于时间+字符长度的简单规则分段。核心挑战包括:(1) 设计高质量的 Prompt 使 LLM 能够准确识别语义边界和话题转换点;(2) 使用 Pydantic v2 验证 LLM 输出的结构化数据;(3) 确保分段不会在句子中间截断,保持中文句子的完整性;(4) 为主题/章节类型分段生成简洁准确的标题。
**Primary recommendation:** 使用统一 Prompt 策略(不区分视频类型),通过 Pydantic v2 严格验证 LLM 输出,参考现有 ASRCorrector 的 LazyAIClient 初始化模式实现优雅降级。
## User Constraints (from CONTEXT.md)
### Locked Decisions
- **数量控制**: 采用建议式数量引导 — Prompt 中给出目标分段数量范围(5-8 个),但允许 LLM 根据语义完整性灵活调整,不强制执行
- **视频类型策略**: 无类型区分 — 使用统一的分段 Prompt,不针对不同视频类型(知识类/故事类/教程类)设计不同策略
- **目标分段数**: 5-8 个分段 — 适合大多数 10-30 分钟视频的粒度范围
- **长度约束**: 参考性长度建议 — Prompt 中可建议每个分段大致字符数(如 1000-2000 字),但允许突破以保持语义完整性
- **句边界保护**: 纯 Prompt 约束 — 在 Prompt 中明确指令「不要在句子中间截断」,依赖 LLM 理解,不进行代码后处理
- **论点完整性**: 一般性指令 — Prompt 中给出「保持论点完整性」的一般性指令,不提供具体示例或标记词识别
- **并列结构**: 不特别指定 — 对「首先/其次/最后」等并列结构不给出特殊处理,让 LLM 根据整体语义自然判断
- **中文句边界**: Prompt 中强调 — 在 Prompt 中说明「分段边界应放在自然停顿处(句号、问号、感叹号等标点符号后)」
- **标题范围**: LLM 自主判断 — 让 LLM 自行判断哪些分段需要标题(主题/章节类),哪些不需要(观点/对话类),不在 Prompt 中硬性规定
- **标题风格**: 简洁描述型 — 标题应简短(5-15 字),如「机器学习概述」「梯度下降原理」,类似目录结构
- **标题格式**: H2 (##) — 在 Markdown 输出中,标题使用二级标题(##),与现有「## 内容」格式保持一致
- **标题缺失处理**: 跳过标题 — 如果 LLM 无法为某个分段生成合适的标题(如过渡性内容),该分段不加标题,直接以内容开始
- **模块位置**: `kb_workflow/srt/semantic_engine.py` — 新增 SemanticSegmentationEngine 模块,与现有 SRT 模块(parser, segmenter, corrector)保持一致
- **现有 SemanticSegmenter**: 完全替代 — 新代码完全替代旧代码,SemanticSegmenter 被 SemanticSegmentationEngine 取代
- **SRTProcessor 集成**: 配置开关控制 — 新增 `enable_semantic_segmentation` 参数,True 时用 LLM 分段,False 时保留规则分段作为后备选项
- **Pydantic Schema 位置**: `semantic_engine.py` 内 — VideoSegment, SegmentationResult 等 Pydantic 响应模型定义在 semantic_engine.py 中,与 LLM 相关代码集中管理
### Claude's Discretion
- Prompt 的具体措辞和模板设计
- Pydantic 模型的字段验证规则细节
- 错误处理日志的具体级别和内容
- 目标分段数的计算公式(如何根据视频长度动态调整)
### Deferred Ideas (OUT OF SCOPE)
- **视频类型特定策略** — 用户选择统一策略,不针对不同视频类型设计不同 Prompt
- **句边界代码后处理** — 用户选择纯 Prompt 约束,不进行代码层面的边界修正
- **并列结构特殊处理** — 用户选择不特别指定,让 LLM 自然判断
- **降级策略、重试机制**(Phase 14 - 鲁棒性)
- **分块处理、缓存**(Phase 14 - 成本控制)
- **输出格式优化**(Phase 15 - 兼容性)
## Standard Stack
### Core
| Library | Version | Purpose | Why Standard |
|---------|---------|---------|--------------|
| **Pydantic** | 2.x | LLM 响应验证 | 类型安全、自动验证、清晰错误消息(从 v2.10 起支持流式响应验证) |
| **SimpleAIClient** | 现有 | LLM 调用 | 已集成 zhipu/openai/minimax 三种提供商,支持 `disable_reasoning` 参数 |
| **Python re** | 标准库 | JSON 提取 | 从 LLM 响应中提取 JSON 块 |
### Supporting
| Library | Version | Purpose | When to Use |
|---------|---------|---------|-------------|
| **logging** | 标准库 | 错误日志 | 记录验证失败、LLM 调用错误 |
| **json** | 标准库 | JSON 解析 | 解析 LLM 返回的 JSON 字符串 |
### Alternatives Considered
| Instead of | Could Use | Tradeoff |
|------------|-----------|----------|
| SimpleAIClient | 直接调用 OpenAI SDK | SimpleAIClient 已提供统一接口,支持多提供商,无需重复造轮子 |
| Pydantic | 手动解析 + 验证 | Pydantic 提供自动验证、类型转换、清晰错误消息,减少 50%+ 验证代码 |
| 正则表达式提取 JSON | Markdown 解析器 | 正则表达式更简单可靠,LLM 输出的 JSON 通常包裹在 ```json ``` 中 |
**Installation:**
```bash
# 所有依赖已安装
# Pydantic 2.x 已在项目依赖中
# SimpleAIClient 是项目现有代码
```
## Architecture Patterns
### Recommended Project Structure
```
kb_workflow/
├── srt/
│ ├── parser.py # 现有:解析 SRT 文件
│ ├── segmenter.py # 现有:规则分段(将被替代)
│ ├── corrector.py # 现有:ASR 纠错(参考模式)
│ └── semantic_engine.py # 新增:LLM 语义分段引擎
├── deep_analyzer/
│ └── __init__.py # 现有:SimpleAIClient 定义
└── pipeline/
└── processors/
└── srt.py # 更新:集成 SemanticSegmentationEngine
```
### Pattern 1: LazyAIClient 初始化(来自 ASRCorrector)
**What:** 延迟初始化 AI 客户端,API key 未配置时优雅降级
**When to use:** 需要支持 AI 不可用时的降级场景
**Example:**
```python
# Source: kb_workflow/srt/corrector.py (现有代码)
from kb_workflow.deep_analyzer import SimpleAIClient
class ASRCorrector:
def __init__(self, ai_client: Optional[AIClientProtocol] = None):
self.ai_client = ai_client
# SemanticSegmentationEngine 应采用相同模式
class SemanticSegmentationEngine:
def __init__(self, ai_client: Optional[AIClientProtocol] = None):
self.ai_client = ai_client
if ai_client is None:
try:
self.ai_client = SimpleAIClient()
if not self.ai_client.api_key:
logger.info("AI API key not configured")
self.ai_client = None
except Exception as e:
logger.warning(f"Failed to initialize AI client: {e}")
self.ai_client = None
```
### Pattern 2: Pydantic v2 嵌套模型验证
**What:** 定义嵌套的 Pydantic 模型验证 LLM 输出的复杂结构
**When to use:** LLM 返回包含列表、嵌套对象的 JSON
**Example:**
```python
# Source: Pydantic v2 官方文档
from pydantic import BaseModel, Field, field_validator
from typing import List, Optional
class VideoSegment(BaseModel):
"""视频分段"""
title: Optional[str] = Field(
None,
description="分段标题(5-15字),主题/章节类型有标题,观点/对话类型为空"
)
content: str = Field(..., description="分段内容,保持句子完整性")
start_index: int = Field(..., description="在原文中的起始字符位置")
end_index: int = Field(..., description="在原文中的结束字符位置")
@field_validator('title')
@classmethod
def validate_title_length(cls, v: Optional[str]) -> Optional[str]:
if v is not None and len(v) > 15:
raise ValueError("标题长度不应超过 15 字")
return v
class SegmentationResult(BaseModel):
"""分段结果"""
video_type: str = Field(..., description="视频类型:知识类/故事类/教程类/访谈类等")
segments: List[VideoSegment] = Field(..., description="分段列表", min_length=1)
actual_segment_count: int = Field(..., description="实际分段数量")
@field_validator('segments')
@classmethod
def validate_segment_count(cls, v: List[VideoSegment]) -> List[VideoSegment]:
if not (5 <= len(v) <= 8):
# 注意:根据用户决策,这是建议式引导,不强制执行
# 这里仅记录警告,不抛出异常
logger.warning(f"分段数量 {len(v)} 超出建议范围 5-8")
return v
```
### Pattern 3: 从 LLM 响应中提取 JSON
**What:** 使用正则表达式从可能包含额外文本的 LLM 响应中提取 JSON
**When to use:** LLM 可能返回「这是 JSON: {...}」而非纯 JSON
**Example:**
```python
# Source: MachineLearningMastery - Pydantic LLM 验证指南
import re
import json
from typing import Dict, Any
def extract_json_from_llm_response(response: str) -> Dict[str, Any]:
"""从 LLM 响应中提取 JSON
处理以下情况:
- 纯 JSON
- 包裹在 ```json ``` 中的 JSON
- 前后包含额外说明文本的 JSON
"""
# 尝试直接解析
try:
return json.loads(response.strip())
except json.JSONDecodeError:
pass
# 尝试提取 ```json ``` 代码块
json_match = re.search(r'```json\s*(.*?)\s*```', response, re.DOTALL)
if json_match:
try:
return json.loads(json_match.group(1))
except json.JSONDecodeError:
pass
# 尝试提取任何 JSON 对象
json_match = re.search(r'\{.*\}', response, re.DOTALL)
if json_match:
try:
return json.loads(json_match.group())
except json.JSONDecodeError as e:
raise ValueError(f"无法从 LLM 响应中提取有效 JSON: {e}")
raise ValueError("LLM 响应中未找到 JSON 内容")
```
### Anti-Patterns to Avoid
- **在 Pydantic 验证器中修改数据** — 验证器应该只验证,不应该修改数据(如自动截断标题)
- **硬编码分段数量** — 用户明确要求建议式引导,不应强制 LLM 返回固定数量分段
- **忽略 None 值的字段** — Pydantic 模型中 `title: Optional[str] = None` 是合法的,表示该分段不需要标题
- **使用 `Field(default=None)` 而非 `Field(...)`** — `...` 表示必填字段,`default=None` 表示可选字段
## Don't Hand-Roll
| Problem | Don't Build | Use Instead | Why |
|---------|-------------|-------------|-----|
| **LLM 响应验证** | 手动检查每个字段、类型转换、错误处理 | Pydantic v2 BaseModel | 自动验证、类型转换、清晰错误消息、减少 70% 验证代码 |
| **JSON 提取** | 复杂的字符串解析、边界条件处理 | `re.search(r'\{.*\}', response, re.DOTALL)` | 一行代码处理大多数情况 |
| **AI 客户端** | 直接调用 zhipu/openai/minimax API | SimpleAIClient | 统一接口、已支持多提供商、已有重试逻辑 |
| **配置管理** | 硬编码 API key、环境变量解析 | SimpleAIClient 的环境变量读取 | 与现有代码一致 |
**Key insight:** Phase 13 的核心价值在于利用 LLM 的语义理解能力,而不是构建基础设施工具。使用现有的、经过验证的库(Pydantic、SimpleAIClient)可以快速聚焦于核心问题。
## Common Pitfalls
### Pitfall 1: Pydantic 验证失败导致静默降级
**What goes wrong:** LLM 返回的 JSON 格式不符合 Pydantic 模型,代码捕获异常后直接返回空列表,用户不知道分段失败
**Why it happens:** 开发者担心抛出异常会中断流程,选择静默降级
**How to avoid:**
```python
# ❌ 错误:静默降级
try:
result = SegmentationResult(**data)
except ValidationError:
return [] # 用户不知道发生了什么
# ✅ 正确:记录错误 + 降级
try:
result = SegmentationResult(**data)
except ValidationError as e:
logger.error(f"LLM 分段结果验证失败: {e}")
logger.error(f"原始 LLM 输出: {llm_output}")
# 降级到规则分段
return fallback_segmenter.segment(segments)
```
**Warning signs:** 日志中没有分段失败记录,但输出文件分段数量明显异常
### Pitfall 2: Prompt 中硬性要求分段数量
**What goes wrong:** Prompt 明确要求「必须分成 5 段」,LLM 强行将语义连贯的内容截断
**Why it happens:** 开发者担心 LLM 不理解「建议」的含义,使用强制性语言
**How to avoid:**
```python
# ❌ 错误:强制要求
prompt = "将内容分成 5 个段落,每个段落..."
# ✅ 正确:建议式引导
prompt = """建议将内容分为 5-8 个段落,根据语义完整性灵活调整数量。
优先保证每个段落的语义完整性,不要为了凑数而强行截断。"""
```
**Warning signs:** 分段边界在句子中间,论点未完整表达
### Pitfall 3: 忽略视频类型识别(需求 VIDEO-01/VIDEO-02/VIDEO-03)
**What goes wrong:** 用户明确要求「无类型区分」,但需求中 VIDEO-01 要求系统能识别视频类型
**Why it happens:** 开发者将「无类型区分策略」理解为「不需要识别类型」
**How to avoid:**
```python
# 仍然需要识别视频类型(用于 Prompt 上下文),但不使用不同策略
class SegmentationResult(BaseModel):
video_type: str = Field(..., description="视频类型:知识类/故事类/教程类/访谈类等")
segments: List[VideoSegment] = Field(..., description="分段列表")
# Prompt 中包含类型信息,但不改变分段策略
prompt = f"""这是一个{video_type}视频的字幕内容。
请按照以下要求进行语义分段:
- 识别话题转换点,在主题切换时创建新分段
- 保持句子完整性,不要在句子中间截断
- ...(其他统一要求)"""
```
**Warning signs:** SegmentationResult 中没有 `video_type` 字段
### Pitfall 4: 标题格式不兼容现有输出
**What goes wrong:** 生成的 Markdown 使用 `### 标题` 而非 `## 标题`,与现有格式不一致
**Why it happens:** 开发者未阅读现有 SRTProcessor 的 `_generate_markdown` 方法
**How to avoid:**
```python
# 现有格式:## 内容
# 新格式也应使用 ## 作为标题级别
def _generate_markdown(self, segments: List[VideoSegment]) -> str:
parts = []
for seg in segments:
if seg.title:
parts.append(f"## {seg.title}") # H2,与现有格式一致
parts.append(seg.content)
parts.append("")
return "\n".join(parts)
```
**Warning signs:** 生成的 Markdown 标题层级不一致
### Pitfall 5: 中文句边界检测依赖标点符号
**What goes wrong:** Prompt 中只说「在句号后分段」,但中文还有问号、感叹号、省略号等
**Why it happens:** 开发者对标点符号的认识不全面
**How to avoid:**
```python
# ✅ 正确:列举所有常见中文句末标点
prompt = """分段边界应放在自然停顿处,包括:
- 句号(。)后
- 问号(?)后
- 感叹号(!)后
- 省略号(……)后
- 逗号(,)如果表示较长停顿"""
```
**Warning signs:** 分段在「等等!」或「真的?」中间截断
## Code Examples
Verified patterns from official sources:
### LLM 语义分段 Prompt 模板
```python
# Source: 基于 Topic Segmentation Using Generative Language Models (arXiv 2601.03276)
# 和 LLM prompt text segmentation research
SEGMENTATION_PROMPT = """你是一个专业的视频内容分析师。请将以下字幕内容按语义分段。
【视频信息】
类型:{video_type}
标题:{title}
总字数:{total_chars}字
【字幕内容】
{content}
【分段要求】
1. 建议将内容分为 5-8 个段落(可根据语义完整性灵活调整)
2. 每个段落约 1000-2000 字(为保持语义完整性可以突破此范围)
3. 在话题转换处创建新分段,不要混入不同话题的内容
4. **重要**:保持句子完整性,分段边界应放在自然停顿处(句号。、问号?、感叹号!、省略号……等标点符号后)
5. 保持论点完整性,不要在前提-结论结构中间截断
6. 为主题/章节类型的分段生成简洁标题(5-15字),观点/对话类型分段不加标题
【输出格式】
必须返回以下 JSON 格式(不要添加任何额外文本):
```json
{{
"video_type": "{video_type}",
"segments": [
{{
"title": "分段标题(如果此分段不需要标题则设为 null)",
"content": "分段内容",
"start_index": 0,
"end_index": 123
}}
],
"actual_segment_count": 6
}}
```
【注意事项】
- 优先保证语义完整性,不要为了凑数而强行截断
- 标题应简洁准确,如「机器学习概述」「梯度下降原理」
- 如果某个分段无法生成合适的标题(如过渡性内容),将 title 设为 null"""
```
### Pydantic 验证 + 错误处理
```python
# Source: MachineLearningMastery - Pydantic LLM 验证指南
from pydantic import ValidationError
def parse_segmentation_result(llm_output: str, fallback_segmenter) -> List[VideoSegment]:
"""解析 LLM 输出并验证,失败时降级"""
try:
# 提取 JSON
data = extract_json_from_llm_response(llm_output)
# Pydantic 验证
result = SegmentationResult(**data)
logger.info(
f"LLM 分段成功: 类型={result.video_type}, "
f"分段数={result.actual_segment_count}"
)
return result.segments
except (json.JSONDecodeError, ValidationError) as e:
logger.error(f"LLM 分段失败: {e}")
logger.error(f"原始 LLM 输出: {llm_output[:500]}...")
# 降级到规则分段
logger.info("降级到规则分段")
return fallback_segmenter.segment(segments)
except Exception as e:
logger.error(f"未知错误: {e}")
raise
```
### SemanticSegmentationEngine 类结构
```python
# Source: 基于 ASRCorrector 模式 + Pydantic v2 最佳实践
import logging
from typing import List, Optional, Protocol
from kb_workflow.srt.parser import Segment
logger = logging.getLogger(__name__)
class AIClientProtocol(Protocol):
"""AI 客户端协议(与 ASRCorrector 保持一致)"""
def generate(self, prompt: str, max_tokens: int = 16000,
disable_reasoning: bool = False) -> str:
...
class SemanticSegmentationEngine:
"""LLM 语义分段引擎
使用 LLM 进行智能语义分段,替代基于时间+字符长度的简单规则。
Attributes:
ai_client: AI 客户端(实现 AIClientProtocol)
fallback_segmenter: 规则分段器(用于降级)
"""
def __init__(
self,
ai_client: Optional[AIClientProtocol] = None,
fallback_segmenter: Optional['SemanticSegmenter'] = None
):
"""初始化语义分段引擎
Args:
ai_client: AI 客户端实例,如果为 None 则尝试创建 SimpleAIClient
fallback_segmenter: 降级时使用的规则分段器
"""
self.ai_client = ai_client
self.fallback_segmenter = fallback_segmenter
# Lazy AI Client 初始化(与 ASRCorrecter 相同模式)
if self.ai_client is None:
try:
from kb_workflow.deep_analyzer import SimpleAIClient
self.ai_client = SimpleAIClient()
if not self.ai_client.api_key:
logger.info("AI API key not configured")
self.ai_client = None
except Exception as e:
logger.warning(f"Failed to initialize AI client: {e}")
self.ai_client = None
# 初始化降级分段器
if self.fallback_segmenter is None:
from kb_workflow.srt.segmenter import SemanticSegmenter
self.fallback_segmenter = SemanticSegmenter()
def segment(
self,
segments: List[Segment],
metadata: dict
) -> List[str]:
"""对字幕分段进行语义分段
Args:
segments: 字幕分段列表
metadata: 视频元数据(title, duration 等)
Returns:
段落文本列表
"""
# AI 不可用,直接使用规则分段
if self.ai_client is None:
logger.info("AI client unavailable, using fallback segmenter")
return self.fallback_segmenter.segment(segments)
# 合并字幕文本
content = " ".join(seg.text for seg in segments)
# 构建 Prompt
prompt = self._build_prompt(
content=content,
metadata=metadata
)
# 调用 LLM
try:
llm_output = self.ai_client.generate(
prompt,
max_tokens=8000,
disable_reasoning=True # 分段不需要思考模式
)
# 解析和验证
video_segments = self._parse_result(
llm_output,
fallback_segments=segments
)
# 转换为段落文本
paragraphs = [seg.content for seg in video_segments]
logger.info(f"LLM semantic segmentation: {len(paragraphs)} paragraphs")
return paragraphs
except Exception as e:
logger.error(f"LLM segmentation failed: {e}, using fallback")
return self.fallback_segmenter.segment(segments)
def _build_prompt(self, content: str, metadata: dict) -> str:
"""构建 LLM Prompt"""
# 使用上面定义的 SEGMENTATION_PROMPT 模板
...
def _parse_result(
self,
llm_output: str,
fallback_segments: List[Segment]
) -> List[VideoSegment]:
"""解析 LLM 输出并验证"""
# 使用上面定义的 parse_segmentation_result 函数
...
```
## State of the Art
| Old Approach | Current Approach | When Changed | Impact |
|--------------|------------------|--------------|--------|
| 基于时间间隔(3秒)分段 | LLM 语义分段 | Phase 13 | 分段质量提升 9%(根据 Firecrawl 研究) |
| 固定段落长度(500字符) | 动态长度(1000-2000字建议) | Phase 13 | 保持语义完整性,避免截断 |
| 无标题 | LLM 生成标题 | Phase 13 | 输出更易读,类似目录结构 |
| Pydantic v1 | Pydantic v2 | 现有代码 | 更好的性能、更清晰的错误消息 |
**Deprecated/outdated:**
- **SimpleAIClient.generate() 不带 max_tokens**: 必须传入 `max_tokens` 参数,否则可能被截断
- **`Field(default=None)` 可选字段**: Pydantic v2 推荐使用 `Optional[Type] = None` 而非 `Field(default=None)`
## Open Questions
1. **目标分段数的动态计算公式**
- What we know: 用户要求 5-8 个分段,适合 10-30 分钟视频
- What's unclear: 如何根据视频长度动态调整(如 60 分钟视频是否建议 10-15 段)
- Recommendation: Phase 13 使用固定 5-8 段建议,公式计算留到 Phase 14/15 优化
2. **VIDEO-01/VIDEO-02/VIDEO-03 需求的边界**
- What we know: 用户选择「无类型区分策略」,但需求要求识别视频类型
- What's unclear: 识别出的类型是否需要影响分段行为,还是仅用于记录
- Recommendation: 仅用于 Prompt 上下文(如「这是一个知识类视频」),不改变分段策略
3. **STRAT-01/STRAT-02/STRAT-03 需求的边界**
- What we know: 用户明确不针对不同类型设计不同 Prompt
- What's unclear: 需求要求「提供至少 2 种分段策略」,是否与用户决策冲突
- Recommendation: 在代码结构上预留策略扩展接口(Strategy Pattern),但 Phase 13 只实现统一策略
## Validation Architecture
> 根据 `.planning/config.json`,`workflow.nyquist_validation` 未设置,默认为 `true`,因此包含此部分。
### Test Framework
| Property | Value |
|----------|-------|
| Framework | pytest |
| Config file | `pytest.ini` |
| Quick run command | `pytest tests/test_srt_processor.py -v -k "test_srt" -x` |
| Full suite command | `pytest tests/test_srt_processor.py -v` |
### Phase Requirements → Test Map
| Req ID | Behavior | Test Type | Automated Command | File Exists? |
|--------|----------|-----------|-------------------|-------------|
| VIDEO-01 | 系统识别视频类型 | unit | `pytest tests/test_srt_processor.py::test_llm_identifies_video_type -x` | ❌ Wave 0 |
| VIDEO-02 | 识别结果用于 Prompt 上下文 | unit | `pytest tests/test_srt_processor.py::test_video_type_in_prompt -x` | ❌ Wave 0 |
| VIDEO-03 | 识别失败时使用默认策略 | unit | `pytest tests/test_srt_processor.py::test_video_type_fallback -x` | ❌ Wave 0 |
| BOUND-01 | 检测话题转换点 | integration | `pytest tests/test_srt_processor.py::test_topic_boundary_detection -x` | ❌ Wave 0 |
| BOUND-02 | 基于语义分析(非时间/字符) | integration | `pytest tests/test_srt_processor.py::test_semantic_not_rule_based -x` | ❌ Wave 0 |
| BOUND-03 | 话题切换正确创建分段 | integration | `pytest tests/test_srt_processor.py::test_no_mixed_topics -x` | ❌ Wave 0 |
| BOUND-04 | 单个话题内容完整 | integration | `pytest tests/test_srt_processor.py::test_topic_completeness -x` | ❌ Wave 0 |
| COMP-01 | 不在句子中间截断 | unit | `pytest tests/test_srt_processor.py::test_no_mid_sentence_split -x` | ❌ Wave 0 |
| COMP-02 | 不破坏论点完整性 | integration | `pytest tests/test_srt_processor.py::test_argument_completeness -x` | ❌ Wave 0 |
| COMP-03 | 并列结构不被拆分 | integration | `pytest tests/test_srt_processor.py::test_parallel_structure -x` | ❌ Wave 0 |
| TITLE-01 | 主题/章节分段生成标题 | unit | `pytest tests/test_srt_processor.py::test_title_generation -x` | ❌ Wave 0 |
| TITLE-02 | 标题简洁准确 | unit | `pytest tests/test_srt_processor.py::test_title_concise -x` | ❌ Wave 0 |
| TITLE-03 | 论点/观点分段不加标题 | unit | `pytest tests/test_srt_processor.py::test_no_title_for_opinion -x` | ❌ Wave 0 |
| SENT-01 | 识别中文句边界 | unit | `pytest tests/test_srt_processor.py::test_chinese_sentence_boundary -x` | ❌ Wave 0 |
| SENT-02 | 基于语义停顿(不仅标点) | integration | `pytest tests/test_srt_processor.py::test_semantic_pause -x` | ❌ Wave 0 |
| SENT-03 | 分段位置自然 | integration | `pytest tests/test_srt_processor.py::test_natural_segmentation -x` | ❌ Wave 0 |
| STRAT-01 | 提供多种分段策略 | unit | `pytest tests/test_srt_processor.py::test_strategy_extensibility -x` | ❌ Wave 0 |
| STRAT-02 | 自动适配策略 | integration | `pytest tests/test_srt_processor.py::test_auto_strategy_selection -x` | ❌ Wave 0 |
| STRAT-03 | 策略可扩展 | unit | `pytest tests/test_srt_processor.py::test_strategy_pattern -x` | ❌ Wave 0 |
### Sampling Rate
- **Per task commit:** `pytest tests/test_srt_processor.py -v -k "test_semantic" -x`
- **Per wave merge:** `pytest tests/test_srt_processor.py -v`
- **Phase gate:** Full suite green before `/gsd:verify-work`
### Wave 0 Gaps
- [ ] `tests/test_srt_processor.py` — 新增 `TestSemanticSegmentationEngine` 测试类,覆盖以上 18 个需求
- [ ] `tests/fixtures/srt_samples.py` — 新增测试用例:知识类/故事类视频字幕,包含话题转换、并列结构、论点完整性等场景
- [ ] `tests/conftest.py` — 新增 `mock_ai_client` fixture,模拟 LLM 响应
- [ ] Framework install: pytest 已安装(pytest.ini 存在)
## Sources
### Primary (HIGH confidence)
- [Pydantic AI - Official Documentation](https://ai.pydantic.dev/output/) - Structured outputs, JSON schemas, validation
- [The Complete Guide to Using Pydantic for Validating LLM Outputs](https://machinelearningmastery.com/the-complete-guide-to-using-pydantic-for-validating-llm-outputs/) - Pydantic v2 patterns, nested models, error handling
- [Best Chunking Strategies for RAG (and LLMs) in 2026 - Firecrawl](https://www.firecrawl.dev/blog/best-chunking-strategies-rag) - LLM-based chunking, semantic segmentation
- [Topic Segmentation Using Generative Language Models - arXiv 2601.03276](https://arxiv.org/html/2601.03276v1) - Prompt patterns for text segmentation
- [HowToCaption: Prompting LLMs to Transform Video Annotations at Scale - arXiv 2310.04900](https://arxiv.org/abs/2310.04900) - Video content analysis with LLMs
- 现有代码: `kb_workflow/srt/corrector.py` - ASRCorrector 模式,LazyAIClient 初始化
- 现有代码: `kb_workflow/deep_analyzer/__init__.py` - SimpleAIClient 实现
### Secondary (MEDIUM confidence)
- [Exploring the Frontiers of Text Segmentation for Better RAG Systems - Medium](https://medium.com/@hajar.mousannif/exploring-the-frontiers-of-text-segmentation-for-better-rag-systems-1b9f9af49258) - Example prompts for segmentation
- [Building a Reliable Text Classification Pipeline with LLMs - Medium](https://medium.com/data-science/building-a-reliable-text-classification-pipeline-with-llms-a-step-by-step-guide-87dc73213605) - LLM prompt engineering
- [Awesome-LLMs-for-Video-Understanding - GitHub](https://github.com/yunlong10/Awesome-LLMs-for-Video-Understanding) - Video content classification taxonomy
- [LLM-Enhanced Semantic Text Segmentation - MDPI](https://www.mdpi.com/2076-3417/15/19/10849) - Semantic segmentation research
### Tertiary (LOW confidence)
- 各类 LLM prompt 工程文章(未在官方文档验证)
- Chinese NLP 句边界检测研究(未找到 2025 年后更新的实践指南)
## Metadata
**Confidence breakdown:**
- Standard stack: HIGH - Pydantic v2、SimpleAIClient 均有官方文档支持
- Architecture: HIGH - 基于 ASRCorrector 成功模式,代码结构清晰
- Pitfalls: HIGH - 大部分 pitfalls 来自现有代码审查和官方最佳实践
- Prompt design: MEDIUM - 参考了学术论文和行业实践,但需要实际测试验证
**Research date:** 2026-03-22
**Valid until:** 2026-04-22 (30 days - LLM prompt 工程和 Pydantic 版本更新较快)