ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AI陪伴机器人情绪陪伴的工程实现-先共情再建议

AI陪伴机器人情绪陪伴的工程实现-先共情再建议 06-情绪陪伴的工程实现-先共情再建议黒漂技术佬 / AI 伙伴AI-Partner系列很多人以为AI 陪伴就是聊天机器人多加几句抱抱你。真要做成一个让老人、孩子、独居的人愿意天天说话的陪伴机器人先共情再建议不是一句产品口号而是要用工程手段落地的系统提示词约束它该怎么说话工具调用让它把情绪记下来回复字数限制逼它别啰嗦。这篇我们就把这条链路从模型判断一直追到数据库落库拆开看清楚。一、先共情再建议到底卡在哪一步陪伴有个天然矛盾用户说我今天有点难过机器人如果张口就给建议“那你出去走走”“别想太多”听起来像在说教反而把人推远了。人设里要求的顺序是先回应感受再提供帮助这个顺序如果靠程序员在代码里写一堆 if-else 去判断会累死也写不全。AI 伙伴AI-Partner的做法是把这条规则写进系统提示词交给大模型去理解并执行。在PersonaProvider拼出来的系统消息尾部有一段「回复要求」其中两条直接相关项目源码节选自 PersonaProvider 注入的回复要求2. 优先共情先回应感受再提供帮助不评判、不说教。 3. 回复控制在 150 字以内简洁有温度能问一句就不答一段。注意第 2 条是顺序约束第 3 条是长度约束。这两条都是软约束——大模型遵守的程度取决于模型能力和提示词质量代码层并没有一个超字数就截断的硬开关。这既是好处自然、不死板也是风险偶尔会啰嗦或跑偏后面会讲到边界。二、情绪工具让机器人会做笔记光靠嘴说还不够。如果机器人每次听完就忘下一次对话又从零开始陪伴感就垮了。于是 AI 伙伴AI-Partner给 Agent 配了两个情绪工具定义在EmotionTool里项目源码EmotionTool 两个 ToolTool(记录用户当前的情绪状态如难过、焦虑、开心和强度、原因。返回记录结果)publicStringrecordEmotion(Stringemotion,Integerintensity,Stringcontext,ToolMemoryIdLonguserId){emotionService.record(userId,emotion,intensity,context,agent);return已记录情绪emotion强度 intensity(context!null?原因context:);}Tool(查询该用户最近的情绪记录用于理解用户近期状态。返回情绪历史列表)publicStringgetRecentEmotion(ToolMemoryIdLonguserId){returnemotionService.recentText(userId);}两个方法分工很清晰recordEmotion把此刻的情绪存下来是写动作。getRecentEmotion把最近的情绪读出来是读动作用于让机器人记得你前几天的状态。工具里写死的source agent很关键它标记这条情绪是机器人对话中识别出来的区别于用户自己在 App 里手动勾选manual或视觉识别vision。后文数据建模会细说。三、一次我今天有点难过的完整链路下面把一次对话从头到尾走一遍。这是最能体现工程如何实现共情的一段建议对照看。链路总览步骤环节干了什么1入口ChatController收到POST /api/chat转交ChatService.chat2Agent 调用companionAssistant.chat(message, userId)3人设注入systemMessageProvider动态拼系统提示词人设时间画像记忆回复要求4模型判断大模型读人设与用户输入决定先共情并调用 recordEmotion5工具执行recordEmotion→EmotionService.record→ 落t_emotion_record6生成回复模型基于共情基调写出 ≤150 字回复7对话落库ChatService把一问一答写入t_conversation第 4 步到第 6 步是核心。大模型拿到输入我今天有点难过结合系统提示词里的优先共情会识别情绪类别为sad难过并大致推断强度比如 6主动调用recordEmotion(emotionsad, intensity6, context今天有点难过, userId...)在工具返回已记录情绪后用温暖语气先回应感受再视情况问一句。模型实际生成的回复类似示意机器人可能给出的共情回复听起来你今天心情有点沉是遇到什么烦心事了吗我在这儿陪着你 要是想说说我随时都在。注意它先接住情绪“心情有点沉”再抛一个开放式问题没有急着给建议——这正是第 2 条提示词在起作用。第 5 步落库的代码项目源码EmotionService.recordpublicEmotionRecordrecord(LonguserId,Stringemotion,Integerintensity,Stringcontext,Stringsource){if(emotionnull||emotion.isBlank()){thrownewBusinessException(情绪类型不能为空);}EmotionRecordrecordnewEmotionRecord();record.setUserId(userId);record.setEmotion(emotion.trim().toLowerCase());record.setIntensity(intensitynull?5:Math.max(1,Math.min(10,intensity)));record.setContext(context);record.setSource(sourcenull?manual:source);returnemotionRepository.save(record);}几个细节值得记emotion会被toLowerCase()所以模型写 “Sad” 也会存成 “sad”避免大小写分裂intensity做了Math.max(1, Math.min(10, ...))的钳制模型就算返回 99也只会存 10传 null 时默认 5source默认 “manual”但工具入口强制传 “agent”。第 7 步落到t_conversation的是userMessage和assistantMessage全文外加tokenUsage、latencyMs。这里有个诚实的未闭环点t_conversation表里还有emotion、toolCalled两个字段本意是回写这次对话触发了什么情绪、是否调了工具但当前写入链路并没有给它们赋值所以这两个字段恒为默认值null / false。也就是说情绪记录和对话记录是各自独立落库的对话表本身不反向标记情绪。这在做会话级情绪分析时要留意。隐私与合规提醒情绪属于敏感个人信息。AI 伙伴AI-Partner按谁的情绪记在谁名下userId 隔离、最小必要原则只存情绪类别强度场景不存原始语音与无关节内容。涉及未成年人时建议取得监护人同意并明确留存期限不做长期画像滥用。四、回复字数限制为什么是 150 字150 字不是拍脑袋。陪伴有两类典型场景老人视力、注意力有限一段话太长读不进去反而没耐心情绪低谷的人本来就累长长篇大论像在被教育。150 字约等于手机两屏、念出来 20~30 秒刚好接住情绪 留个口子让人接话。提示词里还补了一句能问一句就不答一段把目标从说清楚变成引对话这是陪伴和客服的本质区别。但要强调这是提示词约束不是代码强制。当前ChatService没有对reply做长度校验或截断。好处是自然代价是模型偶尔会超字数。真要兜底可在工程上加一层超长则要求模型精简并重生成但那会多一次往返、牺牲延迟属于 trade-off不是必须。五、情绪识别准确性的现实边界这部分最容易飘。必须说清楚AI 伙伴AI-Partner的情绪识别是大模型从自然语言里推断出来的不是临床量表测评。现实情况说明类别靠模型理解我今天有点丧可能识别成 sad 或 tired边界模糊强度是估计值模型给的 intensity 是相对感受不能当心理学评分讽刺/反话难辨我可太开心了模型可能真当成 happy多情绪并存人常又气又委屈模型通常只取主导一个来源标记 agent表示机器推断非用户自述分析时权重应打折所以情绪数据更适合做趋势观察和主动关怀触发绝不能当作诊断依据。当系统发现连续低落、焦虑、失眠时按人设第 4 条去建议联系家人朋友或专业帮助而不是替用户下结论。健康与情绪免责本文涉及的情绪记录仅做善意提醒与陪伴参考不构成任何心理或医疗诊断。若你或家人出现持续情绪困扰请以专业医生/心理咨询师意见为准。六、一个诚实的边界工具调用失败会怎样链路追踪里我们默认一切顺利。但工程上要问如果落库那一刻数据库抽风了recordEmotion抛异常会怎样看回EmotionToolrecordEmotion没有 try-catch对照ReminderTool.createReminder是有 try-catch 的。一旦EmotionService.record抛BusinessException或 JPA 异常它会被全局异常处理器兜成系统繁忙请稍后再试这次对话的回复也可能因此拿不到。场景行为影响情绪写入失败异常上抛全局处理器用户可能收到系统错误情绪也没记下与回复解耦记录失败不影响已生成回复逻辑但当前是同步调用失败即中断整轮改进方向有两个一是给recordEmotion也包一层 try-catch像提醒工具那样记录失败只提示、不影响陪聊二是把情绪记录做成异步/尽力而为主对话链路不因它而崩。对陪伴产品来说“陪聊不能断优先级高于记录不能丢”这点值得在重构时明确。隐私与合规提醒重申情绪记录属于敏感个人信息落库失败不应降级为把原文缓存到别处之类的野路子失败就失败宁可少记一条也不要把未授权内容散落到日志或临时文件。七、小结“先共情再建议在 AI 伙伴AI-Partner里不是一句文案而是一条由三块拼起来的链路人设提示词定下说话顺序与字数、情绪工具负责把感受变成可回看的记录、对话落库让陪伴有连续性。真正难的地方不在能不能存”而在存得准不准、说得暖不暖——前者靠字段设计与来源标记后者靠提示词与模型能力二者都还有打磨空间。
返回列表