LangChain 1.3实战:Agentic RAG架构设计与文档问答系统构建

发布时间:2026/7/14 3:19:02

LangChain 1.3实战:Agentic RAG架构设计与文档问答系统构建 如果你正在学习LangChain可能会遇到这样的困惑看了很多教程代码也能跑起来但一到实际项目就不知道如何下手。特别是面对Agent、RAG这些概念时总觉得理解不够深入无法灵活应用到自己的项目中。这其实不是你的问题。很多LangChain教程只停留在表面API调用没有深入到架构设计和实战场景。本文将带你从根本原理出发通过完整的项目实战掌握LangChain 1.3的核心能力特别是Agent智能体和RAG系统的深度集成。1. 这篇文章真正要解决的问题传统LangChain教程存在三个主要问题一是过分关注API调用而忽视架构设计二是缺乏真实的项目场景三是没有深入Agent和RAG的协同工作机制。本文将从工程实践角度解决以下核心问题架构理解深度不足大多数教程只教你怎么调用LangChain的API但没有解释为什么这样设计。比如Agent的决策机制、RAG的检索优化策略、子Agent的协同原理等。项目实战缺失学完基础概念后面对真实业务需求仍然无从下手。本文将构建一个完整的文档问答系统涵盖从数据准备到生产部署的全流程。版本兼容性挑战LangChain更新频繁很多1.0版本的代码在1.3中已经失效。本文基于最新的1.3版本确保代码的长期可用性。最重要的是本文将重点讲解Agentic RAG这一前沿模式即让Agent智能体来驱动RAG流程而不是简单的检索-生成流水线。这种模式能显著提升问答系统的准确性和智能程度。2. LangChain 1.3 核心架构解析2.1 什么是真正的Agent智能体Agent不是简单的工具调用器而是一个具备规划、执行、反思能力的智能系统。在LangChain 1.3中Agent的核心架构包含三个关键层次认知层Cognitive Layer负责理解用户意图、制定计划、分解任务。这相当于人类的大脑进行高级思维活动。# Agent的认知决策过程示例 def cognitive_decision_making(user_query: str) - List[SubTask]: 将复杂问题分解为可执行的子任务 # 1. 意图识别理解用户想要什么 intent classify_intent(user_query) # 2. 任务规划制定执行步骤 plan create_execution_plan(intent, user_query) # 3. 资源分配决定使用哪些工具和子Agent resource_allocation allocate_resources(plan) return resource_allocation工具层Tool Layer提供具体的能力实现如搜索、计算、文件操作等。每个工具都是Agent的手和脚。协同层Coordination Layer管理多个子Agent之间的协作确保任务高效完成。2.2 RAG系统的演进从基础检索到Agentic RAG传统的RAG系统是线性的检索→生成。而Agentic RAG引入了智能决策机制基础RAG的问题检索结果质量依赖简单的相似度计算无法处理复杂、多步骤的查询缺乏对检索内容的深度理解Agentic RAG的优势智能检索策略选择多轮检索和验证机制检索结果的深度分析和合成# 传统RAG vs Agentic RAG对比 class TraditionalRAG: def retrieve_and_generate(self, query: str) - str: # 简单的一次性检索 docs vector_store.similarity_search(query) # 直接生成答案 return llm.generate(contextdocs, questionquery) class AgenticRAG: def intelligent_qa(self, query: str) - str: # 1. 问题分析和检索策略制定 strategy self.plan_retrieval_strategy(query) # 2. 多轮检索和验证 relevant_docs self.multi_round_retrieval(query, strategy) # 3. 深度分析和答案合成 return self.synthesize_answer(query, relevant_docs)2.3 LangChain 1.3 的关键改进LangChain 1.3在Agent和RAG方面有显著提升性能优化更好的异步支持和流式处理工具生态更丰富的预构建工具集成调试能力增强的LangSmith集成和追踪功能模块化设计更清晰的组件边界和接口定义3. 环境准备与项目搭建3.1 系统要求和依赖管理建议使用Python 3.9环境以下是完整的依赖配置# requirements.txt langchain0.1.3 langchain-core0.1.0 langchain-community0.0.10 langchain-openai0.0.2 langchain-chroma0.1.0 langchain-text-splitters0.0.1 openai1.3.0 chromadb0.4.0 pydantic2.0.0 fastapi0.100.0 uvicorn0.20.0使用uv虚拟环境管理依赖推荐# 创建虚拟环境 python -m uv venv langchain-env source langchain-env/bin/activate # Linux/Mac # 或 langchain-env\Scripts\activate # Windows # 安装依赖 uv pip install -r requirements.txt3.2 项目结构设计合理的项目结构是大型LangChain项目成功的关键rag_agent_project/ ├── src/ │ ├── agents/ # Agent定义 │ │ ├── orchestrator.py │ │ ├── chunk_analyst.py │ │ └── __init__.py │ ├── tools/ # 自定义工具 │ │ ├── retrieval.py │ │ ├── filesystem.py │ │ └── __init__.py │ ├── vectorstores/ # 向量数据库管理 │ │ ├── manager.py │ │ └── __init__.py │ ├── models/ # 数据模型 │ │ └── schemas.py │ └── utils/ # 工具函数 │ └── helpers.py ├── data/ # 数据文件 │ ├── documents/ # 原始文档 │ └── processed/ # 处理后的数据 ├── tests/ # 测试代码 ├── config/ # 配置文件 │ └── settings.py └── main.py # 应用入口3.3 API密钥配置和安全实践安全地管理API密钥至关重要# config/settings.py import os from typing import Optional from pydantic_settings import BaseSettings class Settings(BaseSettings): # OpenAI配置 openai_api_key: Optional[str] None openai_base_url: Optional[str] None # 向量数据库配置 chroma_persist_directory: str ./chroma_db # 应用配置 max_concurrent_agents: int 3 retrieval_top_k: int 4 class Config: env_file .env case_sensitive False def get_settings() - Settings: 获取配置实例 return Settings() # 环境变量配置示例 (.env) # OPENAI_API_KEYyour_api_key_here # OPENAI_BASE_URLyour_base_url_optional4. 核心组件深度实战4.1 文档加载和预处理实战文档处理是RAG系统的基础需要处理多种格式和结构# src/utils/document_processor.py from langchain_community.document_loaders import ( PyPDFLoader, TextLoader, UnstructuredFileLoader ) from langchain_text_splitters import RecursiveCharacterTextSplitter from typing import List, Dict, Any import os class DocumentProcessor: def __init__(self, chunk_size: int 1000, chunk_overlap: int 200): self.text_splitter RecursiveCharacterTextSplitter( chunk_sizechunk_size, chunk_overlapchunk_overlap, length_functionlen, separators[\n\n, \n, 。, , , , ., !, ?] ) def load_documents(self, directory_path: str) - List[Dict[str, Any]]: 加载目录下的所有文档 documents [] supported_extensions {.pdf, .txt, .md, .docx} for filename in os.listdir(directory_path): file_path os.path.join(directory_path, filename) file_ext os.path.splitext(filename)[1].lower() if file_ext not in supported_extensions: continue try: if file_ext .pdf: loader PyPDFLoader(file_path) elif file_ext .txt: loader TextLoader(file_path, encodingutf-8) else: loader UnstructuredFileLoader(file_path) loaded_docs loader.load() for doc in loaded_docs: doc.metadata[source_file] filename doc.metadata[file_path] file_path documents.extend(loaded_docs) except Exception as e: print(fError loading {filename}: {e}) continue return documents def process_documents(self, documents: List[Dict]) - List[Dict]: 处理文档清洗、分割、增强元数据 processed_chunks [] for doc in documents: # 清理文本 cleaned_content self.clean_text(doc.page_content) # 分割文本 chunks self.text_splitter.split_text(cleaned_content) for i, chunk in enumerate(chunks): chunk_metadata doc.metadata.copy() chunk_metadata.update({ chunk_id: i, total_chunks: len(chunks), char_length: len(chunk), word_count: len(chunk.split()) }) processed_chunks.append({ content: chunk, metadata: chunk_metadata }) return processed_chunks def clean_text(self, text: str) - str: 文本清洗函数 # 移除多余的空白字符 text .join(text.split()) # 处理特殊字符根据具体需求调整 text text.replace(\x00, ) # 移除空字符 return text # 使用示例 if __name__ __main__: processor DocumentProcessor() raw_documents processor.load_documents(./data/documents) processed_chunks processor.process_documents(raw_documents) print(fProcessed {len(processed_chunks)} chunks from {len(raw_documents)} documents)4.2 向量数据库集成和优化向量数据库的选择和配置直接影响检索效果# src/vectorstores/manager.py import chromadb from langchain_chroma import Chroma from langchain_openai import OpenAIEmbeddings from typing import List, Dict, Any import hashlib class VectorStoreManager: def __init__(self, persist_directory: str ./chroma_db): self.persist_directory persist_directory self.embeddings OpenAIEmbeddings( modeltext-embedding-3-small, dimensions1536 # 明确指定维度提高兼容性 ) self.vector_store None self._initialize_vector_store() def _initialize_vector_store(self): 初始化向量数据库 try: self.vector_store Chroma( persist_directoryself.persist_directory, embedding_functionself.embeddings, collection_nameknowledge_base ) except Exception as e: print(fError initializing vector store: {e}) # 失败时重新创建 self.vector_store Chroma.from_documents( documents[], # 空文档开始 embeddingself.embeddings, persist_directoryself.persist_directory, collection_nameknowledge_base ) def add_documents(self, documents: List[Dict]) - bool: 添加文档到向量数据库 try: from langchain_core.documents import Document # 转换文档格式 langchain_docs [] for doc in documents: langchain_doc Document( page_contentdoc[content], metadatadoc[metadata] ) langchain_docs.append(langchain_doc) # 批量添加文档 self.vector_store.add_documents(langchain_docs) # 立即持久化 self.vector_store.persist() print(fSuccessfully added {len(documents)} documents to vector store) return True except Exception as e: print(fError adding documents: {e}) return False def similarity_search(self, query: str, k: int 4, **kwargs) - List[Dict]: 相似度搜索 try: results self.vector_store.similarity_search( queryquery, kk, **kwargs ) formatted_results [] for doc in results: formatted_results.append({ content: doc.page_content, metadata: doc.metadata, score: getattr(doc, score, 0.0) # 相似度分数 }) return formatted_results except Exception as e: print(fError in similarity search: {e}) return [] def get_collection_info(self) - Dict[str, Any]: 获取集合信息 try: client self.vector_store._client collection client.get_collection(knowledge_base) return { name: collection.name, count: collection.count(), metadata: collection.metadata } except Exception as e: return {error: str(e)} def optimize_search(self, query: str, filters: Dict None) - List[Dict]: 优化搜索添加过滤和重排序 search_kwargs {} # 添加元数据过滤 if filters: search_kwargs[filter] filters # 执行搜索 results self.similarity_search(query, k10, **search_kwargs) # 重排序逻辑基于自定义规则 reranked_results self.rerank_results(query, results) return reranked_results[:4] # 返回top-4 def rerank_results(self, query: str, results: List[Dict]) - List[Dict]: 基于自定义规则重排序结果 # 简单的基于长度的重排序可根据需求实现更复杂的逻辑 for result in results: content result[content] # 计算长度得分避免过长或过短的片段 length_score 1.0 - abs(len(content) - 500) / 1000 # 理想长度500字 result[rerank_score] result.get(score, 0.0) * 0.7 length_score * 0.3 return sorted(results, keylambda x: x[rerank_score], reverseTrue)4.3 Agent智能体系统构建构建具备复杂决策能力的Agent系统# src/agents/orchestrator.py from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain_core.prompts import ChatPromptTemplate from langchain_core.messages import SystemMessage, HumanMessage from typing import List, Dict, Any import uuid class OrchestratorAgent: 协调Agent负责任务规划和子Agent协调 def __init__(self, llm, tools, subagents: Dict): self.llm llm self.tools tools self.subagents subagents self.agent_executor self._create_agent_executor() def _create_agent_executor(self) - AgentExecutor: 创建Agent执行器 system_template 你是一个高级文档问答协调员。你的职责是 1. 分析用户问题的复杂程度 2. 制定检索和分析计划 3. 协调子Agent完成具体任务 4. 综合所有信息生成最终答案 工作流程 - 简单问题直接检索并回答 - 复杂问题分解为子任务协调子Agent处理 - 需要多轮检索时制定迭代检索策略 可用工具{tools} 可用子Agent{subagents} prompt ChatPromptTemplate.from_messages([ (system, system_template), (human, {input}), (placeholder, {agent_scratchpad}) ]) agent create_tool_calling_agent(self.llm, self.tools, prompt) return AgentExecutor(agentagent, toolsself.tools, verboseTrue) def process_query(self, query: str, context: Dict None) - Dict[str, Any]: 处理用户查询 try: # 分析查询复杂度 complexity self.analyze_query_complexity(query) if complexity simple: return self.handle_simple_query(query, context) else: return self.handle_complex_query(query, context, complexity) except Exception as e: return { success: False, error: str(e), answer: 抱歉处理查询时出现错误。 } def analyze_query_complexity(self, query: str) - str: 分析查询复杂度 complexity_rules { simple: [ 定义, 什么是, 介绍, 简单解释, 基础概念, 基本功能 ], complex: [ 如何实现, 步骤, 教程, 实战, 对比, 优缺点, 高级功能 ] } query_lower query.lower() for level, keywords in complexity_rules.items(): if any(keyword in query_lower for keyword in keywords): return level # 默认根据长度和结构判断 if len(query.split()) 10 or ? in query: return complex else: return simple def handle_simple_query(self, query: str, context: Dict) - Dict[str, Any]: 处理简单查询 # 直接检索并生成答案 result self.agent_executor.invoke({ input: f请回答以下问题{query}, context: context or {} }) return { success: True, answer: result[output], complexity: simple, sources: result.get(sources, []) } def handle_complex_query(self, query: str, context: Dict, complexity: str) - Dict[str, Any]: 处理复杂查询 # 创建执行计划 execution_plan self.create_execution_plan(query, complexity) # 执行计划 results [] for step in execution_plan[steps]: if step[type] subagent: subagent_result self.invoke_subagent(step[agent], query, step[task]) results.append(subagent_result) elif step[type] tool: tool_result self.invoke_tool(step[tool], step[parameters]) results.append(tool_result) # 综合结果 final_answer self.synthesize_results(query, results) return { success: True, answer: final_answer, complexity: complexity, execution_plan: execution_plan, step_results: results } def create_execution_plan(self, query: str, complexity: str) - Dict[str, Any]: 创建执行计划 plan_id str(uuid.uuid4())[:8] if complexity complex: return { plan_id: plan_id, steps: [ { type: subagent, agent: chunk_analyst, task: 初步检索和分析相关文档, parameters: {query: query, depth: preliminary} }, { type: tool, tool: advanced_search, parameters: {query: query, strategy: comprehensive} }, { type: subagent, agent: synthesis_agent, task: 综合分析和生成最终答案, parameters: {query: query} } ] } else: return { plan_id: plan_id, steps: [ { type: tool, tool: basic_search, parameters: {query: query} } ] } def invoke_subagent(self, agent_name: str, query: str, task: str) - Dict: 调用子Agent if agent_name in self.subagents: return self.subagents[agent_name].process(task, query) else: return {error: fSubagent {agent_name} not found} def synthesize_results(self, query: str, results: List[Dict]) - str: 综合子任务结果 # 这里可以实现更复杂的综合逻辑 synthesized f针对问题『{query}』的综合分析\n\n for i, result in enumerate(results, 1): if result.get(success): synthesized f步骤{i}结果{result.get(answer, )}\n\n return synthesized5. Agentic RAG完整项目实战5.1 项目架构设计构建一个完整的基于Agentic RAG的文档问答系统# main.py from src.agents.orchestrator import OrchestratorAgent from src.agents.chunk_analyst import ChunkAnalystAgent from src.vectorstores.manager import VectorStoreManager from src.tools.retrieval import RetrievalTools from langchain_openai import ChatOpenAI import asyncio from typing import Dict, Any import json class AgenticRAGSystem: 完整的Agentic RAG系统 def __init__(self, config: Dict[str, Any]): self.config config self.vector_store None self.llm None self.tools None self.subagents {} self.orchestrator None self._initialize_system() def _initialize_system(self): 初始化系统组件 print(Initializing Agentic RAG System...) # 1. 初始化LLM self.llm ChatOpenAI( modelself.config.get(llm_model, gpt-3.5-turbo), temperature0.1, max_tokens2000 ) # 2. 初始化向量数据库 self.vector_store VectorStoreManager( persist_directoryself.config.get(vector_store_path, ./chroma_db) ) # 3. 初始化工具 self.tools RetrievalTools(vector_storeself.vector_store).get_tools() # 4. 初始化子Agent self._initialize_subagents() # 5. 初始化协调Agent self.orchestrator OrchestratorAgent( llmself.llm, toolsself.tools, subagentsself.subagents ) print(System initialization completed!) def _initialize_subagents(self): 初始化子Agent系统 # 文档分析Agent self.subagents[chunk_analyst] ChunkAnalystAgent( llmself.llm, vector_storeself.vector_store ) # 可以继续添加其他子Agent # self.subagents[synthesis_agent] SynthesisAgent(llmself.llm) async def process_query_async(self, query: str) - Dict[str, Any]: 异步处理查询 try: result await asyncio.get_event_loop().run_in_executor( None, self.orchestrator.process_query, query, {} ) return result except Exception as e: return { success: False, error: str(e), answer: 处理查询时发生错误 } def add_documents(self, documents_path: str) - bool: 添加文档到知识库 from src.utils.document_processor import DocumentProcessor try: processor DocumentProcessor() raw_docs processor.load_documents(documents_path) processed_chunks processor.process_documents(raw_docs) success self.vector_store.add_documents(processed_chunks) return success except Exception as e: print(fError adding documents: {e}) return False def get_system_status(self) - Dict[str, Any]: 获取系统状态 vector_store_info self.vector_store.get_collection_info() return { vector_store: vector_store_info, subagents_count: len(self.subagents), tools_count: len(self.tools), llm_model: self.config.get(llm_model, unknown) } # 配置和启动 def main(): config { llm_model: gpt-3.5-turbo, vector_store_path: ./chroma_db, max_concurrent_agents: 3 } # 创建系统实例 rag_system AgenticRAGSystem(config) # 检查系统状态 status rag_system.get_system_status() print(System Status:, json.dumps(status, indent2, ensure_asciiFalse)) # 示例查询处理 test_queries [ 什么是LangChain的Agent, 如何实现一个复杂的多步骤文档问答系统, 请对比RAG和微调在文档问答中的优缺点 ] for query in test_queries: print(f\n 处理查询: {query} ) result asyncio.run(rag_system.process_query_async(query)) print(f结果: {result.get(answer, 无答案)}) print(f复杂度: {result.get(complexity, unknown)}) if __name__ __main__: main()5.2 高级检索策略实现实现智能的多轮检索和结果验证# src/tools/advanced_retrieval.py from typing import List, Dict, Any import re class AdvancedRetrievalStrategy: 高级检索策略 def __init__(self, vector_store): self.vector_store vector_store def multi_round_retrieval(self, query: str, max_rounds: int 3) - List[Dict]: 多轮检索策略 all_results [] current_query query for round_num in range(max_rounds): print(f检索轮次 {round_num 1}: {current_query}) # 执行检索 round_results self.vector_store.optimize_search(current_query) all_results.extend(round_results) # 检查是否满足需求 if self._satisfaction_check(query, round_results): print(检索结果满足需求停止多轮检索) break # 生成下一轮查询 if round_num max_rounds - 1: current_query self._refine_query(query, round_results, all_results) else: print(达到最大检索轮次) # 去重和排序 final_results self._deduplicate_and_rank(all_results) return final_results def _satisfaction_check(self, original_query: str, results: List[Dict]) - bool: 检查检索结果是否满足需求 if not results: return False # 基于结果数量和质量的简单满意度检查 total_content .join([r[content] for r in results]) # 检查关键概念覆盖 key_concepts self._extract_key_concepts(original_query) coverage_score self._calculate_coverage(key_concepts, total_content) # 检查结果多样性 diversity_score self._calculate_diversity(results) return coverage_score 0.6 and diversity_score 0.5 and len(results) 2 def _refine_query(self, original_query: str, current_results: List[Dict], all_results: List[Dict]) - str: 优化查询语句 # 分析当前结果的不足 missing_concepts self._identify_missing_concepts(original_query, all_results) if missing_concepts: refined_query f{original_query} 重点包括{, .join(missing_concepts)} else: # 如果没有明显缺失尝试不同的角度 refined_query f{original_query} 深入探讨实现细节和最佳实践 return refined_query def _extract_key_concepts(self, query: str) - List[str]: 提取查询中的关键概念 # 简单的概念提取逻辑 concepts [] # 提取名词短语简化版 patterns [ r什么是(.?)[?], r如何(.?)[?], r(.?)的(.?), r(.?)和(.?) ] for pattern in patterns: matches re.findall(pattern, query) for match in matches: if isinstance(match, tuple): concepts.extend([m.strip() for m in match if m.strip()]) else: concepts.append(match.strip()) return list(set(concepts)) def _calculate_coverage(self, concepts: List[str], content: str) - float: 计算概念覆盖率 if not concepts: return 0.0 covered 0 for concept in concepts: if concept.lower() in content.lower(): covered 1 return covered / len(concepts) def _calculate_diversity(self, results: List[Dict]) - float: 计算结果多样性 if len(results) 1: return 1.0 # 单一结果视为完全多样 # 基于内容相似度的简单多样性计算 contents [r[content] for r in results] unique_contents set(contents) return len(unique_contents) / len(contents) def _identify_missing_concepts(self, query: str, results: List[Dict]) - List[str]: 识别缺失的概念 key_concepts self._extract_key_concepts(query) all_content .join([r[content] for r in results]) missing [] for concept in key_concepts: if concept.lower() not in all_content.lower(): missing.append(concept) return missing def _deduplicate_and_rank(self, results: List[Dict]) - List[Dict]: 去重和重排序 # 基于内容哈希去重 seen_hashes set() unique_results [] for result in results: content_hash hash(result[content][:100]) # 前100字符的哈希 if content_hash not in seen_hashes: seen_hashes.add(content_hash) unique_results.append(result) # 基于分数重排序 return sorted(unique_results, keylambda x: x.get(score, 0), reverseTrue)6. 性能优化和最佳实践6.1 向量检索优化策略# src/optimization/retrieval_optimizer.py import numpy as np from typing import List, Dict from sklearn.metrics.pairwise import cosine_similarity class RetrievalOptimizer: 检索优化器 def __init__(self, vector_store): self.vector_store vector_store def hybrid_retrieval(self, query: str, alpha: float 0.7) - List[Dict]: 混合检索结合语义检索和关键词检索 # 语义检索 semantic_results self.vector_store.similarity_search(query, k10) # 关键词检索简化版 keyword_results self.keyword_search(query, k10) # 结果融合 fused_results self.fuse_results( semantic_results, keyword_results, alpha ) return fused_results[:4] def keyword_search(self, query: str, k: int) - List[Dict]: 基于关键词的检索 # 这里可以实现更复杂的关键词匹配逻辑 query_terms set(query.lower().split()) # 简化实现在实际项目中需要访问文档的原始文本 all_docs self.vector_store.get_all_documents() # 需要实现这个方法 scored_docs [] for doc in all_docs: content_terms set(doc[content].lower().split()) overlap len(query_terms.intersection(content_terms)) score overlap / len(query_terms) if query_terms else 0 scored_docs.append({ content: doc[content], metadata: doc[metadata], score: score }) return sorted(scored_docs, keylambda x: x[score], reverseTrue)[:k] def fuse_results(self, results1: List[Dict], results2: List[Dict], alpha: float) - List[Dict]: 结果融合算法 # 创建结果映射 all_results {} # 处理第一组结果 for i, result in enumerate(results1): result_id self._get_result_id(result) all_results[result_id] { result: result, score1: 1.0 - i * 0.1, # 排名得分 score2: 0.0 } # 处理第二组结果 for i, result in enumerate(results2): result_id self._get_result_id(result) if result_id in all_results: all_results[result_id][score2] 1.0 - i * 0.1 else: all_results[result_id] { result: result, score1: 0.0, score2: 1.0 - i * 0.1 } # 计算融合得分 fused_list [] for result_id, scores in all_results.items(): fused_score alpha * scores[score1] (1 - alpha) * scores[score2] result scores[result].copy() result[fused_score] fused_score fused_list.append(result) return sorted(fused_list, keylambda x: x[fused_score], reverseTrue) def _get_result_id(self, result: Dict) - str: 生成结果唯一标识 content_preview result[content][:50] # 前50个字符 source result[metadata].get(source_file, unknown) return f{source}_{hash(content_preview)}6.2 Agent系统性能监控# src/monitoring/performance_monitor.py import time from datetime import datetime from typing import Dict, List, Any import psutil import os class PerformanceMonitor: 性能监控器 def __init__(self):

相关新闻