feat: 完善 N7 智能座舱交互与控制链路

This commit is contained in:
vee
2026-09-07 15:34:59 +08:00
parent 32d179143f
commit c96970f068
100 changed files with 30088 additions and 1174 deletions
+43 -6
View File
@@ -2,7 +2,18 @@
面向车载执行器的认知编排 Agent 单仓工程。系统把自然语言请求转换为可校验的语义配置,再由确定性的领域插件编译为 CAN 命令计划,最后经安全策略和执行器下发。
启动前端:PYTHONPATH=src:domains/seat/src .omx/python311-venv/bin/python -m cognitive_agent.server
Web 控制台与同源 API 由同一个 Python 服务提供。本地启动:
```bash
make dev
```
Windows PowerShell 未安装 `make` 时可直接运行:
```powershell
$env:PYTHONPATH = "src;domains/seat/src"
python -m cognitive_agent.server
```
## 建设阶段
@@ -96,20 +107,46 @@ make dev
浏览器访问 `http://127.0.0.1:8000`。设置 `OPENAI_API_KEY` 后,GPT Structured Outputs 会基于各领域的 `config/capabilities.yaml` 和当前会话状态直接生成通用能力请求;后端只做结构校验、领域路由和确定性执行适配,不用本地语义规则改写 GPT 动作。本地解析器用于未配置 GPT,或 GPT/`auto` 模式因 API Key、模型权限、网络或结构化响应异常而失败时的安全降级;结果会明确标记 `local_rules_fallback`。模型由 `OPENAI_MODEL=gpt-5.6-sol` 指定;兼容 OpenAI Responses API 的服务可通过 `OPENAI_BASE_URL` 指定。无论使用哪种解析器,配置校验、CAN 编译和虚拟执行均为同一确定性路径。
### 一句话、语音听写、快捷模式与手势控制
### Codex AI 助手
首页左侧提供一句话控制,可同时描述座椅、空调、天幕和氛围灯目标;Enter 直接执行,Shift+Enter 换行。观影、午休和零重力是可直接调用的快捷模式,“保存当前”可把当前副驾驶姿态保存为命名模式。复杂跨域自然语言优先使用 GPT 解析,本地规则用于已明确覆盖的离线指令。
首页 AI 助手以长驻 `codex app-server --stdio` 为会话与推理核心。浏览器仍只连接同源 `/api/assistant/stream`,不会接触 Codex 协议或凭据;后端把 App Server 的 thread、turn 和 item 事件转换为 NDJSON 流。普通问题由 Codex 直接回答。涉及本工程能力时,`/api/assistant/capabilities`、回合上下文和只读 MCP 工具 `n7_vehicle.get_n7web_capabilities` 都从同一个运行时能力注册表生成,座舱模式、NFC 绑定红外外设及 CAN0/CAN1 执行绑定会随实际状态更新,不允许模型凭常识猜测。常见能力询问直接由本地权威目录回答,无需等待模型生成。
输入框右侧的麦克风按钮提供本地中文语音听写:优先选择 `TAKSTAR V2` 输入设备,`AudioWorklet` 在音频线程采集(旧浏览器才降级到 `ScriptProcessor`),浏览器端静音检测负责自动停录,16 kHz PCM WAV 发送到同源 `/api/speech/transcribe`。服务端再使用 Silero VAD 做权威分段并保留句首/句尾保护区,SenseVoiceSmall 只负责声学识别;统一 `TranscriptAssembler` 负责 final commit、顺序、重复回调和保守的相邻重叠消除。
显式及复杂车辆需求通过唯一放行的 `n7_vehicle.execute_cockpit_request` MCP 工具进入工程。服务端把一次性工具令牌绑定到本回合原始指令;Codex 可以为原子设备控制提交结构化语义计划,但不能提交新的自然语言指令或原始 CAN。计划必须通过原文证据、能力白名单、目标和参数契约校验,本地确定性解析结果优先,之后仍进入既有 Schema、硬件授权、安全预检、互斥和 CAN 执行链。模型不能扩展用户未请求的控制,也不能覆盖执行模式和硬件授权。
声学 `raw_text` 永远保留。独立的 `UnderstandingTranscriptProcessor` 根据工程能力目录生成 `clean_text`、结构化 `commands`、`cancelled_fragments` 和 `uncertain`,区分“然后”的正常多指令与“不对、改成、算了”等修正/撤销。无关聊天与否定不会激活控制;超出工程参数范围或表达残缺的结果会显示但禁止直接提交,用户修改确认后才能执行。听写本身不自动执行控制命令,也不保存录音。首次部署:
“车上有点热”“车里有点冷”等与受限模式完整匹配、且不包含否定或知识问法的高置信度舒适请求,使用 N7Web 内部快速路由:分别归一化为空调开启、全车 23℃/26℃、2 档风量等确定性指令,绕过模型和 MCP 往返以尽快给出进度与结果。该快速路由只缩短意图理解路径,不绕过能力注册、Schema、执行模式、硬件授权、安全预检、互斥、CAN 编译或反馈确认;其他隐式、复合或含糊请求仍交给 Codex 判断,并受上述 MCP 边界约束。
能力目录中的 `service_surfaces` 仅用于显示语音输入、手势输入、NFC 绑定、座椅自标定和自修复等服务的运行状态,条目固定标记为 `assistant_access=informational`。这里的 `available=true` 只表示对应服务面可用,不表示 AI 助手可以调用它;可执行边界以 `capabilities`、`modes`、`learned_peripherals` 中的 `assistant_callable` 以及服务端再次校验结果为准。
本地运行前需要安装并登录固定兼容版本的 Codex CLI:
```bash
npm install --global @openai/codex@0.150.0-alpha.8
codex login status
make dev
```
也可以让 Codex 使用进程环境中的 `OPENAI_API_KEY`。助手默认选择低推理强度的 `gpt-5.6-luna`,可用 `CODEX_ASSISTANT_MODEL` 覆盖;`CODEX_ASSISTANT_REASONING_EFFORT` 默认为 `low`,`CODEX_ASSISTANT_TURN_TIMEOUT_SECONDS` 默认为 300 秒,`CODEX_ASSISTANT_WORKSPACE` 用来指定隔离的只读工作目录。为避免兼容服务的 WebSocket 断流造成长时间重试,非 `openai`/`chatgpt` 的自定义 provider 默认关闭 WebSocket,并把模型流重试限制为一次;可通过 `CODEX_ASSISTANT_DISABLE_WEBSOCKETS` 和 `CODEX_ASSISTANT_STREAM_MAX_RETRIES` 调整。
启动采用失败关闭语义:CLI 缺失、App Server 握手失败或有效 MCP 配置未能收敛并验证为仅启用 `n7_vehicle` 时,`cognitive_agent.server` 会直接启动失败,不会继续提供一个看似可用的降级网页。进程启动后若 App Server 退出,`/api/health` 返回 `503`,`/api/assistant/status` 显示不可用;模型认证、权限、网络或生成失败则由当前问答流返回 `assistant_model_failed`。这些情况都不会静默回退到旧的正则问答路由;本地能力快答和冷热快速控制仍只按各自严格的确定性条件工作。
App Server 的协议与审批字段以 [Codex App Server 官方文档](https://learn.chatgpt.com/docs/app-server) 和 [Codex 配置参考](https://learn.chatgpt.com/zh-Hans/docs/config-file/config-reference) 为准。线程级 `approvalPolicy=never` 与 MCP 工具级 `default_tools_approval_mode=approve` 作用于不同边界:前者禁止命令/文件修改请求进入交互审批,后者仅避免受限的 N7Web MCP 工具产生前端无法处理的第二次审批;真实执行授权仍完全由 N7Web 的一次性令牌、原文绑定和车辆安全链决定。
### AI 助手语音输入、快捷模式与手势控制
首页左侧的 Codex AI 助手接受普通问题、工程工作和车辆控制需求;Enter 发送,Shift+Enter 换行。观影、午休和零重力是可直接调用的快捷模式,“保存当前”可把当前副驾驶姿态保存为命名模式。能力快答和高置信度舒适请求走确定性快速链,其他请求由 Codex App Server 理解后再通过工程能力与安全边界执行。
语音入口分为两种明确模式:用户点击输入框右侧的麦克风按钮时,以 `manual` 模式立即开始本地中文录音,不要求也不剥离唤醒词;浏览器已获得麦克风权限、AI 助手处于展开状态且页面可见时,则自动进入低干扰的 `wake` 待机,只在识别到“你好,双十一”后展示并继续接收问题。首次使用仍需通过一次手动点击完成浏览器麦克风授权。前端优先选择 `TAKSTAR V2`,使用 `AudioWorklet` 在音频线程采集(旧浏览器才降级到 `ScriptProcessor`),并通过 `X-Speech-Input-Mode: manual|wake` 将两条链路显式隔离。
累积音频按节流窗口发送到同源 `/api/speech/preview`:手动模式直接把未语义清洗的实时转录显示在输入框,唤醒模式在命中前不改动输入框、命中后只显示唤醒词之后的内容,partial 阶段均不会提交或执行。浏览器检测到静音端点后立即停止音轨,再把 16 kHz PCM WAV 发送到 `/api/speech/transcribe` 生成权威 final。服务端使用 Silero VAD 保留句首/句尾保护区,SenseVoiceSmall 负责声学识别,统一 `TranscriptAssembler` 负责 final commit、顺序、重复回调和保守的相邻重叠消除。
最终响应把不同信任层明确拆开:`captured_text` 保留完整声学识别结果;`raw_text` 在 `manual` 模式保留完整原文,在 `wake` 模式仅剥离已确认的唤醒词;`assistant_text` 在保留普通问答的前提下处理重复、结巴、false start、修正、撤销、否定、多设备、多数字和小数,供 AI 助手输入框使用;`clean_text/control_text`、结构化 `commands`、`cancelled_fragments` 和 `execution_eligible` 继续作为严格车控旁路。未知能力或非车控内容不会被清空,也不会绕过 Codex 助手直接执行。听写本身不自动发送消息、不自动执行控制,也不保存录音。首次部署:
```bash
python -m pip install -e ".[speech]"
python tools/install_sensevoice_model.py
```
安装脚本同时校验并部署 `artifacts/models/silero-vad/silero_vad.onnx`。默认使用完整精度 SenseVoice、`language=zh`、ITN 和最多 8 个 CPU 线程;VAD 针对短车控语句使用阈值 `0.45`、最短语音 `0.16s`、结束静音 `0.65s`、最长分段 `12s`、前置 `0.25s`、后置 `0.35s`。可通过 `SPEECH_MODEL_*`、`SPEECH_LANGUAGE`、`SPEECH_USE_ITN`、`SPEECH_NUM_THREADS`、`SPEECH_PROVIDER` 与 `SPEECH_VAD_*` 覆盖。
安装脚本同时校验并部署 `artifacts/models/silero-vad/silero_vad.onnx`。默认使用完整精度 SenseVoice、`language=zh`、ITN 和最多 8 个 CPU 线程;VAD 针对短会话使用阈值 `0.45`、最短语音 `0.16s`、结束静音 `0.65s`、最长分段 `12s`、前置 `0.25s`、后置 `0.35s`。可通过 `SPEECH_MODEL_*`、`SPEECH_LANGUAGE`、`SPEECH_USE_ITN`、`SPEECH_NUM_THREADS`、`SPEECH_PROVIDER` 与 `SPEECH_VAD_*` 覆盖;`SPEECH_WAKE_WORD_ENABLED` 控制唤醒门,`SPEECH_WAKE_WORDS` 使用 `|` 分隔主唤醒词和别名。
当前 sherpa-onnx 版本支持 SenseVoice 的 `hr_lexicon`/`hr_rule_fsts`,只有同时提供经过验证的文件时才会启用:`SPEECH_HR_LEXICON` 和 `SPEECH_HR_RULE_FSTS`。未对非 transducer 的 SenseVoice 使用 hotword decoding。可插拔 `RecoveryRecognizer` 默认关闭,只为将来让 uncertain case 使用二次识别,不会下载大型模型。