AI Agent 的情感计算:用户意图理解与情绪识别

引言:为什么 Agent 需要"读懂"用户?

在传统的对话系统中,用户输入被视为一个待解析的指令字符串——系统提取关键词、匹配意图槽位,然后返回预设答案。然而,真实的人类交流从来不是如此冰冷的。同样一句"我放弃了",可能是轻松的调侃,也可能是绝望的求助。如果 AI Agent 无法感知这种情绪差异,它可能会在用户最需要共情的时候,给出一个令人心寒的"好的,已记录"。 情感计算(Affective Computing)正是为了让 Agent 拥有这种"社交智能"而存在。它让机器不仅能理解用户"说了什么",还能感知用户"感受如何",从而构建更自然、更信任的人机协作关系。本文将深入探讨 Agent 情感计算的技术架构,从文本情绪分析到多模态感知,从显式意图到隐式意图的深层挖掘,并给出可直接落地的代码实践。

一、情感计算在 Agent 交互中的价值

1.1 从"功能正确"到"体验正确"

一个功能正确的回答未必是好的回答。当用户愤怒地投诉产品质量时,Agent 的首要任务不是立即给出技术解决方案,而是先承认用户的情绪、表达理解。情感计算让 Agent 实现了从"功能正确"到"体验正确"的跃迁: - 情绪适配:根据用户情绪状态调整语气、措辞和响应策略 - 冲突降级:在检测到负面情绪时,主动采取安抚、转人工等策略 - 信任构建:持续的共情响应显著提升用户对 Agent 的接受度和满意度 - 意图澄清:情绪线索往往是隐式意图的关键信号

1.2 情感数据的商业与技术价值

情感信号不仅是"软体验",更是硬数据。用户在与 Agent 交互过程中的情绪波动,可以反映产品痛点、服务断点,甚至预测用户流失风险。将情感计算融入 Agent 架构,实际上是构建了一套实时、低成本的用户体验监测体系。

二、情绪识别技术:从文本到多模态

2.1 文本情感分析:Agent 的"读心术"基础

文本仍然是当前 Agent 交互的主要载体。文本情感分析技术经历了从基于词典到深度学习,再到 LLM 时代的演进。

基于 LLM 的情感分类

现代 Agent 可以直接利用 LLM 强大的上下文理解能力进行情感分析,无需额外训练专用模型:

from openai import OpenAI

client = OpenAI()

def analyze_emotion(text: str) -> dict:
    """使用 LLM 进行细粒度情感分析"""
    prompt = f"""
    分析以下用户输入的情感状态。请返回 JSON 格式:
    - emotion: 主要情绪(joy, anger, sadness, fear, surprise, neutral)
    - intensity: 强度(1-5)
    - sentiment: 整体极性(positive, negative, neutral)
    - confidence: 置信度(0-1)
    
    用户输入:"{text}"
    """
    
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "你是一个专业的情感分析助手,只返回 JSON,不添加任何解释。"},
            {"role": "user", "content": prompt}
        ],
        response_format={"type": "json_object"}
    )
    
    import json
    return json.loads(response.choices[0].message.content)

示例

result = analyze_emotion("这产品太难用了,我折腾了一整天还是搞不定!") print(result)

输出: {'emotion': 'anger', 'intensity': 4, 'sentiment': 'negative', 'confidence': 0.92}

这种基于 LLM 的方法的优势在于:无需标注数据、支持细粒度情感维度、理解上下文依赖。对于 Agent 来说,可以将情感分析作为每个用户输入的预处理步骤,将结果注入后续决策流程。

2.2 多模态情感感知:超越文本的维度

人类情感表达是多通道的——语气、表情、语速、停顿都承载着丰富的情绪信息。多模态情感计算让 Agent 能够综合利用这些信号: | 模态 | 情感信号 | 技术方案 | |------|----------|----------| | 文本 | 词汇选择、标点、句式 | LLM 情感分析、BERT 微调 | | 语音 | 音调、语速、能量、停顿 | Wav2Vec + 情感分类器 | | 视觉 | 面部表情、微表情、姿态 | 面部 landmarks + 表情识别模型 | | 生理 | 心率、皮肤电(穿戴设备) | 传感器数据 + 时序模型 | 对于语音 Agent(如客服电话机器人),语音情感识别尤为关键:

import librosa
import numpy as np
from transformers import Wav2Vec2ForSequenceClassification, Wav2Vec2FeatureExtractor

class VoiceEmotionAnalyzer:
    def __init__(self, model_name="facebook/wav2vec2-large-xlsr-53"):
        self.feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(model_name)
        self.model = Wav2Vec2ForSequenceClassification.from_pretrained(
            "your-finetuned-emotion-model"  # 需使用情感数据集微调
        )
    
    def analyze(self, audio_path: str) -> dict:
        """分析音频中的情感"""
        speech, sr = librosa.load(audio_path, sr=16000)
        inputs = self.feature_extractor(
            speech, 
            sampling_rate=16000, 
            return_tensors="pt", 
            padding=True
        )
        
        with torch.no_grad():
            logits = self.model(inputs).logits
        
        predicted_id = torch.argmax(logits, dim=-1).item()
        confidence = torch.softmax(logits, dim=-1)[0][predicted_id].item()
        
        emotion_labels = ["neutral", "happy", "sad", "angry", "fear"]
        return {
            "emotion": emotion_labels[predicted_id],
            "confidence": confidence,
            "audio_features": {
                "pitch_mean": np.mean(librosa.yin(speech, fmin=50, fmax=300)),
                "energy": np.mean(librosa.feature.rms(y=speech)[0])
            }
        }

2.3 情感状态追踪:不只是"当前情绪"

单次情感检测容易受噪声影响,真正有用的情感计算需要情感状态追踪——即在多轮对话中持续建模用户情绪的动态变化:

from dataclasses import dataclass, field
from typing import List
from collections import deque

@dataclass
class EmotionState:
    """用户情感状态追踪"""
    current_emotion: str = "neutral"
    intensity: float = 0.0
    emotion_history: deque = field(default_factory=lambda: deque(maxlen=10))
    trend: str = "stable"  # rising, falling, stable
    
    def update(self, new_emotion: str, new_intensity: float):
        self.emotion_history.append({
            "emotion": new_emotion,
            "intensity": new_intensity
        })
        
        # 计算情绪趋势
        if len(self.emotion_history) >= 3:
            recent = [e["intensity"] for e in list(self.emotion_history)[-3:]]
            if recent[-1] > recent[0] + 0.5:
                self.trend = "rising"
     
Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