外呼调优
AI通话参数实时调优 · 修改即时生效
场景: --
// ========== 话术配置 v2.0 ==========
let promptData = null;
let currentFaqScene = 'general';
const SOP_PHASES = ['greeting','probing','objection','invite','closing'];
const SOP_LABELS = {greeting:'开场破冰',probing:'探需提问',objection:'异议处理',invite:'邀约转化',closing:'收尾'};
async function loadPrompts() {
try {
const resp = await fetch('/api/prompt');
const result = await resp.json();
if (result.code === 0) {
promptData = result.data;
populatePromptForm(promptData);
}
} catch(e) { console.error('Failed to load prompts:', e); }
}
function populatePromptForm(d) {
// Identity
const id = d.identity || {};
setVal('p_name', id.name || '');
setVal('p_firm', id.firm || '');
setVal('p_role', id.role || '');
setVal('p_style_desc', id.style_desc || '');
// Speaking Style
const ss = d.speaking_style || {};
setVal('p_style_core', ss.core || '');
setVal('p_style_dos', Array.isArray(ss.dos) ? ss.dos.join('\n') : '');
setVal('p_style_donts', Array.isArray(ss.donts) ? ss.donts.join('\n') : '');
setVal('p_max_len', ss.max_reply_length || '');
// Iron rules
setVal('p_iron_rules', Array.isArray(d.iron_rules) ? d.iron_rules.join('\n') : '');
// Hangup rules
const hr = d.hangup_rules || {};
setVal('p_can_hangup', Array.isArray(hr.can_hangup) ? hr.can_hangup.join('\n') : '');
setVal('p_never_hangup', Array.isArray(hr.never_hangup_on) ? hr.never_hangup_on.join('\n') : '');
// Context
setVal('p_context', d.context_info || '');
// SOP phases
renderSopPhases(d.sop_phases || {});
// FAQ
const faq = d.faq || {};
setVal('p_faq', faq[currentFaqScene] || faq['general'] || '');
// Opening & no voice
setVal('p_opening', d.opening_template || '');
const nvt = d.no_voice_tips || [];
setVal('p_no_voice', Array.isArray(nvt) ? nvt.join(',') : '');
// Barge in
setVal('p_barge_in', d.barge_in_strategy || '');
}
function renderSopPhases(sop) {
const container = document.getElementById('sop-phases-container');
let html = '';
for (const phase of SOP_PHASES) {
const data = sop[phase] || {};
const label = SOP_LABELS[phase] || phase;
const inst = data.instruction || '';
const extraKeys = Object.keys(data).filter(k => k !== 'label' && k !== 'instruction');
let extraHtml = '';
for (const k of extraKeys) {
const v = data[k];
const displayV = typeof v === 'object' ? JSON.stringify(v).slice(0,120) : String(v);
extraHtml += '