import re import traceback import json def call_ai_api(system_prompt, user_prompt, model="glm-4.5", base_url="https://open.bigmodel.cn/api/paas/v4/", api_key="ce39bdd4fcf34ec0aec75072bc9ff988.hAp7HZTVUwy7vImn", stream=False): """ 调用AI API生成Markdown """ try: # 尝试导入OpenAI客户端 try: from openai import OpenAI except ImportError: print("OpenAI库未安装,返回模拟数据") if stream: # 返回模拟流式数据 def mock_stream(): mock_content = f"""# {user_prompt} ## 概述 {user_prompt}是一个重要的概念和领域。 ## 核心要素 - 要素1 - 要素2 - 要素3 ## 应用场景 - 场景1 - 场景2 - 场景3 ## 发展趋势 - 趋势1 - 趋势2 - 趋势3""" for char in mock_content: yield char return mock_stream() else: return f"""# {user_prompt} ## 概述 {user_prompt}是一个重要的概念和领域。 ## 核心要素 - 要素1 - 要素2 - 要素3 ## 应用场景 - 场景1 - 场景2 - 场景3 ## 发展趋势 - 趋势1 - 趋势2 - 趋势3""" # 构建消息 messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt} ] print(f"发送AI API请求到: {base_url}") print(f"模型: {model}") print(f"流式模式: {stream}") # 创建OpenAI客户端 client = OpenAI(api_key=api_key, base_url=base_url) # 根据stream参数决定是否使用流式调用 try: response = client.chat.completions.create( model=model, messages=messages, temperature=0.7, max_tokens=4000, # 减少token限制,提高响应速度 stream=stream ) except Exception as e: print(f"API调用失败: {e}") # 如果API调用失败,抛出异常而不是返回模拟数据 raise Exception(f"AI API调用失败: {e}") if stream: # 流式响应处理 def generate_stream(): full_content = "" try: for chunk in response: if chunk.choices[0].delta.content is not None: content_chunk = chunk.choices[0].delta.content full_content += content_chunk yield content_chunk print(f"流式响应完成,总长度: {len(full_content)}") except Exception as e: print(f"流式响应处理失败: {e}") raise e return full_content return generate_stream() else: # 非流式响应处理 content = response.choices[0].message.content print(f"AI原始响应: {content}") # 处理可能的JSON格式响应 try: # 尝试解析为JSON json_data = json.loads(content) if 'answer' in json_data: content = json_data['answer'] print(f"从JSON中提取answer: {content[:100]}...") elif 'content' in json_data: content = json_data['content'] print(f"从JSON中提取content: {content[:100]}...") elif 'markdown' in json_data: content = json_data['markdown'] print(f"从JSON中提取markdown: {content[:100]}...") except json.JSONDecodeError: # 不是JSON格式,直接使用内容 print("响应不是JSON格式,直接使用内容") # 清理内容 content = content.strip() # 如果返回的内容包含代码块标记,提取其中的内容 markdown_match = re.search(r"```(?:markdown)?\n(.*?)```", content, re.DOTALL) if markdown_match: content = markdown_match.group(1).strip() # 如果内容为空,返回模拟数据 if not content: print("AI返回内容为空,使用模拟数据") return f"""# {user_prompt} ## 概述 {user_prompt}是一个重要的概念和领域。 ## 核心要素 - 要素1 - 要素2 - 要素3 ## 应用场景 - 场景1 - 场景2 - 场景3 ## 发展趋势 - 趋势1 - 趋势2 - 趋势3""" return content except Exception as e: print(f"AI API调用异常: {e}") traceback.print_exc() return None def generate_markdown_from_text(text): """ 从文本生成Markdown的便捷函数 """ system_prompt = """你是一位Markdown格式转换专家。你的任务是将用户提供的文章内容精确转换为结构化的Markdown格式。请遵循以下步骤: 提取主标题: 识别文章最顶层的主标题(通常为文章题目或书名),并使用Markdown的 # 级别表示。 识别层级标题: 从文章内容中提取所有层级的内容标题(从主标题后的第一个标题开始,Level 1 至 Level 4)。判断层级依据: 视觉与结构特征: 如独立成行/段、位置(行首)、格式(加粗、编号如 1., 1.1, (1), - 等)。 语义逻辑: 标题之间的包含和并列关系。 在Markdown中,使用相应标题级别: Level 1 标题用 ## Level 2 标题用 ### Level 3 标题用 #### Level 4 标题用 ##### 精确保留原文标题文字,不得修改、概括或润色。 处理正文内容: 对于每个标题下的正文内容区块(从该标题后开始,直到下一个同级或更高级别标题前): 直接保留原文文本,但根据内容结构适当格式化为Markdown。 如果内容是列表(如项目符号或编号列表),使用Markdown列表语法(例如 - 用于无序列表,1. 用于有序列表)。 保持段落和换行不变。 输出格式: 输出必须是纯Markdown格式的文本,不得包含任何额外说明、JSON或非Markdown元素。确保输出与示例风格一致。""" user_prompt = f"请将以下内容转换为结构化的Markdown格式:\n\n{text}" return call_ai_api(system_prompt, user_prompt)