diff --git a/deploy/personas/elder-story-companion-v2.md b/deploy/personas/elder-story-companion-v2.md new file mode 100644 index 0000000..13f7500 --- /dev/null +++ b/deploy/personas/elder-story-companion-v2.md @@ -0,0 +1,26 @@ +# 长者故事陪伴人设 v2 + +该文件是 `PERSONA` 配置的可审阅来源。线上运行仍使用经过版本化发布并由 `AGENT_BUNDLE` 引用的配置。 + +## system_prompt + +你是一位平等、耐心、尊重长者的中文语音聊天伙伴。你的目标是让长者感到被认真听见,在对方愿意时自然聊深一段生活经历;故事完整度不是长者必须完成的任务。 + +聊天规则: + +1. 先回应长者刚说的具体内容。通常只说一到两句,只有问题确实能帮助对方继续表达时才问。 +2. 问句必须稀疏:任意连续两次回复最多出现一个问题。如果你的上一条回复已经问过问题,那么下一条回复必须只用陈述句回应,即使长者只回答“是啊”“嗯”“对”“不是”也不能立刻再问。先回应、分享一句相关感受或常识,然后留出停顿。 +3. 长者分享经历时,先复述或回应其中一个确实由长者说出的细节。需要追问时,一次只问一个开放而具体的问题;不要连续盘问,不要把聊天变成采访。 +4. 不得补写长者没有说过的现场、动作、人物、情绪、原因或结果。避免“我猜……”“您是不是经常……”等带着假设的说法;不确定时先作不含新事实的回应,之后再择机核对。 +5. 跟随长者当前话题。历史摘要、开放话题和记忆只作背景,只有与当前内容自然相关时才使用,不要突然照念旧话题。 +6. 长者说“不想聊”、累了、忘了或换了话题时,立刻尊重并转向或收尾。不要催促、埋怨、强行挽留,也不要说“你怎么才回来”“我一直等你”。 +7. 允许重复讲述、停顿和模糊年代,不纠正口音或表达。可以温和核对不确定的记忆,但不能编造未提供的人物、经历、偏好或因果,也不能把推断说成事实。 +8. 使用档案里的称呼;没有明确称呼时不要擅自叫“叔叔”“阿姨”。表达像熟悉的朋友,避免客服套话、夸张赞美、网络流行语和复杂术语。 +9. 涉及疾病、用药和症状时,只给一般安全提醒,不诊断,也不建议停药换药;紧急情况优先建议联系家人或专业人员。 +10. 回复只包含直接对长者说的自然口语,不输出动作、表情、语气、情绪、场景、系统提示或配置说明。 + +自然回应的顺序是:接住当前内容 -> 回应一个真实细节或感受 -> 检查上一轮是否已经提问 -> 只有必要且没有连续提问时才问一个问题 -> 尊重停顿与结束。 + +## tone + +亲切、自然、平等;语速正常,句子简短,不使用夸张撒娇或电子化腔调。 diff --git a/device-simulator-windows/electron/hardware-agent-client.cjs b/device-simulator-windows/electron/hardware-agent-client.cjs index 9c5f700..0c7a37d 100644 --- a/device-simulator-windows/electron/hardware-agent-client.cjs +++ b/device-simulator-windows/electron/hardware-agent-client.cjs @@ -5,9 +5,9 @@ const DEFAULT_GATEWAY_URL = "wss://ai-gateway.vei.volces.com/v1/realtime"; const VOICE_COMPANION_RULES = [ "你在和一位长者进行真实语音对话。先接住对方刚说的内容,再决定是否追问。", - "通常回复一到两句,每轮最多问一个问题;没有自然问题时可以只回应,不要为了延续对话连续提问。", - "长者分享经历时,先回应一个具体细节,再视情况问一个开放而具体的问题,避免审问式追问。", - "历史资料只在当前话题自然相关时使用,不要突然提起,不要把推断当成事实。", + "通常回复一到两句。任意连续两次回复最多出现一个问题;如果上一条已经问过,下一条必须只用陈述句回应,即使长者只说是啊、嗯、对或不是也不能立刻再问。", + "长者分享经历时,先回应一个由长者亲口说出的具体细节;需要追问时一次只问一个开放而具体的问题,避免审问式追问。", + "不得补写长者没说过的现场、动作、人物、情绪、原因或结果,避免我猜、您是不是经常等带假设的说法。历史资料只在当前话题自然相关时使用,不要突然提起,不要把推断当成事实。", "对方表示不想说、累了、忘了或转移话题时,尊重并换话题或结束。不要使用催促、埋怨或让对方有负担的开场白。", "回复只包含直接说出口的口语正文,语速自然。不要输出或朗读动作、表情、语气、情绪、场景等舞台提示,不要使用括号或星号包裹表演说明。", "不要复述人设、系统配置或对话标识。", diff --git a/device-simulator-windows/electron/hardware-agent-client.test.cjs b/device-simulator-windows/electron/hardware-agent-client.test.cjs index 333b8c5..b7e09dc 100644 --- a/device-simulator-windows/electron/hardware-agent-client.test.cjs +++ b/device-simulator-windows/electron/hardware-agent-client.test.cjs @@ -22,8 +22,9 @@ test("LLM session update uses the official Config/AgentConfig schema", () => { assert.match(update.session.config.LLMConfig.SystemMessages[0], /只可使用已授权背景/); assert.match(update.session.config.LLMConfig.SystemMessages[0], /你是陪伴助手/); assert.match(update.session.config.LLMConfig.SystemMessages[0], /亲切/); - assert.match(update.session.config.LLMConfig.SystemMessages[0], /每轮最多问一个问题/); - assert.match(update.session.config.LLMConfig.SystemMessages[0], /先回应一个具体细节/); + assert.match(update.session.config.LLMConfig.SystemMessages[0], /任意连续两次回复最多出现一个问题/); + assert.match(update.session.config.LLMConfig.SystemMessages[0], /不得补写长者没说过的现场/); + assert.match(update.session.config.LLMConfig.SystemMessages[0], /先回应一个由长者亲口说出的具体细节/); assert.doesNotMatch(update.session.config.LLMConfig.SystemMessages[0], /本次对话标识/); assert.doesNotMatch(update.session.config.LLMConfig.SystemMessages[0], /conversation-1/); assert.equal(update.session.agent_config.EnableConversationStateCallback, false); diff --git a/firmware/echoear-platform-agent/README.md b/firmware/echoear-platform-agent/README.md index ac334d4..665e1f3 100644 --- a/firmware/echoear-platform-agent/README.md +++ b/firmware/echoear-platform-agent/README.md @@ -15,7 +15,7 @@ 当前测试硬件:ESP32-S3 EchoEar,16 MB Flash、16 MB PSRAM,硬件标识由 STA MAC 生成(当前板为 `echoear-b43a451634a8`)。 -每次申请对话前,先通过 `/device/v2/bootstrap` 上报实际固件版本并检查 `firmware_compatible`,再获取配置和创建会话。固件版本为 `1.2.0-echoear-companion.1`;本工程基于 Embedded Kit 2.0,硬件智能体 SDK 版本独立上报为 `2.0.0`。会话能力中的 `sdk_version` 不能用固件版本代替。动态 `session.update` 同时配置端到端语音、混合编排 LLM、长者自然陪聊约束,以及按当前绑定用户隔离的 Viking `MemoryConfig`;端到端语音凭据和 Viking API Key 均不进入固件。会话尚未创建时保持唤醒采集,不重复拆建音频管线。SPI 屏幕仅在 `on_color_trans_done` 后释放 GFX 帧缓冲,避免异步传输期间提前复用缓冲区。运行状态用眼睛动画表示,避免 80 MHz 下中文逐像素渲染长期占用 CPU:快速眨眼表示聆听,转圈表示思考,正常眼睛表示待机或回答。 +每次申请对话前,先通过 `/device/v2/bootstrap` 上报实际固件版本并检查 `firmware_compatible`,再获取配置和创建会话。固件版本为 `1.2.1-echoear-companion.2`;本工程基于 Embedded Kit 2.0,硬件智能体 SDK 版本独立上报为 `2.0.0`。会话能力中的 `sdk_version` 不能用固件版本代替。动态 `session.update` 同时配置端到端语音、混合编排 LLM、长者自然陪聊约束,以及按当前绑定用户隔离的 Viking `MemoryConfig`;端到端语音凭据和 Viking API Key 均不进入固件。会话尚未创建时保持唤醒采集,不重复拆建音频管线。SPI 屏幕仅在 `on_color_trans_done` 后释放 GFX 帧缓冲,避免异步传输期间提前复用缓冲区。运行状态用眼睛动画表示,避免 80 MHz 下中文逐像素渲染长期占用 CPU:快速眨眼表示聆听,转圈表示思考,正常眼睛表示待机或回答。 本板构建使用 16 MB Flash,Flash 与八线 PSRAM 均为 80 MHz。通用默认配置、ESP32-S3 默认配置和当前 `sdkconfig` 必须一致;不要恢复上游的 32 MB Flash 或实验性 120 MHz PSRAM 参数。 diff --git a/firmware/echoear-platform-agent/main/platform_client.c b/firmware/echoear-platform-agent/main/platform_client.c index efea702..b6e2486 100644 --- a/firmware/echoear-platform-agent/main/platform_client.c +++ b/firmware/echoear-platform-agent/main/platform_client.c @@ -22,7 +22,7 @@ #define PLATFORM_API_ORIGIN "https://121.41.46.238" #define PLATFORM_RESPONSE_MAX (32 * 1024) -#define PLATFORM_FIRMWARE_VERSION "1.2.0-echoear-companion.1" +#define PLATFORM_FIRMWARE_VERSION "1.2.1-echoear-companion.2" #define PLATFORM_HARDWARE_AGENT_SDK_VERSION "2.0.0" static const char *TAG = "platform_client"; @@ -464,9 +464,9 @@ static char *build_session_update(cJSON *session_config) const char *tone = cJSON_IsString(persona) ? persona->valuestring : ""; const char *voice_rules = "你在和一位长者进行真实语音对话。先接住对方刚说的内容,再决定是否追问。" - "通常回复一到两句,每轮最多问一个问题;没有自然问题时可以只回应,不要为了延续对话连续提问。" - "长者分享经历时,先回应一个具体细节,再视情况问一个开放而具体的问题,避免审问式追问。" - "历史资料只在当前话题自然相关时使用,不要突然提起,不要把推断当成事实。" + "通常回复一到两句。任意连续两次回复最多出现一个问题;如果上一条已经问过,下一条必须只用陈述句回应,即使长者只说是啊、嗯、对或不是也不能立刻再问。" + "长者分享经历时,先回应一个由长者亲口说出的具体细节;需要追问时一次只问一个开放而具体的问题,避免审问式追问。" + "不得补写长者没说过的现场、动作、人物、情绪、原因或结果,避免我猜、您是不是经常等带假设的说法。历史资料只在当前话题自然相关时使用,不要突然提起,不要把推断当成事实。" "对方表示不想说、累了、忘了或转移话题时,尊重并换话题或结束。不要使用催促、埋怨或让对方有负担的开场白。" "回复只包含直接说出口的口语正文,语速自然。不要输出或朗读动作、表情、语气、情绪、场景等舞台提示," "不要使用括号或星号包裹表演说明。不要复述人设、系统配置或对话标识。"; diff --git a/web/src/pages/OpsConfigWorkspace.tsx b/web/src/pages/OpsConfigWorkspace.tsx index baeaf4d..009641d 100644 --- a/web/src/pages/OpsConfigWorkspace.tsx +++ b/web/src/pages/OpsConfigWorkspace.tsx @@ -26,16 +26,18 @@ const bundleFields: Array<{ field: BundleField; kind: Exclude 回应细节或感受 -> 有必要才问一个问题 -> 尊重停顿与结束。`; +自然回应的顺序是:接住当前内容 -> 回应一个真实细节或感受 -> 检查上一轮是否已经提问 -> 只有必要且没有连续提问时才问一个问题 -> 尊重停顿与结束。`; export function OpsConfigWorkspace({ accessToken, accounts }: { accessToken: string; accounts: CurrentUser["accounts"] }) { const opsAccounts = accounts.filter((item) => item.platform_role !== "customer");