Skip to main content
Glama

MCP RAG

by kalicyh
document_tools.py10.6 kB
""" MCP 文档工具 =========== 此模块包含与文档处理相关的工具。 从 rag_server.py 迁移而来,用于模块化架构。 注意:这些函数被设计为在主服务器中使用 @mcp.tool() 装饰器。 """ import os from datetime import datetime from rag_core_openai import ( add_text_to_knowledge_base, add_text_to_knowledge_base_enhanced, load_document_with_elements ) from utils.logger import log from models import DocumentModel, MetadataModel # 必须在服务器中可用的全局变量 rag_state = {} initialize_rag_func = None save_processed_copy_func = None md_converter = None # deprecated placeholder, MarkItDown support removed def set_rag_state(state): """设置全局 RAG 状态。""" global rag_state rag_state = state def set_initialize_rag_func(func): """设置 RAG 初始化函数。""" global initialize_rag_func initialize_rag_func = func def set_md_converter(converter): """Deprecated: previously used to set a MarkItDown converter. This is now a no-op kept for API compatibility.""" global md_converter md_converter = converter log("警告: set_md_converter 已弃用 — MarkItDown 支持已移除,传入的转换器将被忽略。") def set_save_processed_copy_func(func): """设置保存处理副本的函数。""" global save_processed_copy_func save_processed_copy_func = func def initialize_rag(): """初始化 RAG 系统。""" if initialize_rag_func: initialize_rag_func() elif "initialized" in rag_state: return # 此函数必须在主服务器中实现 pass def save_processed_copy(file_path: str, processed_content: str, processing_method: str = "unstructured") -> str: """保存文档的处理副本。""" if save_processed_copy_func: return save_processed_copy_func(file_path, processed_content, processing_method) return "" def learn_text(text: str, source_name: str = "manual_input") -> str: """ 将新的文本片段添加到 RAG 知识库以供将来参考。 当您想要教授AI应该记住的新信息时使用此功能。 使用场景示例: - 添加事实、定义或解释 - 存储对话中的重要信息 - 保存研究发现或笔记 - 添加特定主题的上下文 Args: text: 要学习并存储在知识库中的文本内容。 source_name: 来源的描述性名称(例如,"user_notes"、"research_paper"、"conversation_summary")。 """ log(f"MCP Server: 正在处理来自源 {source_name} 的 {len(text)} 个字符的文本") initialize_rag() try: # 使用 MetadataModel 创建结构化元数据 metadata_model = MetadataModel( source=source_name, input_type="manual_text", processed_date=datetime.now(), processing_method="manual_input", chunking_method="standard", chunk_count=1, avg_chunk_size=len(text) ) # 转换为字典以与核心兼容 source_metadata = metadata_model.to_dict() # 使用核心函数将文本与元数据一起添加 add_text_to_knowledge_base(text, rag_state["vector_store"], source_metadata) log(f"MCP Server: 文本已成功添加到知识库") return f"文本已成功添加到知识库。片段: '{text[:70]}...' (来源: {source_name})" except Exception as e: log(f"MCP Server: 添加文本时出错: {e}") return f"添加文本时出错: {e}" def learn_document(file_path: str) -> str: """ 使用高级 Unstructured 处理和真正的语义分块读取和处理文档文件,并将其添加到知识库。 当您想要通过智能处理从文档文件中教授AI时使用此功能。 支持的文件类型:PDF、DOCX、PPTX、XLSX、TXT、HTML、CSV、JSON、XML、ODT、ODP、ODS、RTF、 图像(PNG、JPG、TIFF、BMP 带OCR)、电子邮件(EML、MSG)以及总共超过25种格式。 高级功能: - 基于文档结构(标题、段落、列表)的真正语义分块 - 智能文档结构保持(标题、列表、表格) - 自动噪音去除(页眉、页脚、无关内容) - 结构元数据提取 - 任何文档类型的健壮回退系统 - 通过语义边界增强上下文保持 使用场景示例: - 处理具有复杂布局的研究论文或文章 - 从带有表格和列表的报告或手册中添加内容 - 从带有格式的电子表格导入数据 - 将演示文稿转换为可搜索的知识 - 使用OCR处理扫描文档 文档将通过真正的语义分块进行智能处理,并使用增强的元数据存储。 处理后的文档副本将被保存以供验证。 Args: file_path: 要处理的文档文件的绝对或相对路径。 """ log(f"MCP Server: 开始高级文档处理: {file_path}") log(f"MCP Server: DEBUG - 接收到的路径: {repr(file_path)}") log(f"MCP Server: DEBUG - 检查绝对路径是否存在: {os.path.abspath(file_path)}") initialize_rag() # 确保 RAG 系统已准备就绪 try: if not os.path.exists(file_path): log(f"MCP Server: 在路径中未找到文件: {file_path}") return f"错误: 在 '{file_path}' 中未找到文件" log(f"MCP Server: 使用高级 Unstructured 系统处理文档...") # 使用新的带结构元素的处理系统 processed_content, raw_metadata, structural_elements = load_document_with_elements(file_path) if not processed_content or processed_content.isspace(): log(f"MCP Server: 警告: 文档已处理但无法提取内容: {file_path}") return f"警告: 文档 '{file_path}' 已处理,但无法提取文本内容。" log(f"MCP Server: 文档处理成功 ({len(processed_content)} 个字符)") # 创建结构化文档模型 file_name = os.path.basename(file_path) file_type = os.path.splitext(file_path)[1].lower() file_size = os.path.getsize(file_path) # 提取结构信息 structural_info = raw_metadata.get("structural_info", {}) titles_count = structural_info.get("titles_count", 0) tables_count = structural_info.get("tables_count", 0) lists_count = structural_info.get("lists_count", 0) total_elements = structural_info.get("total_elements", 0) # 创建 DocumentModel document_model = DocumentModel( file_path=file_path, file_name=file_name, file_type=file_type, file_size=file_size, content=processed_content, # 原始内容(在这种情况下与处理后的内容相同) processed_content=processed_content, processing_method=raw_metadata.get("processing_method", "unstructured_enhanced"), processing_date=datetime.now(), structural_elements=structural_elements or [], total_elements=total_elements, titles_count=titles_count, tables_count=tables_count, lists_count=lists_count, chunk_count=0 # 分块后将计算 ) # 创建 MetadataModel metadata_model = MetadataModel( source=file_name, input_type="file_upload", processed_date=datetime.now(), file_path=file_path, file_type=file_type, file_size=file_size, processing_method=raw_metadata.get("processing_method", "unstructured_enhanced"), structural_info=structural_info, total_elements=total_elements, titles_count=titles_count, tables_count=tables_count, lists_count=lists_count, narrative_blocks=structural_info.get("narrative_blocks", 0), other_elements=structural_info.get("other_elements", 0), chunking_method="semantic" if structural_elements else "standard", avg_chunk_size=len(processed_content) / max(total_elements, 1) ) # 验证文档 if not document_model.is_valid(): log(f"MCP Server: 错误: 根据模型标准文档无效") return f"错误: 处理后的文档不符合有效性标准" log(f"MCP Server: 文档和元数据模型创建成功") log(f"MCP Server: 文档摘要: {document_model.get_summary()}") log(f"MCP Server: 元数据摘要: {metadata_model.get_summary()}") # 保存处理后的副本 log(f"MCP Server: 保存处理后的副本...") saved_copy_path = save_processed_copy(file_path, processed_content, document_model.processing_method) # 使用真正的语义分块将内容添加到知识库 log(f"MCP Server: 使用结构元数据将内容添加到知识库...") # 将元数据转换为字典以与核心兼容 enhanced_metadata = metadata_model.to_dict() # 使用增强函数和结构元素进行真正的语义分块 add_text_to_knowledge_base_enhanced( processed_content, rag_state["vector_store"], enhanced_metadata, use_semantic_chunking=True, structural_elements=structural_elements ) log(f"MCP Server: 处理完成 - 文档处理成功") # 使用的分块信息 chunking_info = "" if structural_elements and len(structural_elements) > 1: chunking_info = f"🧠 高级语义分块 包含 {len(structural_elements)} 个结构元素" elif metadata_model.is_rich_content(): chunking_info = f"📊 增强语义分块 基于结构元数据" else: chunking_info = f"📝 优化传统分块" return f"""✅ 文档处理成功 📄 文件: {document_model.file_name} 📋 类型: {(document_model.file_type or 'unknown').upper()} 🔧 方法: {document_model.processing_method} {chunking_info} 📊 处理字符数: {len(processed_content):,} 📈 结构: {titles_count} 个标题, {tables_count} 个表格, {lists_count} 个列表 💾 保存的副本: {saved_copy_path if saved_copy_path else "不可用"} ✅ 验证: 使用结构化模型处理的文档""" except Exception as e: log(f"MCP Server: 处理文档 '{file_path}' 时出错: {e}") return f"处理文档时出错: {e}"

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kalicyh/mcp-rag'

If you have feedback or need assistance with the MCP directory API, please join our Discord server