构建基于WxAuto+LangChain+数据库的微信AI助手(有需要微信作为小助手的可以私聊我,不封号)

构建基于WxAuto+LangChain+数据库的微信AI助手

我将指导你如何使用WxAuto、LangChain和数据库构建一个微信AI助手。这个助手能够自动回复微信消息,并利用LangChain的AI能力和数据库存储对话历史。

系统架构

微信客户端 → WxAuto(监听消息) → LangChain(处理AI回复) → 数据库(存储历史) → 返回回复 → WxAuto(发送消息)

所需工具和库

pip install wxauto langchain openai chromadb sqlite3 pydantic

完整实现代码

import sqlite3
import json
from datetime import datetime
from typing import List, Dict, Any
from wxauto import WeChat
from langchain.chains import ConversationChain
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferWindowMemory
from langchain.schema import BaseMemory
from langchain.prompts import PromptTemplate
import time
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger("WeChatAIAssistant")

class DatabaseManager:
    """数据库管理类,用于存储和检索对话历史"""
    
    def __init__(self, db_path: str = "wechat_assistant.db"):
        self.db_path = db_path
        self.init_database()
    
    def init_database(self):
        """初始化数据库表"""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        
        # 创建对话历史表
        cursor.execute('''
        CREATE TABLE IF NOT EXISTS conversations (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            wxid TEXT NOT NULL,
            sender TEXT NOT NULL,
            message TEXT NOT NULL,
            response TEXT NOT NULL,
            timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
        )
        ''')
        
        # 创建用户信息表
        cursor.execute('''
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            wxid TEXT UNIQUE NOT NULL,
            name TEXT,
            last_interaction DATETIME,
            custom_context TEXT
        )
        ''')
        
        conn.commit()
        conn.close()
    
    def save_conversation(self, wxid: str, sender: str, message: str, response: str):
        """保存对话记录"""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        
        cursor.execute(
            "INSERT INTO conversations (wxid, sender, message, response) VALUES (?, ?, ?, ?)",
            (wxid, sender, message, response)
        )
        
        # 更新用户最后交互时间
        cursor.execute(
            "INSERT OR REPLACE INTO users (wxid, last_interaction) VALUES (?, ?)",
            (wxid, datetime.now())
        )
        
        conn.commit()
        conn.close()
    
    def get_conversation_history(self, wxid: str, limit: int = 10) -> List[Dict]:
        """获取用户对话历史"""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        
        cursor.execute(
            "SELECT sender, message, response, timestamp FROM conversations WHERE wxid = ? ORDER BY timestamp DESC LIMIT ?",
            (wxid, limit)
        )
        
        history = []
        for row in cursor.fetchall():
            history.append({
                "sender": row[0],
                "message": row[1],
                "response": row[2],
                "timestamp": row[3]
            })
        
        conn.close()
        return history[::-1]  # 返回正序的历史记录

