手搓一个会“共情”的AI智能体:如何让AI回答像人

14 阅读9分钟

本文为微信公众号 敏叔的技术札记 原创文章,版权归 敏叔的技术札记 所有。如需转载或引用本文内容,请务必注明原文出处、作者以及原文链接。欢迎关注我的微信公众号 「敏叔的技术札记」,获取最新技术分享与深度解析。对于任何未注明来源的转载、摘编、修改或商业使用行为,本人保留追究法律责任的权利。

前言

搞AI智能体项目,一定会碰到这种需求:“能不能让这个AI说话别那么机械?最好能有点人情味,能理解用户的情绪。”

我一听,这不就是情感计算和拟人化交互嘛!

其实一开始我也觉得这玩意儿挺玄乎的,什么情感识别、情绪建模,听着就头大。但用下来之后发现,其实核心就那么几个技术点,而且现在开源的工具已经很成熟了,咱们自己也能搞起来。

这篇文章,我就把我从零搭建一个“会共情”的AI智能体的过程、踩过的坑、以及最终可用的代码,都分享给大家。贴不贴心吧!

环境准备

先搞个基础项目,我用的是Python,毕竟AI生态还是Python最全。

# 创建项目目录mkdir emotional-ai-agentcd emotional-ai-agent# 创建虚拟环境(隔离依赖,好习惯)python3 -m venv venvsource venv/bin/activate  # Linux/Mac# 或者 venv\Scripts\activate  # Windows

接下来安装核心依赖,情感计算这块主要用这几个库:

pip install transformers torch numpy pandaspip install scikit-learn nltk textblobpip install flask fastapi  # 如果需要做API服务

附赠安装小技巧:国内环境可以用清华源加速,亲测下载速度飞起:

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

情感识别模块:让AI“读懂”情绪

1. 基础版:用TextBlob快速上手

一开始我试了最简单的TextBlob,发现效果还行,适合快速原型验证,但不够精细:

from textblob import TextBlobdef basic_sentiment(text):    blob = TextBlob(text)    polarity = blob.sentiment.polarity  # -11,负到正    subjectivity = blob.sentiment.subjectivity  # 01,客观到主观        # 简单阈值判断    if polarity > 0.1:        return "positive", polarity    elif polarity 2. 进阶版:上Hugging Face预训练模型

TextBlob虽然简单,但对复杂语境和反讽识别不太准。我发现用Hugging Face的预训练模型效果直接上了一个台阶:

from transformers import pipeline# 加载情感分析模型(这个模型支持多语言,包括中文)sentiment_analyzer = pipeline("sentiment-analysis", model="nlptown/bert-base-multilingual-uncased-sentiment")def advanced_sentiment(text): result = sentiment_analyzer(text)[0] label = result['label'] # 例如 “5 stars” score = result['score'] # 置信度 # 把星级评分转成我们用的情感标签 if '1 star' in label or '2 stars' in label: return "negative", score elif '3 stars' in label: return "neutral", score else: # 4 or 5 stars return "positive", score# 测试text = "这个产品太糟糕了,完全不符合预期"result = advanced_sentiment(text)print(f"情感: {result[0]}, 置信度: {result[1]:.2f}")


## 情绪状态管理:给AI一个“人设”

光识别用户情感还不够,智能体自己也得有“情绪状态”,这样交互才有来有回。我设计了一个简单的情绪状态机:

import timeclass EmotionalState: def init(self): self.mood = "neutral" # 当前情绪:happy, concerned, neutral, excited... self.intensity = 0.5 # 情绪强度 0-1 self.memory = [] # 历史交互记录,用于长期情绪建模 def update(self, user_sentiment, user_intensity): """根据用户情绪更新自身状态(简单的情感传染模型)""" # 用户开心,AI也更容易开心 if user_sentiment == "positive": self.mood = "happy" self.intensity = min(1.0, self.intensity + 0.2) # 强度增加,但有上限 elif user_sentiment == "negative": self.mood = "concerned" # 用concerned比sad更符合助手身份 self.intensity = min(1.0, self.intensity + 0.3) else: # neutral self.mood = "neutral" self.intensity = max(0.1, self.intensity - 0.1) # 情绪衰减,回归平静 # 记录历史,方便后续分析或实现长期记忆 self.memory.append({ "user_sentiment": user_sentiment, "user_intensity": user_intensity, "ai_mood": self.mood, "timestamp": time.time() }) # 保持最近100条记录,防止内存无限增长 if len(self.memory) > 100: self.memory = self.memory[-100:] def get_response_style(self): """根据当前情绪状态返回对应的响应风格""" styles = { "happy": {"tone": " cheerful", "emojis": ["😊", "🎉", "👍"]}, "concerned": {"tone": " gentle", "emojis": ["🤔", "💭", "🙏"]}, "neutral": {"tone": " professional", "emojis": ["😐", "👌"]}, "excited": {"tone": " enthusiastic", "emojis": ["🚀", "🔥", "💪"]} } # 如果没定义,默认返回中性风格 return styles.get(self.mood, styles["neutral"])


