cli-anything-audacity 音频编辑命令行实战:以 JSON 工程状态为核心的 Agent 原生有状态音频处理方案
本文围绕 CLI-Anything 仓库中的 cli-anything-audacity SKILL.md 展开,介绍一套面向 AI Agent 的、有状态的 Audacity 命令行接口:它用 JSON 工程文件替代原生 .aup3 数据库格式来跟踪音轨、片段、效果器、标签与选区,并用 Python 标准库完成 WAV 读写与渲染。读完本文,你将掌握从项目创建、多轨混音、效果链应用到导出成品的完整命令行工作流,也能理解其 --json 机器输出与回滚机制为何天然适合被 Agent 与脚本驱动。
一、为什么需要一个"有状态"的 Audacity CLI
Audacity 本身是多平台音频编辑器,其原生 .aup3 工程是一个 SQLite 数据库,内部混合存放二进制音频块(自定义压缩)、轨道/片段/包络的关系型 schema、内嵌的撤销历史与工程元数据。直接解析与回写该格式需要对 Audacity 内部实现有深入理解,成本高且脆弱。
因此 AUDACITY.md 明确交代了本仓库的 CLI 策略:用 JSON 工程清单承载全部状态,渲染时输出到标准音频格式。核心设计原则有三条:
- JSON project format 跟踪所有状态(轨道、片段、效果器、标签、选区);
- Python stdlib(
wave、struct、math)负责 WAV I/O 与音频处理,核心功能零第三方依赖; - 效果器记录在工程 JSON 中,在导出/渲染阶段统一应用到音频数据。
本 CLI 采用与仓库中 GIMP、Blender CLI 相同的模式——一个有全局会话(Session)、支持撤销/重做、可用一行命令完成 GUI 对应操作的命令行层。入口代码见 audacity_cli.py,其 docstring 与模块结构清晰体现了"状态即工程 JSON + 子命令即编辑动作"的架构。
二、安装与运行前提
SKILL.md 规定该 CLI 随 cli-anything-audacity 包安装:
pip install cli-anything-audacity
运行前提(以 setup.py 与 README.md 为准):
- Python 3.10+(
python_requires=">=3.10"); - 依赖
click>=8.0.0、prompt-toolkit>=3.0.0、numpy>=1.24.0(其中 numpy 主要用于测试侧,核心音频逻辑走 Python stdlib); - 安装后提供控制台入口
cli-anything-audacity,对应cli_anything.audacity.audacity_cli:main(见 setup.py 的entry_points)。
如需从源码仓库内直接体验,可在 audacity/agent-harness/ 下通过模块方式运行,例如:
python3 -m cli_anything.audacity.audacity_cli project new --name "My Podcast"
快速开始
# 查看帮助
cli-anything-audacity --help
# 进入交互式 REPL
cli-anything-audacity
# 新建工程并写入文件
cli-anything-audacity project new -o project.json
# 以 JSON 输出工程信息(供 Agent 解析)
cli-anything-audacity --json project info -p project.json
注意其中的 -p/--project 全局参数用于加载一个既有的 .audacity-cli.json 工程文件;在 audacity_cli.py 中可以看到,CLI 在启动时会先据此打开工程再执行子命令。
三、命令分组总览
CLI 采用 Click 子命令组组织,全部命令与 GUI 操作一一对应。下表汇总各分组及其子命令(与 SKILL.md 中列出的命令完全一致,具体参数见下文逐组说明):
| 分组 | 子命令 |
|---|---|
project |
new、open、save、info、settings、json |
track |
add、remove、list、set |
clip |
import、add、remove、trim、split、move、list |
effect |
list-available、info、add、remove、set、list |
selection |
set、all、none、info |
label |
add、remove、list |
media |
probe、check |
export |
presets、preset-info、render |
session |
status、undo、redo、history |
另有独立的 eval 命令用于运行评测套件(见第五节)。
project —— 工程生命周期
| 命令 | 说明 | 关键参数 |
|---|---|---|
new |
新建工程 | --name/-n(默认 untitled)、--sample-rate/-sr(默认 44100)、--bit-depth/-bd(默认 16)、--channels/-ch(默认 2,1=单声道 2=立体声)、--output/-o 保存路径 |
open |
打开既有工程 | <path> |
save |
保存当前工程 | [path](缺省存回原路径) |
info |
展示工程信息 | — |
settings |
查看/更新采样率、位深、声道 | 不传参数只读,传参即修改 |
json |
打印原始工程 JSON | — |
参数实现细节可对照 audacity_cli.py:新建工程默认采样率 44100 Hz、16 bit、双声道,与 Podcast 等常规语音工程场景吻合。
track —— 轨道管理
track add 支持 --name/-n、--type(audio 或 label,默认 audio)、--volume/-v(0.0–2.0,默认 1.0)、--pan/-p(-1.0–1.0,默认 0.0)。
track set <index> <prop> <value> 支持修改 name、mute、solo、volume、pan 五个属性。其余为:
cli-anything-audacity track add --name "Voice" # 加音轨
cli-anything-audacity track list # 列出所有音轨
cli-anything-audacity track set 0 mute true # 静音 0 号轨
cli-anything-audacity track set 0 volume 0.8 # 调音量
cli-anything-audacity track set 0 pan -0.5 # 调声像
clip —— 片段编辑
| 命令 | 说明 | 位置参数 | 关键选项 |
|---|---|---|---|
import |
探测音频文件并展示元数据 | <path> |
— |
add |
向指定音轨添加片段 | <track_index> <source> |
--start/-s 时间轴起点(默认 0.0)、--end/-e 终点、--trim-start/--trim-end 源内裁剪、--volume/-v |
remove |
删除片段 | <track_index> <clip_index> |
— |
trim |
修剪片段头尾 | <track_index> <clip_index> |
--trim-start、--trim-end |
split |
在指定时间点切开片段 | <track_index> <clip_index> <split_time> |
— |
move |
把片段移到新的时间起点 | <track_index> <clip_index> <new_start> |
— |
list |
列出某轨道上的片段 | <track_index> |
— |
一个典型用法:
# 在 0 号轨 0.5s 处放入主录音
cli-anything-audacity clip add 0 host_recording.wav --start 0.5
effect —— 效果链
效果器不立即改写音频数据,而是追加到轨道的效果链并存入工程 JSON,在渲染时统一施加(见 effects.py 模块注释与 AUDACITY.md 的"Rendering Pipeline")。
| 命令 | 说明 |
|---|---|
list-available |
列出全部可用效果,--category/-c 可按 volume/fade/transform/delay/eq/dynamics/generate/restoration 过滤 |
info <name> |
查看效果详情与参数规格 |
add <name> |
给轨道追加效果,--track/-t 指定轨道索引(默认 0),-p key=value 可多次传入参数 |
remove <effect_index> |
按索引移除轨道效果(--track/-t) |
set <effect_index> <param> <value> |
修改效果参数(--track/-t) |
list |
列出某轨道上的效果链 |
selection / label —— 选区与标签
# 选区
cli-anything-audacity selection set 5.0 30.0 # 设置 5s–30s 选区
cli-anything-audacity selection all # 全选
cli-anything-audacity selection none # 清除选区
cli-anything-audacity selection info # 查看选区
# 标签
cli-anything-audacity label add 0.0 --text "Intro" # 点标签
cli-anything-audacity label add 30.0 -e 60.0 --text "Main" # 区间标签
cli-anything-audacity label list
media / session —— 媒体校验与会话
cli-anything-audacity media probe song.mp3 # 分析任意音频文件
cli-anything-audacity media check # 校验工程引用的音频文件是否齐全
cli-anything-audacity session status # 会话状态
cli-anything-audacity session history # 撤销历史
四、GUI 操作与 CLI 命令映射
AUDACITY.md 给出了"GUI 动作 → CLI 命令"的完整对照表,对习惯 Audacity 界面的用户非常友好:
| GUI 动作 | CLI 命令 |
|---|---|
| File → New | project new --name "My Project" |
| File → Open | project open <path> |
| File → Save | project save [path] |
| File → Export Audio | export render <output> [--preset wav] |
| Tracks → Add New → Audio | track add --name "Track" |
| Track → Mute/Solo | track set <index> mute true |
| Track → Volume | track set <index> volume 0.8 |
| Track → Pan | track set <index> pan -0.5 |
| File → Import → Audio | clip add <track> <file> |
| Edit → Clip Boundaries → Split | clip split <track> <clip> <time> |
| Effect → Amplify | effect add amplify --track 0 -p gain_db=6.0 |
| Effect → Normalize | effect add normalize --track 0 -p target_db=-1.0 |
| Effect → Fade In | effect add fade_in --track 0 -p duration=2.0 |
| Edit → Undo / Redo | session undo / session redo |
五、完整实战:一条命令链制作一期 Podcast
综合 README.md 中的示例工作流,演示从零到成品的全过程:
# 1. 创建工程
cli-anything-audacity project new --name "Episode 1" -o project.json
# 2. 建三条轨:主播 / 嘉宾 / 背景音乐
cli-anything-audacity --project project.json track add --name "Host"
cli-anything-audacity --project project.json track add --name "Guest"
cli-anything-audacity --project project.json track add --name "Music"
# 3. 导入片段(带起始时间与音量)
cli-anything-audacity --project project.json clip add 0 host_recording.wav
cli-anything-audacity --project project.json clip add 1 guest_recording.wav --start 0.5
cli-anything-audacity --project project.json clip add 2 music.wav --volume 0.3
# 4. 给 0 号轨叠效果链:先归一化到 -3 dB,再压缩,音乐轨加 2s 淡入
cli-anything-audacity --project project.json effect add normalize --track 0 -p target_db=-3.0
cli-anything-audacity --project project.json effect add compress --track 0 -p threshold=-20 -p ratio=4.0
cli-anything-audacity --project project.json effect add fade_in --track 2 -p duration=2.0
# 5. 打标签做章节标记
cli-anything-audacity --project project.json label add 0.0 --text "Intro"
cli-anything-audacity --project project.json label add 30.0 -e 60.0 --text "Main discussion"
# 6. 渲染导出
cli-anything-audacity --project project.json export render episode1.wav --preset wav
关于参数解析的一点实现提示:在 effect add 中 -p key=value 会被拆成键值对并自动推断数值类型——含小数点解析为 float、否则尝试 int,字符串则原样保留;随后经 effects.py 的 validate_params 按注册表规格做类型转换与范围校验,越界会直接抛出 ValueError(例如 gain_db 只接受 -60 到 60)。
由于每个带 --project 的一次性命令都会改动文件再自动保存(REPL/--dry-run 除外,参见 audacity_cli.py 的结果回调),上述分步执行是幂等且可回滚的——每一步前都会先 snapshot 记录现场。
关于 SKILL.md 中的 export 示例
SKILL.md 给出的导出示例为:
cli-anything-audacity --project myproject.json export render output.pdf --overwrite
根据命令签名,export render <output_path> 仅要求输出路径与 --preset/-p(默认 wav);结合导出预设看,实际导出应使用音频扩展名(如 .wav)。用 .pdf 之类扩展名属于文档示例的笔误,实践时应以音频输出格式为准。渲染完成后,如无 --overwrite 且目标文件已存在,命令会以 FileExistsError 分支报错退出(参见 audacity_cli.py 的错误处理)。
六、工程 JSON 格式:一切状态的载体
工程的底层载体是一个 JSON manifest(AUDACITY.md 中给出其顶层结构):
{
"version": "1.0",
"name": "my_podcast",
"settings": {
"sample_rate": 44100,
"bit_depth": 16,
"channels": 2
},
"tracks": [],
"labels": [],
"selection": { "start": 0.0, "end": 0.0 },
"metadata": { "title": "", "artist": "", "album": "" }
}
project new -o xxx.json会写盘;-p/--project xxx.json则让每条后续命令都在该工程上继续编辑。- 由于渲染管线(见第八节)完全依据 JSON 中的轨道顺序、片段时间轴位置、效果链顺序与音量声像来合成音频,因此这个文件本身就是可复现的"工程源代码",适合版本管理与 Agent 逐步构建。
- 持久化采用原子写入 + 文件锁(
fcntl.flock)避免并发写坏文件,见 session.py。
七、状态管理:50 层快照式撤销/重做
SKILL.md 声明 CLI 会话具备"最多 50 层撤销历史"。实现上,Session 通过变更前对工程 JSON 做深拷贝入栈来实现快照式撤销:
MAX_UNDO = 50,超出上限时从栈底丢弃最老快照(session.py);- 每个 mutation 命令在执行前都会调用
sess.snapshot("<操作描述>"),如Add track: Voice、Remove clip 2 on track 0,快照同时记录 ISO 时间戳; undo把当前状态压入 redo 栈再恢复栈顶快照,redo反向操作;任何一次新 mutation 都会清空 redo 栈;session history会按"最新在前"列出撤销栈中每条操作及时间戳,方便 Agent 确认自己刚做了什么;- 会话还暴露
has_project / is_modified / undo_count / redo_count等状态供上层判断。
因此,即便在长链路自动化中误操作,Agent 也能用一条 session undo 精确回退上一步,而无需重放整个脚本。
八、效果注册表与导出渲染
效果注册表(参数与取值范围)
效果参数规格集中定义在 effects.py 的 EFFECT_REGISTRY 中。下表列出全部 15 种效果及其可校验的关键参数范围(范围由 min/max 字段约束,超界即报错):
| CLI 名称 | 分类 | 关键参数(默认值与取值范围) |
|---|---|---|
amplify |
volume | gain_db 默认 0.0(-60 到 60 dB) |
normalize |
volume | target_db 默认 -1.0(-60 到 0 dB) |
fade_in |
fade | duration 默认 1.0(0.01–300 s) |
fade_out |
fade | duration 默认 1.0(0.01–300 s) |
reverse |
transform | 无参数(倒放) |
silence |
generate | duration 默认 1.0(0.01–3600 s) |
tone |
generate | frequency 默认 440.0(20–20000 Hz)、duration、amplitude 默认 0.5(0.0–1.0) |
change_speed |
transform | factor 默认 1.0(0.1–10.0,变速同时变调) |
change_pitch |
transform | semitones 默认 0.0(-24 到 24) |
change_tempo |
transform | factor 默认 1.0(0.1–10.0,变速不变调) |
echo |
delay | delay_ms 默认 500.0(1–5000 ms)、decay 默认 0.5(0.0–1.0) |
low_pass |
eq | cutoff 默认 1000.0(20–20000 Hz) |
high_pass |
eq | cutoff 默认 100.0(20–20000 Hz) |
compress |
dynamics | threshold 默认 -20(-60 到 0 dB)、ratio 默认 4.0(1.0–20.0)、attack 默认 5.0(0.1–1000 ms)、release 默认 50.0(1–5000 ms) |
limit |
dynamics | threshold_db 默认 -1.0(-60 到 0 dB) |
noise_reduction |
restoration | reduction_db 默认 12.0(0–48 dB) |
注:SKILL.md 未列出效果参数细节,上表按 effects.py 与 AUDACITY.md 的 Effect Registry 归纳,供实际拼参时参照。
导出预设
cli-anything-audacity export presets # 列出全部预设
cli-anything-audacity export preset-info wav
cli-anything-audacity export render out.wav --preset wav --overwrite
预设矩阵如下(WAV 系列走 Python wave 原生支持;MP3/FLAC/OGG/AIFF 需额外工具链):
| 预设 | 格式 | 位深 | 说明 |
|---|---|---|---|
wav |
WAV | 16-bit | 标准、原生支持 |
wav-24 |
WAV | 24-bit | 高质量 |
wav-32 |
WAV | 32-bit | 录音室级 |
wav-8 |
WAV | 8-bit | 低质量 |
mp3 |
MP3 | — | 需 pydub/ffmpeg |
flac |
FLAC | — | 需 pydub/ffmpeg |
ogg |
OGG | — | 需 pydub/ffmpeg |
aiff |
AIFF | — | 需 pydub/ffmpeg |
export render 还支持 --channels/-ch 覆盖工程声道数。
渲染管线
渲染模块位于 core/export.py,其混合流程(据 AUDACITY.md):
- 对每条未静音轨道(尊重 solo 逻辑): a. 逐片段读取源 WAV,应用头尾裁剪后放置到时间轴位置; b. 叠加同轨重叠片段; c. 依序施加该轨效果链; d. 应用轨道音量;
- 将所有轨道按声像与音量混音;
- 钳制到 [-1.0, 1.0] 防止削波;
- 写出为所选格式。
进阶效果(变调、变速)在纯 Python 内使用简化算法实现;WAV 全链路原生可用,而 MP3/FLAC/OGG/AIFF 导出需要外部工具(pydub + ffmpeg),README 亦提示缺少此类工具时相关预设不可用。
九、交互式 REPL
不带子命令直接运行即进入 REPL 会话(audacity_cli.py 的 repl 实现),具备:
- 基于
prompt-toolkit的补全与历史(皮肤逻辑见 utils/repl_skin.py); - 提示符上展示当前工程名与未保存标记;
- 直接键入任意子命令(内部以
standalone_mode=False复用同一 CLI 主入口); help列出全部命令组,undo/redo走会话历史导航,quit/exit/q退出。
cli-anything-audacity
# project new -o demo.json
# track add --name Voice
# session history
# quit
十、输出格式:人类可读与 --json 双模式
所有命令都支持两种输出(全局 --json 标志切换):
- 人类可读(默认):缩进树状文本(
_print_dict/_print_list递归打印字典与列表); - 机器可读(
--json):json.dumps(..., indent=2, default=str)输出结构化数据,供 Agent/脚本解析。
# 人类输出
cli-anything-audacity project info -p project.json
# Agent 友好 JSON
cli-anything-audacity --json project info -p project.json
错误处理同样双模式:FileNotFoundError 在 JSON 模式输出 {"error": ..., "type": "file_not_found"},其他运行时错误输出带类型的 JSON 错误体,人类模式则打印 Error: ... 到 stderr(audacity_cli.py)。
十一、面向 AI Agent 的集成规范
SKILL.md 专门给出了 Agent 调用时的五条纪律,这与仓库"HARNESS 方法论"一致:
- 始终加
--json:输出才是可解析的结构化数据,不要依赖表格文本; - 检查返回码:0 表示成功,非 0 表示出错(
FileNotFoundError、ValueError、IndexError、RuntimeError、FileExistsError等都会使一次性命令以sys.exit(1)退出); - 失败时解析 stderr 获取错误信息(人类模式下错误消息写入 stderr);
- 文件操作一律使用绝对路径,避免工作目录漂移导致引用失效;
- 导出后验证产物存在(
media check可校验工程引用文件完整性,导出后也应确认输出文件已生成)。
此外还有两条高阶建议来自源码结构:
- 需要回退时用
session undo而非重放脚本,因为每步 mutation 前都已有快照; - 分步执行时统一带
-p/--project project.json,CLI 会在每次成功变更后自动保存(除非--dry-run)。
十二、评测与测试覆盖
仓库为该 CLI 提供了自带的评测与回归手段,可作为 Agent 上线前的验收基线。
内置 eval 命令(入口在 audacity_cli.py,运行逻辑在 eval/runner.py):
cli-anything-audacity eval # 默认输出 eval_results/<时间戳>/
cli-anything-audacity eval --out ./eval_out # 指定输出目录
cli-anything-audacity eval --baseline baseline.json --fail-on-regression # 对比基线,回归则退出码 2
cli-anything-audacity eval --baseline baseline.json --update-baseline # 写入/更新基线
产物含 eval_report.json、eval_report.md 与 artifacts/ 任务输出;评测任务覆盖效果注册表、WAV 导出、工程 roundtrip 与轨道-片段流程(见 eval/tasks/)。
测试覆盖(详见 tests/TEST.md,正文记录于 AUDACITY.md):
- test_core.py:60+ 个单元测试,纯合成数据,覆盖工程 CRUD 与设置、轨道增删改、片段增删/分割/移动/裁剪、效果注册表与参数校验、标签、选区、撤销重做、音频工具函数;
- test_full_e2e.py:40+ 个端到端测试,生成真实 WAV,覆盖 16/24 位与立体声往返、效果音频验证(增益/淡入淡出/倒放/回声/滤波)、单轨/多轨/静音/solo 的完整渲染、含效果的工程保存加载、多步 Podcast 工作流、CLI 子进程调用与媒体探测。
十三、结语与延伸阅读
cli-anything-audacity 用"JSON 工程 + stdlib 渲染 + 快照式会话"三件套,把 Audacity 的编辑能力收敛成一套稳定、可脚本化、可回滚的接口,是 CLI-Anything 体系面向"音频编辑"域的标准落点,也是 Agent 在无头环境中自动完成播客剪辑、语音清理与多轨混音的基础设施。
深入阅读:
- 完整 CLI 文档:README.md
- 架构取舍与渲染管线分析:AUDACITY.md
- 测试说明:tests/TEST.md
- 仓库通用的 Agent 驱动方法论:cli-anything-plugin/HARNESS.md
- 打包与发布配置:setup.py
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00