Files
zyt/docs/plans/followup-audio-deployment.md
T

9.8 KiB
Raw Blame History

回访录音提炼:实现与发布门禁

当前交付边界

源码在隔离工作副本 /Users/long/.codex/worktrees/followup-audio/zyt。原目录 /Users/long/Work/zyt 的已有源码保持不变;未提交、未推送、未迁移生产、未部署。入口默认关闭。

已完成网页患者编辑入口、诊单绑定私有分片上传、独立持久异步任务、Dify原始音频传递、可编辑审阅草稿、显式人工确认、多表原子写入、同日真实记录明细、历史跟踪备注、来源审核轨迹及90天清理。

真实模型门禁仍未通过:本地 qwen/openai 探针都真实执行并返回 CONFIG_MISSING,没有上传录音、没有产生已知模型调用。只能说明隔离环境未配置,不能推断生产Dify是否支持。媒体测试中的完整一小时WAV→MP3、HTTP回环模型和浏览器合成数据不是实际Dify识别验收;混合口音需代表性脱敏样例。

使用与数据规则

  • 入口:网页问诊列表→编辑患者→回访录音。PC/H5共用现有编辑组件;桌面客户端不增加入口。
  • 每次一个文件,MP3/M4A/WAV/AMR,最多500MiB/3600秒,按服务端实际元数据检查,2MiB分片。
  • 原件只在 server/runtime/private/followup_audio/;播放需登录令牌请求头及患者权限。没有公开录音URL,没有伪造医生通话记录。
  • AMR或超出上游预算的录音生成私有临时32kbps/16kHz单声道MP3,校验完整时长,不截断、不自动分段改语义;默认上游预算20MiB。原件保留不改,处理副本在成功或失败后清理。
  • 通话时间采用北京时间,模型解释今天/昨天等;模糊范围需客服确认,不能自动随便取一天。时段缺钟点时早上08:00、中午12:00、下午15:00、晚上20:00、睡前22:00,明确标记估算并要求审阅。
  • 同值不同测量保留不同记录;重复提及同一事件才合并。默认钟点相同不自动去重。相同诊单+音频SHA256+模型复用原任务,换文件名、上传ID或通话时间不绕过未知请求防重发;日期错误在审阅中修正,已采纳任务不重新写入。
  • 字段、字典、身份锁、phonePlain和dailyRecord权限均在服务端校验。未提及不等于正常/无,不自动生成诊断或处方。病历当前值与历史记录分开选择。
  • 草稿有版本和不可变来源证据。冲突刷新最新快照并取消选择,保留用户编辑供重新确认;不静默覆盖。原病历表单有未保存修改时不允许被录音结果覆盖。
  • 确认写入使用一个事务(单次READ COMMITTED,不更改连接默认),锁定任务与真实记录,审计同事务,重复确认幂等。存在不明确的值可不采纳,不要求全部接受。

配置与运行前检查

  1. 核对实际数据库字段/表前缀,先在线备份;经发布授权后应用 server/sql/2026_09_29_followup_audio.sql。SQL使用现有 zyt_ 前缀,可重复执行;新增四表及血糖时间来源字段,不改旧数据。不得把测试库模拟schema当作生产已核验。
  2. 使用 server/.env.followup-audio.example,继续复用现有 [prescription_ai] base URL/profile凭据。不要把生产数据库凭据复制到本地测试环境,不要把API密钥放前端或提交Git。
  3. PHP8.2已做本地验证;需要curl/fileinfo/openssl、可执行FFmpeg/FFprobe。Web/worker用户都必须可读写同一个私有录音目录,目录不能放在public或公开存储域名下。部署多节点需共享私有存储和稳定加密密钥(至少32字符,离线备份),不要依赖各节点自动生成不同runtime key。
  4. 反向代理/PHP单请求上限至少容纳2MiB分片及表单开销;不要将500MiB整个请求交给PHP上传。短期处理副本也要计入磁盘容量。
  5. Dify存储副本/缓存的保留与删除策略另行核验;本系统90天删除不代表Dify侧已删除。现实现没有通用Dify远端删除凭证或删除API,不能作此承诺。

合成音频能力门禁

本地生成器仅接收输出目录,不接受患者录音;使用macOS say(默认Tingting)和FFmpeg/FFprobe。Linux消费者不需要say;可安全转移已生成合成夹具及清单。不要重新生成已有manifest或重发状态未确认的探针。

现成合成夹具:/private/tmp/zyt-followup-audio-synthetic-gate/manifest.json(60/900/3598秒,独立首尾口令和事实;预期答案只在本地manifest,不能放进提示词)。需要重建时使用新的输出目录:

cd /Users/long/.codex/worktrees/followup-audio/zyt
python3 scripts/generate_followup_audio_fixtures.py --output /private/tmp/followup-audio-new-synthetic-gate
cd server
php think followup-audio:probe --synthetic --manifest /private/tmp/zyt-followup-audio-synthetic-gate/manifest.json --profile qwen --case all
# 仅当另一个profile也准备供客服使用时,再单独验证openai。

