118 lines
5.9 KiB
Python
118 lines
5.9 KiB
Python
|
|
import re
|
|||
|
|
import traceback
|
|||
|
|
from openai import OpenAI
|
|||
|
|
|
|||
|
|
|
|||
|
|
# "model": "glm-4.5",
|
|||
|
|
# "base_url": "https://open.bigmodel.cn/api/paas/v4/",
|
|||
|
|
# "api_key": "ce39bdd4fcf34ec0aec75072bc9ff988.hAp7HZTVUwy7vImn"
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
EXTRACT_OUNTLINE_SYSTEM_PROMPT = """
|
|||
|
|
## 角色
|
|||
|
|
你是一位专业的内容结构分析专家。你的核心任务是精确解析用户提供的文章内容,并严格按照指定格式输出分析结果。
|
|||
|
|
|
|||
|
|
## 任务
|
|||
|
|
根据用户提供的文章内容,执行以下分析步骤:
|
|||
|
|
1. **提取主标题:** 精确识别并提取文章最顶层的**主标题**(通常为文章题目或书名)。
|
|||
|
|
2. **构建标题大纲:**
|
|||
|
|
* 从文章中**第一个具体的内容标题**(即忽略文章主标题之后出现的第一个具有层级意义的标题)开始提取。
|
|||
|
|
* 提取所有层级的**内容标题**(Level 1 至 Level 4,Level 1 为最高级)。
|
|||
|
|
* **精确保留**原文中的标题文字,不得进行任何修改、概括或润色。
|
|||
|
|
* 判断标题层级的依据:
|
|||
|
|
* **视觉与结构特征:** 是否独立成行/段、位置(如行首)、格式(如加粗、字体大小、编号 `1.`, `1.1`, `(1)`, `-` 等)。
|
|||
|
|
* **语义逻辑:** 标题之间的包含、并列关系。
|
|||
|
|
3. **分析每个标题对应的正文内容区块:** 对于大纲 (`outline`) 中的每个标题项,分析其**直接管辖**的正文内容区块(即从该标题后开始,直到下一个**同级或更高级别**标题出现之前的所有文本内容)。
|
|||
|
|
* **`content_length` (整数):** 精确统计该正文内容区块的**字符数(含标点、空格)**。
|
|||
|
|
* **`content_summary` (字符串):** 用简洁的语言(1-3句话)概括该区块的**核心要点和关键信息**。
|
|||
|
|
* **`writing_style` (字符串):** 分析该区块的写作方法,需涵盖以下方面:
|
|||
|
|
* **内容组织方式:** 例如,分点论述 (`Listing`)、案例对比 (`Case Comparison`)、时间顺序 (`Chronological`)、问题-解决方案 (`Problem-Solution`)、因果分析 (`Cause-Effect`)、流程说明 (`Process Description`)、论点-论据 (`Argument-Support`) 等。
|
|||
|
|
* **使用的支撑元素:** 例如,数据 (`Data/Statistics`)、图表 (`Charts/Graphs`)、引用 (`Quotes/Citations`)、具体示例 (`Examples`)、类比 (`Analogy`)、定义 (`Definitions`) 等。
|
|||
|
|
* **核心写作技巧:** 例如,先定义后举例 (`Define then Illustrate`)、设置悬念 (`Suspense Building`)、总结强调 (`Summarization & Emphasis`)、使用修辞手法 (`Rhetorical Devices`) 等。分析应具体指出技巧如何应用。
|
|||
|
|
|
|||
|
|
## 输出格式
|
|||
|
|
* 结果**必须**以**严格有效的 JSON 对象**输出。
|
|||
|
|
* JSON 结构如下,不得增减任何字段或改变层级:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"title": "文章主标题",
|
|||
|
|
"outline": [
|
|||
|
|
{
|
|||
|
|
"level": 1, // 或 2, 3, 4
|
|||
|
|
"title": "原文标题文字",
|
|||
|
|
"content_length": 520, // 整数
|
|||
|
|
"content_summary": "内容概括",
|
|||
|
|
"writing_style": "写作方法分析"
|
|||
|
|
},
|
|||
|
|
// ... 其他标题项
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
def llm_format_text(model, base_url, api_key, messages, max_tokens):
|
|||
|
|
all_content = ""
|
|||
|
|
all_reasoning_content = ""
|
|||
|
|
client = OpenAI(api_key=api_key, base_url=base_url)
|
|||
|
|
try:
|
|||
|
|
try:
|
|||
|
|
response = client.chat.completions.create(
|
|||
|
|
model=model,
|
|||
|
|
messages=messages,
|
|||
|
|
temperature=0.99,
|
|||
|
|
top_p=0.5,
|
|||
|
|
response_format={"type": "json_object"},
|
|||
|
|
max_tokens=max_tokens,
|
|||
|
|
stream=True,
|
|||
|
|
extra_body={
|
|||
|
|
"thinking": {
|
|||
|
|
# "type": "enabled",
|
|||
|
|
"type": "disabled"
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"--llm_format_text------异常报错:e={e}-----启用新的llm方式-----")
|
|||
|
|
response = client.chat.completions.create(
|
|||
|
|
model=model,
|
|||
|
|
messages=messages,
|
|||
|
|
temperature=0.99,
|
|||
|
|
top_p=0.5,
|
|||
|
|
response_format={"type": "json_object"},
|
|||
|
|
max_tokens=max_tokens,
|
|||
|
|
stream=True
|
|||
|
|
)
|
|||
|
|
# 获取内容
|
|||
|
|
for chunk in response:
|
|||
|
|
content = ""
|
|||
|
|
reasoning_content = ""
|
|||
|
|
try:
|
|||
|
|
# 判断是 思维链 还是 最终回答
|
|||
|
|
if (hasattr(chunk.choices[0].delta, "reasoning_content") and chunk.choices[0].delta.reasoning_content and (0 < len(chunk.choices[0].delta.reasoning_content))):
|
|||
|
|
reasoning_content = (chunk.choices[0].delta.reasoning_content if chunk.choices[0].delta.reasoning_content else "")
|
|||
|
|
print(reasoning_content)
|
|||
|
|
all_reasoning_content = all_reasoning_content + reasoning_content
|
|||
|
|
else:
|
|||
|
|
content = (chunk.choices[0].delta.content if chunk.choices[0].delta.content else "")
|
|||
|
|
print(content)
|
|||
|
|
all_content = all_content + content
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"--llm_format_text---1---异常报错:e={e}----------")
|
|||
|
|
traceback.print_exc()
|
|||
|
|
print(f'------------------------------------------------')
|
|||
|
|
print(chunk)
|
|||
|
|
print(f'------------------------------------------------')
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"--llm_format_text--2----异常报错:e={e}----------")
|
|||
|
|
traceback.print_exc()
|
|||
|
|
print(f'------------------------------------------------')
|
|||
|
|
# 整个 stream 调用就结束了
|
|||
|
|
# 尝试提取 Markdown 内容
|
|||
|
|
markdown_match = re.search(r"```(?:[^\n]*)\n(.*?)```", all_content, re.DOTALL)
|
|||
|
|
if markdown_match:
|
|||
|
|
all_content = markdown_match.group(1)
|
|||
|
|
# 返回
|
|||
|
|
return all_content
|