AI 工具

Synthesia 数字人视频脚本的安全预检

生成数字人视频前,先检查脚本长度、标题,并拦截常见冒充/转账诱导等模式。这篇 scriptguard.py 是预检,不是平台审核的替代。

BINBHO · 图文教程

生成数字人视频前,先检查脚本长度、标题,并拦截常见冒充/转账诱导等模式。这篇 script_guard.py 是预检,不是平台审核的替代。

先看清成品

  • 培训样例 OK;冒充转账样例 FINDINGS。
  • 3 项 pytest 通过。

合规提醒:定制以真人为原型的数字人必须取得本人同意,并按平台完成身份验证;不得用数字人冒充他人、从事欺诈或未披露的政治宣传。Video API 通常需 Pro 及以上(以官网为准);test: true 有水印且有每日测试限额。本文不编造价格与配额数字(除文档已写明的测试限额提示外,以你控制台为准)。

运行说明:无 Synthesia 正式密钥。A/C 本地合规检查;B 用 mock 创建+轮询到 complete。对官方主机无效 Authorization 实测 HTTP 403。2026-10-23(Asia/Shanghai)pytest 通过。

做完之后你会得到什么?

成果 说明
script_guard.py 脚本预检
样例 txt ok/bad
test_100a.py 测试

需要准备哪些环境?

项目 说明
Python 3.10+

关键事实

事实 来源
创建视频可把旁白放在 scriptText(Quickstart)或更丰富的 input 多场景 官方 Create / Quickstart
test: true 不计入配额但有水印;文档提及测试日限额 官方 Video API / Quickstart
内容可能被审核拒绝(status=rejected) 官方 Videos 对象说明

文件结构

100-synthesia-A-src/
├── script_guard.py
├── sample_ok.txt
├── sample_bad.txt
└── test_100a.py

第 1 步:预检脚本

#!/usr/bin/env python3
"""Pre-flight checks for Synthesia avatar video scripts."""
from __future__ import annotations

import argparse
import json
import re
from pathlib import Path

# Soft practical limits for tutorial (not official hard caps).
MAX_CHARS = 5000
MIN_CHARS = 10
BANNED = [
    r"我是\s*(总统|总理|CEO\s*本人)",
    r"冒充",
    r"deepfake",
    r"未经授权",
    r"transfer\s+all\s+your\s+money",
    r"转账到此账户",
]


def check(script: str, *, title: str = "", test_mode: bool = True) -> list[str]:
    errs = []
    s = script.strip()
    if len(s) < MIN_CHARS:
        errs.append(f"脚本过短(<{MIN_CHARS})")
    if len(s) > MAX_CHARS:
        errs.append(f"脚本过长(>{MAX_CHARS}),建议拆成多场景 input[]")
    if not title.strip():
        errs.append("title 建议填写,便于分享页与检索")
    for pat in BANNED:
        if re.search(pat, s, re.I):
            errs.append(f"命中风险模式: {pat}")
    if re.search(r"https?://\S+", s) and "点击链接" in s:
        errs.append("脚本含链接+诱导点击,注意钓鱼风险审核")
    if not test_mode:
        errs.append("提醒: test=false 会计入配额;教程默认建议先 test=true")
    # blank-line scenes hint
    if s.count("\n\n") >= 8 and len(s) > 1500:
        errs.append("长脚本场景很多:考虑 API input 多 clip 而不是单 scriptText")
    return errs


def main(argv=None) -> int:
    ap = argparse.ArgumentParser(description=__doc__)
    ap.add_argument("script_file")
    ap.add_argument("--title", default="Untitled")
    ap.add_argument("--production", action="store_true", help="声明非 test 模式")
    ap.add_argument("--json", action="store_true")
    args = ap.parse_args(argv)
    text = Path(args.script_file).read_text(encoding="utf-8")
    errs = check(text, title=args.title, test_mode=not args.production)
    # filter soft reminder when --production intentionally set
    if args.production:
        errs = [e for e in errs if not e.startswith("提醒: test=false")]
    payload = {
        "ok": not errs,
        "chars": len(text.strip()),
        "title": args.title,
        "test_mode_recommended": not args.production,
        "findings": errs,
    }
    if args.json:
        print(json.dumps(payload, ensure_ascii=False, indent=2))
    else:
        print("OK" if not errs else "FINDINGS")
        for e in errs:
            print("-", e)
        print(f"chars={payload['chars']}")
    return 1 if errs else 0


if __name__ == "__main__":
    raise SystemExit(main())

第 2 步:测试

from pathlib import Path
import subprocess
import sys
from script_guard import check

HERE = Path(__file__).resolve().parent


def test_ok():
    t = (HERE / "sample_ok.txt").read_text()
    assert check(t, title="安全培训", test_mode=True) == []


def test_bad():
    t = (HERE / "sample_bad.txt").read_text()
    errs = check(t, title="x", test_mode=True)
    assert errs


def test_cli():
    r = subprocess.run(
        [
            sys.executable,
            str(HERE / "script_guard.py"),
            str(HERE / "sample_ok.txt"),
            "--title",
            "安全培训",
        ],
        capture_output=True,
        text=True,
    )
    assert r.returncode == 0

第 3 步:运行

OK
chars=81
FINDINGS
- 命中风险模式: 我是\s*(总统|总理|CEO\s*本人)
- 命中风险模式: 转账到此账户
- 脚本含链接+诱导点击,注意钓鱼风险审核
chars=45
...                                                                      [100%]
3 passed in 0.03s

怎么检查结果?

  • 生产脚本仍需走平台审核与人工审阅。
  • 长培训稿考虑拆成多 clip。

调试示例

预检通过 ≠ 平台通过。 Synthesia 仍可能 rejected。把 guard 当第一道闸,保留人工与法务闸。

常见问题

现象 原因 处理
字数上限 教程软限制 以你账号与文档为准
多语言 脚本语言与配音匹配 在产品里选 voice
要 SSML 视套餐/端点 先查当前文档

模板规则

  • 禁止冒充与欺诈脚本。
  • 先 test 再生产。
  • 定制形象必须授权。

项目资源

用途 地址
API Quickstart(官方) https://docs.synthesia.io/reference/synthesia-api-quickstart
Create a video(官方) https://docs.synthesia.io/reference/create-video
Synthesia 官网 https://www.synthesia.io/

脚本过关,再消耗生成配额。