🔄 卡若AI 同步 2026-03-11 15:17 | 更新:水溪整理归档、卡木、运营中枢工作台 | 排除 >20MB: 11 个

This commit is contained in:
2026-03-11 15:17:50 +08:00
parent d64a8cab0e
commit 3c287a93a0
10 changed files with 519 additions and 7 deletions

View File

@@ -1,6 +1,6 @@
{
"updated": "2026-03-10 15:13:06",
"date": "2026-03-10",
"updated": "2026-03-11 15:17:21",
"date": "2026-03-11",
"scan_total": 0,
"copied_new": 0,
"skipped_idempotent": 0,

View File

@@ -1,8 +1,8 @@
---
name: 视频切片
description: Soul派对视频切片 + 切片动效包装(片头/片尾/程序化)+ 剪映思路借鉴(智能剪口播/镜头分割)。触发词含视频剪辑、切片发布、切片动效包装、程序化包装、片头片尾。
description: Soul派对视频切片 + 快速混剪 + 切片动效包装(片头/片尾/程序化)+ 剪映思路借鉴(智能剪口播/镜头分割)。触发词含视频剪辑、切片发布、快速混剪、切片动效包装、程序化包装、片头片尾。
group: 木
triggers: 视频剪辑、切片发布、字幕烧录、**切片动效包装、程序化包装、片头片尾、批量封面、视频包装**、镜头切分、场景检测
triggers: 视频剪辑、切片发布、字幕烧录、**快速混剪、混剪预告、快剪串联、切片动效包装、程序化包装、片头片尾、批量封面、视频包装**、镜头切分、场景检测
owner: 木叶
version: "1.3"
updated: "2026-03-03"
@@ -14,7 +14,7 @@ updated: "2026-03-03"
> **Soul 视频输出**Soul 剪辑的成片统一导出到 `/Users/karuo/Movies/soul视频/最终版/`,原视频在 `原视频/`,中间产物在 `其他/`。
> **联动规则**:每次执行视频切片时,自动检查是否需要「切片动效包装」。若用户提到片头/片尾/程序化包装/批量封面,则联动调用 `切片动效包装/10秒视频` 模板渲染,再与切片合成。
> **联动规则**:每次执行视频切片时,自动检查是否需要「切片动效包装」或「快速混剪」。若用户提到片头/片尾/程序化包装/批量封面,则联动调用 `切片动效包装/10秒视频` 模板渲染,再与切片合成。若用户提到快速混剪/混剪预告/快剪串联,则在切片或成片生成后再调用 `脚本/quick_montage.py` 输出一条节奏版预告。
## ⭐ Soul派对切片流程默认
@@ -30,6 +30,21 @@ updated: "2026-03-03"
**Soul 竖屏专用**:抖音/首页用竖屏成片、完整参数与流程见 → **`Soul竖屏切片_SKILL.md`**(竖屏 498×1080、crop 参数、批量命令)。
### 最新切片风格(当前默认)
以后默认按这套风格出切片与成片:
| 项 | 当前默认风格 |
|------|------|
| **封面** | **Soul 绿 + 半透明质感 + 深色渐变** |
| **前3秒** | **优先提问→回答**,有提问时 Hook = `question` |
| **标题** | **一句刺激性观点**,文件名 = 封面标题 = `highlights.title` |
| **字幕** | 居中、白字黑描边、关键词亮金黄高亮 |
| **节奏** | 去语助词 + 整体加速 10% |
| **成片尺寸** | 竖屏 **498×1080** |
这套风格与 `参考资料/高光识别提示词.md``参考资料/热点切片_标准流程.md``Soul竖屏切片_SKILL.md` 保持一致。
### 一键命令Soul派对专用
#### 一体化流水线(推荐)
@@ -41,6 +56,9 @@ python3 soul_slice_pipeline.py --video "/path/to/soul派对会议第57场.mp4" -
# 仅重新烧录(字幕转简体后重跑增强)
python3 soul_slice_pipeline.py -v "视频.mp4" -n 6 --skip-transcribe --skip-highlights --skip-clips
# 切片+成片后,额外生成一条快速混剪
python3 soul_slice_pipeline.py -v "视频.mp4" -n 8 --two-folders --quick-montage
```
流程:**转录 → 字幕转简体 → 高光识别 → 批量切片 → 增强**
@@ -64,6 +82,39 @@ python3 batch_clip.py -i 视频.mp4 -l highlights.json -o clips/ -p soul
python3 soul_enhance.py -c clips/ -l highlights.json -t transcript.srt -o clips_enhanced/
```
### 快速混剪(新增)
适用场景:已经有 `切片/``成片/`,需要快速出一条 2040 秒节奏版预告、招商预热视频、短视频串联版。
**默认策略**
| 项 | 规则 |
|------|------|
| **顺序** | 优先按 `virality_score` / `rank` 排序;无分数时按序号 |
| **取样** | 每条默认截取 **4 秒**高密度片段 |
| **成片目录输入** | 自动跳过前 **2.6 秒**封面,避免混剪里全是封面 |
| **输出** | 统一分辨率、统一节奏后拼成一条 `快速混剪.mp4` |
```bash
# 从成片目录生成快速混剪(推荐)
python3 脚本/quick_montage.py \
-i "/path/to/成片" \
-o "/path/to/快速混剪.mp4" \
-l "/path/to/highlights.json" \
--source-kind final \
-n 8 \
-s 4
# 一体化流水线里直接附带生成
python3 脚本/soul_slice_pipeline.py \
-v "/path/to/原视频.mp4" \
--two-folders \
--quick-montage \
--montage-source finals \
--montage-max-clips 8 \
--montage-seconds 4
```
#### 按章节主题提取推荐第9章单场成片
以**章节 .md 正文**为来源提取核心主题,再在转录稿中匹配时间,不限于 5 分钟、片段数与章节结构一致。详见 `参考资料/主题片段提取规则.md`
@@ -492,6 +543,7 @@ python3 soul_enhance.py -c "输出目录/clips/" -l "输出目录/highlights_fro
- **剪映逆向分析**`03_卡木/木叶_视频内容/视频切片/参考资料/剪映_智能剪口播与智能片段分割_逆向分析.md`
- 智能剪口播 H5 路径、智能片段分割 config 与参数、自实现建议与合规说明。
- **热点切片标准流程**`参考资料/热点切片_标准流程.md`(五步、两目录、命令速查)。
- **高光识别提示词**`参考资料/高光识别提示词.md`(提问→回答、节奏感、快速混剪优先片段规则)。
---

View File

@@ -57,6 +57,28 @@
---
## 可选第六步:快速混剪预告
当已经产出 `切片/``成片/` 后,可再生成一条**节奏更快、便于预热/招商/引流**的混剪视频:
1. **输入**:优先使用 **成片/** 目录,自动跳过每条前 2.6 秒封面。
2. **顺序**:优先按 `highlights.json` 里的 `virality_score` / `rank` 排序;没有分数则按序号。
3. **取样**:每条默认抽 **4 秒**高密度片段,统一分辨率后拼成一条 `快速混剪.mp4`
**命令:**
```bash
python3 脚本/quick_montage.py \
-i 成片/ \
-o 快速混剪.mp4 \
-l highlights.json \
--source-kind final \
-n 8 \
-s 4
```
---
## 流程小结(顺序执行)
| 步骤 | 内容 | 产出 |
@@ -66,6 +88,7 @@
| 3 | 按时间节点切片提取30 秒8 分钟/段) | **切片/** |
| 4 | 去语助词(合并在步骤 5 | — |
| 5 | 加封面 + 烧录字幕 | **成片/** |
| 6可选 | 从切片/成片生成节奏预告 | **快速混剪.mp4** |
**只保留两个目录****切片**、**成片**。其他中间目录不保留。

View File

@@ -111,6 +111,7 @@ CTA的目的是引导用户完成下一步动作。
4. **开场**尽量以金句或问题开头3秒内抓住注意力
5. **语助词与空格**:识别时标注或剔除语助词(嗯、啊、呃、那个、就是、然后等)及中间无意义空排/停顿,与主题片段提取规则一致,成片剪辑时由 soul_enhance 统一清理
6. **节奏感**:优先选讲话有步骤、有节奏的片段(起承转合清晰、不拖沓、少重复),避免大段碎碎念或断句混乱
7. **快速混剪友好**:优先保留开场 35 秒就进入观点/问题的片段,避免前摇过长、背景铺垫太久,方便后续 `quick_montage.py` 直接抽取成混剪预告
# 输出格式严格JSON
@@ -159,6 +160,7 @@ CTA的目的是引导用户完成下一步动作。
6. 只输出JSON不要其他解释
7. **与主题片段提取一致**Soul 剪辑全流程(高光识别 → batch_clip → soul_enhance → 竖屏裁剪)继承本提示词;主题片段由章节拆解时,判断标准、语助词与节奏感要求与本提示词保持一致。
8. **有提问时**:片段内有人提问则必须填 `question`,且 `hook_3sec` 与 question 一致成片前3秒先展示提问再回答去语助词覆盖整条成片含提问与回答
9. **用于快速混剪时**:优先让 `transcript_excerpt` 保持强观点、高密度,便于后续按 `virality_score` / `rank` 做混剪排序。
# 视频文字稿(带时间戳)

View File

@@ -0,0 +1,390 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
快速混剪:从切片/成片目录中抽取高密度片段,快速拼成一条预告混剪。
默认策略:
1. 优先读取 highlights.json 的 virality_score / rank 决定顺序
2. 若输入是成片目录,自动跳过前 2.6 秒封面
3. 每条取 3~5 秒高密度片段,统一分辨率后拼接
"""
import argparse
import json
import os
import random
import shutil
import subprocess
import tempfile
from pathlib import Path
def run(cmd: list[str], desc: str = "", check: bool = True) -> subprocess.CompletedProcess:
if desc:
print(f" {desc}...", flush=True)
result = subprocess.run(cmd, capture_output=True, text=True)
if check and result.returncode != 0:
raise RuntimeError(result.stderr.strip() or f"{desc or '命令'} 执行失败")
if desc:
print("", flush=True)
return result
def ffprobe_json(video_path: Path) -> dict:
result = run(
[
"ffprobe",
"-v",
"error",
"-show_entries",
"stream=index,codec_type,width,height:format=duration",
"-of",
"json",
str(video_path),
],
check=True,
)
return json.loads(result.stdout or "{}")
def get_video_info(video_path: Path) -> dict:
info = ffprobe_json(video_path)
streams = info.get("streams", [])
video_stream = next((s for s in streams if s.get("codec_type") == "video"), {})
has_audio = any(s.get("codec_type") == "audio" for s in streams)
duration = float(info.get("format", {}).get("duration", 0) or 0)
return {
"path": video_path,
"width": int(video_stream.get("width", 0) or 0),
"height": int(video_stream.get("height", 0) or 0),
"duration": duration,
"has_audio": has_audio,
}
def parse_clip_index(filename: str) -> int:
import re
matches = re.findall(r"_(\d+)_", filename)
if matches:
return min(int(m) for m in matches)
fallback = re.search(r"(\d+)", filename)
return int(fallback.group(1)) if fallback else 0
def load_highlights(highlights_path: Path | None) -> list[dict]:
if not highlights_path or not highlights_path.exists():
return []
with open(highlights_path, "r", encoding="utf-8") as f:
data = json.load(f)
if isinstance(data, dict) and "clips" in data:
data = data["clips"]
return data if isinstance(data, list) else []
def detect_source_kind(input_dir: Path, source_kind: str) -> str:
if source_kind != "auto":
return source_kind
name = input_dir.name
if name in {"成片", "clips_enhanced", "clips_enhanced_vertical"}:
return "final"
return "clip"
def choose_window(info: dict, source_kind: str, seconds_per_clip: float, skip_cover_sec: float, tail_guard_sec: float) -> tuple[float, float]:
duration = max(0.0, float(info["duration"]))
if duration <= 0.2:
return 0.0, 0.0
if source_kind == "final":
start_sec = min(skip_cover_sec, max(0.0, duration - seconds_per_clip - tail_guard_sec))
else:
lead_in = min(1.2, duration * 0.12)
start_sec = min(lead_in, max(0.0, duration - seconds_per_clip - tail_guard_sec))
usable = max(0.0, duration - start_sec - tail_guard_sec)
clip_sec = min(seconds_per_clip, usable)
if clip_sec < 1.2:
clip_sec = max(0.8, min(duration, seconds_per_clip))
start_sec = max(0.0, (duration - clip_sec) / 2)
end_sec = min(duration, start_sec + clip_sec)
return round(start_sec, 3), round(end_sec, 3)
def scale_pad_filter(target_w: int, target_h: int, speed_factor: float) -> str:
return (
f"scale={target_w}:{target_h}:force_original_aspect_ratio=decrease,"
f"pad={target_w}:{target_h}:(ow-iw)/2:(oh-ih)/2:black,"
f"setsar=1,fps=30,setpts=PTS/{speed_factor}"
)
def build_candidates(videos: list[Path], highlights: list[dict]) -> list[dict]:
results = []
for video in videos:
info = get_video_info(video)
clip_index = parse_clip_index(video.name)
highlight = highlights[clip_index - 1] if 0 < clip_index <= len(highlights) else {}
virality = highlight.get("virality_score", 0) if isinstance(highlight, dict) else 0
rank = highlight.get("rank", clip_index or 999) if isinstance(highlight, dict) else clip_index or 999
title = (
(highlight.get("title") if isinstance(highlight, dict) else None)
or video.stem
)
results.append(
{
"video": video,
"info": info,
"highlight": highlight if isinstance(highlight, dict) else {},
"clip_index": clip_index,
"virality_score": float(virality or 0),
"rank": int(rank or 999),
"title": str(title),
}
)
return results
def order_candidates(candidates: list[dict], order: str, seed: int) -> list[dict]:
ordered = list(candidates)
if order == "shuffle":
random.Random(seed).shuffle(ordered)
return ordered
if order == "viral":
has_score = any(item.get("virality_score", 0) > 0 for item in ordered)
if has_score:
return sorted(
ordered,
key=lambda item: (
-item.get("virality_score", 0),
item.get("rank", 999),
item["video"].name,
),
)
return sorted(
ordered,
key=lambda item: (
item.get("clip_index", 999) or 999,
item["video"].name,
),
)
def render_segment(
source: Path,
output: Path,
start_sec: float,
end_sec: float,
target_w: int,
target_h: int,
has_audio: bool,
speed_factor: float,
) -> None:
duration = max(0.1, end_sec - start_sec)
cmd = [
"ffmpeg",
"-y",
"-ss",
f"{start_sec:.3f}",
"-i",
str(source),
"-t",
f"{duration:.3f}",
"-vf",
scale_pad_filter(target_w, target_h, speed_factor),
"-c:v",
"libx264",
"-preset",
"fast",
"-crf",
"23",
"-pix_fmt",
"yuv420p",
]
if has_audio:
cmd += ["-af", f"atempo={speed_factor}", "-c:a", "aac", "-b:a", "128k"]
else:
cmd += ["-an"]
cmd.append(str(output))
run(cmd, check=True)
def concat_segments(segment_paths: list[Path], output_path: Path) -> None:
concat_list = output_path.with_suffix(".txt")
with open(concat_list, "w", encoding="utf-8") as f:
for path in segment_paths:
f.write(f"file '{path}'\n")
result = subprocess.run(
[
"ffmpeg",
"-y",
"-f",
"concat",
"-safe",
"0",
"-i",
str(concat_list),
"-c",
"copy",
str(output_path),
],
capture_output=True,
text=True,
)
if result.returncode == 0 and output_path.exists():
return
run(
[
"ffmpeg",
"-y",
"-f",
"concat",
"-safe",
"0",
"-i",
str(concat_list),
"-c:v",
"libx264",
"-preset",
"fast",
"-crf",
"22",
"-c:a",
"aac",
"-b:a",
"128k",
str(output_path),
],
desc="拼接混剪视频",
check=True,
)
def write_manifest(output_path: Path, items: list[dict], source_kind: str, seconds_per_clip: float) -> None:
manifest = {
"output": str(output_path),
"source_kind": source_kind,
"seconds_per_clip": seconds_per_clip,
"clips": items,
}
with open(output_path.with_suffix(".json"), "w", encoding="utf-8") as f:
json.dump(manifest, f, ensure_ascii=False, indent=2)
def main() -> None:
parser = argparse.ArgumentParser(description="快速混剪:从切片/成片目录一键生成节奏版预告")
parser.add_argument("--input-dir", "-i", required=True, help="输入目录(切片/成片)")
parser.add_argument("--output", "-o", required=True, help="输出混剪视频路径")
parser.add_argument("--highlights", "-l", help="highlights.json 路径,用于按热度排序")
parser.add_argument("--source-kind", choices=["auto", "clip", "final"], default="auto", help="输入目录类型")
parser.add_argument("--order", choices=["viral", "chronological", "shuffle"], default="viral", help="混剪顺序")
parser.add_argument("--max-clips", "-n", type=int, default=8, help="最多取多少条视频")
parser.add_argument("--seconds-per-clip", "-s", type=float, default=4.0, help="每条混剪截取秒数")
parser.add_argument("--skip-cover-sec", type=float, default=2.6, help="成片目录默认跳过前几秒封面")
parser.add_argument("--tail-guard-sec", type=float, default=0.6, help="片尾预留秒数,避免切到收尾黑屏")
parser.add_argument("--speed-factor", type=float, default=1.05, help="混剪整体加速倍数")
parser.add_argument("--seed", type=int, default=42, help="shuffle 时的随机种子")
args = parser.parse_args()
input_dir = Path(args.input_dir).resolve()
output_path = Path(args.output).resolve()
output_path.parent.mkdir(parents=True, exist_ok=True)
if not input_dir.exists():
raise SystemExit(f"❌ 输入目录不存在: {input_dir}")
videos = sorted([p for p in input_dir.glob("*.mp4") if p.is_file()])
if not videos:
raise SystemExit(f"❌ 目录下没有 mp4: {input_dir}")
source_kind = detect_source_kind(input_dir, args.source_kind)
highlights = load_highlights(Path(args.highlights).resolve()) if args.highlights else []
candidates = build_candidates(videos, highlights)
ordered = order_candidates(candidates, args.order, args.seed)
if args.max_clips > 0:
ordered = ordered[: args.max_clips]
if not ordered:
raise SystemExit("❌ 没有可用视频用于混剪")
target_w = ordered[0]["info"]["width"] or 498
target_h = ordered[0]["info"]["height"] or 1080
print("=" * 60)
print("⚡ 快速混剪")
print("=" * 60)
print(f"输入目录: {input_dir}")
print(f"目录类型: {source_kind}")
print(f"选取数量: {len(ordered)}")
print(f"每条秒数: {args.seconds_per_clip}")
print(f"输出视频: {output_path}")
print("=" * 60)
manifest_items = []
temp_dir = Path(tempfile.mkdtemp(prefix="quick_montage_"))
segment_paths: list[Path] = []
try:
for idx, item in enumerate(ordered, 1):
info = item["info"]
start_sec, end_sec = choose_window(
info,
source_kind,
args.seconds_per_clip,
args.skip_cover_sec,
args.tail_guard_sec,
)
if end_sec - start_sec < 0.8:
print(f" 跳过过短视频: {item['video'].name}", flush=True)
continue
segment_path = temp_dir / f"segment_{idx:02d}.mp4"
print(
f" [{idx}/{len(ordered)}] {item['title']} {start_sec:.1f}s -> {end_sec:.1f}s",
flush=True,
)
render_segment(
item["video"],
segment_path,
start_sec,
end_sec,
target_w,
target_h,
info["has_audio"],
args.speed_factor,
)
segment_paths.append(segment_path)
manifest_items.append(
{
"index": idx,
"file": item["video"].name,
"title": item["title"],
"start_sec": start_sec,
"end_sec": end_sec,
"virality_score": item.get("virality_score", 0),
}
)
if not segment_paths:
raise SystemExit("❌ 没有成功生成任何混剪片段")
concat_segments(segment_paths, output_path)
write_manifest(output_path, manifest_items, source_kind, args.seconds_per_clip)
size_mb = output_path.stat().st_size / (1024 * 1024)
print()
print("=" * 60)
print("✅ 快速混剪完成")
print("=" * 60)
print(f"输出: {output_path}")
print(f"大小: {size_mb:.1f}MB")
print(f"清单: {output_path.with_suffix('.json')}")
finally:
shutil.rmtree(temp_dir, ignore_errors=True)
if __name__ == "__main__":
main()

View File

@@ -4,7 +4,7 @@
Soul 切片一体化流水线
视频制作(封面/Hook格式+ 视频切片
流程:转录 → 字幕转简体 → 高光识别(AI) → 批量切片 → 增强(封面+字幕+CTA)
流程:转录 → 字幕转简体 → 高光识别(AI) → 批量切片 → 增强(封面+字幕+CTA) → 快速混剪(可选)
"""
import argparse
import atexit
@@ -116,6 +116,10 @@ def main():
parser.add_argument("--two-folders", action="store_true", help="仅用两文件夹:切片、成片(默认 clips、clips_enhanced")
parser.add_argument("--slices-only", action="store_true", help="只做到切片MLX 转录→高光→批量切片),不跑成片增强")
parser.add_argument("--prefix", default="", help="切片文件名前缀,如 soul112")
parser.add_argument("--quick-montage", action="store_true", help="额外生成一条快速混剪视频")
parser.add_argument("--montage-source", choices=["auto", "clips", "finals"], default="auto", help="快速混剪使用切片还是成片")
parser.add_argument("--montage-max-clips", type=int, default=8, help="快速混剪最多取多少条片段")
parser.add_argument("--montage-seconds", type=float, default=4.0, help="快速混剪每条截取秒数")
args = parser.parse_args()
video_path = Path(args.video).resolve()
@@ -245,6 +249,19 @@ def main():
sys.exit(1)
if getattr(args, "slices_only", False):
if getattr(args, "quick_montage", False):
montage_output = base_dir / "快速混剪.mp4"
montage_cmd = [
sys.executable,
str(SCRIPT_DIR / "quick_montage.py"),
"--input-dir", str(clips_dir),
"--output", str(montage_output),
"--highlights", str(highlights_path),
"--source-kind", "clip",
"--max-clips", str(args.montage_max_clips),
"--seconds-per-clip", str(args.montage_seconds),
]
run(montage_cmd, "生成快速混剪", timeout=600, check=False)
print()
print("=" * 60)
print("✅ 切片阶段完成(--slices-only")
@@ -277,12 +294,37 @@ def main():
for f in sorted(clips_dir.glob("*.mp4")):
shutil.copy(f, enhanced_dir / f.name)
if getattr(args, "quick_montage", False):
montage_output = base_dir / "快速混剪.mp4"
if args.montage_source == "clips":
montage_input = clips_dir
montage_kind = "clip"
elif args.montage_source == "finals":
montage_input = enhanced_dir
montage_kind = "final"
else:
montage_input = enhanced_dir if enhanced_count > 0 else clips_dir
montage_kind = "final" if enhanced_count > 0 else "clip"
montage_cmd = [
sys.executable,
str(SCRIPT_DIR / "quick_montage.py"),
"--input-dir", str(montage_input),
"--output", str(montage_output),
"--highlights", str(highlights_path),
"--source-kind", montage_kind,
"--max-clips", str(args.montage_max_clips),
"--seconds-per-clip", str(args.montage_seconds),
]
run(montage_cmd, "生成快速混剪", timeout=600, check=False)
print()
print("=" * 60)
print("✅ 流水线完成")
print("=" * 60)
print(f" 切片: {clips_dir}")
print(f" 成片: {enhanced_dir}")
if getattr(args, "quick_montage", False):
print(f" 混剪: {base_dir / '快速混剪.mp4'}")
print(f" 清单: {base_dir / 'clips_manifest.json'}")

View File

@@ -288,3 +288,4 @@
| 2026-03-11 14:38:13 | 🔄 卡若AI 同步 2026-03-11 14:38 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 |
| 2026-03-11 14:45:54 | 🔄 卡若AI 同步 2026-03-11 14:45 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 |
| 2026-03-11 14:55:15 | 🔄 卡若AI 同步 2026-03-11 14:55 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 |
| 2026-03-11 15:07:58 | 🔄 卡若AI 同步 2026-03-11 15:07 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 |

View File

@@ -291,3 +291,4 @@
| 2026-03-11 14:38:13 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-11 14:38 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-11 14:45:54 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-11 14:45 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-11 14:55:15 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-11 14:55 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-11 15:07:58 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-11 15:07 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |

View File

@@ -14,6 +14,7 @@
| T003 | 卡若AI 4项优化落地 | 大总管 | 🔄 执行中 | 减重+收口+规则+输出+护栏 | 2026-02-25 21:00 |
| T004 | 一人公司Agent开发第一优先级 | 火炬+木叶 | 🔄 执行中 | 视频切片/文章/直播/小程序/朋友圈→聚合平台 5% | 2026-02-27 |
| T005 | 玩值电竞推进(第二优先级) | 火炬 | 🔄 执行中 | Docker 3001MongoDB wanzhi_esports 25% | 2026-02-27 |
| T006 | 视频切片与快速混剪能力补强 | 木叶+火炬 | ✅ 已完成 | 已收口最新切片风格/提示词/规则,新增 quick_montage 与流水线一键入口 | 2026-03-11 23:23 |
---