refactor(s2s): 语音助手基础提示词迁移到后端统一管理

- 后端 config.py:新增 S2S_INSTRUCTIONS(.env DPM_S2S_INSTRUCTIONS 可覆盖)
- rag.py:build_instructions() 组装 配置提示词 + 园区知识库摘要
- routers.py:GET /api/s2s/instructions 下发(前端连接时拉取)
- 前端 VoiceAssistant:删除硬编码 DEFAULT_INSTRUCTIONS,改拉取后端指令;
  仅保留后端不可用时的极简兜底

改提示词只需改后端(.env 或代码),前端零硬编码。
This commit is contained in:
Pine
2026-08-18 02:28:55 +08:00
parent e653c4b2f2
commit f4067c1f0e
4 changed files with 39 additions and 9 deletions
+9 -9
View File
@@ -16,7 +16,9 @@ import './voice-original.css';
import './voice-overrides.css';
const VOICE_URL = window.__DPM_VOICE_WS__ || `ws://${window.location.hostname}:8765/v1/realtime`;
const DEFAULT_INSTRUCTIONS = '你是 PineSound 园区智能语音助手。可用工具:get_park_overview(园区实时数据)、query_companies(企业名录)、control_display(大屏控制)、get_time(时间)。涉及园区数据/企业/大屏控制时务必调用工具获取准确信息。请用简洁专业的中文回答,不超过三句话。';
// 基础提示词由后端统一管理(GET /api/s2s/instructions:配置提示词 + 园区知识库),
// 前端不硬编码;此处仅为后端不可用时的兜底
const FALLBACK_INSTRUCTIONS = '你是 PineSound 园区智能语音助手,请用简洁专业的中文回答,不超过三句话。';
const DEFAULT_VOICE = 'Cherry';
const DEFAULT_GATE_DB = -50;
@@ -316,15 +318,13 @@ export default function VoiceAssistant() {
if (!audioCtxRef.current) audioCtxRef.current = new AudioContext();
if (audioCtxRef.current.state === 'suspended') await audioCtxRef.current.resume();
// 知识库:拉取园区知识摘要拼进 instructions(静态知识一次注入;失败不影响对话)
let instructions = DEFAULT_INSTRUCTIONS;
// 基础提示词:从后端拉取(配置 + 园区知识库已由服务端组装);失败用极简兜底
let instructions = FALLBACK_INSTRUCTIONS;
try {
const kbRes = await fetch(`${API_BASE}/api/kb/brief`, { cache: 'no-store' });
const kbData = await kbRes.json();
if (kbData?.ok && kbData.brief) {
instructions = `${DEFAULT_INSTRUCTIONS}\n\n【园区知识库】\n${kbData.brief}`;
}
} catch { /* 知识库不可用不影响对话 */ }
const insRes = await fetch(`${API_BASE}/api/s2s/instructions`, { cache: 'no-store' });
const insData = await insRes.json();
if (insData?.ok && insData.instructions) instructions = insData.instructions;
} catch { /* 后端不可用不影响对话 */ }
const client = new S2sWsRealtimeClient({
directUrl: VOICE_URL,