## 拟人化响应生成:让AI“说人话”

### 1. 模板法:低成本高可控

直接让大模型生成拟人化响应效果最好,但成本高、响应慢。折中方案是模板+变量,可控性强:

import randomclass PersonalizedResponse: def init(self): # 准备多套模板,避免回复重复 self.templates = { "greeting": [ "嗨!今天过得怎么样呀?{emoji}", "你好呀~{emoji} 有什么可以帮你的吗?", "来啦来啦!{emoji} 我准备好为你服务了!" ], "positive_feedback": [ "太棒了!{emoji} 听到你这么说我也很开心!", "真好!{emoji} 继续加油哦~", "哇!{emoji} 这真是个好消息!" ], "negative_feedback": [ "啊这...{emoji} 听起来不太顺利呢,需要我帮忙吗?", "抱抱~{emoji} 事情会好起来的!", "我理解你的感受{emoji},我们一起想办法解决好吗?" ], "neutral_response": [ "明白了{emoji},", "好的{emoji},", "收到{emoji}," ] } def generate(self, intent, emotional_state): """生成带情绪的响应""" style = emotional_state.get_response_style() templates = self.templates.get(intent, self.templates["neutral_response"]) # 根据情绪强度选择不同活跃度的模板 if emotional_state.intensity > 0.7: template = templates[0] # 情绪强烈,用列表里第一个(通常更活泼) elif emotional_state.intensity 2. 大模型法:效果天花板(可选)

如果预算够,追求极致效果,直接让大模型生成响应,拟人化程度最高:

