构建基于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
部署和使用说明
-
安装依赖:
pip install -r requirements.txt
-
配置API密钥:
在代码中替换your-openai-api-key-here为你的实际OpenAI API密钥 -
运行程序:
python wechat_assistant.py
-
确保微信客户端已登录并保持在前台
注意事项
-
微信版本兼容性:WxAuto可能不兼容所有微信版本,建议使用较新的微信PC版
-
性能考虑:频繁的消息检查可能会占用系统资源,适当调整检查间隔
-
隐私保护:确保妥善处理用户数据,遵守相关隐私法规
-
错误处理:添加适当的错误处理机制,避免程序因异常崩溃

被折叠的 条评论
为什么被折叠?



