Parcourir la source

修改搜索模型

xueyiming il y a 1 jour
Parent
commit
8c62e6ea8a

+ 8 - 8
applications/utils/chat/rag_chat_agent.py

@@ -1,4 +1,5 @@
 import asyncio
+import json
 from typing import List
 
 from applications.config import Chunk
@@ -107,22 +108,21 @@ class RAGChatAgent:
         return response
 
     @staticmethod
-    def make_decision_prompt(chat_res, search_res):
+    def make_decision_prompt(query, chat_res, search_res):
         # 创建一个 prompt 请求给大模型
         prompt = f"""
         这是一个问题的回答任务,以下是两个来源的结果:
 
         1. **RAG 搜索回答**:
-        问题: {chat_res["query"]}
+        问题: {query}
         总结: {chat_res["summary"]}
         相关度评分: {chat_res["relevance_score"]}
         状态: {"可以回答" if chat_res["status"] == 1 else "无法回答"}
 
         2. **AI 搜索结果**:
-        问题: {search_res["question"]}
-        答案: {search_res["answer"]}
-        来源: {search_res["source"]}
-        状态: {"可以回答" if search_res["status"] == 1 else "无法回答"}
+        问题: {query}
+        回复内容: {search_res["content"]}
+        搜索结果: {json.dumps(search_res["search_results"], ensure_ascii=False)}
         
         基于这两个结果,请你综合判断并生成一个更好的答案,如果可能的话。你可以选择结合 `chat_res` 和 `search_res`,或者选择其中更合适的一个进行回答。如果没有足够的信息可以回答,请用你自己已有的知识回答"。
         基于回答的结果,总结回答的答案中使用的工具,名称以及用途,如果没有涉及到工具的使用,则不需要总结
@@ -138,8 +138,8 @@ class RAGChatAgent:
 
         return prompt
 
-    async def make_decision(self, chat_res, search_res):
-        prompt = self.make_decision_prompt(chat_res, search_res)
+    async def make_decision(self, query, chat_res, search_res):
+        prompt = self.make_decision_prompt(query, chat_res, search_res)
         response = await fetch_deepseek_completion(
             model="DeepSeek-R1", prompt=prompt, output_type="json"
         )

+ 0 - 0
applications/utils/search/__init__.py


+ 140 - 0
applications/utils/search/qwen.py

@@ -0,0 +1,140 @@
+import dashscope
+
+
+class QwenClient:
+    def __init__(self):
+        self.api_key = "sk-1022fe8e15ff4e0e9abc20541b281165"
+
+    def chat(self, model="qwen3-max", system_prompt="You are a helpful assistant.", user_prompt=""):
+        """
+        普通聊天,不使用搜索功能
+
+        Args:
+            model: 模型名称,默认为qwen3-max
+            system_prompt: 系统提示词
+            user_prompt: 用户提示词
+
+        Returns:
+            str: AI回复内容
+        """
+        try:
+            messages = [
+                {"role": "system", "content": system_prompt},
+                {"role": "user", "content": user_prompt},
+            ]
+
+            response = dashscope.Generation.call(
+                api_key=self.api_key,
+                model=model,
+                messages=messages,
+                result_format="message"
+            )
+
+            if response.status_code != 200:
+                raise Exception(f"API调用失败: {response.message}")
+
+            return response["output"]["choices"][0]["message"]["content"]
+
+        except Exception as e:
+            raise Exception(f"QwenClient chat失败: {str(e)}")
+
+    def search_and_chat(self, model="qwen3-max", system_prompt="You are a helpful assistant.", user_prompt="", search_strategy="max"):
+        """
+        搜索并聊天
+
+        Args:
+            model: 模型名称,默认为qwen3-max
+            system_prompt: 系统提示词
+            user_prompt: 用户提示词
+            search_strategy: 搜索策略,可选值: turbo, max, agent
+
+        Returns:
+            dict: 包含回复内容和搜索结果
+        """
+        try:
+            messages = [
+                {"role": "system", "content": system_prompt},
+                {"role": "user", "content": user_prompt},
+            ]
+
+            response = dashscope.Generation.call(
+                api_key=self.api_key,
+                model=model,
+                messages=messages,
+                enable_search=True,
+                search_options={
+                    "forced_search": True,
+                    "enable_source": True,
+                    "search_strategy": search_strategy
+                },
+                result_format="message"
+            )
+
+            if response.status_code != 200:
+                raise Exception(f"API调用失败: {response.message}")
+
+            content = response["output"]["choices"][0]["message"]["content"]
+            search_results = []
+
+            if hasattr(response.output, 'search_info') and response.output.search_info:
+                search_results = response.output.search_info.get("search_results", [])
+
+            return {
+                "content": content,
+                "search_results": search_results
+            }
+
+        except Exception as e:
+            raise Exception(f"QwenClient search_and_chat失败: {str(e)}")
+
+
+if __name__ == "__main__":
+    client = QwenClient()
+
+    # 测试
+    try:
+
+        # result = client.chat(user_prompt="hello")
+        # print(result)
+
+        user_prompt = """你是一个专业的信息搜索专家,负责从网络中搜索某个工具的页面操作路径
+
+**名词解释**
+页面操作路径:表示在网页上使用某个工具完成某个功能需要进行的必要操作。通常是分步骤操作,最后形成一个完整的页面操作路径。
+比如:1. 打开xxx网站, 2. 输入xxx提示词, 3. 点击确认按钮, 4. 等待图片生成完成, 5. 返回图片的url
+
+**任务目标**
+搜索并整理 新红热搜词榜单功能 的页面操作路径
+
+**数据要求**
+- 操作页面必须是官方网站,排除任何第三方网站、移动端APP、PC软件
+- 页面操作路径数据最好有详细的操作步骤,如果没有,也可以是简单的操作步骤描述。步骤中如果包含账号注册/登录,需要去除,我们假设网站已经成功登录了
+- 页面操作路径数据要排除关于API的调用数据
+- 保留原始链接用于追溯,输出在 content_link 字段
+- 整理工具的核心功能名称和功能描述
+- 如果有多份数据,保留和任务目标最相关的一份数据即可
+
+**输出要求:**
+严格按照以下JSON格式输出,不添加任何其他文字说明:
+
+{
+  "content_link": "原始链接地址",
+  "功能名称": "具体功能名称",
+  "功能描述": "功能用途和作用描述",
+  "页面操作路径": "完整的页面操作路径"
+}"""
+
+
+        # user_prompt = "请搜索 白瓜AI 官网"
+
+        result = client.search_and_chat(user_prompt=user_prompt, search_strategy="agent")
+
+        print("="*20 + "搜索结果" + "="*20)
+        for web in result["search_results"]:
+            print(f"[{web['index']}]: [{web['title']}]({web['url']})")
+
+        print("="*20 + "回复内容" + "="*20)
+        print(result["content"])
+
+    except Exception as e:
+        print(f"错误: {e}")

+ 8 - 7
mcp_server/server.py

@@ -8,6 +8,7 @@ from mcp.server.lowlevel import Server
 from applications.resource import get_resource_manager
 from applications.utils.chat import RAGChatAgent
 from applications.utils.mysql import ChatResult
+from applications.utils.search.qwen import QwenClient
 from applications.utils.spider.study import study
 from routes.blueprint import query_search
 
@@ -18,7 +19,7 @@ def create_mcp_server() -> Server:
 
     @app.call_tool()
     async def call_tool(
-        name: str, arguments: Dict[str, Any]
+            name: str, arguments: Dict[str, Any]
     ) -> List[types.TextContent]:
         """处理工具调用"""
         # ctx = app.request_context
@@ -77,11 +78,11 @@ async def process_question(question, query_text, rag_chat_agent):
         if chat_result["status"] == 0:
             study_task_id = study(question)["task_id"]
 
-        # 异步获取 LLM 搜索结果
-        llm_search_result = await rag_chat_agent.llm_search(question)
+        qwen_client = QwenClient()
+        llm_search = qwen_client.search_and_chat(user_prompt=question, search_strategy="agent")
 
         # 执行决策逻辑
-        decision = await rag_chat_agent.make_decision(chat_result, llm_search_result)
+        decision = await rag_chat_agent.make_decision(question, chat_result, llm_search)
 
         # 构建返回的数据
         data = {
@@ -99,9 +100,9 @@ async def process_question(question, query_text, rag_chat_agent):
             chat_result["summary"],
             chat_result["relevance_score"],
             chat_result["status"],
-            llm_search_result["answer"],
-            llm_search_result["source"],
-            llm_search_result["status"],
+            llm_search["content"],
+            json.dumps(llm_search["search_results"], ensure_ascii=False),
+            1,
             decision["result"],
             study_task_id,
         )

+ 2 - 1
requirements.txt

@@ -25,4 +25,5 @@ neo4j==5.28.2
 langchain==0.3.27
 langchain-core==0.3.76
 langchain-text-splitters==0.3.11
-mcp==1.14.1
+mcp==1.14.1
+dashscope==1.24.6

+ 24 - 27
routes/blueprint.py

@@ -20,6 +20,7 @@ from applications.resource import get_resource_manager
 from applications.search import HybridSearch
 from applications.utils.chat import RAGChatAgent
 from applications.utils.mysql import Dataset, Contents, ContentChunks, ChatResult
+from applications.utils.search.qwen import QwenClient
 from applications.utils.spider.study import study
 
 server_bp = Blueprint("api", __name__, url_prefix="/api")
@@ -302,16 +303,16 @@ async def content_list():
 
 
 async def query_search(
-    query_text,
-    filters=None,
-    search_type="",
-    anns_field="vector_text",
-    search_params=BASE_MILVUS_SEARCH_PARAMS,
-    _source=False,
-    es_size=10000,
-    sort_by=None,
-    milvus_size=20,
-    limit=10,
+        query_text,
+        filters=None,
+        search_type="",
+        anns_field="vector_text",
+        search_params=BASE_MILVUS_SEARCH_PARAMS,
+        _source=False,
+        es_size=10000,
+        sort_by=None,
+        milvus_size=20,
+        limit=10,
 ):
     if filters is None:
         filters = {}
@@ -413,17 +414,15 @@ async def chat():
             result["datasetName"] = dataset_name
 
     rag_chat_agent = RAGChatAgent()
+    qwen_client = QwenClient()
     chat_result = await rag_chat_agent.chat_with_deepseek(query_text, query_results)
-    # study_task_id = None
-    # if chat_result["status"] == 0:
-    #     study_task_id = study(query_text)['task_id']
-    llm_search = await rag_chat_agent.llm_search(query_text)
-    decision = await rag_chat_agent.make_decision(chat_result, llm_search)
+    llm_search = qwen_client.search_and_chat(user_prompt=query_text, search_strategy="agent")
+    decision = await rag_chat_agent.make_decision(query_text, chat_result, llm_search)
     data = {
         "results": query_results,
         "chat_res": decision["result"],
         "rag_summary": chat_result["summary"],
-        "llm_summary": llm_search["answer"],
+        "llm_summary": llm_search["content"],
         # "used_tools": decision["used_tools"],
     }
     await chat_result_mapper.insert_chat_result(
@@ -433,9 +432,9 @@ async def chat():
         chat_result["summary"],
         chat_result["relevance_score"],
         chat_result["status"],
-        llm_search["answer"],
-        llm_search["source"],
-        llm_search["status"],
+        llm_search["content"],
+        json.dumps(llm_search["search_results"], ensure_ascii=False),
+        1,
         decision["result"],
         is_web=1,
     )
@@ -561,11 +560,9 @@ async def process_question(question, query_text, rag_chat_agent):
         if chat_result["status"] == 0:
             study_task_id = study(question)["task_id"]
 
-        # 异步获取 LLM 搜索结果
-        llm_search_result = await rag_chat_agent.llm_search(question)
-
-        # 执行决策逻辑
-        decision = await rag_chat_agent.make_decision(chat_result, llm_search_result)
+        qwen_client = QwenClient()
+        llm_search = qwen_client.search_and_chat(user_prompt=query, search_strategy="agent")
+        decision = await rag_chat_agent.make_decision(query_text, chat_result, llm_search)
 
         # 构建返回的数据
         data = {
@@ -584,9 +581,9 @@ async def process_question(question, query_text, rag_chat_agent):
             chat_result["summary"],
             chat_result["relevance_score"],
             chat_result["status"],
-            llm_search_result["answer"],
-            llm_search_result["source"],
-            llm_search_result["status"],
+            llm_search["content"],
+            json.dumps(llm_search["search_results"], ensure_ascii=False),
+            1,
             decision["result"],
             study_task_id,
         )