告别空谈!手把手教你用LangChain构建"能干活"的垂直领域AI Agent

1. 项目概述与环境配置

1.1 项目目标

构建一个专门用于客服领域的AI Agent,能够理解用户查询、查询知识库、提供准确回答,并处理复杂的多轮对话。

1.2 环境准备

首先创建项目结构并安装必要的依赖包。

创建文件:requirements.txt

txt 复制代码
langchain==0.0.347
langchain-community==0.0.8
openai==1.3.0
chromadb==0.4.15
tiktoken==0.5.1
python-dotenv==1.0.0
faiss-cpu==1.7.4
streamlit==1.28.0
pypdf2==3.0.1
unstructured==0.10.30
sentence-transformers==2.2.2

创建文件:setup_environment.py

python 复制代码
import os
import subprocess
import sys

def setup_environment():
    """设置项目环境"""
    
    # 创建必要的目录
    directories = [
        "data",
        "knowledge_base", 
        "models",
        "logs",
        "outputs"
    ]
    
    for directory in directories:
        os.makedirs(directory, exist_ok=True)
        print(f"✓ 创建目录: {directory}")
    
    # 检查是否已安装依赖
    try:
        import langchain
        print("✓ LangChain 已安装")
    except ImportError:
        print("正在安装依赖包...")
        subprocess.check_call([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"])
        print("✓ 所有依赖包安装完成")
    
    # 创建环境变量文件模板
    env_template = """# OpenAI API 配置
OPENAI_API_KEY=your_openai_api_key_here

# 其他配置
MODEL_NAME=gpt-3.5-turbo
EMBEDDING_MODEL=text-embedding-ada-002

# 向量数据库配置
VECTOR_DB_PATH=./knowledge_base/vector_store

# 日志配置
LOG_LEVEL=INFO
"""
    
    if not os.path.exists(".env"):
        with open(".env", "w", encoding="utf-8") as f:
            f.write(env_template)
        print("✓ 已创建 .env 文件模板,请填写您的 API 密钥")
    
    print("\n🎉 环境设置完成!")
    print("请在 .env 文件中配置您的 OpenAI API 密钥")

if __name__ == "__main__":
    setup_environment()

运行环境设置脚本:

bash 复制代码
python setup_environment.py

2. 核心架构设计

以下是AI Agent的完整系统架构:

graph TD A[用户输入] --> B[输入处理器] B --> C[意图识别器] C --> D{意图分类} D -->|查询类| E[知识库检索] D -->|操作类| F[工具调用] D -->|聊天类| G[对话管理器] E --> H[向量数据库] H --> I[相关信息检索] F --> J[工具执行器] J --> K[API调用/计算] G --> L[对话记忆] I --> M[响应生成器] K --> M L --> M M --> N[输出格式化] N --> O[用户响应] style A fill:#4CAF50,stroke:#388E3C,color:white style O fill:#4CAF50,stroke:#388E3C,color:white style H fill:#2196F3,stroke:#1976D2,color:white style L fill:#FF9800,stroke:#F57C00,color:white style M fill:#9C27B0,stroke:#7B1FA2,color:white classDef default fill:#2E2E2E,stroke:#666,color:white; classDef process fill:#3F51B5,stroke:#303F9F,color:white; classDef data fill:#009688,stroke:#00796B,color:white; class B,C,D,E,F,G,J,M,N process; class H,L data;

创建文件:agent_architecture.py

python 复制代码
from typing import Dict, List, Any, Optional
from enum import Enum
import json

class AgentState(Enum):
    """代理状态枚举"""
    IDLE = "空闲"
    PROCESSING = "处理中"
    AWAITING_INPUT = "等待输入"
    ERROR = "错误"

class IntentType(Enum):
    """意图类型枚举"""
    QUERY = "查询"
    ACTION = "操作" 
    CHAT = "聊天"
    CLARIFICATION = "澄清"

class AgentArchitecture:
    """AI Agent 核心架构"""
    
    def __init__(self):
        self.components = {
            "input_processor": "输入处理器",
            "intent_recognizer": "意图识别器", 
            "knowledge_retriever": "知识检索器",
            "tool_executor": "工具执行器",
            "dialogue_manager": "对话管理器",
            "response_generator": "响应生成器",
            "memory_manager": "记忆管理器"
        }
        
        self.current_state = AgentState.IDLE
        self.conversation_history = []
    
    def get_architecture_info(self) -> Dict[str, Any]:
        """获取架构信息"""
        return {
            "components": self.components,
            "current_state": self.current_state.value,
            "active_components": len(self.components),
            "conversation_count": len(self.conversation_history)
        }
    
    def add_to_conversation(self, role: str, content: str):
        """添加对话记录"""
        self.conversation_history.append({
            "role": role,
            "content": content,
            "timestamp": self._get_timestamp()
        })
    
    def _get_timestamp(self) -> str:
        """获取时间戳"""
        from datetime import datetime
        return datetime.now().isoformat()
    
    def visualize_workflow(self) -> str:
        """生成工作流描述"""
        workflow = """
        AI Agent 工作流程:
        1. 📥 用户输入 → 输入处理器
        2. 🎯 意图识别 → 分类为查询/操作/聊天
        3. 🔍 知识检索 → 从向量数据库获取相关信息
        4. 🛠️ 工具执行 → 调用外部API或执行计算
        5. 💬 对话管理 → 维护对话上下文和记忆
        6. 🎨 响应生成 → 合成最终回答
        7. 📤 输出返回 → 格式化并返回给用户
        """
        return workflow

if __name__ == "__main__":
    architecture = AgentArchitecture()
    print(architecture.visualize_workflow())
    print("\n架构信息:", json.dumps(architecture.get_architecture_info(), indent=2, ensure_ascii=False))

3. 知识库构建

3.1 文档处理与向量化

创建文件:knowledge_base.py

python 复制代码
import os
import glob
from typing import List, Dict, Any
from langchain.schema import Document
from langchain.document_loaders import (
    PyPDFLoader,
    TextLoader,
    UnstructuredFileLoader
)
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
import logging

class KnowledgeBaseBuilder:
    """知识库构建器"""
    
    def __init__(self, persist_directory: str = "./knowledge_base/vector_store"):
        self.persist_directory = persist_directory
        self.embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
        self.vector_store = None
        self.setup_logging()
    
    def setup_logging(self):
        """设置日志"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('logs/knowledge_base.log'),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)
    
    def load_documents(self, data_directory: str) -> List[Document]:
        """加载文档"""
        supported_extensions = {
            '.pdf': PyPDFLoader,
            '.txt': TextLoader,
            '.md': TextLoader
        }
        
        all_documents = []
        
        for ext, loader_class in supported_extensions.items():
            file_pattern = os.path.join(data_directory, f"*{ext}")
            files = glob.glob(file_pattern)
            
            for file_path in files:
                try:
                    self.logger.info(f"正在加载文件: {file_path}")
                    loader = loader_class(file_path)
                    documents = loader.load()
                    all_documents.extend(documents)
                    self.logger.info(f"成功加载 {len(documents)} 个文档片段")
                except Exception as e:
                    self.logger.error(f"加载文件 {file_path} 时出错: {str(e)}")
        
        return all_documents
    
    def chunk_documents(self, documents: List[Document], 
                       chunk_size: int = 1000, 
                       chunk_overlap: int = 200) -> List[Document]:
        """文档分块"""
        text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=chunk_size,
            chunk_overlap=chunk_overlap,
            length_function=len,
            separators=["\n\n", "\n", "。", "!", "?", ";", ",", "、", " "]
        )
        
        chunks = text_splitter.split_documents(documents)
        self.logger.info(f"文档分块完成: 共 {len(chunks)} 个块")
        return chunks
    
    def create_vector_store(self, documents: List[Document]) -> Chroma:
        """创建向量存储"""
        self.logger.info("正在创建向量存储...")
        
        vector_store = Chroma.from_documents(
            documents=documents,
            embedding=self.embeddings,
            persist_directory=self.persist_directory
        )
        
        vector_store.persist()
        self.logger.info(f"向量存储创建完成,已保存到: {self.persist_directory}")
        return vector_store
    
    def build_knowledge_base(self, data_directory: str) -> Chroma:
        """构建完整知识库"""
        self.logger.info("开始构建知识库...")
        
        # 加载文档
        documents = self.load_documents(data_directory)
        if not documents:
            raise ValueError(f"在目录 {data_directory} 中未找到支持的文档")
        
        # 文档分块
        chunks = self.chunk_documents(documents)
        
        # 创建向量存储
        self.vector_store = self.create_vector_store(chunks)
        
        # 统计信息
        self._print_statistics(chunks)
        
        return self.vector_store
    
    def _print_statistics(self, chunks: List[Document]):
        """打印统计信息"""
        total_chars = sum(len(chunk.page_content) for chunk in chunks)
        avg_chunk_size = total_chars / len(chunks) if chunks else 0
        
        print("\n" + "="*50)
        print("📊 知识库构建统计")
        print("="*50)
        print(f"文档块数量: {len(chunks)}")
        print(f"总字符数: {total_chars}")
        print(f"平均块大小: {avg_chunk_size:.0f} 字符")
        print(f"向量存储路径: {self.persist_directory}")
        print("="*50)
    
    def query_knowledge_base(self, query: str, k: int = 5) -> List[Document]:
        """查询知识库"""
        if not self.vector_store:
            raise ValueError("知识库未初始化,请先调用 build_knowledge_base()")
        
        return self.vector_store.similarity_search(query, k=k)

# 示例数据创建
def create_sample_data():
    """创建示例数据"""
    sample_data = [
        {
            "file": "data/产品介绍.txt",
            "content": """产品名称: AI智能客服系统

核心功能:
1. 自动问答 - 基于知识库的智能问答系统
2. 意图识别 - 准确识别用户意图和需求
3. 多轮对话 - 支持复杂的上下文对话管理
4. 情感分析 - 识别用户情绪并提供相应服务

技术特点:
- 采用最先进的Transformer架构
- 支持中英文混合对话
- 响应时间小于2秒
- 准确率达到95%以上

适用场景:
• 电商客服
• 技术支持
• 业务咨询
• 售后支持

定价方案:
基础版: 999元/月
专业版: 1999元/月
企业版: 4999元/月"""
        },
        {
            "file": "data/使用指南.txt", 
            "content": """AI智能客服系统使用指南

快速开始:
1. 注册账号并登录系统
2. 上传您的产品文档和知识库
3. 配置客服工作流程和应答规则
4. 集成到您的网站或APP中

最佳实践:
• 定期更新知识库内容
• 设置常见问题模板
• 监控对话质量并优化
• 培训客服团队使用系统

故障排除:
问题1: 响应速度慢
解决方案: 检查网络连接,优化知识库大小

问题2: 回答不准确
解决方案: 补充相关知识,调整相似度阈值

技术支持:
电话: 400-123-4567
邮箱: support@example.com
工作时间: 周一至周五 9:00-18:00"""
        },
        {
            "file": "data/API文档.txt",
            "content": """AI智能客服系统 API 文档

基础信息:
API端点: https://api.example.com/v1/chat
认证方式: Bearer Token
数据格式: JSON

主要接口:
1. 对话接口
POST /v1/chat/message
请求参数:
{
  "message": "用户消息",
  "session_id": "会话ID",
  "user_id": "用户ID"
}

响应示例:
{
  "response": "AI回复内容",
  "session_id": "会话ID", 
  "timestamp": "2024-01-01T00:00:00Z"
}

2. 知识库管理接口
POST /v1/knowledge/upload
GET /v1/knowledge/search

3. 系统状态接口
GET /v1/system/status

错误代码:
200 - 成功
400 - 请求参数错误
401 - 认证失败
500 - 服务器内部错误

限流策略:
免费版: 1000次/天
付费版: 10000次/天"""
        }
    ]
    
    # 创建数据目录
    os.makedirs("data", exist_ok=True)
    
    # 写入示例文件
    for data in sample_data:
        with open(data["file"], "w", encoding="utf-8") as f:
            f.write(data["content"])
        print(f"✓ 创建示例文件: {data['file']}")

if __name__ == "__main__":
    # 创建示例数据
    create_sample_data()
    
    # 构建知识库
    kb_builder = KnowledgeBaseBuilder()
    vector_store = kb_builder.build_knowledge_base("data")
    
    # 测试查询
    test_queries = [
        "产品价格是多少?",
        "如何解决响应速度慢的问题?",
        "API认证方式是什么?"
    ]
    
    for query in test_queries:
        print(f"\n🔍 查询: {query}")
        results = kb_builder.query_knowledge_base(query, k=2)
        for i, doc in enumerate(results):
            print(f"结果 {i+1}: {doc.page_content[:100]}...")

4. 核心Agent实现

4.1 工具系统设计

创建文件:tools_system.py

python 复制代码
from typing import Dict, Any, List, Optional
from datetime import datetime, timedelta
import json
import requests
from langchain.tools import BaseTool
from langchain.agents import Tool
from pydantic import BaseModel, Field
import logging

class CalculatorInput(BaseModel):
    """计算器工具输入模型"""
    expression: str = Field(description="数学表达式,例如: 2 + 2 * 3")

class CalculatorTool(BaseTool):
    """自定义计算器工具"""
    name = "calculator"
    description = "用于执行数学计算,支持加减乘除和更复杂的表达式"
    args_schema = CalculatorInput
    
    def _run(self, expression: str) -> str:
        """执行计算"""
        try:
            # 简单的表达式求值(生产环境应该使用更安全的方式)
            allowed_chars = set('0123456789+-*/.() ')
            if not all(c in allowed_chars for c in expression):
                return "错误: 表达式包含不安全字符"
            
            result = eval(expression)
            return f"计算结果: {expression} = {result}"
        except Exception as e:
            return f"计算错误: {str(e)}"

class WeatherInput(BaseModel):
    """天气查询工具输入模型"""
    city: str = Field(description="城市名称,例如: 北京")

class WeatherTool(BaseTool):
    """天气查询工具"""
    name = "weather_query"
    description = "查询指定城市的天气信息"
    args_schema = WeatherInput
    
    def _run(self, city: str) -> str:
        """查询天气"""
        try:
            # 这里使用模拟数据,实际应用中应该调用天气API
            weather_data = {
                "北京": {"temperature": "25°C", "condition": "晴朗", "humidity": "45%"},
                "上海": {"temperature": "28°C", "condition": "多云", "humidity": "65%"},
                "广州": {"temperature": "32°C", "condition": "阵雨", "humidity": "75%"},
                "深圳": {"temperature": "30°C", "condition": "阴天", "humidity": "70%"}
            }
            
            if city in weather_data:
                data = weather_data[city]
                return f"{city}天气: 温度{data['temperature']}, {data['condition']}, 湿度{data['humidity']}"
            else:
                return f"未找到城市 {city} 的天气信息"
        except Exception as e:
            return f"天气查询失败: {str(e)}"

class KnowledgeQueryInput(BaseModel):
    """知识库查询工具输入模型"""
    query: str = Field(description="要查询的问题或关键词")

class KnowledgeQueryTool(BaseTool):
    """知识库查询工具"""
    name = "knowledge_query"
    description = "从知识库中查询相关信息"
    args_schema = KnowledgeQueryInput
    
    def __init__(self, knowledge_base):
        super().__init__()
        self.knowledge_base = knowledge_base
    
    def _run(self, query: str) -> str:
        """查询知识库"""
        try:
            results = self.knowledge_base.query_knowledge_base(query, k=3)
            if not results:
                return "在知识库中未找到相关信息"
            
            response = "根据知识库内容,找到以下相关信息:\n\n"
            for i, doc in enumerate(results, 1):
                response += f"{i}. {doc.page_content}\n\n"
            
            return response
        except Exception as e:
            return f"知识库查询失败: {str(e)}"

class SystemStatusTool(BaseTool):
    """系统状态工具"""
    name = "system_status"
    description = "检查系统当前状态和运行信息"
    
    def _run(self) -> str:
        """获取系统状态"""
        import psutil
        import platform
        
        # 系统信息
        system_info = {
            "系统类型": platform.system(),
            "处理器": platform.processor(),
            "Python版本": platform.python_version(),
        }
        
        # 内存使用
        memory = psutil.virtual_memory()
        memory_info = {
            "总内存": f"{memory.total // (1024**3)}GB",
            "已使用": f"{memory.percent}%",
            "可用内存": f"{memory.available // (1024**3)}GB"
        }
        
        # CPU使用
        cpu_info = {
            "CPU使用率": f"{psutil.cpu_percent()}%",
            "CPU核心数": psutil.cpu_count()
        }
        
        status_report = "📊 系统状态报告\n\n"
        status_report += "系统信息:\n" + "\n".join([f"  • {k}: {v}" for k, v in system_info.items()]) + "\n\n"
        status_report += "内存使用:\n" + "\n".join([f"  • {k}: {v}" for k, v in memory_info.items()]) + "\n\n"
        status_report += "CPU信息:\n" + "\n".join([f"  • {k}: {v}" for k, v in cpu_info.items()])
        
        return status_report

class ToolManager:
    """工具管理器"""
    
    def __init__(self, knowledge_base=None):
        self.tools = {}
        self.knowledge_base = knowledge_base
        self.setup_tools()
    
    def setup_tools(self):
        """设置所有可用工具"""
        # 计算器工具
        self.tools["calculator"] = CalculatorTool()
        
        # 天气查询工具
        self.tools["weather"] = WeatherTool()
        
        # 知识库查询工具
        if self.knowledge_base:
            self.tools["knowledge"] = KnowledgeQueryTool(self.knowledge_base)
        
        # 系统状态工具
        self.tools["system_status"] = SystemStatusTool()
    
    def get_tool_names(self) -> List[str]:
        """获取所有工具名称"""
        return list(self.tools.keys())
    
    def get_tool_descriptions(self) -> str:
        """获取工具描述"""
        descriptions = []
        for name, tool in self.tools.items():
            descriptions.append(f"• {name}: {tool.description}")
        return "\n".join(descriptions)
    
    def execute_tool(self, tool_name: str, **kwargs) -> str:
        """执行指定工具"""
        if tool_name not in self.tools:
            return f"错误: 工具 '{tool_name}' 不存在"
        
        try:
            tool = self.tools[tool_name]
            return tool.run(kwargs)
        except Exception as e:
            return f"工具执行错误: {str(e)}"

# 测试工具系统
if __name__ == "__main__":
    # 创建工具管理器
    tool_manager = ToolManager()
    
    # 测试各个工具
    test_cases = [
        ("calculator", {"expression": "2 + 3 * 4"}),
        ("weather", {"city": "北京"}),
        ("system_status", {})
    ]
    
    print("🛠️ 工具系统测试")
    print("=" * 50)
    
    for tool_name, args in test_cases:
        print(f"\n测试工具: {tool_name}")
        print(f"参数: {args}")
        result = tool_manager.execute_tool(tool_name, **args)
        print(f"结果: {result}")
        print("-" * 50)
    
    print(f"\n可用工具: {', '.join(tool_manager.get_tool_names())}")

4.2 智能Agent核心

创建文件:smart_agent.py

python 复制代码
import os
from typing import Dict, List, Any, Optional
from datetime import datetime
import json
from dotenv import load_dotenv

from langchain.agents import AgentType, initialize_agent
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferWindowMemory
from langchain.schema import SystemMessage, HumanMessage, AIMessage
from langchain.callbacks.base import BaseCallbackHandler
import logging

# 加载环境变量
load_dotenv()

class CustomCallbackHandler(BaseCallbackHandler):
    """自定义回调处理器"""
    
    def __init__(self):
        self.actions = []
    
    def on_agent_action(self, action, **kwargs):
        """代理动作回调"""
        self.actions.append({
            "type": "agent_action",
            "action": action,
            "timestamp": datetime.now().isoformat()
        })
    
    def on_tool_start(self, serialized, input_str, **kwargs):
        """工具开始回调"""
        self.actions.append({
            "type": "tool_start",
            "tool": serialized.get('name', 'unknown'),
            "input": input_str,
            "timestamp": datetime.now().isoformat()
        })
    
    def on_tool_end(self, output, **kwargs):
        """工具结束回调"""
        self.actions.append({
            "type": "tool_end",
            "output": output,
            "timestamp": datetime.now().isoformat()
        })

class SmartAgent:
    """智能客服Agent"""
    
    def __init__(self, tools, knowledge_base=None):
        self.tools = tools
        self.knowledge_base = knowledge_base
        self.callback_handler = CustomCallbackHandler()
        self.setup_logging()
        self.initialize_agent()
    
    def setup_logging(self):
        """设置日志"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('logs/agent.log'),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)
    
    def initialize_agent(self):
        """初始化Agent"""
        # 初始化LLM
        self.llm = ChatOpenAI(
            model="gpt-3.5-turbo",
            temperature=0.1,
            streaming=False
        )
        
        # 初始化记忆系统
        self.memory = ConversationBufferWindowMemory(
            memory_key="chat_history",
            k=10,
            return_messages=True
        )
        
        # 系统提示词
        system_message = SystemMessage(content=self._get_system_prompt())
        
        # 初始化Agent
        self.agent = initialize_agent(
            tools=self.tools,
            llm=self.llm,
            agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,
            memory=self.memory,
            verbose=True,
            handle_parsing_errors=True,
            agent_kwargs={
                "system_message": system_message,
            }
        )
        
        self.logger.info("智能Agent初始化完成")
    
    def _get_system_prompt(self) -> str:
        """获取系统提示词"""
        return """你是一个专业的AI客服助手,专门帮助用户解决各种问题。

你的能力包括:
1. 回答关于产品和服务的相关问题
2. 使用计算器工具进行数学计算
3. 查询天气信息
4. 从知识库中检索准确信息
5. 检查系统状态

请遵循以下准则:
- 始终以友好、专业的态度回应
- 如果信息不足,请主动询问更多细节
- 对于复杂问题,可以分步骤解决
- 如果无法回答,请诚实地告知用户
- 尽量提供准确、有用的信息

请根据用户的问题选择合适的工具,并提供有帮助的回答。"""

    def process_query(self, user_input: str) -> Dict[str, Any]:
        """处理用户查询"""
        self.logger.info(f"处理用户查询: {user_input}")
        
        try:
            # 重置回调处理器
            self.callback_handler.actions = []
            
            # 执行Agent
            response = self.agent.run(
                input=user_input,
                callbacks=[self.callback_handler]
            )
            
            # 收集执行轨迹
            execution_trace = self._format_execution_trace()
            
            result = {
                "success": True,
                "response": response,
                "execution_trace": execution_trace,
                "timestamp": datetime.now().isoformat()
            }
            
            self.logger.info("查询处理完成")
            return result
            
        except Exception as e:
            error_msg = f"处理查询时出错: {str(e)}"
            self.logger.error(error_msg)
            
            return {
                "success": False,
                "response": "抱歉,处理您的请求时出现了问题。请稍后重试或联系技术支持。",
                "error": str(e),
                "timestamp": datetime.now().isoformat()
            }
    
    def _format_execution_trace(self) -> List[Dict[str, Any]]:
        """格式化执行轨迹"""
        trace = []
        for action in self.callback_handler.actions:
            if action['type'] == 'tool_start':
                trace.append({
                    "step": len(trace) + 1,
                    "action": "使用工具",
                    "tool": action['tool'],
                    "input": action['input']
                })
            elif action['type'] == 'tool_end':
                if trace and trace[-1]['action'] == "使用工具":
                    trace[-1]['output'] = action['output']
        
        return trace
    
    def get_conversation_history(self) -> List[Dict[str, str]]:
        """获取对话历史"""
        memory_dict = self.memory.load_memory_variables({})
        chat_history = memory_dict.get("chat_history", [])
        
        formatted_history = []
        for message in chat_history:
            if isinstance(message, HumanMessage):
                formatted_history.append({"role": "user", "content": message.content})
            elif isinstance(message, AIMessage):
                formatted_history.append({"role": "assistant", "content": message.content})
        
        return formatted_history
    
    def clear_memory(self):
        """清空记忆"""
        self.memory.clear()
        self.logger.info("对话记忆已清空")

class IntentRecognizer:
    """意图识别器"""
    
    def __init__(self):
        self.intent_patterns = {
            "product_query": ["价格", "多少钱", "费用", "套餐", "版本"],
            "technical_support": ["怎么", "如何", "教程", "指南", "帮助"],
            "weather_query": ["天气", "气温", "下雨", "温度"],
            "calculation": ["计算", "算一下", "等于多少", "+", "-", "*", "/"],
            "system_status": ["状态", "运行", "性能", "监控"]
        }
    
    def recognize_intent(self, text: str) -> str:
        """识别用户意图"""
        text_lower = text.lower()
        
        for intent, patterns in self.intent_patterns.items():
            for pattern in patterns:
                if pattern in text_lower:
                    return intent
        
        return "general_chat"

# 测试智能Agent
if __name__ == "__main__":
    # 首先需要构建知识库
    from knowledge_base import KnowledgeBaseBuilder
    
    print("🤖 初始化智能Agent...")
    
    # 构建知识库
    kb_builder = KnowledgeBaseBuilder()
    vector_store = kb_builder.build_knowledge_base("data")
    
    # 初始化工具
    from tools_system import ToolManager
    tool_manager = ToolManager(knowledge_base=kb_builder)
    
    # 创建Agent
    agent = SmartAgent(tools=list(tool_manager.tools.values()))
    
    # 测试对话
    test_queries = [
        "你们的产品有哪些版本?价格分别是多少?",
        "帮我计算一下 125 * 8 + 360 等于多少?",
        "北京的天气怎么样?",
        "系统当前状态如何?"
    ]
    
    print("\n🧪 开始测试对话")
    print("=" * 60)
    
    for query in test_queries:
        print(f"\n👤 用户: {query}")
        result = agent.process_query(query)
        
        if result["success"]:
            print(f"🤖 AI: {result['response']}")
            
            if result["execution_trace"]:
                print("\n执行轨迹:")
                for step in result["execution_trace"]:
                    print(f"  {step['step']}. {step['action']}: {step.get('tool', '')}")
                    if 'input' in step:
                        print(f"     输入: {step['input']}")
                    if 'output' in step:
                        print(f"     输出: {step['output'][:100]}...")
        else:
            print(f"❌ 错误: {result['error']}")
        
        print("-" * 60)
    
    # 显示对话历史
    print("\n📝 完整对话历史:")
    history = agent.get_conversation_history()
    for i, message in enumerate(history, 1):
        print(f"{i}. {message['role']}: {message['content'][:50]}...")

5. 用户界面与部署

5.1 Web界面实现

创建文件:web_interface.py

python 复制代码
import streamlit as st
import json
import sys
import os
from datetime import datetime
from typing import Dict, Any

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from smart_agent import SmartAgent, IntentRecognizer
from knowledge_base import KnowledgeBaseBuilder
from tools_system import ToolManager

class ChatInterface:
    """聊天界面类"""
    
    def __init__(self):
        self.setup_page_config()
        self.initialize_session_state()
        self.setup_sidebar()
    
    def setup_page_config(self):
        """设置页面配置"""
        st.set_page_config(
            page_title="AI智能客服系统",
            page_icon="🤖",
            layout="wide",
            initial_sidebar_state="expanded"
        )
    
    def initialize_session_state(self):
        """初始化会话状态"""
        if 'agent' not in st.session_state:
            st.session_state.agent = None
        if 'messages' not in st.session_state:
            st.session_state.messages = []
        if 'knowledge_base' not in st.session_state:
            st.session_state.knowledge_base = None
        if 'initialized' not in st.session_state:
            st.session_state.initialized = False
    
    def setup_sidebar(self):
        """设置侧边栏"""
        with st.sidebar:
            st.title("⚙️ 系统配置")
            
            # API密钥配置
            api_key = st.text_input(
                "OpenAI API密钥",
                type="password",
                help="请输入您的OpenAI API密钥",
                value=os.getenv("OPENAI_API_KEY", "")
            )
            
            if api_key:
                os.environ["OPENAI_API_KEY"] = api_key
            
            # 初始化按钮
            if st.button("🚀 初始化AI客服系统", use_container_width=True):
                self.initialize_system()
            
            st.divider()
            
            # 系统信息
            if st.session_state.initialized:
                st.success("✅ 系统已初始化")
                
                # 显示工具列表
                if st.session_state.agent:
                    st.subheader("🛠️ 可用工具")
                    for tool in st.session_state.agent.tools:
                        st.write(f"• {tool.name}: {tool.description}")
                
                # 清空对话按钮
                if st.button("🗑️ 清空对话历史", use_container_width=True):
                    st.session_state.messages = []
                    if st.session_state.agent:
                        st.session_state.agent.clear_memory()
                    st.rerun()
            else:
                st.warning("⚠️ 请先初始化系统")
            
            st.divider()
            
            # 使用说明
            st.subheader("💡 使用说明")
            st.markdown("""
            1. 输入OpenAI API密钥
            2. 点击初始化系统
            3. 在下方输入您的问题
            4. AI客服将为您提供帮助
            
            **支持的功能:**
            - 产品咨询
            - 技术问题解答  
            - 数学计算
            - 天气查询
            - 系统状态检查
            """)
    
    def initialize_system(self):
        """初始化系统"""
        try:
            with st.spinner("正在初始化系统,请稍候..."):
                # 构建知识库
                kb_builder = KnowledgeBaseBuilder()
                vector_store = kb_builder.build_knowledge_base("data")
                
                # 初始化工具管理器
                tool_manager = ToolManager(knowledge_base=kb_builder)
                
                # 创建智能Agent
                agent = SmartAgent(tools=list(tool_manager.tools.values()))
                
                # 保存到会话状态
                st.session_state.knowledge_base = kb_builder
                st.session_state.agent = agent
                st.session_state.initialized = True
            
            st.success("✅ 系统初始化完成!")
            
        except Exception as e:
            st.error(f"❌ 系统初始化失败: {str(e)}")
    
    def display_chat_messages(self):
        """显示聊天消息"""
        chat_container = st.container()
        
        with chat_container:
            for message in st.session_state.messages:
                with st.chat_message(message["role"]):
                    st.markdown(message["content"])
                    
                    # 显示执行轨迹
                    if message.get("execution_trace"):
                        with st.expander("🔍 查看执行过程"):
                            for step in message["execution_trace"]:
                                st.write(f"**步骤 {step['step']}**: {step['action']}")
                                if step.get('tool'):
                                    st.write(f"   工具: `{step['tool']}`")
                                if step.get('input'):
                                    st.write(f"   输入: `{step['input']}`")
                                if step.get('output'):
                                    st.write(f"   输出: {step['output'][:200]}...")
    
    def handle_user_input(self):
        """处理用户输入"""
        if prompt := st.chat_input("请输入您的问题..."):
            # 添加用户消息到界面
            st.session_state.messages.append({"role": "user", "content": prompt})
            st.chat_message("user").markdown(prompt)
            
            # 处理查询
            if st.session_state.agent:
                with st.chat_message("assistant"):
                    with st.spinner("正在思考..."):
                        result = st.session_state.agent.process_query(prompt)
                    
                    if result["success"]:
                        # 显示AI回复
                        st.markdown(result["response"])
                        
                        # 添加助手消息到会话状态
                        st.session_state.messages.append({
                            "role": "assistant",
                            "content": result["response"],
                            "execution_trace": result.get("execution_trace", [])
                        })
                    else:
                        error_msg = "抱歉,处理您的请求时出现了问题。"
                        st.error(error_msg)
                        st.session_state.messages.append({
                            "role": "assistant", 
                            "content": error_msg
                        })
            else:
                warning_msg = "系统未初始化,请先在侧边栏配置API密钥并初始化系统。"
                st.warning(warning_msg)
                st.session_state.messages.append({
                    "role": "assistant",
                    "content": warning_msg
                })
    
    def display_system_info(self):
        """显示系统信息"""
        if st.session_state.initialized and st.session_state.agent:
            with st.sidebar:
                st.divider()
                st.subheader("📊 系统信息")
                
                # 对话统计
                user_msgs = [m for m in st.session_state.messages if m["role"] == "user"]
                assistant_msgs = [m for m in st.session_state.messages if m["role"] == "assistant"]
                
                col1, col2 = st.columns(2)
                with col1:
                    st.metric("用户消息", len(user_msgs))
                with col2:
                    st.metric("AI回复", len(assistant_msgs))
                
                # 意图识别示例
                recognizer = IntentRecognizer()
                if user_msgs:
                    last_query = user_msgs[-1]["content"]
                    intent = recognizer.recognize_intent(last_query)
                    st.write(f"最后意图: `{intent}`")
    
    def run(self):
        """运行主界面"""
        st.title("🤖 AI智能客服系统")
        st.markdown("欢迎使用智能客服助手!我可以帮助您解答问题、查询信息、进行计算等。")
        
        # 显示系统信息
        self.display_system_info()
        
        # 显示聊天消息
        self.display_chat_messages()
        
        # 处理用户输入
        self.handle_user_input()

def main():
    """主函数"""
    interface = ChatInterface()
    interface.run()

if __name__ == "__main__":
    main()

5.2 部署脚本

创建文件:deploy.py

python 复制代码
import os
import sys
import subprocess
import logging
from typing import Dict, Any

class DeploymentManager:
    """部署管理器"""
    
    def __init__(self):
        self.setup_logging()
        self.requirements = [
            "langchain",
            "openai", 
            "chromadb",
            "streamlit",
            "python-dotenv",
            "faiss-cpu",
            "pypdf2",
            "unstructured",
            "sentence-transformers"
        ]
    
    def setup_logging(self):
        """设置日志"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('logs/deployment.log'),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)
    
    def check_environment(self) -> Dict[str, bool]:
        """检查环境"""
        self.logger.info("检查系统环境...")
        
        checks = {
            "python_version": sys.version_info >= (3, 8),
            "required_directories": all(os.path.exists(d) for d in ["data", "knowledge_base", "logs"]),
            "env_file": os.path.exists(".env"),
            "sample_data": any(os.path.exists(f"data/{f}") for f in os.listdir("data") if f.endswith('.txt'))
        }
        
        for check, result in checks.items():
            status = "✓" if result else "✗"
            self.logger.info(f"{status} {check}: {result}")
        
        return checks
    
    def install_dependencies(self):
        """安装依赖"""
        self.logger.info("安装项目依赖...")
        
        for package in self.requirements:
            try:
                subprocess.check_call([
                    sys.executable, "-m", "pip", "install", package
                ])
                self.logger.info(f"✓ 安装成功: {package}")
            except subprocess.CalledProcessError as e:
                self.logger.error(f"✗ 安装失败: {package}, 错误: {e}")
    
    def setup_sample_data(self):
        """设置示例数据"""
        self.logger.info("设置示例数据...")
        
        # 从knowledge_base导入示例数据创建函数
        from knowledge_base import create_sample_data
        
        try:
            create_sample_data()
            self.logger.info("✓ 示例数据创建成功")
        except Exception as e:
            self.logger.error(f"✗ 示例数据创建失败: {e}")
    
    def build_knowledge_base(self):
        """构建知识库"""
        self.logger.info("构建知识库...")
        
        try:
            from knowledge_base import KnowledgeBaseBuilder
            
            kb_builder = KnowledgeBaseBuilder()
            vector_store = kb_builder.build_knowledge_base("data")
            self.logger.info("✓ 知识库构建成功")
            return True
        except Exception as e:
            self.logger.error(f"✗ 知识库构建失败: {e}")
            return False
    
    def test_system(self):
        """测试系统"""
        self.logger.info("运行系统测试...")
        
        try:
            # 测试知识库查询
            from knowledge_base import KnowledgeBaseBuilder
            kb_builder = KnowledgeBaseBuilder()
            results = kb_builder.query_knowledge_base("产品价格", k=1)
            
            if results:
                self.logger.info("✓ 知识库查询测试通过")
            else:
                self.logger.warning("⚠ 知识库查询返回空结果")
            
            # 测试工具系统
            from tools_system import ToolManager
            tool_manager = ToolManager()
            
            test_result = tool_manager.execute_tool("calculator", expression="2+2")
            if "4" in test_result:
                self.logger.info("✓ 工具系统测试通过")
            else:
                self.logger.error("✗ 工具系统测试失败")
            
            self.logger.info("✓ 系统测试完成")
            return True
            
        except Exception as e:
            self.logger.error(f"✗ 系统测试失败: {e}")
            return False
    
    def create_startup_script(self):
        """创建启动脚本"""
        self.logger.info("创建启动脚本...")
        
        scripts = {
            "start_app.bat": """
@echo off
echo 启动AI客服系统...
streamlit run web_interface.py
pause
""",
            "start_app.sh": """
#!/bin/bash
echo "启动AI客服系统..."
streamlit run web_interface.py
"""
        }
        
        for filename, content in scripts.items():
            with open(filename, "w", encoding="utf-8") as f:
                f.write(content.strip())
            
            if filename.endswith(".sh"):
                os.chmod(filename, 0o755)
            
            self.logger.info(f"✓ 创建启动脚本: {filename}")
    
    def deployment_report(self) -> Dict[str, Any]:
        """生成部署报告"""
        checks = self.check_environment()
        
        report = {
            "timestamp": self._get_timestamp(),
            "environment_checks": checks,
            "python_version": sys.version,
            "system_platform": sys.platform,
            "required_packages": self.requirements,
            "deployment_status": all(checks.values())
        }
        
        return report
    
    def _get_timestamp(self):
        """获取时间戳"""
        from datetime import datetime
        return datetime.now().isoformat()
    
    def run_deployment(self):
        """运行完整部署流程"""
        self.logger.info("开始部署AI客服系统...")
        
        # 环境检查
        environment_ok = all(self.check_environment().values())
        if not environment_ok:
            self.logger.warning("环境检查未通过,尝试自动修复...")
            self.install_dependencies()
            self.setup_sample_data()
        
        # 构建知识库
        kb_success = self.build_knowledge_base()
        
        # 系统测试
        test_success = self.test_system()
        
        # 创建启动脚本
        self.create_startup_script()
        
        # 生成报告
        report = self.deployment_report()
        
        self.logger.info("\n" + "="*50)
        self.logger.info("🏁 部署完成!")
        self.logger.info("="*50)
        
        if kb_success and test_success:
            self.logger.info("✅ 所有组件部署成功!")
            self.logger.info("\n🚀 启动命令:")
            self.logger.info("   streamlit run web_interface.py")
            self.logger.info("   或双击 start_app.bat (Windows)")
            self.logger.info("   或运行 ./start_app.sh (Linux/Mac)")
        else:
            self.logger.warning("⚠️ 部分组件部署有问题,请检查日志")
        
        self.logger.info(f"\n📊 部署报告已保存到: logs/deployment.log")
        
        return report

def main():
    """主部署函数"""
    deployer = DeploymentManager()
    report = deployer.run_deployment()
    
    # 保存详细报告
    import json
    with open("logs/deployment_report.json", "w", encoding="utf-8") as f:
        json.dump(report, f, indent=2, ensure_ascii=False)
    
    print("\n📋 部署摘要:")
    print(f"系统平台: {report['system_platform']}")
    print(f"Python版本: {report['python_version']}")
    print(f"部署状态: {'成功' if report['deployment_status'] else '部分成功'}")
    print(f"环境检查: {sum(report['environment_checks'].values())}/{len(report['environment_checks'])} 通过")

if __name__ == "__main__":
    main()

6. 运行与测试

6.1 完整系统启动

运行部署脚本来自动设置整个系统:

bash 复制代码
python deploy.py

然后启动Web界面:

bash 复制代码
streamlit run web_interface.py

6.2 系统测试脚本

创建文件:test_system.py

python 复制代码
import unittest
import os
import sys
from knowledge_base import KnowledgeBaseBuilder, create_sample_data
from tools_system import ToolManager
from smart_agent import SmartAgent, IntentRecognizer

class TestKnowledgeBase(unittest.TestCase):
    """知识库测试"""
    
    def setUp(self):
        """测试前准备"""
        create_sample_data()
        self.kb_builder = KnowledgeBaseBuilder()
        self.vector_store = self.kb_builder.build_knowledge_base("data")
    
    def test_query_knowledge_base(self):
        """测试知识库查询"""
        results = self.kb_builder.query_knowledge_base("产品价格", k=2)
        self.assertGreater(len(results), 0, "知识库查询应该返回结果")
        
        # 检查结果内容
        content = " ".join([doc.page_content for doc in results])
        self.assertIn("价格", content, "查询结果应该包含价格信息")

class TestToolsSystem(unittest.TestCase):
    """工具系统测试"""
    
    def setUp(self):
        """测试前准备"""
        self.tool_manager = ToolManager()
    
    def test_calculator_tool(self):
        """测试计算器工具"""
        result = self.tool_manager.execute_tool("calculator", expression="2 + 3 * 4")
        self.assertIn("14", result, "计算器应该正确计算表达式")
    
    def test_weather_tool(self):
        """测试天气工具"""
        result = self.tool_manager.execute_tool("weather", city="北京")
        self.assertIn("北京", result, "天气查询应该包含城市名称")
        self.assertIn("温度", result, "天气查询应该包含温度信息")

class TestIntentRecognizer(unittest.TestCase):
    """意图识别测试"""
    
    def setUp(self):
        """测试前准备"""
        self.recognizer = IntentRecognizer()
    
    def test_product_intent(self):
        """测试产品查询意图"""
        intent = self.recognizer.recognize_intent("这个产品多少钱?")
        self.assertEqual(intent, "product_query", "应该识别为产品查询意图")
    
    def test_weather_intent(self):
        """测试天气查询意图"""
        intent = self.recognizer.recognize_intent("今天天气怎么样")
        self.assertEqual(intent, "weather_query", "应该识别为天气查询意图")

class TestSmartAgent(unittest.TestCase):
    """智能Agent测试"""
    
    def setUp(self):
        """测试前准备"""
        create_sample_data()
        kb_builder = KnowledgeBaseBuilder()
        vector_store = kb_builder.build_knowledge_base("data")
        
        tool_manager = ToolManager(knowledge_base=kb_builder)
        self.agent = SmartAgent(tools=list(tool_manager.tools.values()))
    
    def test_agent_initialization(self):
        """测试Agent初始化"""
        self.assertIsNotNone(self.agent.agent, "Agent应该成功初始化")
        self.assertIsNotNone(self.agent.llm, "LLM应该成功初始化")
    
    def test_simple_query(self):
        """测试简单查询"""
        result = self.agent.process_query("你好,请介绍一下你自己")
        self.assertTrue(result["success"], "查询应该成功处理")
        self.assertIsInstance(result["response"], str, "响应应该是字符串")
        self.assertGreater(len(result["response"]), 10, "响应应该有合理长度")

def run_performance_test():
    """运行性能测试"""
    import time
    
    print("🚀 开始性能测试...")
    
    # 初始化系统
    create_sample_data()
    kb_builder = KnowledgeBaseBuilder()
    vector_store = kb_builder.build_knowledge_base("data")
    tool_manager = ToolManager(knowledge_base=kb_builder)
    agent = SmartAgent(tools=list(tool_manager.tools.values()))
    
    # 测试查询
    test_queries = [
        "产品价格是多少?",
        "帮我计算 123 * 456",
        "北京的天气如何?",
        "系统状态怎么样?"
    ]
    
    response_times = []
    
    for query in test_queries:
        start_time = time.time()
        result = agent.process_query(query)
        end_time = time.time()
        
        response_time = end_time - start_time
        response_times.append(response_time)
        
        status = "✓" if result["success"] else "✗"
        print(f"{status} 查询: '{query}'")
        print(f"   响应时间: {response_time:.2f}秒")
        print(f"   响应长度: {len(result['response'])}字符")
    
    avg_response_time = sum(response_times) / len(response_times)
    print(f"\n📊 平均响应时间: {avg_response_time:.2f}秒")
    print(f"📊 最短响应时间: {min(response_times):.2f}秒")
    print(f"📊 最长响应时间: {max(response_times):.2f}秒")

if __name__ == "__main__":
    # 运行单元测试
    print("🧪 运行单元测试...")
    unittest.main(exit=False)
    
    # 运行性能测试
    print("\n" + "="*50)
    run_performance_test()
    
    print("\n🎉 所有测试完成!")

7. 项目总结与扩展

7.1 项目结构总览

bash 复制代码
ai-customer-service/
├── 📁 data/                    # 知识库文档
├── 📁 knowledge_base/          # 向量数据库
├── 📁 logs/                    # 日志文件
├── 📁 outputs/                 # 输出文件
├── 📄 requirements.txt         # 依赖包列表
├── 📄 setup_environment.py    # 环境设置
├── 📄 knowledge_base.py       # 知识库构建
├── 📄 tools_system.py         # 工具系统
├── 📄 smart_agent.py          # 智能Agent
├── 📄 web_interface.py        # Web界面
├── 📄 deploy.py               # 部署脚本
└── 📄 test_system.py          # 测试脚本

7.2 扩展建议

  1. 数据库集成: 添加MySQL/PostgreSQL支持持久化存储
  2. 多模型支持: 集成更多LLM如Claude、文心一言等
  3. 监控系统: 添加Prometheus + Grafana监控
  4. 用户认证: 添加用户登录和权限管理
  5. API服务: 提供RESTful API接口
  6. 移动端: 开发手机APP版本

这个完整的AI Agent系统具备了知识库检索、工具调用、对话管理、Web界面等完整功能。您可以根据具体业务需求进一步定制和扩展。

相关推荐
想你依然心痛2 小时前
视界无界:基于Rokid眼镜的AI商务同传系统开发与实践
人工智能·智能硬件·rokid·ai眼镜·ar技术
Learn Beyond Limits2 小时前
Data Preprocessing|数据预处理
大数据·人工智能·python·ai·数据挖掘·数据处理
shmexon2 小时前
上海兆越亮相无锡新能源盛会,以硬核通信科技赋能“能碳未来”
网络·人工智能
ziwu2 小时前
【宠物识别系统】Python+TensorFlow+Vue3+Django+人工智能+深度学习+卷积神经网络算法
人工智能·深度学习·图像识别
北京耐用通信3 小时前
告别“牵一发而动全身”:耐达讯自动化Profibus PA分线器为石化流量计网络构筑安全屏障
人工智能·网络协议·安全·自动化·信息与通信
ziwu3 小时前
海洋生物识别系统【最新版】Python+TensorFlow+Vue3+Django+人工智能+深度学习+卷积神经网络算法
人工智能·深度学习·图像识别
luoganttcc3 小时前
RoboTron-Drive:自动驾驶领域的全能多模态大模型
人工智能·机器学习·自动驾驶
向阳逐梦4 小时前
DC-DC Buck 电路(降压转换器)全面解析
人工智能·算法
xcLeigh4 小时前
AI的提示词专栏:“Prompt Chaining”把多个 Prompt 串联成工作流
人工智能·ai·prompt·提示词·工作流