把大模型接进心理服务,聊起来容易,用起来难。做了大半年的多模态交互与任务执行,我最大的体会是:情绪理解固然重要,但真正让服务落地的,是系统能不能在对话之外完成动作。OpenClaw是我这边用于多模态交互与任务执行的一个内部框架代号,在AI心理服务场景里,它承担了语音、文本、生理信号等多种输入的归一化处理,以及意图识别之后的任务调度。这篇文章把它的设计思路、任务执行链路、边界划分和踩坑记录完整整理出来,给同样在折腾AI心理应用的人一个参考。
1. AI心理服务的核心瓶颈:模型能对话,但欠缺服务闭环
先说结论:绝大多数AI心理服务Demo都死在同一个地方——用户说了半天,系统只回了一段漂亮话,然后什么都没有发生。
1.1 心理服务本质上是动作序列,不是聊天记录
心理服务和我们平时用的客服机器人有本质区别。客服任务是"回答问题、转人工、查订单",它是可以被明确定义的动作集合;心理服务则是"倾听、评估、提供情绪支撑、引导行为改变、安排后续跟进",这些动作之间还有严格的时序关系。你可以把它理解成一个闭环流程,而不是一串对话轮次。
举个例子,用户说"我最近总是睡不着"。如果系统只是一般意义上的共情回应,"听起来睡眠问题让你很困扰",这句话没有错,但对用户没有任何实际帮助。合理的服务闭环应该是:先采集相关信息(失眠时长、频率、伴随情绪),再执行一个风险评估动作(判断是否需要转介),然后生成一个可执行的应对计划(睡眠卫生建议、放松练习引导),最后把"三日后回访"登记到任务队列里。这些动作里面只有一小部分是"对话",大部分是系统层面的任务执行。
OpenClaw在设计时把目标定得很明确:不做"更会聊天的模型",而是做"能把服务流程跑通的执行框架"。对话只是交互入口之一,它背后的任务链才是价值所在。
1.2 服务闭环需要哪几类基础动作
我们在拆需求时,把AI心理服务里的所有动作分成了四类,这四类决定了框架需要什么样的执行能力:
- 采集类任务:主动询问量表条目、收集睡眠日志、记录情绪打卡。这类任务的关键是"按预设结构收集数据",不能想到哪问到哪。
- 评估类任务:基于收集到的信息做风险分级、情绪状态推断、危机信号检测。这类任务必须可追溯,每个判断都要有依据来源。
- 干预类任务:推送呼吸练习引导、播放放松音频、生成认知重评的思考提示。这类任务需要多模态输出能力,不只是文字。
- 跟进类任务:预约回访、提醒服药或复诊、周期性发送情绪追踪问卷。这类任务需要定时调度和执行记录。
OpenClaw的定位,就是把这四类任务统一收口到一套执行框架里。对话模型负责"理解"和"生成",框架负责"编排"和"执行",两者之间用意图结构衔接,而不是把AI生成的自然语言直接当命令用。
1.3 OpenClaw的总体分层
整个框架分成三层,信息从下往上汇总、决策从上往下分派:
- 感知层:接收语音、文本、按钮点击、可穿戴设备同步过来的生理信号,统一转成结构化的感知数据。
- 意图层:把多模态感知数据融合成用户意图,包括当前对话意图、情绪状态、风险信号、任务需求。
- 执行层:根据意图触发任务编排,调度各类执行器完成动作,并把执行结果反馈回对话系统。
这个分层看起来简单,但实际落地时每一层都有大量细节。接下来重点讲感知和意图层,因为这是多模态交互最容易翻车的地方。
2. OpenClaw的多模态交互设计:同一份意图,多种输入形态
多模态这个词被用烂了,很多项目只是把"语音转文字+摄像头拍照"叫多模态。真正服务于AI心理应用的多模态,是让不同模态的信号共同指向同一个用户意图,并且互相校验、互为补充。
2.1 统一意图表示:语义槽位与置信度合并
OpenClaw的意图层不直接消费原始文本,而是消费一种统一的意图结构。这个结构包含三个部分:
- 意图类型:比如
symptom_report、risk_disclosure、task_response、help_request。 - 槽位集合:意图挂载的实体信息,比如
duration(持续时间)、frequency(频率)、intensity(严重程度)、trigger(诱因)。 - 置信度向量:每个槽位来自不同模态的置信度,以及融合后的最终置信度。
这样做的好处是,下游执行器不需要关心信息是从哪里来的。语音说"我头疼了三天",文本输入框里写"头疼3天",或者用户在量表上选了"持续时间:3天",最终到达评估模块的都是同一个意图结构:symptom_report(duration=3d, confidence=0.92)。
我见过很多团队在这一步图省事,直接把大模型的JSON输出当意图结构用。问题在于,大模型输出的字段名不稳定,今天是duration_days,明天变成days_duration,下游逻辑就得跟着改。所以OpenClaw在模型输出和任务执行之间加了一个意图归一化层,用固定Schema把模型输出映射成标准结构,映射失败的字段宁可丢弃也不能带病执行。
2.2 语音情绪特征和文本情感分析的协同判读
这是多模态设计里最值得展开的一块。纯文本情感分析对心理服务的支持非常有限,因为中文表达情绪的方式太含蓄,"我没事"这三个字在不同语气下的含义天差地别。如果只依赖文本,系统会把大量需要关注的用户漏掉。
OpenClaw的做法是,在用户通过语音输入时,同时跑两条分析支线:
- 文本支线:对ASR转写结果做情感极性分析、主题识别,提取文本中明确表达的负性词汇和自杀风险相关词汇。
- 声学支线:从原始音频中提取韵律特征,包括语速、停顿频率、基频均值与波动、能量变化率,用一个小型分类器输出情绪标签(低落、焦虑、平稳、激动)和唤醒度评分。
融合策略不是简单的"取平均",而是分场景决策:
| 场景 | 文本信号 | 声学信号 | 融合决策 |
|---|---|---|---|
| 用户说"我没事" | 中性偏弱负向 | 低能量、音调下降、长停顿 | 标记为"低落",触发主动关注任务 |
| 用户说"我很崩溃" | 强负向 | 平静、无明显波动 | 文本为主,声学作为确认,不升级紧急度 |
| 用户说"不想活了" | 强负向 | 激动、高唤醒 | 双通道强信号,立即触发危机干预流程 |
这里的关键是,声学特征只能作为置信度调节因子,不能单独作为风险判断依据。声学分析容易受录音环境、网络传输、麦克风质量影响,误报率很高。但如果文本信号已经达到风险阈值,声学信号又提供了"激动/低能量"的佐证,系统就可以提高风险等级,缩短人工复核的时间。
2.3 感知入口选型:录音、键盘输入、穿戴设备
实际部署时,感知入口不是越多越好,每个入口都带来隐私和工程成本。我们按优先级排了三档:
- 必选入口:键盘文本输入、麦克风语音输入。这两个入口覆盖绝大多数使用场景,语音输入适合不方便打字的用户,也是情绪特征提取的主要数据源。
- 可选入口:摄像头面部表情识别。在用户明确授权的条件下,通过面部表情判断情绪状态。我实测下来,这东西在光照不足、用户佩戴眼镜、侧脸角度大的时候准确率掉得很厉害,更适合做辅助信号,不建议当主信号。
- 暂缓入口:可穿戴设备生理数据(心率、皮电、睡眠监测)。理论上很有价值,但接入成本高、设备兼容性差,而且跨设备的数据口径不一致。我们只在特定测试用户群体里做了小范围验证,没有全面放开。
提醒一句:每多一个感知入口,隐私合规和用户信任成本就会上一个台阶。用户愿意对一个AI说心里话,前提是他觉得系统能守住边界。感知层不能无限堆硬件。
3. 任务编排的隐藏难点:不是"执行",而是"何时执行"
任务执行听起来很直白,把动作做掉就行。但心理服务场景里,绝大多数执行器在一个对话轮次里是不能直接触发的,它需要满足前置条件,否则就是乱作为。
3.1 心理服务流程怎么拆成行为节点
我们把一套标准的"首次心理评估"流程拆成了下面这些行为节点,每一个节点在执行层都是一个可独立调用的服务:
- 状态感知:确认用户当前处于可沟通状态,没有醉酒、极度激动等不适配情形。
- 基础信息采集:询问年龄、职业、当前困扰等,通过表单或自由对话收集。
- 量表评估:按预设规则选择PHQ-9、GAD-7或自定义量表,逐题采集。
- 风险筛查:根据量表得分和对话内容计算风险分级,高风险的直接进入人工干预通道。
- 反馈生成:生成评估报告摘要和初步建议,采用模板+个性化填充,避免模型自由编造。
- 跟进登记:将回访时间写入调度服务,设置提醒。
只设计节点是不够的,还要定义节点间的转换条件。比如"风险筛查"节点的输出如果是"高风险",就不能进入"反馈生成"正常流程,必须跳转到"人工介入"的并发流程。传统办法是在代码里写if-else,但流程多了以后,if-else就变成一团乱麻。我们改用配置化的行为节点描述,每个节点声明前置条件、输入槽位、输出事件和跳转目标。
3.2 主动型任务与响应型任务的调度策略
任务执行还有一个经常被忽略的维度:任务到底是谁发起的?
- 响应型任务:用户说"我想做放松练习",系统立刻触发放松练习引导。这类任务简单,用户意图明确,直接映射即可。
- 主动型任务:系统判断"用户该做情绪打卡了"或者"三天后该回访了",主动发起对话。这类任务难度大得多,因为主动打扰在心理服务里是有风险的,发出去的提醒可能变成用户的压力源。
我们给主动型任务设计了两条铁律:
- 低优先级触发:主动型任务不能打断当前正在进行的服务会话,只能排队等待合适时机;如果用户连续两轮回复表现出不耐烦情绪,主动任务自动取消。
- 软提醒机制:主动提醒不使用硬通知,而是以静默消息形式出现在对话列表里,文案尽量中性,比如"上一次记录是三天前,方便的话可以更新一下",让用户有充分的选择权。
从工程实现上,OpenClaw的调度器维护了一个任务队列,每个任务带优先级、触发条件、冷却时间。每次对话轮次结束时调度器都会跑一次任务匹配,看有没有满足触发条件的等待任务。这个设计让主动型任务不至于变成骚扰。
3.3 用轻量状态机管理任务生命周期与中断恢复
心理服务任务一个显著特点是容易中断。用户做着量表突然不答了,或者语音引导放松练习进行到一半被打断。如果执行框架不考虑中断恢复,会出两个问题:数据采集不完整导致评估失真;用户被迫重新开始,体验非常挫败。
OpenClaw为每个执行中的任务维护一个轻量状态机,至少包含四个状态:进行中、已暂停、已完成、已放弃。关键字段包括:当前断点位置、已完成节点的数据缓存、最后一次交互时间。
以"量表评估"任务为例,用户答题到第5题时切走了。十分钟后回来,系统检测到存在已暂停状态的评估任务,会主动提示"上次评估进行到第5题,是否继续?"而不是让用户从头开始。实现上只需要在量表服务里保存答题进度,状态机负责标记状态和恢复入口。这个小功能对用户好感度的提升比任何花哨的共情话术都明显。
4. 心理服务场景中OpenClaw的职责边界:先画红线再写代码
技术框架做得再好,如果职责边界不清楚,上线就是事故。AI心理服务不是"AI做心理咨询师",而是"AI辅助心理服务流程",这个定位必须在系统设计阶段就钉死。
4.1 为什么不能做成全自动咨询
最大的风险不在于模型能力不够,而在于责任归属不清晰。如果系统以全自动方式对用户提供心理干预,一旦干预方式不适用或者引发负面反应,这个责任是无法划分的。我见过一些团队把问题完全推给大模型,理由是大模型自己生成的回复,这非常不负责任。用户在心理服务场景里处于脆弱状态,系统设计者必须为每一次响应负责。
所以我把OpenClaw的执行原则定成"副驾驶原则":系统可以执行低风险的陪伴类、记录类、知识类任务,但凡是涉及诊断、危机干预、治疗方案的任务,系统只能执行"转介"和"上报",不能执行"处置"。这是工程红线,不是模型调参能解决的问题。
4.2 分级响应与人工介入的路径设计
应对不同风险强度,我们设计了四级响应:
| 级别 | 判定依据 | 系统动作 | 人工介入 |
|---|---|---|---|
| L0 平稳 | 情绪状态正常,无风险信号 | 常规陪伴对话,推送自助工具 | 不需要 |
| L1 关注 | 轻度负性情绪持续 | 推送心理科普和自助练习 | 次日人工回访 |
| L2 明显 | 量表得分中高度,负性表达集中 | 暂停自助引导,启动人工在线沟通 | 15分钟内接入 |
| L3 危机 | 明确自伤/自杀表述,且有一定计划性 | 停止聊天动作,进入危机干预协议 | 立即联系紧急联系人或专业热线 |
人工介入路径要提前做成标准流程,不能临时找人。我们的做法是:L2和L3事件通过钉钉/企业微信机器人通知到值班人员,值班人员有一个专门的处理台,能看到系统整理的用户时间线、风险依据、已执行的安抚动作。系统把"能做的都做好",然后把人准时叫进来。
4.3 数据隐私和风险评估的工程化方案
AI心理服务的数据比医疗数据还敏感,因为用户可能在完全放松的情况下说出一生中最脆弱的秘密。我们在工程上做了几件扎实的事:
- 最小化采集:能本地处理的绝不上传。语音情绪特征分析全程在端侧完成,只把结构化特征值传到服务端,原始音频默认不保留。
- 昵称化与去标识化:用户表、对话记录表、量表结果表三张表分离,通过不可逆ID关联,即使数据泄露也无法拼出完整用户画像。
- 对话数据分级存储:普通对话保留3个月,量表评估结果保留12个月,高风险记录单独加密长期保存并严格控制访问权限。
- 操作审计:所有对用户敏感数据的访问都留痕,连续访问异常触发警报。
做这些工作的核心动力是让用户在认知上感到"这个系统可以信任"。信任感是心理服务的第一生产力,技术框架再先进,用户不信任就不敢说真话,感知识别得再准也没用。
5. 一次完整的任务闭环复盘:从"我最近睡不着"到动作完成
前面讲了不少设计原则,这里用一个实际场景把整条链路串起来。假定用户晚上十点打开小程序,按下录音键说了一句"我最近总是睡不着,白天也很累"。
5.1 输入归一化与意图抽取
语音首先走ASR转写,得到文本"我最近总是睡不着,白天也很累。"与此同时,声学分析模块从原始音频中提取出特征:语速偏慢、基频方差偏小、能量偏弱,初步标记情绪状态为"疲惫/低落"。
文本进入意图层后,语义解析结果指向sleep_issue_report意图,槽位提取结果为:
intent_type: sleep_issue_report slots: symptom: insomnia duration: unknown impact: daytime_fatigue severity: unknown confidence: text: 0.88 acoustic: 0.74 fused: 0.85注意,duration和severity两个槽位是空的,这就是下游评估模块继续追问的依据。系统不会假装什么都懂,明确知道自己缺什么信息,比为用户补全信息重要得多。
5.2 执行器的组合调用与上下文管理
意图层把归一化后的结构抛给执行层。执行层的编排器按照sleep_issue_report对应的任务模板,按顺序触发三个执行器:
- 信息补全执行器:生成追问"这种情况大概持续多久了?白天累会影响到工作或学习吗?"语气保持中性,不追问过多细节,避免让用户觉得在被审问。
- 风险评估执行器:结合当前信息和历史对话记录,判断当前风险等级为L1,不需要触发人工介入。
- 干预建议执行器:推送睡眠卫生基础建议,并附一条渐进式放松练习的音频链接,同时询问用户是否愿意设置睡眠打卡提醒。
这三个动作的上下文始终在同一个会话容器里。容器里保存了当前用户的情绪状态、已完成的任务节点、已采集的槽位数据。执行器之间不直接通信,都通过容器读写数据,这样可以避免流程跳转时上下文丢失。
5.3 任务结束后我们留下来的沉淀
用户完成睡眠打卡登记后,整套任务并没有真正结束。后续还有两个隐藏动作:
- 三天回访任务被写入调度队列,到期后由调度器触发主动型任务,询问用户睡眠改善情况。
- 本次交互的全过程被压缩成一条结构化摘要存入用户档案,包括时间、情绪标签、症状类型、已执行任务、用户反馈。下次用户再来时,系统可以基于这份档案提供更连续的陪伴,而不是每次都像第一次见面一样陌生。
这次闭环走完,用户获得的是"我说了一句话,系统帮我做完了一整套事",而不是"我说了一句话,系统回了我一句话"。两者的体验差距,是天壤之别。
6. 实测中踩过的坑:三件最常见的翻车事故
任何框架的真实价值都要靠踩坑来验证。OpenClaw在测试和小范围试用阶段翻过很多次车,我挑三个最典型的讲,给准备自己动手搭的同学提个醒。
6.1 情绪识别阈值乱调的后果
早期我们把声学支线的"低落"判定阈值调得很灵敏,本意是宁可多关注也不放过。结果连续两周收到大量误报,很多用户只是刚睡醒、声音沙哑或者鼻音重,就被系统标记成"情绪低落",蜂拥进入L1人工回访队列,值班人员被淹没在无效工单里。
后来我们单独统计了误报分布,发现绝大多数误报集中在上午9点到11点。原因很好理解,这个时段用户的嗓音状态普遍不如下午稳定。修正方案是:不对全体用户用同一套阈值,而是按用户建立个性化声学基线,结合该用户历史语音的平均基频和语速做相对判断。这个改动让误报率下降了接近一半。
6.2 口语噪声污染任务槽位
用户在语音输入时经常夹带口语化填充词,"那个""就是说""嗯……怎么讲呢"。ASR转写结果把这些词保留了下来,直接污染了意图抽取。最典型的一个事故是,用户说"我就是那个……有点焦虑吧",槽位抽取时把"那个"解析成了reference_indicator,导致后续追问完全跑偏,用户明显不耐烦。
解决方式是在文本进入意图层之前先做一步口语噪声清洗:剔除语气词、填充词、重复片段,并在清洗过程中保留原文的停顿信息。停顿时间过长本身是声学支线判断犹豫情绪的输入,不能因为清洗而丢给后面的情感判断用。
6.3 记忆膨胀导致执行链路线错误
OpenClaw初期把用户的全部历史对话都塞进上下文窗口,认为"记得越多服务越贴心"。实际效果是:上下文中有用的信息被大量无关细节淹没,任务执行时模型容易被历史里的某句话带偏,链路走向错误。
比如一个用户两周前提到过"和同事关系紧张",当时已经做过一次干预任务。两周后用户因为失眠问题来访,只要历史上下文里出现"同事"这个词,执行器就会倾向于把任务链导向人际冲突评估,而不是睡眠评估。这个错误非常隐蔽,因为从单轮对话看系统回答得挺专业,但检查执行轨迹就能发现任务意图被污染了。
最终的方案是给上下文做了一个记忆分区:短期工作记忆只保留当前任务相关的内容;长期档案只保留结构性摘要和关键里程碑事件,对话原文不再直接进入模型上下文。执行器读取档案时按需提取,而不是全量加载。这之后,任务链路的稳定性明显上了一个台阶。
我在实际调试中还有一个体会,多模态融合时优先相信任务信号,而不是情绪信号。情绪信号再丰富,也只能给任务执行提供参考,不能替任务做决定。比如系统识别到用户很沮丧,但用户明确说"我想先不做量表,只想随便聊聊",那就应该尊重用户的任务选择,把量表任务挂起,先让对话保持在陪伴状态。框架再聪明,服务的永远是人,这句话在心理服务场景里尤其不能忘。