diff --git a/skills/kb-deep-analyzer/SKILL.md b/skills/kb-deep-analyzer/SKILL.md index 74b5d64..c58e78c 100644 --- a/skills/kb-deep-analyzer/SKILL.md +++ b/skills/kb-deep-analyzer/SKILL.md @@ -8,41 +8,44 @@ - Template-based output - Quality scoring - Automatic tagging +- **多格式元数据支持**: 支持扁平结构 `{"title":"xxx"}` 和嵌套结构 `{"data":{"metadata":{...}}}` ## Commands ```bash -# Analyze content +# 分析内容 python deep_analyzer.py --metadata meta.json --content content.json --output analysis.md -# Specify type +# 指定类型 python deep_analyzer.py --metadata meta.json --content content.json --type tutorial --output tutorial.md + +# 指定 AI 提供商 +python deep_analyzer.py -m meta.json -c content.json -o out.md --provider zhipu --model glm-4 ``` -## Output +## Metadata Format -```markdown ---- -title: "分析标题" -source: "bilibili" -quality_score: 95 -tags: - - python - - tutorial ---- +支持两种元数据格式: -## 一句话总结 +```json +// 格式1: 扁平结构 +{ + "title": "视频标题", + "author": "作者名", + "duration": 619, + "bvid": "BVxxx" +} -内容摘要... - -## 核心要点 - -1. 要点1 -2. 要点2 +// 格式2: 嵌套结构(kb-bilibili-metadata 输出) +{ + "data": { + "metadata": { + "title": "视频标题", + "author": "作者名", + "duration": "10:19" + } + } +} ``` -## Installation - -```bash -cp -r kb-deep-analyzer/ ~/skills/ -``` +会自动转换为扁平格式进行分析。 diff --git a/skills/kb-deep-analyzer/deep_analyzer.py b/skills/kb-deep-analyzer/deep_analyzer.py index b674539..a0c0e8e 100644 --- a/skills/kb-deep-analyzer/deep_analyzer.py +++ b/skills/kb-deep-analyzer/deep_analyzer.py @@ -751,6 +751,70 @@ def load_json(file_path: str) -> Dict: return json.load(f) +def normalize_metadata(metadata: Dict) -> Dict: + """ + 标准化元数据格式,支持嵌套和平面两种结构 + + 支持以下输入格式: + 1. 扁平结构: {"title": "xxx", "author": "yyy", "duration": 619} + 2. 嵌套结构: {"data": {"metadata": {"title": "xxx", "author": "yyy", "duration": "10:19"}}} + + 输出: 扁平结构,duration 转换为秒数 + """ + if not metadata: + return {} + + # 如果已经包含 title 字段,认为是扁平结构 + if 'title' in metadata: + # 处理 duration 格式(可能是 "10:19" 字符串或数字) + duration = metadata.get('duration', 0) + if isinstance(duration, str) and ':' in duration: + parts = duration.split(':') + try: + seconds = int(parts[0]) * 60 + int(parts[1]) + metadata['duration'] = seconds + except (ValueError, IndexError): + pass + return metadata + + # 如果是嵌套结构,提取 data.metadata + data = metadata.get('data', {}) + meta = data.get('metadata', {}) + + # 提取扁平化字段 + normalized = { + 'title': meta.get('title', metadata.get('title', '未知')), + 'author': meta.get('author', metadata.get('author', '')), + 'bvid': meta.get('bvid', metadata.get('bvid', '')), + 'aid': meta.get('aid', metadata.get('aid', 0)), + 'pubtime': meta.get('pubtime', metadata.get('pubtime', '')), + 'platform': meta.get('platform', 'unknown'), + 'url': meta.get('url', ''), + } + + # 处理 duration + duration = meta.get('duration', 0) + if isinstance(duration, str): + if ':' in duration: + # "10:19" 格式 + parts = duration.split(':') + try: + normalized['duration'] = int(parts[0]) * 60 + int(parts[1]) + except (ValueError, IndexError): + normalized['duration'] = 0 + else: + try: + normalized['duration'] = int(duration) + except ValueError: + normalized['duration'] = 0 + elif isinstance(duration, (int, float)): + normalized['duration'] = int(duration) + else: + normalized['duration'] = 0 + + return normalized + + def format_duration(seconds: int) -> str: """格式化时长""" h = seconds // 3600 @@ -827,7 +891,8 @@ def main(): # 加载数据 print(f"[Main] 加载元数据: {args.metadata}") - metadata = load_json(args.metadata) + raw_metadata = load_json(args.metadata) + metadata = normalize_metadata(raw_metadata) print(f"[Main] 加载内容: {args.content}") content = load_json(args.content)