From af250800d6e4844107be9dd8549e617493ceacdf Mon Sep 17 00:00:00 2001 From: DelLevin-Home Date: Thu, 15 Jan 2026 14:20:44 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 + .idea/inspectionProfiles/Project_Default.xml | 23 +++ .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 7 + .idea/modules.xml | 8 + .idea/python_script.iml | 10 ++ .../__pycache__/extract_doc_tag.cpython-312.pyc | Bin 0 -> 4507 bytes 根据文章内容生成标签/extract_doc_tag.py | 138 ++++++++++++++++++ 根据文章内容生成标签/main.py | 36 +++++ 根据文章内容生成标签/test.txt | 28 ++++ 10 files changed, 264 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/python_script.iml create mode 100644 根据文章内容生成标签/__pycache__/extract_doc_tag.cpython-312.pyc create mode 100644 根据文章内容生成标签/extract_doc_tag.py create mode 100644 根据文章内容生成标签/main.py create mode 100644 根据文章内容生成标签/test.txt diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..0077c35 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,23 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..e977e8a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..757243a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/python_script.iml b/.idea/python_script.iml new file mode 100644 index 0000000..2c80e12 --- /dev/null +++ b/.idea/python_script.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/根据文章内容生成标签/__pycache__/extract_doc_tag.cpython-312.pyc b/根据文章内容生成标签/__pycache__/extract_doc_tag.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f26bdbe59b55a034aac946ebeb983a62af313d4 GIT binary patch literal 4507 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 literal 0 HcmV?d00001 diff --git a/根据文章内容生成标签/extract_doc_tag.py b/根据文章内容生成标签/extract_doc_tag.py new file mode 100644 index 0000000..900c550 --- /dev/null +++ b/根据文章内容生成标签/extract_doc_tag.py @@ -0,0 +1,138 @@ +import requests +import json +import re +import time # 导入 time 模块 + +OLLAMA_BASE_URL = "http://127.0.0.1:11434/api/generate" +def extract_tags_with_ollama_from_content(model, article_content, max_tags=10, min_length=2, max_length=6): + """ + 使用本地 Ollama 大语言模型分析文章内容并提取关键词。 + + Args: + article_content (str): 输入的文章内容字符串。 + max_tags (int): 希望返回的最大标签数量。 + min_length (int): 关键词最小长度。 + max_length (int): 关键词最大长度。 + + Returns: + list: 提取到的关键词/标签列表。 + """ + if not article_content or not article_content.strip(): + return { + 'code': 0, + 'message': 'success', + 'data': { + 'model': model, + 'think': '警告:输入的文章内容为空或仅包含空白字符。', + 'tags': [], + 'consume': 0.0 + } + } + + # 2. 构建 Prompt + # 使用中文提示,更符合 qwen 模型的特点 + prompt = f""" +请严格按照以下要求,从提供的文章内容中提取关键词。 + +文章内容: +{article_content} + +要求: +- 提取最多 {max_tags} 个最能概括文章主旨和核心概念的关键词。 +- 关键词必须来源于文章内容,准确反映文章主题。 +- 每个关键词的长度必须在 {min_length} 到 {max_length} 个字符之间。 +- 输出格式为:关键词1, 关键词2, 关键词3, ... +- 只输出关键词列表,不要有任何其他解释或前缀。 + +""" + # 记录开始时间 + start_time = time.time() + # 3. 准备发送给 Ollama API 的 payload + payload = { + "model": model, + "prompt": prompt, + "system": "你是一个专门生成文章标签的助手,请你根据我给你的文章的内容总结并生成一系列的标签,格式可以参考[关键词1, 关键词2, 关键词3].你只需要给我生成这种形式的标签即可,其他分析内容无需输出.", + "stream": False, + "options": { + "top_p": 0.9, + "temperature": 0.1, # 较低的温度使输出更确定、更聚焦 + "num_predict": 64000, # 控制预测的最大 token 数 + } + } + + try: + # 4. 发送 POST 请求到 Ollama API + response = requests.post(OLLAMA_BASE_URL, json=payload) + # 5. 检查响应状态 + if response.status_code != 200: + # print(f"Error: Ollama API returned status code {response.status_code}") + print(response.text) + return { + 'code': 404, + 'message': f"{response['error']}", + } + # 6. 解析 JSON 响应 + result = response.json() + if "response" not in result: + print(result) + return { + 'code': 500, + 'message': "Error: Unexpected response format from Ollama", + } + + llm_output = result["response"].strip() + # print(llm_output) + think_match = re.search(r'(.*?)', llm_output, re.DOTALL) + ai_think = think_match.group(1).strip() if think_match else "" + # 移除 ... 标签及其内容,得到纯净的关键词列表部分 + clean_output = re.sub(r'.*?', '', llm_output, count=1, flags=re.DOTALL).strip() + # 7. 简单清洗和验证关键词 + # 假设 LLM 输出格式为 "关键词1, 关键词2, ..." + raw_tags = [tag.strip() for tag in clean_output.split(',') if tag.strip()] + # print(raw_tags) + # 过滤掉不符合长度要求的词 + # filtered_tags = [ + # tag for tag in raw_tags + # if min_length <= len(tag) <= max_length and tag # 忽略空字符串 + # ] + # 去重并保持顺序 + seen = set() + unique_filtered_tags = [] + for tag in raw_tags: + if tag not in seen: + seen.add(tag) + unique_filtered_tags.append(tag) + + # 记录结束时间 + end_time = time.time() + # 计算耗时 + elapsed_time = end_time - start_time + return { + 'code':0, + 'message': 'success', + 'data': { + 'model': model, + 'think': ai_think, + 'tags': unique_filtered_tags, + 'consume': elapsed_time + } + } + + except requests.exceptions.RequestException as e: + # print(f"Error calling Ollama API: {e}") + return { + 'code': 500, + 'message': f"Error calling Ollama API: {e}", + } + except json.JSONDecodeError as e: + # print(f"Error decoding JSON response from Ollama: {e}") + return { + 'code': 500, + 'message': f"Error decoding JSON response from Ollama: {e}" + } + except Exception as e: + # print(f"An unexpected error occurred: {e}") + return { + 'code': 500, + 'message': f"An unexpected error occurred: {e}" + } diff --git a/根据文章内容生成标签/main.py b/根据文章内容生成标签/main.py new file mode 100644 index 0000000..fcf5482 --- /dev/null +++ b/根据文章内容生成标签/main.py @@ -0,0 +1,36 @@ +import extract_doc_tag as ex_doc_tag + +# --- 方式一:指定文件路径 --- +file_path = 'test.txt' + +try: + with open(file_path, 'r', encoding='utf-8') as file: + my_article_content = file.read() +except FileNotFoundError: + print(f"错误:找不到文件 '{file_path}'") + exit(1) +except Exception as e: + print(f"读取文件时发生错误: {e}") + exit(1) + +model = "qwen3:1.7b" +extracted_tags = ex_doc_tag.extract_tags_with_ollama_from_content( + model, + my_article_content, + max_tags=8, + min_length=2, + max_length=6 +) + +if extracted_tags['code'] == 0: + print('思考过程:') + print(extracted_tags['data']['think']) + print('=' * 60) + print('文章内容长度', len(my_article_content)) + # print(f"Ollama 模型:{model}") + print('=' * 60) + print('文章标签:', extracted_tags['data']['tags']) + print('=' * 60) + print(f"总耗时: {extracted_tags['data']['consume']:.2f} 秒") +else: + print(extracted_tags) diff --git a/根据文章内容生成标签/test.txt b/根据文章内容生成标签/test.txt new file mode 100644 index 0000000..3e7af0e --- /dev/null +++ b/根据文章内容生成标签/test.txt @@ -0,0 +1,28 @@ + +一位作家曾说过:“我想换一种方式,换一只手,也许是练好字的一个新契机。”由此可见,尝试换一只手做事,说不定能遇见全新的自己,将目光移开,可能会发现更广阔的天地,发现新的机遇。‍ + + +< 01 >要善于发现机会 +生活中,有人埋怨大展宏图的机会很少。 +殊不知,在你不以为然的事情中,恰恰藏着机会的钥匙。 +那些逆袭转运的人,会主动从危机中发现转机,在困境中寻觅出口,一旦发现契机,便会毫不犹豫抓住,打破困局、迎来重生。 + +< 02 >要有把握机会的勇气 +很多时候,人生变好不在于能力的高下、学识的多少,而在于你是否具备打开新思路、把握新时机的勇气。 +很喜欢一句话:“决定我们成为什么样人的,不是我们的能力,而是我们的选择。” +换个角度看世界,世界也会以更广阔的面貌回馈于你。 + +< 03 >要为机会做出努力 +人生有种困境叫路径依赖。 +有时候,阻碍我们发展进步的,恰恰是那些不断被证明有效的经验。 +过分依赖路径,内在的智慧就难以发挥。没有行动,什么都不会发生。 +这个世界上,大部分人最缺的不是机遇,而是抓住机会的执行力。 +光想不做,只会让梦想落空,永远困于原地。 +唯有敲碎经验牢笼,才能在机遇一闪而过时快速把握、顺势而为。 +摒弃干扰因素,放下惯性洞察,不断评估和修正自己。 +不盲从、不武断地抓住破局点,做出明智判断,开启全新人生。 +“挡在你面前的,只有你自己。” +人这一生,需要不断刷新自己、重塑自己。 +转变思维,拆掉内心的高墙,难题才能迎刃而解;换另一只手做事,方可不断成长、越来越强。 + +