def llm_emotional_response(user_input, emotional_state, api_key):    """调用大模型(如OpenAI)生成情感化响应"""    import openai        prompt = f"""    你是一个有情感的AI助手,当前情绪状态:{emotional_state.mood}(强度:{emotional_state.intensity})        用户说:{user_input}        请根据你的情绪状态,生成一个自然、拟人化的回复。    要求:    1. 语气要符合你的情绪状态    2. 适当使用表情符号    3. 长度在1-3句话        你的回复:    """        response = openai.ChatCompletion.create(        model="gpt-3.5-turbo",        messages=[{"role": "user", "content": prompt}],        temperature=0.7 + emotional_state.intensity * 0.3,  # 情绪越强,回复随机性(创造性)越高        api_key=api_key    )        return response.choices[0].message.content

完整示例:把模块组装成智能体

好了,零件都齐了,现在把它们组装起来:

class EmotionalAIAgent:    def __init__(self):        # 初始化三个核心模块        self.sentiment_analyzer = pipeline("sentiment-analysis")        self.emotional_state = EmotionalState()        self.response_generator = PersonalizedResponse()            def process(self, user_input):        # 1. 分析用户情感        sentiment_result = self.sentiment_analyzer(user_input)[0]        # 简化处理,假设模型返回POSITIVE/NEGATIVE标签        user_sentiment = "positive" if sentiment_result['label'] == "POSITIVE" else "negative"        user_intensity = sentiment_result['score']                # 2. 更新AI自身情绪状态        self.emotional_state.update(user_sentiment, user_intensity)                # 3. 判断交互意图(这里是个简单规则版,可以用分类模型增强)        if any(word in user_input.lower() for word in ["你好", "hi", "hello", "嗨"]):            intent = "greeting"        elif user_sentiment == "positive":            intent = "positive_feedback"        elif user_sentiment == "negative":            intent = "negative_feedback"        else:            intent = "neutral_response"                # 4. 生成拟人化响应        tone, response = self.response_generator.generate(intent, self.emotional_state)                # 返回完整结果        return {            "user_sentiment": user_sentiment,            "ai_mood": self.emotional_state.mood,            "response_tone": tone,            "response": response        }# 运行测试,看看效果agent = EmotionalAIAgent()test_inputs = [    "你好呀!",    "今天工作好累啊...",    "我考试通过啦!太开心了!",    "这个功能怎么用?"]print("=== 情感AI智能体测试 ===")for input_text in test_inputs:    result = agent.process(input_text)    print(f"用户: {input_text}")    print(f"AI情绪: {result['ai_mood']}")    print(f"AI回复: {result['response']}")    print("-" * 50)

部署为API服务:让更多人能用

如果需要做成服务,供其他应用调用,用FastAPI几分钟就能搭好:

from fastapi import FastAPIfrom pydantic import BaseModelapp = FastAPI(title="Emotional AI Agent API")# 定义请求响应格式class ChatRequest(BaseModel):    message: str    user_id: str = "default"  # 支持多用户,情绪状态隔离class ChatResponse(BaseModel):    response: str    ai_mood: str    sentiment: str# 全局agent实例(生产环境可以考虑用缓存或数据库)agent = EmotionalAIAgent()@app.post("/chat", response_model=ChatResponse)async def chat(request: ChatRequest):    """核心聊天接口"""    result = agent.process(request.message)        return ChatResponse(        response=result["response"],        ai_mood=result["ai_mood"],        sentiment=result["user_sentiment"]    )@app.get("/mood/{user_id}")async def get_mood(user_id: str):    """获取AI对应用户的当前情绪状态(可用于前端展示情绪图标)"""    # 注意:这里简化了,实际应该根据user_id返回对应的状态实例    return {        "mood": agent.emotional_state.mood,        "intensity": agent.emotional_state.intensity,        "interaction_count": len(agent.emotional_state.memory)    }

运行服务命令:

uvicorn emotional_api:app --host 0.0.0.0 --port 8000 --reload

访问 http://localhost:8000/docs 就能看到自动生成的API文档,也不卖关子,就是这么方便。

踩坑经验 & 实用技巧

搞这个项目过程中,踩了不少坑,也总结了一些技巧:

情感识别不准怎么办?

  • :一开始用简单规则或基础库,发现很多反讽、复杂句式识别不出来。

  • 解决:换用Hugging Face上更先进的预训练模型(如bert-base-multilingual系列),并注意选择适合中文语境的模型。如果领域特殊(如医疗、金融),可以收集数据自己微调。

AI情绪状态“漂移”或太假?

  • :情绪变化太频繁或太剧烈,AI会显得不稳定或做作。

  • 解决:在状态更新逻辑里加入衰减机制(像我代码里intensity的减少),让情绪能慢慢回归中性。也可以设置情绪变化的阈值和上限。

模板化响应听起来假?

  • :模板有限,用户很快就能发现重复模式。

  • 解决:准备足够多的模板(至少每个意图5-10条),并引入随机性。或者采用“模板+大模型润色”的混合模式。

性能问题?

  • :预训练模型加载慢、推理慢。
  • 解决:使用pipeline(..., device="cpu")指定设备,或对模型进行量化以减小体积、提升速度。对于高并发API,可以考虑模型预热和缓存。

附赠小技巧:情感词典可以自己扩充!收集你业务领域特定的情感词(比如游戏里的“爆肝”、“氪金”,职场里的“摸鱼”、“996”),加到分析逻辑里,识别准确率会立竿见影地提升。

后记AI的情感计算,其实没那么神秘

它的核心逻辑非常清晰:

  • 感知:识别用户的情绪(情感分析模块)。
  • 内化:管理AI自身的情绪状态(状态机)。
  • 表达:生成符合当前情绪的拟人化回应(响应生成)。

现在的开源工具(像Hugging Face Transformers)已经非常成熟,我们站在巨人的肩膀上,完全可以用不多的代码,搭建出体验不错的“共情”AI。

最后说个有意思的发现:在项目中加入这个情感模块后,用户满意度和对话时长真的有明显提升。虽然AI并没有真正的“情感”,但这种拟人化的、有温度的交互,确实让人更愿意和它聊下去。

技术栈总结:Python + Transformers (Hugging Face) + 情感状态机 + FastAPI。你也可以根据自己的需求,替换其中的任何一环。

最后要一波三连吧(点赞+关注+转发)~