必须核实真实音频被读取、首尾事实和数值/否定/时间关系、未截断长录音,再用获准的代表性脱敏口音样例人工回听评估。上传成功、HTTP200或纯文本回复都不是通过。探针有状态文件:已通过的case复用;结果未知先核对原Dify任务/账单,禁止自动重发。不要删除未知状态来强制重试。

只有验证通过的profile可加入 VERIFIED_PROFILES;人工核验通过后才设置 AUDIO_VERIFIED=true,经授权发布后再设 ENABLED=true。默认 timestamp_verified=false,不把LLM编出的毫秒位置当成ASR对齐。

独立消费者、清理与故障处理

# cwd为部署目录的server;用Supervisor/systemd管理,不在网页请求内跑模型。
php think followup-audio:work
php think followup-audio:work --once
php think followup-audio:cleanup
  • 初始全局并发1,可通过CONCURRENCY配置1–8;独立数据库租约/互斥,不占用原处方队列。
  • 600秒租约高于240秒请求预算,处理过程中续租。权限撤销、患者重绑、旧worker令牌均不得继续上传/回写。
  • needs_reconciliation 表示请求可能已经被接收,不能自动/手动再次调用;请核对已保存上游IDs、任务和账单。现版本不提供绕过此状态的“强制重试”按钮。
  • 经确认且允许重试的本地失败保留已有成果。模型不支持音频、结构校验失败或能力未验证,不得成功落诊单。
  • 将cleanup纳入目标环境已批准的定时任务(本轮未安装定时任务)。90天起点为上传创建时间;清除原件、完整转写及可还原全文的分析副本,保留正式记录和必要采纳审计;活动租约不被清理,清理部分失败退出非零,便于监控。
  • 关注队列等待时间、needs_reconciliation、失败码、租约恢复、磁盘和清理errors;日志不得包含录音内容、完整病历或凭据。

本地检查与回退

已有验证:真正隔离MySQL并发claim/create/apply、权限撤回/转派、单事务故障回滚;真实HTTP multipart和媒体处理;实际Vue组件测试;浏览器合成数据完成任务详情→草稿→确认采纳→刷新。完整网页构建通过,未执行发布脚本。全量vue-tsc在同一生成声明环境下基线和修改后均60条诊断,本功能文件0条,新诊断签名0。

cd /Users/long/.codex/worktrees/followup-audio/zyt
FOLLOWUP_AUDIO_TEST_ALLOW_DISPOSABLE=1 FOLLOWUP_AUDIO_TEST_MYSQL_PORT=23316 FOLLOWUP_AUDIO_TEST_MYSQL_PASSWORD=followup_audio_isolated_test php server/tests/FollowupAudioCoreTest.php
node --test admin/tests/followup-audio.test.cjs
node admin/scripts/verify-daily-records.cjs

数据库命令只允许一次性本地测试容器,禁止换为线上端口。测试容器连接信息是固定合成测试凭据,不是业务凭据。

发布回退先关闭入口并停止本功能消费者,保留旧静态资源和数据库备份。新增表/列应保留以保护审计;源码回退脚本只恢复源码,不撤销已写入病历。正式记录若需恢复,必须按审核轨迹和当前版本另做受控补偿,不能整库回滚覆盖其他人的新数据。

主交付四角色及源码回退验证位于 /Users/long/Work/zyt/artifacts/followup-audio-20260929/;补充研究、局部检查与未通过的真实模型门禁保留在工作副本 artifacts/followup-audio-implementation/。

2026-09-29 页面重整与提炼补测

  • 页面改为“紧凑录音列表 → 摘要和分类结果表 → 单项核对弹窗”。上传和原文默认收起,已写入记录用只读文本;窄屏固定核对操作列,日期/估算标记仍可见。
  • 在真实诊单抽屉组件、1440×1000视口、相同4项合成数据下,常驻输入控件从25个减至4个复选框,内容滚动高度从2802px减至852px;上传、取消单项编辑、分类不丢选择、草稿与确认写入均做了浏览器合成接口验证。它不是生产/真实模型识别证据。
  • 独立补测发现并修复:临床语义候选不再因空字段而默认采纳;对家属/提问/否定/纠正等上下文强制人工复核。该规则是保守防守,不证明语言语义识别准确。
  • 饮食早餐/午餐/晚餐提炼别名映射到实际*_foods字段,审阅读回、审计、现有日常表单编辑和提交保持一致,未选餐食及图片不清空;CSV合法值0不再被empty()抹去;医院诊断选项使用现有页面的三个静态枚举。
  • 补测通过30条规则、16条防守和5条跨层检查,以及真实隔离MySQL113项检查。9个模型语义案例仍标注NOT_VERIFIED;真实Dify最新探针仍CONFIG_MISSING。不得把这些本地测试描述为真实ASR、方言或一小时录音识别已通过。
  • 本次完整补测账本见工作副本artifacts/followup-audio-implementation/extraction-acceptance-20260929.md和.json,保留修复前结果、修复后结果及独立回滚证据。主四角色路径保持不变,本次记录追加到原验证记录。