---
name: voice-casting
description: 为短剧、漫剧、旁白或角色配音查找参考音色。通过声选 API 检索 1248 条参考音频，匹配主选和备选；仅有画布工具时，可读取随附分片索引选声并返回稳定音频链接。用于选声音、音色匹配、给角色找参考音频，不生成配音或提交视频任务。
---

# 声选：为角色选择参考音频

网站：<https://voices.ebeb.fun>。API 基址同上，无需密钥。音频是原始 WAV/MP3 试听样本，不是 TTS 模型。

## 先选当前环境可执行的路径

- 有 HTTP、网页读取或命令执行工具：使用 API 路径。优先使用真实 HTTP 工具；有 shell 时可用 curl 或 Python 标准库。画布的 Codex Agent 模式通常可使用 Codex 自身工具，但以本次实际暴露的工具和联网权限为准。
- 只有 `get_canvas_summary`、`get_node`、`read_skill_file` 等画布工具：使用附属索引路径。当前版本内置画布 Agent 没有通用 HTTP 工具，Skill 文字不能新增工具；不要声称已经发出 API 请求，也不要虚构 `http_request`、shell 或音频导入工具。
- 没有联网工具，也不能读取附属文件：说明缺少所需工具或索引，并给出网站链接供用户选声。不能凭空猜音色编号。

角色来自用户输入或当前已有剧本/角色节点。只在缺少会明显影响选声的信息时询问；其余先按已有信息给出候选。分离角色性别、年龄感、语言/方言、声线质感、性格、表演风格和应避免的特点；声音身份与某一句台词的情绪分开处理。

## API 路径

多角色优先一次调用 `POST https://voices.ebeb.fun/api/match`，请求头：

```text
Content-Type: application/json
User-Agent: VoiceCasting/1.0
```

使用真实、非空的客户端 User-Agent，示例值如上。Python urllib 或没有 User-Agent 的客户端可能被站点入口返回 403 / error 1010；此时以真实应用名称标识客户端后重试，不需要登录或 Cloudflare 管理令牌。

```json
{
  "roles": [
    {"id":"lead", "name":"林舟", "gender":"male", "language":"zh", "description":"32岁，低沉磁性、沉稳克制的男主"},
    {"id":"heroine", "name":"苏晚", "gender":"female", "language":"zh", "description":"22岁，清甜自然、有韧性的温柔少女"}
  ],
  "uniqueAudio": true,
  "limit": 3
}
```

一次支持 1–20 个角色；`limit` 是每角主选与备选的总数，1–10。`uniqueAudio:true` 默认开启，按录音 SHA-256 统筹主选去重，而不只是比较编号。

将明确的性别、语言写入结构化字段；年龄不确定时放在描述中作为偏好。`ageGroup`、`category`、`tags` 是硬筛选，避免随意填满导致无结果。`avoid` / `excludeTags` 可排除不希望的标签；`excludeVoiceIds` 排除已定音色编号。没有明确语言要求时，中文角色默认 `language:zh`；外语必须指定相应语言。

候选返回 `voice`、`score`、`reasons`、`evidence`、`warnings`；角色返回 `primary`、`alternatives` 和 `candidateCount`。使用响应里的真实 `voice.id`、`voice.audioUrl`、`voice.sha256`，不要把网页详情页当作音频，也不要构造临时签名地址。没有满足硬筛选条件时 `primary:null`；说明缺口，不擅自改变性别/语言要求。

需要查找已知音色、精确筛选、分页或读取详情时，见 [references/API.md](references/API.md)。不要为每个角色反复下载完整目录。

若当前只有 shell，下面的标准库示例可直接请求；用本次真实角色替换请求体：

```python
import json, urllib.request
payload = {"roles":[{"id":"lead","name":"男主","gender":"male","language":"zh","description":"低沉磁性，沉稳克制"}],"uniqueAudio":True,"limit":3}
request = urllib.request.Request("https://voices.ebeb.fun/api/match", data=json.dumps(payload,ensure_ascii=False).encode(), headers={"Content-Type":"application/json","User-Agent":"VoiceCasting/1.0"})
with urllib.request.urlopen(request,timeout=30) as response:
    result = json.load(response)
print(json.dumps(result,ensure_ascii=False,indent=2))
```

网络超时或 5xx 可重试一次；继续失败则明确说明，转附属索引路径。不要循环尝试、索取 Cloudflare 凭据或修改网络权限。

## 附属索引路径（适用于当前内置画布 Agent）

先读取 [references/INDEX.md](references/INDEX.md)，再按它的目录读取相关分片。画布中使用 `read_skill_file`，`skillId` 必须取当前激活 Skill 上下文中提供的真实 ID，`path` 使用相对路径，例如 `references/catalog/male-01.md`。在文件型宿主中直接读取相对文件。

按角色性别、语言、年龄感选择相关分片，结合索引概述和实际条目选 2–3 个候选；不必一次读完 1248 条。每条记录包含原名、声线、标签、语言、稳定 `audioUrl` 和 `sha256`。使用这些真实条目，不能编造未读到的音色。不同角色主选尽量不共享相同 `sha256`；如受限而必须复用，明确提示。

向用户说明“依据随附索引匹配”，不要称为实时 API 返回或伪造 API 分数。需要最新目录时，引导使用联网 Agent 或网站更新后的技能包。

## 比较与交付

- 主选与备选要结合角色用途比较：日常对白、旁白、新闻、宣传片的表演方式不同；不能只因音高标签相符就把宣传片声线断言为最佳对白声音。
- API 评分表示原站名称、标签和角色要求的匹配程度，不是声学相似度、真实年龄、真人身份或最终效果保证。未试听就说“建议优先试听”，不要声称听过或完成声学验证。角色的年龄感也只是名称/标签线索。
- 返回每角：角色名、主选音色名与编号、推荐理由、1–2 个备选、可试听/下载的 `audioUrl`。对比语言、性别和录音哈希，检查不能违背明确要求。
- 用户已要求记录到画布时，可用已有文本节点工具保存“角色 → 音色编号 → 音频直链 → 理由”，沿用真实角色节点做来源连线。节点 ID 必须来自真实画布查询。
- 只有实际存在“从 URL 导入音频”的工具时，才导入参考音频并返回真实音频节点 ID。否则返回链接和对应关系，说明尚未导入；不把文本节点冒充音频节点，也不使用 `generate_audio` 假装导入录音。
- 若视频工具只接受音频节点引用，应先导入为真实音频节点；支持 URL 的生成接口才直接用 `audioUrl`。选音色本身不构成提交付费配音、克隆或视频生成任务的授权。

本站只提供参考音频检索，不提供语音生成。音频使用范围以来源与相关声音权利人的许可为准。
