""" 摘要提取模块 使用大模型生成文档摘要 """ import os import re from openai import OpenAI def _load_llm_config() -> dict: """从 config.yaml 加载 LLM 配置,环境变量可覆盖。""" config = { "base_url": "https://yiming.zeroerr.team/v1", "api_key": "", "model": "minimax-2.5", "max_tokens": 40960, } # 尝试从项目根目录 config.yaml 读取(与 0209 一致) config_path = os.path.join(os.path.dirname(__file__), "..", "config.yaml") if os.path.exists(config_path): try: import yaml with open(config_path, "r", encoding="utf-8") as f: data = yaml.safe_load(f) or {} llm = data.get("llm", {}) config.update({k: v for k, v in llm.items() if v}) except Exception: # 保持静默降级,继续使用默认值/环境变量 pass # 环境变量优先级更高 config["base_url"] = os.environ.get("ZEROERR_LLM_BASE_URL", config["base_url"]) config["api_key"] = os.environ.get("ZEROERR_LLM_API_KEY", config["api_key"]) config["model"] = os.environ.get("ZEROERR_LLM_MODEL", config["model"]) config["max_tokens"] = int( os.environ.get("ZEROERR_LLM_MAX_TOKENS", config["max_tokens"]) ) return config _LLM_CONFIG = _load_llm_config() API_BASE_URL = _LLM_CONFIG["base_url"] API_KEY = _LLM_CONFIG["api_key"] MODEL = _LLM_CONFIG["model"] MAX_TOKENS = _LLM_CONFIG["max_tokens"] def generate_abstract(all_pages: list[dict], category_name: str, index_url: str = None) -> str: """ 使用大模型生成文档摘要 Args: all_pages: 所有页面数据列表,每个元素包含 'title', 'url', 'markdown' 等字段 category_name: 文档类别名称(如"应用案例") index_url: 索引页完整URL(可选),如果提供则会在摘要前添加原文链接 Returns: 摘要文本(Markdown格式),包含摘要内容和链接列表 """ if not all_pages: return "" if not API_KEY: print(" 警告: 未设置 ZEROERR_LLM_API_KEY,跳过摘要生成") return "" try: # 构建文档内容(用于生成摘要) # 只使用标题和部分内容,避免内容过长 content_parts = [] for page in all_pages: title = page.get('title', '') markdown = page.get('markdown', '') # 只取前500字符的内容,避免输入过长 content_preview = markdown[:500] if len(markdown) > 500 else markdown content_parts.append(f"标题:{title}\n内容预览:{content_preview}") document_content = "\n\n".join(content_parts) # 构建提示词 prompt = f"""面向客户售前咨询,请为以下"{category_name}"类别的文档集合生成一个简洁的摘要。 文档内容: {document_content} 要求: 1. 摘要应概括该页面的主题和主要内容 2. 摘要长度控制在100-200字之间 3. 使用简洁、专业的语言 4. 突出该页面主题的价值和特点 请直接输出摘要内容,不要包含其他说明文字。""" # 调用大模型API client = OpenAI( base_url=API_BASE_URL, api_key=API_KEY ) response = client.chat.completions.create( model=MODEL, temperature=0.3, # 使用较低的温度值,保证摘要的准确性 max_tokens=MAX_TOKENS, messages=[{"role": "user", "content": prompt}], ) abstract_text = response.choices[0].message.content.strip() # 过滤掉 ... 推理过程 abstract_text = re.sub(r".*?\s*", "", abstract_text, flags=re.DOTALL).strip() # 构建链接列表 links_section = "\n\n**相关链接:**\n\n" for i, page in enumerate(all_pages, 1): title = page.get('title', '未命名') url = page.get('url', '') links_section += f"{i}. [{title}]({url})\n" # 组合摘要和链接,如果提供了索引页URL,则在摘要前添加原文链接 if index_url: result = f"原文链接: {index_url}\n\n{abstract_text}{links_section}" else: result = f"{abstract_text}{links_section}" return result except Exception as e: print(f" 警告: 生成摘要失败: {e}") # 如果生成摘要失败,至少返回链接列表 links_section = "\n\n**相关链接:**\n\n" for i, page in enumerate(all_pages, 1): title = page.get('title', '未命名') url = page.get('url', '') links_section += f"{i}. [{title}]({url})\n" # 如果提供了索引页URL,在链接列表前添加原文链接 if index_url: return f"原文链接: {index_url}{links_section}" return links_section