15 KiB
我这样每次都确认太麻烦,能不能写个交接文档,如果需要的话。
我准备重启Cluade,下次启动会加上参数--permission-mode auto,这样就不用每次都确认了。
但是我还想续着本次的工作。你看我怎么样处理合适,你做哪些?
1
# 在本地路径下,建一个工作目录,比如`D:\AI\ClaudeCode\voice-ge`,运行powershell,
# cli进入工作目录
cd D:\AI\ClaudeCode\voice-ge
# 启动Claude 自动审批模式
claude --permission-mode auto
# 以下是对话内容:
我有一个Mmx CLI的Skill,你看看能不能用?
2
你也用的是minimax,账户是一套。它的这些能力,准确说应该你也有,你能做这些么?
3
那么我准备基于mmx cli开发一个语音生成的系统,或者叫Agent系统。
分为环境准备和工作两部分:
环境准备:
- 我指定一个我的语音文件,确定生成的voice id,你调用Mmx 生成这个voice id,记录下来。
- 我可能有多个语音,账户下生成多个voice id
工作:
- 有voice id 清单,我选择具体的voice id
- 指定一个口播稿路径,基于路径下的文稿,在指定的目标目录下生成语音文件
- 可能是一个口播稿,也可能是多个;
- 口播稿文件名,需要与口播稿同名,只是后缀不同:口播稿是.md格式,生成的语音文件看能生成什么格式的。
使用方式:
- 是命令行的方式,我可以包装成一个技能,直接在Cluade Code,Codex或者OpenClaw中进行调用。
基于以上,你能帮我做一个规划么?
你的工作目录是D:\AI\ClaudeCode\voice-ge,你可以认为这个就是开发用的路径。你的规划,将来的脚本或者过程产物都放在这里。
4
plan我看了,我同意。 只是一个小小的修正,我本地是有Conda环境的,不要直接用python,在Conda中建一个与本次配套的新环境,及环境清单(如果我想移植到别的机器的话);将来测试跑脚本,都在Conda的环境里。
接下来你就要进入开发阶段了么?
5
远程仓库:https://git.wantsong.life/wantsong/voice-generation.git 我们把这个项目push 到远程仓库里。
6
我输入 voice-gen init报错了,下面是执行信息:
(base) PS C:\Users\wangq> conda activate voice-gen
(voice-gen) PS C:\Users\wangq> cd D:/AI/ClaudeCode/voice-ge
(voice-gen) PS D:\AI\ClaudeCode\voice-ge> voice-gen init
voice-gen : 无法将“voice-gen”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确
保路径正确,然后再试一次。
所在位置 行:1 字符: 1
+ voice-gen init
+ ~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (voice-gen:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
7
我确认一下,我刚执行了:
(base) PS C:\Users\wangq> conda activate voice-gen
(voice-gen) PS C:\Users\wangq> cd D:/AI/ClaudeCode/voice-ge
(voice-gen) PS D:\AI\ClaudeCode\voice-ge> cd D:\Mine\口播
(voice-gen) PS D:\Mine\口播> voice-gen init
initialized in D:\Mine\口播
(voice-gen) PS D:\Mine\口播> voice-gen voices list
(no voices registered; run `voice-gen voices add <name> <mp3>`)
(voice-gen) PS D:\Mine\口播>
现在通知我没有no voices registered,服务器上的已经删过了是么?
因为voice id是和minimax cli的账号绑定的,如果我在本机这个路径下做了voice id,那么我在别的机器也用这个账号的话,init时应该能拿下来。
除了init外,是否应该有一个pull voice id的指令,把voice id在本地与服务器同步一下。
8
现在服务器上的文件都是旧的,需要清掉。 先清服务器上的旧文件。
我在D:\Mine\口播环境下,上传新的音频,在新环境里测试。完了再说看需要补充哪些功能。
9
voice-gen voices add wantsong ./your-sample.mp3 --notes "anchor"
示例命令中的--notes "anchor" 是什么意思,是voice-id么? 我看你刚给的,又变成了"anchor voice",这个给谁用的,我能填中文么?
voiceid默认就是音频文件名对吧?
10
voice-gen voices add这个命令需要更新,增加friendly name,或者将notes直接改成friendly name。
notes对我没用,将来显示friendly name,我直接用这个:
voice-gen voices add wantsong C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a --name "BroTsong-2026-06-10"
你看下这个命令格式是否正确。
json形如:
"voices": {
"wantsong": {
"file_id":396061597295017,
"filename": "your-sample.mp3",
"created_at": "2026-06-10T...",
"friendly_name": "BroTsong-2026-06-10" }
}
你看下我的这个诉求,是否合理,合理的话。
- 改程序
- 我的这个
D:\Mine\口播环境需要重新初始化么,还是直接可以继续。
C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a
11
Dict key干啥用的?
你的意思比如wantsong类似于张三,可以作为分组,他名下有好多voice;还可以有个李四,名下也好多voice。这个我这里不需要。
直接拿 BroTsong-2026-06-10 当 dict key 和 --voice 的入参,不要 wantsong。我开始没明白json里的wantong是啥。这样的话,json里也不用出现friendly_name了。
那么调整完,形如:
voice-gen voices add wantsong C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a --name "BroTsong-2026-06-10"
"voices": {
"BroTsong-2026-06-10": {
"file_id":396061597295017,
"filename": "your-sample.mp3",
"created_at": "2026-06-10T..." }
}
这样就ok了。
若对齐思路,你可以做调整了。
12
我执行:
voice-gen voices add BroTsong-2026-06-10 "C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a"
报错了:
(voice-gen) PS D:\Mine\口播> voice-gen voices add BroTsong-2026-06-10 "C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a"
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "C:\Users\wangq\miniconda3\envs\voice-gen\Scripts\voice-gen.exe\__main__.py", line 5, in <module>
File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 226, in main
return cmd_voices_add(args)
^^^^^^^^^^^^^^^^^^^^
File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 121, in cmd_voices_add
info = _upload_voice_file(audio)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 61, in _upload_voice_file
raise MmxError(exit_code=result.returncode, stderr=result.stderr, command=" ".join(cmd))
voice_gen.errors.MmxError: mmx command failed (exit=1): {
"error": {
"code": 1,
"message": "API error: HTTP 404 (HTTP 404)"
}
} [cmd: mmx file upload --non-interactive --quiet --output json --file C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a --purpose voice_clone]
13
应该是生成了'BroTsong-2026-06-10' voice,按照你的测试,生成了hello.md
然后生成语音报错了
(voice-gen) PS D:\Mine\口播> voice-gen voices add BroTsong-2026-06-10 "C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a"
registered 'BroTsong-2026-06-10' → file_id=407449867293232
(voice-gen) PS D:\Mine\口播> echo "Hello, this is a test." > scripts/hello.md
(voice-gen) PS D:\Mine\口播> voice-gen gen --voice BroTsong-2026-06-10 scripts
✗ hello.md: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
done: 0 ok, 1 failed
14
执行后,报错:
(voice-gen) PS D:\Mine\口播> voice-gen gen --voice BroTsong-2026-06-10 scripts
✗ hello.md: mmx command failed (exit=1): {
"error": {
"code": 1,
"message": "API error: voice id not exist (HTTP 200)"
}
} [cmd: mmx speech synthesize --non-interactive --quiet --text Hello, this is a test. --voice 407449867293232 --format mp3 --out output\hello.mp3]
done: 0 ok, 1 failed
(voice-gen) PS D:\Mine\口播>
15
报错:
(voice-gen) PS D:\Mine\口播> voice-gen voices list
(no voices registered; run `voice-gen voices add <name> <mp3>`)
(voice-gen) PS D:\Mine\口播> voice-gen voices add BroTsong-2026-06-10 "C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a"
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "C:\Users\wangq\miniconda3\envs\voice-gen\Scripts\voice-gen.exe\__main__.py", line 5, in <module>
File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 357, in main
return cmd_voices_add(args)
^^^^^^^^^^^^^^^^^^^^
File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 248, in cmd_voices_add
_clone_voice_file(info["file_id"], args.name)
File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 197, in _clone_voice_file
raise MmxError(
voice_gen.errors.MmxError: mmx command failed (exit=1): voice_clone failed: status_code=2039 msg=voice clone voice id duplicate raw={'input_sensitive': False, 'input_sensitive_type': 0, 'demo_audio': '', 'base_resp': {'status_code': 2039, 'status_msg': 'voice clone voice id duplicate'}} [cmd: curl ... https://api.minimaxi.com/v1/voice_clone]
16
好的测试成功了,拿到了音频。 提交并push到远程,标记一下,这个是可以跑通的版本。
现在应该有一套完整的Voice id的管理,及与服务器同步的命令。我考虑的有以下,不一定准确,你自己判断。 制订个管理和同步的规划:
- 项目init时,应该去pull一下
- 应该在create mp3 前,去pull 一下。若服务器没有,MP3也做不成功。
- 功能上,应该有pull命令
- 可以由用户指定,删除某个voice id,同步服务器删除。
- 与服务器操作前,应该都需要pull,包括add
17
基于服务器不能删的话,那么我们做个简化
- 加 pull 命令
- 在 add 前做pull,判断是否能加
工作范围,我调整如下:
##范围| 命令 |状态 |
|---|---|
| voices add |改:加服务端去重预检 |
| voices list | 不变 |
| voices cleanup | 不变 |
| voices pull | 新增|
| voices status | 新增 |
| gen | 不变 |
| init | 不变(保持离线)|
| README + SKILL.md |同步 |
voices status是做什么的,查服务器端的Voices list?
如果是的话,可否考虑:
- voices list local
- voices list server
为了避免类似的情况,我前面的voiceid其实已经打了时间戳。那么pull下来就好了。不做voices remove
你觉得呢?
18
我们现在的remove是假的,由于server 不支持,我建议删掉这个命令:voice-gen voices remove <name>,不然会造成混淆。
即,服务器上不支持删,客户端上也不支持。
pull 从 filename派生,所以我后续会保持,文件名与voice id一致。那么,我们需要改add:
- 形如
voice-gen voices add "C:\Users\wangq\Documents\录音\BroTsong-Saying-2026-06-10.m4a",这样没有命名的问题,就用文件名,也不需要重新命名。你add的时候friendly name就从文件名取。 - 增加pull
前面上传的文件没有日期,后面的文件都会有日期,所以也没问题。
你觉得呢?
后续我的测试: 这个改完后,
- 我重新找个文件夹,初始化
init,然后pull下来,会有一个从服务器上拉下来的voice,我尝试生成 - 我上传一个新的语音文件,尝试生成
19
你后续测试的预期行为测试1(新目录 + pull):
powershellmkdir D:\Mine\pull-test;
cd D:\Mine\pull-test
voice-gen init # voices.json 是空的(local 也空)
voice-gen pull # 自动从服务器拉下所有 voice_clone 文件,按 filename派生 voice_id
#当前服务端有:BroTsong-Saying.m4a(file_id407449867293232)
# → 本地会有一个 entry:{"BroTsong-Saying": {file_id:..., filename:"BroTsong-Saying.m4a", ...}}
voice-gen listvoice-gen gen --voice BroTsong-Saying scripts
测试2(新文件 add + 生成):
powershell#准备一个带日期的文件,比如 BroTsong-Saying-2026-06-10.m4avoice-gen
voices add "C:\path\to\BroTsong-Saying-2026-06-10.m4a"
#内部:filename → "BroTsong-Saying-2026-06-10" voice_id# 上传 + voice_clone +存 registryvoice-gen
list#应该有:BroTsong-Saying-2026-06-10 file_id=... filename=...
voice-gen gen --voice BroTsong-Saying-2026-06-10 scripts
20
之前,我们传的BroTsong-Saying.m4a,voice-id为BroTsong-2026-06-10,现在pull下来后默认按文件名走的话,这个名字对应不上了。
(voice-gen) PS D:\Mine\口播2> voice-gen pull
usage: voice-gen [-h] {init,voices,gen} ...
voice-gen: error: argument command: invalid choice: 'pull' (choose from 'init', 'voices', 'gen')
(voice-gen) PS D:\Mine\口播2> voice-gen voices pull
file_id=407449867293232 filename=BroTsong-Saying.m4a
friendly name [BroTsong-Saying]:
+ 'BroTsong-Saying' file_id=407449867293232 filename=BroTsong-Saying.m4a
pulled: 1 added
(voice-gen) PS D:\Mine\口播2> voice-gen gen --voice BroTsong-Saying scripts
✗ hello.md: mmx command failed (exit=1): {
"error": {
"code": 1,
"message": "API error: voice id not exist (HTTP 200)"
}
} [cmd: mmx speech synthesize --non-interactive --quiet --text Hello, this is a test. --voice BroTsong-Saying --format mp3 --out output\hello.mp3]
done: 0 ok, 1 failed
(voice-gen) PS D:\Mine\口播2> voice-gen list server
usage: voice-gen [-h] {init,voices,gen} ...
voice-gen: error: argument command: invalid choice: 'list' (choose from 'init', 'voices', 'gen')
(voice-gen) PS D:\Mine\口播2> voice-gen voices list server
BroTsong-Saying.m4a file_id=407449867293232
(voice-gen) PS D:\Mine\口播2>
上面是我的测试,我觉得服务器上应该有记录friendLy name。 你检查下api,是否可以查到friendly name。 完了我们再判断,这里怎么优化。
21
行了,不用改了。先提交并push到远程,标记为完善了voice id命名从文件名取,增加了pull。
我在PowerShell里做了测试。那么Cluade code/这里可以按技能调用么?
22
我看到这个目录,放在这里的话,是不是本机都能看见? C:\Users\wangq\.agents\skills
C:\Users\wangq\.claude\skills,cluade的技能其实都引用的是C:\Users\wangq\.agents\skills这里的。
另外,文件夹有点问题,skill的默认文件夹叫voice-gen更合理些,包括技能名字也叫voice-gen
我在新机器上,是否能够利用npx 这样的命令,给一个我的git服务器链接,就能安装技能?
所以,如果我说的没问题的话,先回答问题,再处理:
- 更新相应的说明文件,配置文件
- 删掉 claude skills,将skill放到
.agents/skills/,.claude/skills/里应该只是个引用