[U-thread] P5.U-autotune-batch-pipeline
[部门] 后端 .NET · ADR-AIOS-11 §4.1 fork 5 自动调音编排端点(I/O 编排 + P7 桥接 + 不做数学) · skill: dotnet-realtime-communication
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/
[Occupies] P5.K-api-routes(write · 新增 /api/auto_tune/iterate + /api/auto_tune/analyze)+ P5.K-services(write · 新增 AutoTunePipelineService + 复用 PysidecarMeterBridge)+ P5.K-controllers(write · 新增 AutoTuneController)
[优先级] P1 · 1.5d · 跨栈独立 · 与 P7.U-autotune-multi-target 同 ClaudeB 串行(建议先做 P7 fork 6 · 后做本任务)
[ADR] d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-11-xitune-autotune.md (§1.3.1 + §1.3.2 + §2.1.1 + §2.2 边界铁律 + §4.1 fork 5)
[参考文档]
- 上述 ADR 主文(accepted v1.1)· 重点读 §1.3.1 Harman 4-Phase 流程 + §1.3.2 GEQ-LSQ 锁定 + §2.2 边界铁律 + §4.1 fork 5 实施清单 + §5.2 验收标准
- 上游 ADR:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-07-p3-p4-overlap.md(§1.3.4 三层分工铁律 · 必读)
- 同部门标本(强制 read · 4 维度对齐):d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/done/P5.U-meter-source-tap--4adda88.md(同部门 ClaudeB · 同 P5 · 同三层分工 · PysidecarMeterBridge HTTP 桥接 + dev-api WS 模式参考)
- backend_csharp/Services/Meter/PysidecarMeterBridge.cs(已实装 · 4adda88 落 · HttpClient BaseAddress=http://localhost:8001 · 你的 PysidecarAutotuneBridge 直接仿写)
- backend_csharp/Services/PysidecarProcessManager.cs(已实装 · pysidecar 子进程拉起 + 健康检查 · 你的 HttpClient 复用其注入实例)
- backend_csharp/Routes/MeterDevApiRoutes.cs(参考路由风格 · /dev-api/meter/{nodes,stream})
- backend_csharp/Controllers/(REST 风格 · 复用 PresetProfileController.cs / AudioEngineController.cs 模式)
- pysidecar/main.py(P7 已暴露 19 端点 · 你直接复用)· 本任务关键端点:
· POST /auto_tune/realtime_frame(已实装 · 你 /api/auto_tune/analyze 调它)
· POST /auto_tune/geq_optimize(已实装 · 你 /api/auto_tune/iterate 调它)
· POST /auto_tune/calculate(已实装 · 备用)
- 同期派 P7 fork(读以同步 schema):d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/active/P7.U-autotune-multi-target.md(P7 新增 multi-target + smoothing · 你的 /iterate target_curve 字段必须能映射)
- 前端待派 fork 1-4(读以同步契约):ADR-AIOS-11 §1.3.1 Phase 2/3 描述定义了前端调用 /api/auto_tune/analyze + /api/auto_tune/iterate 的 schema 期望
- contract-v1.0(已 frozen · 不修改):d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/contracts/protocol-v1.md(本任务走 dev-api 桥接 · 待 K2-protocol-v2 fork ADR 时正式入)
【背景】
ADR-AIOS-11 已 accepted(2026-05-29 13:46 用户原话 "accept ADR-AIOS-11 · 顺便 start fork 5+6") · P3 自动调音 MVP 走 Harman 4-Phase 流程(Measure/Analyze/Optimize/Apply)· 本任务实装后端编排层。
**架构契约 ADR-07 §1.3.4 三层分工铁律(本任务核心红线)**:
- **P5(本任务)= I/O 编排 + 转发** · 调 P7 + 组合多次 P7 调用 + 错误重试 + WS 推送 · ❌ **不做任何数学计算**(不许做 FFT / RMS / 相位 / 偏差曲线计算 / GEQ 求解 / 共振峰识别 / 1/3 oct 平滑 / 多点平均)
- **P7-pysidecar(同期派 fork 6 · ClaudeB 先做)= 数学分析** · numpy/scipy 全栈 · 端口 8001
- **前端(待派 fork 1-4)= UI + 状态机** · 订阅 P5 端点 · 不做数学
**业务流程**:
- Phase 1 测量(P3 前端做 · 通过 ADR-07 §4.3 已落的 /dev-api/meter/stream 拿 raw FFT 帧)
- **Phase 2 分析(本任务 /api/auto_tune/analyze)**:接收前端送来的"已平均的 FFT 帧" + 目标曲线 ID → 调 P7 /auto_tune/realtime_frame 拿 freq/magnitude/phase → 调 P7(本期 fork 6 新增端点)做"偏差曲线 + 共振峰识别"→ 包装返回前端
- **Phase 3 优化迭代(本任务 /api/auto_tune/iterate)**:接收前端 "当前响应 + 目标曲线 + 约束条件" → 调 P7 /auto_tune/geq_optimize 拿优化结果 → 调用 mock 链路应用 → 调 P7 拿"模拟应用后的预测响应"→ 多次迭代(默认 3 轮上限) → 收敛或不收敛都返回前端
- Phase 4 应用(P3 前端做 · 走 set_params 协议 · 不在本任务范围)
**契约策略**:不修改 contract-v1.0(已 frozen) · 走 /api/auto_tune/* dev-api 桥接(类比已落的 /dev-api/meter/* · 待 K2-protocol-v2 时正式入)
【执行步骤】
1. 自查 + 同步前端类型(若已 push):
git status # 工作区干净
git branch --show-current # = xistudio
git pull origin xistudio --no-rebase # 拿同期派 P7 fork 6 已落代码 + 前端 fork 1 已落 types(若已 push)
ls frontend_vue3/src/stages/xitune/modes/auto/ # 看前端 useAutoTuningState.ts 当前 schema(c039075)
2. 新增 backend_csharp/Models/AutoTune/(目录新建 · 编排层 record):
- AnalyzeRequest.cs(record · fields: averagedFrame {freq[], mag[], phase[]}, targetCurveId, sampleRate)
- AnalyzeResponse.cs(record · fields: deviationCurveDb[], resonancePeaks[{freq, q, gainDb}], suggestions[])
- IterateRequest.cs(record · fields: currentResponse, targetCurveId, constraints {phaseContinuity?, groupDelayMin?, gainBoundsDb?}, maxIterations=3)
- IterateResponse.cs(record · fields: optimizedFilters[{type, freq, q, gainDb}], predictedResponse, iterationsUsed, converged, rmsErrorDb)
- 与 P7 fork 6 端点 schema 对齐(看 P7 prompt §schema 段 + git pull 后看 pysidecar/models.py)
3. 新增 backend_csharp/Services/AutoTune/PysidecarAutotuneBridge.cs(P7 桥接层 · 仿 PysidecarMeterBridge):
- public interface IPysidecarAutotuneBridge {
Task<DeviationResult> ComputeDeviationAsync(AveragedFrame frame, string targetId, CancellationToken ct);
Task<GeqOptimizeResult> OptimizeGeqAsync(CurrentResponse resp, string targetId, OptimizerConstraints constraints, CancellationToken ct);
Task<PredictedResponse> SimulateApplyAsync(GeqFilters filters, CurrentResponse currentResp, CancellationToken ct);
}
- 内部用 HttpClient(BaseAddress=http://localhost:8001 · 复用 PysidecarProcessManager 注入)
- POST /auto_tune/realtime_frame(已实装) · POST /auto_tune/geq_optimize(已实装 · target_curve 参数 P7 fork 6 扩展) · POST /auto_tune/deviation(P7 fork 6 新增) · POST /auto_tune/simulate_apply(P7 fork 6 新增)
- ❌ **此 Bridge 不做任何数学** · 仅 HTTP 转发 + JSON 反序列化 + 错误重试(3 次 + 指数退避 100/200/400ms · 复用 Polly 若现有依赖)
4. 新增 backend_csharp/Services/AutoTune/AutoTunePipelineService.cs(编排层 · 核心):
- public interface IAutoTunePipelineService {
Task<AnalyzeResponse> AnalyzeAsync(AnalyzeRequest req, CancellationToken ct);
Task<IterateResponse> IterateAsync(IterateRequest req, CancellationToken ct);
}
- AnalyzeAsync 实施:
· ① 调 PysidecarAutotuneBridge.ComputeDeviationAsync(frame, targetId)
· ② 拿到 P7 返回的 deviation_curve + resonance_peaks
· ③ 包装成 AnalyzeResponse 返回(❌ 不做任何曲线计算 · 仅字段映射)
- IterateAsync 实施:
· ① 初始化 currentResp = req.currentResponse
· ② loop maxIterations(默认 3 轮):
a) 调 OptimizeGeqAsync(currentResp, targetId, constraints) 拿 filters
b) 调 SimulateApplyAsync(filters, currentResp) 拿 predictedResponse
c) 计算 RMS 偏差 = ❌ **不在 .NET 算 · 调 P7 ComputeDeviationAsync(predictedResponse, targetId) 拿 rmsErrorDb**
d) if rmsErrorDb <= 3.0 → converged = true · break
e) else currentResp = predictedResponse · continue
· ③ 返回 IterateResponse{optimizedFilters, predictedResponse, iterationsUsed, converged, rmsErrorDb}
- ⚠️ 关键:RMS 偏差判定也调 P7 · 不在 .NET 自算 · 严守 §禁止 #1
5. DI 注册(Program.cs):
- AddSingleton<IPysidecarAutotuneBridge, PysidecarAutotuneBridge>()
- AddSingleton<IAutoTunePipelineService, AutoTunePipelineService>()
- 验证已注册 PysidecarProcessManager(应已 4adda88 落)
6. 新增 backend_csharp/Controllers/Dev/AutoTuneController.cs:
- [Route("api/auto_tune")](注:走 /api/auto_tune/* 而非 /dev-api/auto_tune/* · 因为前端已存量 /api/auto_tune/calculate 既有调用 · 保持命名空间一致)
- POST /api/auto_tune/analyze:接受 AnalyzeRequest body · 调 IAutoTunePipelineService.AnalyzeAsync · 返回 AnalyzeResponse
- POST /api/auto_tune/iterate:接受 IterateRequest body · 调 IAutoTunePipelineService.IterateAsync · 返回 IterateResponse
- 错误处理:P7 不可用返回 503 · 超时返回 504(Iterate 默认 30s) · 参数无效返回 400 · 内部错误 500 + 详细 message(开发期)
- **不修改既有** /api/auto_tune/calculate 端点(已 c039075 实装)
7. 单测 + 验收:
cd backend_csharp
# 新增 Tests/Services/AutoTune/AutoTunePipelineServiceTests.cs(>= 4 case:Analyze 正常路径 + Iterate 收敛分支 + Iterate 不收敛分支 + Iterate 中断分支)
# 新增 Tests/Services/AutoTune/PysidecarAutotuneBridgeTests.cs(>= 3 case:HttpClient mock 成功 + 重试 + 超时)
# 至少 6 个新 case 总计
dotnet build # 零错误零警告
dotnet test # 通过 + 新增 >= 6 用例(基线 111/0 → >= 117/0)
# 手动 e2e(可选 · 若 P7 fork 6 已 push 联调):
curl -X POST http://localhost:5000/api/auto_tune/analyze -H "Content-Type: application/json" -d '{...mock frame...}'
8. Commit + push:
git add backend_csharp/Models/AutoTune/ \
backend_csharp/Services/AutoTune/ \
backend_csharp/Controllers/Dev/AutoTuneController.cs \
backend_csharp/Tests/Services/AutoTune/ \
backend_csharp/Program.cs
git commit -m "..."(见下)
git push origin xistudio
【验收】
- 9-10 文件落地(Models/AutoTune ×4 + Services/AutoTune ×2 + Controllers/Dev ×1 + Tests ×2 + Program.cs DI)
- dotnet build 零错误零警告 · dotnet test 全绿(基线 111/0 → >= 117/0 · +6 用例)
- /api/auto_tune/analyze + /api/auto_tune/iterate 端点可达 · Swagger UI 可见 · 错误码语义正确
- ❌ **PR 自查**:确认 .NET 代码零 FFT/RMS/相位/GEQ/平滑/聚类计算(grep MathNet|System.Math.Sqrt|FFT|fft 应在 .Tests 之外零命中)· 全部数学走 PysidecarAutotuneBridge HTTP 转发
- 三元组完整 · commit hash 7 位
- 端到端验证(若 P7 fork 6 已 push):/api/auto_tune/iterate 跑 3 轮迭代 · iterationsUsed/converged/rmsErrorDb 字段返回正确
【commit】
commit subject:`feat(P5): add /api/auto_tune/{analyze,iterate} pipeline (P7 bridge · pure I/O orchestration) [ADR-AIOS-11 §4.1 fork 5]`
trailer(必须精确):
[step=1/1] [pid=P5] [uid=U-autotune-batch-pipeline] [occupies=P5.K-api-routes+P5.K-services+P5.K-controllers]
[files=backend_csharp/Models/AutoTune/**, backend_csharp/Services/AutoTune/**, backend_csharp/Controllers/Dev/AutoTuneController.cs, backend_csharp/Tests/Services/AutoTune/**, backend_csharp/Program.cs]
[ipc=api/auto_tune/analyze, api/auto_tune/iterate, pysidecar/auto_tune/realtime_frame, pysidecar/auto_tune/geq_optimize, pysidecar/auto_tune/deviation(p7-new), pysidecar/auto_tune/simulate_apply(p7-new)]
回告格式参考 done/P5.U-meter-source-tap--4adda88.md 末尾(同部门 · 同三层分工 · 同模式)。
【禁止】
- ❌ **不许在 .NET 里实装任何数学计算**(FFT / RMS / 相位 / 群延迟 / 偏差曲线 / GEQ 求解 / 共振峰识别 / 1/3 oct 平滑 / 多点平均 / 拓扑识别 / 聚类 全部禁止)· 数学全归 P7 · 见 ADR-07 §1.3.4 + ADR-11 §2.2 边界铁律 #1
- ❌ **不许引入 MathNet.Numerics / System.Numerics.Vector(数学用途) / Accord.NET / 任何 .NET 数学库**
- ❌ 不许修改 contracts/protocol-v1.md(已 frozen 永久 sleeping · auto_tune-api 留 v2)
- ❌ 不许修改既有 /api/auto_tune/calculate 端点(c039075 已实装 · 前端 useAutoTuningState 在用)
- ❌ 不许改 P5 现有业务服务(SourceListService / RefreshLinkService / WorkspaceFileHelper / PysidecarProcessManager / PresetProfileService / MeterTapService / AudioDeviceService / PysidecarMeterBridge)· 严格新增范围(可调用不可改)
- ❌ 不许改前端代码(P3 fork 1-4 由 ClaudeC 跑)
- ❌ 不许改 pysidecar/* 代码(P7 fork 6 由 ClaudeB 自己另一线跑 · 通过 P7 端点扩展协调)
- ❌ 不许改 P6-dsp-algo 代码
- ❌ 不许跳验收 · dotnet build/test 任一红必须修到全绿
- ❌ 不许省略三元组 trailer
- ❌ 不许自改本 prompt 文件