فهرست منبع

增加总结功能

xueyiming 2 ماه پیش
والد
کامیت
402ce77019
3فایلهای تغییر یافته به همراه61 افزوده شده و 183 حذف شده
  1. 21 9
      api/search.py
  2. 3 3
      service/search_service.py
  3. 37 171
      utils/deepseek_utils.py

+ 21 - 9
api/search.py

@@ -6,7 +6,8 @@ from schemas import ResponseWrapper
 from schemas.schemas import ContentParam, DatasetParam
 from service.content_service import get_contents, add_contents, get_content
 from service.dataset_service import get_datasets, add_datasets
-from utils.embedding_utils import get_embedding_content_data
+from service.search_service import query_data
+from utils.deepseek_utils import generate_summary_query
 
 router = APIRouter()
 
@@ -15,15 +16,25 @@ executor = ThreadPoolExecutor(max_workers=10)
 
 
 @router.get("/query", response_model=ResponseWrapper)
-async def query_keyword(query, datasetIds):
-    print(query)
-    print(datasetIds)
-    embedding_res = get_embedding_content_data(query, datasetIds.split(','))
-    res = {'results': embedding_res}
+async def query(query, datasetIds):
+    res = query_data(query, datasetIds.split(','))
+    data = {'results': res}
     return ResponseWrapper(
         status_code=200,
         detail="success",
-        data=res
+        data=data
+    )
+
+
+@router.get("/chat", response_model=ResponseWrapper)
+async def chat(query, datasetIds):
+    res = query_data(query, datasetIds.split(','))
+    chat_res = generate_summary_query(query, res)
+    data = {'results': res, 'chat_res': chat_res}
+    return ResponseWrapper(
+        status_code=200,
+        detail="success",
+        data=data
     )
 
 
@@ -56,8 +67,9 @@ async def dataset_list():
         data=data
     )
 
+
 @router.post("/dataset/add", response_model=ResponseWrapper)
-async def get_dataset(dataset_param : DatasetParam):
+async def get_dataset(dataset_param: DatasetParam):
     res = add_datasets(dataset_param)
     return ResponseWrapper(
         status_code=200,
@@ -73,4 +85,4 @@ async def content_get(docId):
         status_code=200,
         detail="success",
         data=data
-    )
+    )

+ 3 - 3
utils/embedding_utils.py → service/search_service.py

@@ -7,7 +7,7 @@ from data_models.content_chunks import ContentChunks
 from data_models.dataset import Dataset
 
 
