RAG系统运行
发布于 2025-12-31
RAG系统运行
Section titled “RAG系统运行”- 1.掌握如何通过命令行参数和增强的错误处理运行EduRAG系统。
- 2.了解整合核心的RAG逻辑。
main.py是EduRAG系统的运行模块,涵盖错误处理、参数灵活性和日志记录等功能。main.py作为命令行入口,支持数据处理和交互式查询,适合开发和调试;该模块整合了前几章的核心逻辑,为用户提供了健壮的交互方式。
7.1 系统运行入口
Section titled “7.1 系统运行入口”main.py是EduRAG系统的运行入口,提供两种运行模式:
- 数据处理模式:加载并向量化文档,构建向量数据库,支持多学科目录处理。
- 查询模式:通过命令行交互式回答用户查询,支持学科过滤。
- 完整代码
import osimport sysfrom base import Config, loggerfrom core.document_loader import process_documents # 导入处理文档的函数from core.vector_store import VectorStorefrom core.rag_system import RAGSystemfrom openai import OpenAI # 使用 OpenAI 接口
conf = Config()
def main(query_mode=True, directory_path="data"):
# 初始化 DashScope API 客户端 (通过 OpenAI 接口) # 确保环境变量 DASHSCOPE_API_KEY 和 DASHSCOPE_BASE_URL 已设置 try:
client = OpenAI(api_key=conf.DASHSCOPE_API_KEY, base_url=conf.DASHSCOPE_BASE_URL)
except Exception as e: logger.error(f"初始化 OpenAI 客户端失败 (请检查 API Key 和 Base URL): {e}") # 如果客户端初始化失败,可能无法继续,取决于模式 if query_mode: # 查询模式下必须要有 LLM print("错误:无法初始化语言模型客户端,无法进入查询模式。") return # 数据处理模式可能不需要 LLM,可以继续,但最好记录错误 client = None # 标记客户端不可用
# 定义 LLM 调用函数 (仅在需要时定义和使用) def call_dashscope(prompt): if not client: # 检查客户端是否可用 logger.error("LLM 客户端未初始化,无法调用 call_dashscope") return f"错误: LLM客户端不可用" try: completion = client.chat.completions.create( model=conf.LLM_MODEL, messages=[ {"role": "system", "content": "你是一个有用的助手."}, {"role": "user", "content": prompt}, ] # 可以添加 temperature 等参数 ) if completion.choices and completion.choices[0].message: return completion.choices[0].message.content else: logger.error("LLM API 调用返回无效响应或空消息") return "错误: LLM返回无效响应" except Exception as e: logger.error(f"LLM API (call_dashscope) 调用失败: {e}") return f"错误: 调用LLM失败 - {e}"
# 初始化 VectorStore try: vector_store = VectorStore( collection_name=conf.MILVUS_COLLECTION_NAME, host=conf.MILVUS_HOST, port=conf.MILVUS_PORT, database=conf.MILVUS_DATABASE_NAME, ) except Exception as e: logger.error(f"初始化 VectorStore 失败 (请检查 Milvus 连接配置): {e}") print("错误:无法连接到向量数据库,程序无法继续。") return
# 根据模式执行不同操作 if not query_mode: # --- 数据处理模式 --- logger.info("进入数据处理模式...") total_chunks_added = 0 for source_dir in conf.VALID_SOURCES: dir_path = os.path.join(directory_path, f"{source_dir}_data") if os.path.exists(dir_path): logger.info(f"开始处理目录: {dir_path}") try: chunks = process_documents( dir_path, conf.PARENT_CHUNK_SIZE, conf.CHILD_CHUNK_SIZE, conf.CHUNK_OVERLAP, ) if chunks: vector_store.add_documents(chunks) total_chunks_added += len(chunks) logger.info(f"成功处理目录 {dir_path},添加了 {len(chunks)} 个文档块") else: logger.info(f"目录 {dir_path} 未发现有效文档或处理结果为空") except Exception as e: logger.error(f"处理目录 {dir_path} 时出错: {e}") else: logger.warning(f"目录 {dir_path} 不存在,跳过处理") logger.info(f"数据处理完成,共添加了 {total_chunks_added} 个文档块到向量存储") else: # --- 交互式查询模式 --- if not client: # 再次检查 LLM 客户端是否必须且可用 print("错误:查询模式需要语言模型客户端,但初始化失败。") return
logger.info("进入交互式查询模式...") try: rag_system = RAGSystem(vector_store, call_dashscope) except Exception as e: logger.error(f"初始化 RAGSystem 失败: {e}") print("错误:无法初始化 RAG 系统,无法进入查询模式。") return
valid_sources = conf.VALID_SOURCES print("\n欢迎使用 EduRAG 交互式查询系统!") print(f"支持的学科类别:{valid_sources}") print("输入您的问题,或输入 'exit' 退出。")
while True: query = input("\n请输入您的问题:") if query.lower() == "exit": logger.info("用户退出查询模式") print("再见!") break
source_filter_input = input(f"请输入学科类别 ({'/'.join(valid_sources)}) (直接回车默认不过滤):").strip() source_filter = None # 默认不过滤 if source_filter_input: if source_filter_input in valid_sources: source_filter = source_filter_input logger.info(f"用户选择了学科过滤: {source_filter}") else: logger.warning( f"无效的学科类别 '{source_filter_input}',将不过滤" ) print(f"提示:输入的学科 '{source_filter_input}' 无效,将不过滤。")
try: print("正在生成答案,请稍候...") answer = rag_system.generate_answer(query, source_filter=source_filter) print("-" * 30) print(f"问题: {query}") print(f"回答: {answer}") print("-" * 30) except Exception as e: logger.error(f"处理查询 '{query}' 时失败: {str(e)}") print(f"抱歉,处理您的问题时遇到了错误,请稍后重试或联系管理员。\n")
if __name__ == "__main__": # 默认进入查询模式 # 若要执行数据处理,可以修改调用方式,例如: # main(query_mode=False) # 或者通过命令行参数控制 import argparse parser = argparse.ArgumentParser(description="EduRAG System Main Entry Point") parser.add_argument('--data-processing', action='store_true', help='Run in data processing mode instead of query mode.') parser.add_argument('--data-dir', type=str, default='./data', help='Path to the data directory.') args = parser.parse_args() main(query_mode=(not args.data_processing), directory_path=args.data_dir)- 环境变量加载:
- 使用
Config文件,确保API密钥等配置从环境变量读取。
- 使用
- LLM客户端初始化:
- 增强错误处理,若初始化失败,在查询模式下退出,数据处理模式可继续。
- 定义
call_dashscope函数,封装DashScope API调用,包含详细异常处理。
- VectorStore初始化:
- 使用显式参数初始化,确保配置可控,若失败则终止程序。
- 数据处理模式:
- 遍历
VALID_SOURCES,处理每个学科目录,记录处理的文档块数量。 - 支持自定义分块参数(如
PARENT_CHUNK_SIZE)。
- 遍历
- 查询模式:
- 显示支持的学科类别,提供输入提示。
- 校验
source_filter,若无效则提示并忽略。 - 输出格式化答案,增强用户体验。
- 命令行参数:
- 使用
argparse支持--data-processing和--data-dir,提高灵活性。
- 使用
6.2 RAG系统运行
Section titled “6.2 RAG系统运行”- 命令行运行(main.py):
-
数据处理:
python main.py --data-processing --data-dir ./data -
查询模式:
python main.py示例输出:
欢迎使用 EduRAG 交互式查询系统!支持的学科类别:['ai', 'java', 'test', 'ops', 'bigdata']输入您的问题,或输入 'exit' 退出。请输入您的问题:AI学科学费是多少?请输入学科类别 (ai/java/test/ops/bigdata) (直接回车默认不过滤):ai正在生成答案,请稍候...------------------------------问题: AI学科学费是多少?回答: ...------------------------------
-
本章节详细介绍了RAG系统运行的main.py:
main.py:命令行入口,支持数据处理和交互式查询。
发布于 2025-12-31