class DatabaseEnhancedMemory(BaseMemory):
    """增强的内存类,结合数据库和LangChain内存"""
    
    def __init__(self, db_manager: DatabaseManager, memory_key: str = "history", k: int = 5):
        self.db_manager = db_manager
        self.memory = ConversationBufferWindowMemory(k=k, memory_key=memory_key)
        self.memory_key = memory_key
    
    @property
    def memory_variables(self) -> List[str]:
        return [self.memory_key]
    
    def load_memory_variables(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
        wxid = inputs.get("wxid", "unknown")
        
        # 从数据库获取历史记录
        db_history = self.db_manager.get_conversation_history(wxid, limit=10)
        
        # 将历史记录转换为LangChain内存格式
        for record in db_history:
            if record["sender"] == "user":
                self.memory.save_context(
                    {"input": record["message"]},
                    {"output": record["response"]}
                )
        
        return self.memory.load_memory_variables(inputs)
    
    def save_context(self, inputs: Dict[str, Any], outputs: Dict[str, str]):
        # 保存到LangChain内存
        self.memory.save_context(inputs, outputs)
        
        # 保存到数据库
        wxid = inputs.get("wxid", "unknown")
        message = inputs.get("input", "")
        response = outputs.get("output", "")
        
        if wxid != "unknown" and message and response:
            self.db_manager.save_conversation(wxid, "user", message, response)

class WeChatAIAssistant:
    """微信AI助手主类"""
    
    def __init__(self, openai_api_key: str):
        self.wx = WeChat()
        self.db_manager = DatabaseManager()
        
        # 初始化LangChain组件
        self.llm = ChatOpenAI(
            model_name="gpt-3.5-turbo",
            openai_api_key=openai_api_key,
            temperature=0.7
        )
        
        # 创建自定义记忆
        self.memory = DatabaseEnhancedMemory(self.db_manager, k=5)
        
        # 自定义提示模板
        template = """你是一个有用的微信AI助手,与用户进行友好、自然的对话。
        
        当前对话历史:
        {history}
        
        用户: {input}
        助手:"""
        
        self.prompt = PromptTemplate(
            input_variables=["history", "input"],
            template=template
        )
        
        # 创建对话链
        self.conversation = ConversationChain(
            llm=self.llm,
            memory=self.memory,
            prompt=self.prompt,
            verbose=True
        )
        
        logger.info("微信AI助手初始化完成")
    
    def process_message(self, message: str, wxid: str, sender: str) -> str:
        """处理消息并生成回复"""
        try:
            # 添加wxid到输入中,供内存系统使用
            inputs = {"input": message, "wxid": wxid}
            
            # 生成回复
            response = self.conversation.predict(**inputs)
            
            # 保存到数据库
            self.db_manager.save_conversation(wxid, sender, message, response)
            
            return response
        except Exception as e:
            logger.error(f"处理消息时出错: {e}")
            return "抱歉,我暂时无法处理您的消息。"
    
    def start_listening(self, check_interval: int = 2):
        """开始监听微信消息"""
        logger.info("开始监听微信消息...")
        
        # 获取当前最新消息作为起始点
        last_msg = self.wx.GetLastMessage()
        
        while True:
            try:
                # 获取最新消息
                current_msg = self.wx.GetLastMessage()
                
                # 检查是否有新消息
                if current_msg != last_msg:
                    last_msg = current_msg
                    
                    # 解析消息
                    msg_info = self.wx.GetAllMessage(last_msg)
                    message = msg_info['message']
                    sender = msg_info['sender']
                    wxid = f"wxid_{hash(sender)}"  # 生成简易用户ID
                    
                    logger.info(f"收到新消息 - 发送人: {sender}, 内容: {message}")
                    
                    # 处理非自己发送的消息
                    if sender != self.wx.GetSessionList()[0]:  # 假设第一个会话是自己
                        # 生成回复
                        response = self.process_message(message, wxid, sender)
                        
                        # 发送回复
                        self.wx.SendMsg(response)
                        
                        logger.info(f"已发送回复: {response}")
                
                time.sleep(check_interval)
                
            except Exception as e:
                logger.error(f"监听过程中出错: {e}")
                time.sleep(5)  # 出错后等待5秒再继续

# 使用示例
if __name__ == "__main__":
    # 替换为你的OpenAI API密钥
    OPENAI_API_KEY = "your-openai-api-key-here"
    
    # 创建并启动助手
    assistant = WeChatAIAssistant(OPENAI_API_KEY)
    
    # 开始监听消息
    assistant.start_listening()

高级功能扩展

1. 添加用户上下文管理

class UserContextManager:
    """用户上下文管理器"""
    
    def __init__(self, db_manager: DatabaseManager):
        self.db_manager = db_manager
    
    def get_user_context(self, wxid: str) -> Dict:
        """获取用户上下文"""
        conn = sqlite3.connect(self.db_manager.db_path)
        cursor = conn.cursor()
        
        cursor.execute(
            "SELECT custom_context FROM users WHERE wxid = ?",
            (wxid,)
        )
        
        result = cursor.fetchone()
        conn.close()
        
        if result and result[0]:
            return json.loads(result[0])
        return {}
    
    def update_user_context(self, wxid: str, context: Dict):
        """更新用户上下文"""
        conn = sqlite3.connect(self.db_manager.db_path)
        cursor = conn.cursor()
        
        cursor.execute(
            "UPDATE users SET custom_context = ? WHERE wxid = ?",
            (json.dumps(context), wxid)
        )
        
        conn.commit()
        conn.close()

2. 添加命令系统

class CommandSystem:
    """命令处理系统"""
    
    def __init__(self, assistant: WeChatAIAssistant):
        self.assistant = assistant
        self.commands = {
            "/help": self.handle_help,
            "/clear": self.handle_clear,
            "/history": self.handle_history
        }
    
    def is_command(self, message: str) -> bool:
        """检查是否是命令"""
        return message.startswith('/')
    
    def handle_command(self, message: str, wxid: str, sender: str) -> str:
        """处理命令"""
        command = message.split()[0]
        handler = self.commands.get(command)
        
        if handler:
            return handler(message, wxid, sender)
        return "未知命令,输入 /help 查看可用命令"
    
    def handle_help(self, message: str, wxid: str, sender: str) -> str:
        """帮助命令"""
        help_text = """
        可用命令:
        /help - 显示帮助信息
        /clear - 清除对话历史
        /history - 查看最近对话
        """
        return help_text
    
    def handle_clear(self, message: str, wxid: str, sender: str) -> str:
        """清除历史命令"""
        # 这里可以实现清除数据库中的对话历史
        return "对话历史已清除"
    
    def handle_history(self, message: str, wxid: str, sender: str) -> str:
        """查看历史命令"""
        history = self.assistant.db_manager.get_conversation_history(wxid, limit=5)
        if not history:
            return "暂无对话历史"
        
        history_text = "最近对话:\n"
        for i, record in enumerate(history, 1):
            history_text += f"{i}. {record['message']} -> {record['response']}\n"
        
        return history_text

部署和使用说明

  1. 安装依赖

    pip install -r requirements.txt
  2. 配置API密钥
    在代码中替换your-openai-api-key-here为你的实际OpenAI API密钥

  3. 运行程序

    python wechat_assistant.py
  4. 确保微信客户端已登录并保持在前台

注意事项

  1. 微信版本兼容性:WxAuto可能不兼容所有微信版本,建议使用较新的微信PC版

  2. 性能考虑:频繁的消息检查可能会占用系统资源,适当调整检查间隔

  3. 隐私保护:确保妥善处理用户数据,遵守相关隐私法规

  4. 错误处理:添加适当的错误处理机制,避免程序因异常崩溃

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值