-def get_embedding_data(query, dataset_ids, limit=10):
+def search_data(query, dataset_ids, limit=10):
     try:
         response = requests.post(
             url='http://61.48.133.26:8001/api/search',
@@ -25,10 +25,10 @@ def get_embedding_data(query, dataset_ids, limit=10):
         logger.error(e)
 
 
-def get_embedding_content_data(query, dataset_ids):
+def query_data(query, dataset_ids):
     res = []
     db_helper = DBHelper()
-    results = get_embedding_data(query, dataset_ids)
+    results = search_data(query, dataset_ids)
     if results:
         for result in results:
             content_chunk = db_helper.get(ContentChunks, doc_id=result['doc_id'], chunk_id=result['chunk_id'])

+ 37 - 171
utils/deepseek_utils.py

@@ -1,189 +1,54 @@
-from typing import List
 import json
 from openai import OpenAI
 
+from service.search_service import query_data
 
-def create_segmentation_prompt(text):
-    prompt = f"""
-请对以下文本进行分段处理,要求如下:
-
-1. **内容相近原则**:将语义相近、主题一致的内容划分到同一段落
-2. **长度适中**:每段不要太长(一般不超过200字)也不要太短(一般不少于50字)
-3. **语意完整**:确保每段都能表达一个相对完整的意思或观点
-4. **结构清晰**:保持原文的逻辑顺序,不要改变原意
-5. **过渡自然**:段落之间应有合理的过渡或衔接
-6. **关键词提取**:提取5-8个最能代表当前分析范围(整体或段落)核心内容的关键词或短语。避免使用过于通用和宽泛的词汇。
-7. **实体提取**:识别并分类以下类型的实体(如果存在):
-    *   人物姓名、别名、称号。
-    *   组织、公司、机构、政府部门。
-    *   地点、国家、城市、区域。
-    *   绝对或相对的日期、时间、年份、时期。
-    *   产品、作品、物品的名称。
-    *   历史事件、会议、活动名称。
-    (*注:实体需要去重)
-
-请直接输出分段后的文本,不需要额外解释或标注
-
-请返回以下JSON格式:
-{{
-  "segments": [
-    {{
-      "id": 1,
-      "content": "第一段内容",
-      "summary": "本段摘要",
-      "keywords": ["关键词1", "关键词2", ...],
-      "entities": ["实体1", "实体2", ...]
-    }},
-    {{
-      "id": 2,
-      "content": "第二段内容", 
-      "summary": "本段摘要",
-      "keywords": ["关键词1", "关键词2", ...],
-      "entities": ["实体1", "实体2", ...]
-    }}
-  ],
-  "total_segments": 2
-}}
-
-需要分段的文本:
-"{text}"
-"""
-    return prompt
-
-
-def text_segment(text: str):
-    prompt = create_segmentation_prompt(text)
-    res = chat_with_deepseek(prompt)
-    return res
 
-
-def create_question_generation_prompt(text):
+def generate_summary_prompt(query, search_results):
     """
-    创建生成文本内容问题的 prompt
-
-    参数:
-        text (str): 需要生成问题的文本
-        num_questions (int): 需要生成的问题数量
+    生成总结的prompt。
 
-    返回:
-        str: 格式化后的 prompt
+    :param query: 问题
+    :param search_results: 搜索结果列表,每个元素包含 'content', 'contentSummary', 'score'
+    :return: 生成的总结prompt
     """
-    prompt = f"""
-请基于以下文本内容生成相关问题。要求:
-
-1. 问题应覆盖文本的主要内容和关键信息
-2. 问题类型多样(事实性、理解性、分析性等)
-3. 问题应清晰明确,易于理解
-4. 问题不应过于简单或复杂,适合文本内容的理解深度
-
-请以严格的 JSON 数组格式返回结果,每个元素是一个问题对象,包含以下字段:
-- id: 问题序号(从1开始)
-- question: 问题文本
-
-请返回以下JSON格式:
-{{
-  "questions": ["问题1", "问题2", ...]
-}}
-
-文本内容:
-"{text}"
-"""
-    return prompt
 
+    # 为了让AI更好地理解,我们将使用以下格式构建prompt:
+    prompt = f"问题: {query}\n\n请结合以下搜索结果,生成一个总结:\n"
 
-def text_question(text_to_question: str):
-    prompt = create_question_generation_prompt(text_to_question)
-    return chat_with_deepseek(prompt)
+    # 先生成基于相似度加权的summary
+    weighted_summaries = []
+    weighted_contents = []
 
+    for result in search_results:
+        content = result['content']
+        content_summary = result['contentSummary']
+        score = result['score']
 
-def create_keyword_summary_prompt(text, keyword):
-    prompt = f"""
-    
-    请基于以下关于关键词"{keyword}"的多条知识,生成一段全面、准确且连贯的知识,不要输出与知识无关的内容,只返回关键词知识内容。
+        # 加权内容摘要和内容
+        weighted_summaries.append((content_summary, score))
+        weighted_contents.append((content, score))
 
-## 描述内容:
-{text}
+    # 为了生成更准确的总结,基于相似度加权内容和摘要
+    weighted_summaries.sort(key=lambda x: x[1], reverse=True)  # 按相似度降序排列
+    weighted_contents.sort(key=lambda x: x[1], reverse=True)  # 按相似度降序排列
 
-## 知识要求:
-1. 识别重叠与重复:找出不同文本中表述不同但含义相同的内容。
-2. 解决矛盾与冲突:当不同文本的信息不一致时,需要辨别或调和。
-3. 建立联系与结构:将分散的知识点连接起来,形成逻辑层次。
-4. 提炼与升华:从合并后的信息中总结出更高层次的洞察和结论。
+    # 将加权的摘要和内容加入到prompt中
+    prompt += "\n-- 加权内容摘要 --\n"
+    for summary, score in weighted_summaries:
+        prompt += f"摘要: {summary} | 相似度: {score:.2f}\n"
 
+    prompt += "\n-- 加权内容 --\n"
+    for content, score in weighted_contents:
+        prompt += f"内容: {content} | 相似度: {score:.2f}\n"
 
-请返回以下JSON格式:
-{{
-  "keyword_summary": "关键词知识内容"
-}}
+    # 最后请求AI进行总结
+    prompt += "\n基于上述内容,请帮我生成一个简洁的总结。"
 
-"""
     return prompt
 
-
-def get_keyword_summary(text, keyword):
-    prompt = create_keyword_summary_prompt(text, keyword)
-    return chat_with_deepseek(prompt)
-
-
-def update_keyword_summary_prompt(text, keyword, new_content):
-    prompt = f"""
-
-    请基于以下关于关键词"{keyword}"的相关知识,融合最新的知识到现有的知识中,不要输出与知识无关的内容,只返回关键词知识内容。
-
-## 知识要求:
-1. 识别重叠与重复:找出不同文本中表述不同但含义相同的内容。
-2. 解决矛盾与冲突:当不同文本的信息不一致时,需要辨别或调和。
-3. 建立联系与结构:将分散的知识点连接起来,形成逻辑层次。
-4. 提炼与升华:从合并后的信息中总结出更高层次的洞察和结论。
-
-## 现有知识:
-{text}
-
-## 新知识:
-{new_content}
-
-
-请返回以下JSON格式:
-{{
-  "keyword_summary": "关键词知识内容"
-}}
-
-"""
-    return prompt
-
-
-def update_keyword_summary(text, keyword, new_content):
-    prompt = update_keyword_summary_prompt(text, keyword, new_content)
-    return chat_with_deepseek(prompt)
-
-
-def create_keyword_prompt(text):
-    """
-    创建生成关键词总结的 prompt
-
-    参数:
-        text (str): 需要生成总结的文本
-        keyword (int): 关键词
-
-    返回:
-        str: 格式化后的 prompt
-    """
-    prompt = f"""
-提取最能代表当前分析范围(整体或段落)核心内容的关键词或短语,如果本身就是一个词,直接返回这个词。避免使用过于通用和宽泛的词汇,
-## 描述内容:
-{text}
-
-请返回以下JSON格式:
-{{
-  "keywords": ["关键词1", "关键词2", ...]
-}}
-
-"""
-    return prompt
-
-
-def get_keywords(text):
-    prompt = create_keyword_prompt(text)
+def generate_summary_query(query, search_results):
+    prompt = generate_summary_prompt(query, search_results)
     return chat_with_deepseek(prompt)
 
 
@@ -213,16 +78,17 @@ def chat_with_deepseek(prompt, model="deepseek-chat", max_tokens=8192, temperatu
             messages=[{"role": "user", "content": prompt}],
             max_tokens=max_tokens,
             temperature=temperature,
-            stream=False,
-            response_format={"type": "json_object"}
+            stream=False
         )
 
         # 返回回复内容
-        return json.loads(response.choices[0].message.content)
+        return response.choices[0].message.content
 
     except Exception as e:
         return f"发生异常: {str(e)}"
 
 
 if __name__ == '__main__':
-    print(get_keyword_summary('这样去发布你的视频,才能增加播放量! #新人如何做抖音 #短视频创业 #自媒体创业 #抖音创业','播放量'))
+    query = '帮我查询一些AI工具'
+    search_results = query_data(query, [1,2])
+    print(generate_summary_query(query, search_results))