Jasper 的 Brand Voice(API 里 tones)靠一段可执行的语气描述。这篇在调用
POST /v1/tones前,用voice_brief.py检查 name/value/metadata 是否齐全、是否过短,并挡掉明显的冒充类提示词。
先看清成品
- sample_ok 返回 OK;sample_bad 报告 name/过短/metadata 键数。
- 3 项 pytest 通过。
合规提醒:Jasper API 需工作区管理员/开发者权限开通;密钥勿进前端或公开仓库。生成营销文案须遵守广告与行业法规,禁止虚假疗效、保证收益等表述。品牌声音与知识库应使用你有权使用的资料。价格与套餐以官网为准,本文不编造。
运行说明:无 Jasper 正式密钥。A/C 为本地校验;B 用本机 mock(X-API-Key)跑通创建 tone + run task。2026-10-23(Asia/Shanghai)pytest 全部通过。对接正式环境时把
--base设为 https://api.jasper.ai 。
做完之后你会得到什么?
| 成果 | 说明 |
|---|---|
voice_brief.py |
校验器 |
sample_ok.json / sample_bad.json |
样例 |
test_97a.py |
3 项测试 |
需要准备哪些环境?
| 项目 | 说明 |
|---|---|
| Python | 3.10+ 标准库 + pytest |
关键事实
| 事实 | 来源 |
|---|---|
创建 voice 需 name 与 value;metadata 最多 10 键,键≤40、值≤500 字符 |
官方 Create a voice |
请求头使用 X-API-Key |
官方 Authentication |
| 本校验器的 value 最短长度是教程启发式,便于写出可操作描述 | 实践 |
文件结构
97-jasper-A-src/
├── voice_brief.py
├── sample_ok.json
├── sample_bad.json
└── test_97a.py
第 1 步:校验脚本
#!/usr/bin/env python3
"""Validate a Jasper Brand Voice brief before POST /v1/tones."""
from __future__ import annotations
import argparse
import json
import re
from pathlib import Path
# Soft limits aligned with practical API usage (official create tone: name + value required;
# metadata up to 10 keys, key<=40, value<=500 per Jasper docs).
NAME_MAX = 80
VALUE_MIN = 40
VALUE_MAX = 4000
META_MAX_KEYS = 10
META_KEY_MAX = 40
META_VAL_MAX = 500
def validate(brief: dict) -> list[str]:
errs: list[str] = []
name = (brief.get("name") or "").strip()
value = (brief.get("value") or "").strip()
if not name:
errs.append("name 必填")
elif len(name) > NAME_MAX:
errs.append(f"name 过长(>{NAME_MAX})")
if not value:
errs.append("value(声音描述)必填")
else:
if len(value) < VALUE_MIN:
errs.append(f"value 过短(<{VALUE_MIN}),品牌声音需要可操作的语气说明")
if len(value) > VALUE_MAX:
errs.append(f"value 过长(>{VALUE_MAX})")
if not re.search(r"[\u4e00-\u9fffA-Za-z]", value):
errs.append("value 似乎没有可读文字")
meta = brief.get("metadata") or {}
if meta is not None and not isinstance(meta, dict):
errs.append("metadata 必须是对象")
elif isinstance(meta, dict):
if len(meta) > META_MAX_KEYS:
errs.append(f"metadata 键数 > {META_MAX_KEYS}")
for k, v in meta.items():
if len(str(k)) > META_KEY_MAX:
errs.append(f"metadata 键过长: {k}")
if len(str(v)) > META_VAL_MAX:
errs.append(f"metadata 值过长: {k}")
# discourage impersonation / fake authority
bad = ("冒充", "伪造官方", "假装是", "undisclosed paid", "fake review")
low = value.lower()
for b in bad:
if b.lower() in low or b in value:
errs.append(f"疑似不当用途提示词: {b}")
return errs
def main(argv=None) -> int:
ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument("brief_json")
args = ap.parse_args(argv)
brief = json.loads(Path(args.brief_json).read_text(encoding="utf-8"))
errs = validate(brief)
if errs:
print("INVALID")
for e in errs:
print("-", e)
return 1
print("OK")
print(json.dumps({"name": brief["name"], "value_len": len(brief["value"].strip())}, ensure_ascii=False))
return 0
if __name__ == "__main__":
raise SystemExit(main())
第 2 步:测试
from pathlib import Path
import json
import subprocess
import sys
from voice_brief import validate
HERE = Path(__file__).resolve().parent
def test_ok():
brief = json.loads((HERE / "sample_ok.json").read_text())
assert validate(brief) == []
def test_bad():
brief = json.loads((HERE / "sample_bad.json").read_text())
errs = validate(brief)
assert any("name" in e for e in errs)
assert any("过短" in e for e in errs)
assert any("键数" in e for e in errs)
def test_cli_ok():
r = subprocess.run(
[sys.executable, str(HERE / "voice_brief.py"), str(HERE / "sample_ok.json")],
capture_output=True,
text=True,
)
assert r.returncode == 0
assert "OK" in r.stdout
第 3 步:运行
OK
{"name": "Acme 专业稳重", "value_len": 63}
... [100%]
3 passed in 0.03s
# bad:
INVALID
- name 必填
- value 过短(<40),品牌声音需要可操作的语气说明
- metadata 键数 > 10
怎么检查结果?
- OK 时打印 value_len。
- 正式创建前再人工读一遍 value。
调试示例
value 太文学、不可执行。 「专业、有温度」不够;要写称呼、句长、禁用词、产品名大小写。校验器只保证长度与结构,不能代替品牌手册。
常见问题
| 现象 | 原因 | 处理 |
|---|---|---|
| 官方限制不同 | 文档更新 | 以 developers.jasper.ai 为准 |
| 要批量导入 | CSV→JSON | 逐条 validate |
| 误报冒充 | 词表 | 按团队政策改 bad 列表 |
模板规则
- 密钥不进仓库。
- 声音描述避免冒充真人/官方。
- 不编造套餐价。
项目资源
| 用途 | 地址 |
|---|---|
| Authentication(官方) | https://developers.jasper.ai/docs/authentication |
| Create a voice(官方) | https://developers.jasper.ai/reference/createtone |
| Jasper 官网 | https://www.jasper.ai/ |
先把声音说明写清楚,再交给 API。