feat: improve elder companion conversations

This commit is contained in:
Codex Local
2026-08-29 22:06:30 +08:00
parent e652516147
commit f0849119f7
11 changed files with 176 additions and 22 deletions
+24 -2
View File
@@ -23,6 +23,28 @@ const bundleFields: Array<{ field: BundleField; kind: Exclude<Kind, "AGENT_BUNDL
{ field: "routing_version_id", kind: "ROUTING", label: "路由版本" }
];
const elderCompanionSystemPrompt = `你是一位温和、耐心、尊重长者的陪伴型语音助手。
你的目标不是快速获得答案,而是让长者愿意表达,并感到自己被认真倾听。
聊天规则:
1. 使用简单、自然、口语化的中文,每次尽量只说一到两句话。
2. 一次只问一个问题,不连续盘问;每连续提问两次后,加入一次共情、总结或简短回应。
3. 先回应长者的情绪,再继续聊天,优先围绕长者刚刚提到的人、事、物展开。
4. 长者回答很短时,可以给出两个简单选项帮助继续,但不要替长者作决定。
5. 长者沉默时不要催促,可以说“没关系,我们慢慢聊”。
6. 长者重复讲同一件事时,不要指出“已经讲过”,应接住其中的情绪或细节。
7. 不要编造没有提供过的家庭信息、经历、记忆或事实;不确定时明确表示不确定。
8. 不主动提起背景资料中标记为避免的话题;长者主动提及时先共情,再谨慎回应。
9. 涉及疾病、用药和症状时,只做一般性安全提醒,不代替医生诊断或擅自建议停药换药。
10. 长者想结束聊天时自然收尾,不强行挽留,也不为了延长对话制造话题。
11. 不纠正长者的口音、表达方式或生活选择,不使用网络流行语和复杂术语。
12. 没有合适话题时,可从天气、饮食、睡眠、花草、电视节目或家人近况中选择一个开场。
推荐流程:问候近况 -> 找到兴趣或记忆关键词 -> 温和追问一个细节 -> 回应情绪 -> 自然收尾。
表达风格应像熟悉的晚辈或朋友,不像客服、医生或采访者。`;
export function OpsConfigWorkspace({ accessToken, accounts }: { accessToken: string; accounts: CurrentUser["accounts"] }) {
const opsAccounts = accounts.filter((item) => item.platform_role !== "customer");
const [tenantID, setTenantID] = useState(opsAccounts[0]?.tenant_id ?? "");
@@ -250,7 +272,7 @@ export function OpsConfigWorkspace({ accessToken, accounts }: { accessToken: str
{kind === "AGENT_BUNDLE" ? <fieldset className="ops-bundle-composer ops-config-form__wide"><legend>组合组件版本</legend>{bundleFields.map((definition) => {
const candidates = bundleCandidates.get(definition.kind) ?? [];
return <label key={definition.field}><span>{definition.label}</span><select value={bundlePayload[definition.field]} disabled={!candidates.length} required onChange={(event) => selectBundleComponent(definition.field, event.target.value)}><option value="">{candidates.length ? "请选择已发布版本" : "暂无可用版本"}</option>{candidates.map((candidate) => <option key={candidate.id} value={candidate.id}>{candidate.display_name} · {candidate.config_key} v{candidate.version_no}{candidate.status === "RETIRED" ? " · 已退役(可追溯复用)" : " · 已发布"}</option>)}</select></label>;
})}<small className={unavailableBundleKinds.length ? "ops-bundle-composer__warning" : ""}>{unavailableBundleKinds.length ? `缺少可用组件:${unavailableBundleKinds.map((item) => item.label).join("、")}。请先完成对应配置的审批发布。` : "仅列出当前客户组织内已经发布过的不可变版本;提交和发布时服务端仍会复核租户、类型与状态。"}</small></fieldset> : <label className="ops-config-form__wide"><span>配置正文(JSON)</span><textarea rows={8} value={payloadText} onChange={(event) => setPayloadText(event.target.value)} spellCheck={false} /></label>}
})}<small className={unavailableBundleKinds.length ? "ops-bundle-composer__warning" : ""}>{unavailableBundleKinds.length ? `缺少可用组件:${unavailableBundleKinds.map((item) => item.label).join("、")}。请先完成对应配置的审批发布。` : "仅列出当前客户组织内已经发布过的不可变版本;提交和发布时服务端仍会复核租户、类型与状态。"}</small></fieldset> : <label className="ops-config-form__wide"><span>配置正文(JSON)</span><textarea rows={kind === "PERSONA" ? 18 : 8} value={payloadText} onChange={(event) => setPayloadText(event.target.value)} spellCheck={false} />{kind === "PERSONA" ? <small>默认模板包含倾听、单问题追问、沉默处理、事实边界、敏感话题和医疗安全规则;创建后仍需完成评测、审批和灰度发布。</small> : null}</label>}
{kind === "AGENT_BUNDLE" ? <p className="ops-config-form__wide ops-config-form__note">组合不直接保存密钥引用,模型和音色凭据由各自已发布组件管理。</p> : <label className="ops-config-form__wide"><span>受控密钥引用(JSON,不得填写密钥明文)</span><textarea rows={3} value={secretRefsText} onChange={(event) => setSecretRefsText(event.target.value)} spellCheck={false} /></label>}
<label className="ops-config-form__wide"><span>变更说明</span><input value={summary} maxLength={500} onChange={(event) => setSummary(event.target.value)} placeholder="说明变更目的、预期影响和验证依据" required /></label>
<button type="submit" disabled={busy || !summary.trim() || !configKey.trim() || !displayName.trim() || (kind === "AGENT_BUNDLE" && !bundleReady)}>创建草稿</button>
@@ -272,7 +294,7 @@ export function OpsConfigWorkspace({ accessToken, accounts }: { accessToken: str
function defaultPayload(kind: Kind) {
const values: Record<Kind, unknown> = {
PERSONA: { system_prompt: "你是一位耐心、尊重长者的陪伴型语音助手。", tone: "warm" },
PERSONA: { system_prompt: elderCompanionSystemPrompt, tone: "warm" },
VOICE: { provider: "volcengine", voice_resource_ref: "voice://approved/default" }, MODEL: { provider: "volcengine", model_id: "model://approved/default" },
ROUTING: { default_engine_mode: "s2s_hybrid", routes: [{ goal: "open_conversation", engine_mode: "s2s_hybrid" }] },
AGENT_BUNDLE: { persona_version_id: "", voice_version_id: "", model_version_id: "", routing_version_id: "" }