diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml index 71e7d66e..e2c35e67 100644 --- a/main/xiaozhi-server/config.yaml +++ b/main/xiaozhi-server/config.yaml @@ -82,14 +82,12 @@ selected_module: TTS: EdgeTTS # 记忆模块,默认不开启记忆;如果想使用超长记忆,推荐使用mem0ai;如果注重隐私,请使用本地的mem_local_short Memory: nomem - # 意图识别模块,默认使用function_call。开启后,可以播放音乐、控制音量、识别退出指令 - # 意图识别使用intent_llm,优点:通用性强,缺点:增加串行前置意图识别模块,会增加处理时间 - # 意图识别使用function_call,缺点:需要所选择的LLM支持function_call,优点:按需调用工具、速度快 + # 意图识别模块开启后,可以播放音乐、控制音量、识别退出指令。 + # 不想开通意图识别,就设置成:nointent + # 意图识别可使用intent_llm,如果你的LLM是DifyLLM或CozeLLM,建议使用这个。优点:通用性强,缺点:增加串行前置意图识别模块,会增加处理时间,这个意图识别暂时不支持控制音量大小等iot操作 + # 意图识别可使用function_call,缺点:需要所选择的LLM支持function_call,优点:按需调用工具、速度快,理论上能全部操作所有iot指令 # 默认免费的ChatGLMLLM就已经支持function_call,但是如果像追求稳定建议把LLM设置成:DoubaoLLM,使用的具体model_name是:doubao-pro-32k-functioncall-241028 - Intent: intent_llm - -# 意图识别专用LLM配置,如果设置,则意图识别会使用这个模型而不是主LLM -IntentLLM: XinferenceSmallLLM #ChatGLMLLM #XinferenceSmallLLM # 设置为空字符串""或不设置则使用主LLM + Intent: function_call # 意图识别,是用于理解用户意图的模块,例如:播放音乐 Intent: @@ -100,9 +98,13 @@ Intent: intent_llm: # 不需要动type type: intent_llm + # 配备意图识别独立的思考模型 + # 如果这里不填,则会默认使用selected_module.LLM的模型作为意图识别的思考模型 + # 如果你的selected_module.LLM选择了DifyLLM或CozeLLM,这里最好使用独立的LLM作为意图识别,例如使用免费的ChatGLMLLM + llm: ChatGLMLLM function_call: # 不需要动type - type: nointent + type: function_call # plugins_func/functions下的模块,可以通过配置,选择加载哪个模块,加载后对话支持相应的function调用 # 系统默认已经记载“handle_exit_intent(退出识别)”、“play_music(音乐播放)”插件,请勿重复加载 # 下面是加载查天气、角色切换、加载查新闻的插件示例 @@ -184,18 +186,6 @@ VAD: LLM: # 所有openai类型均可以修改超参,以AliLLM为例 # 当前支持的type为openai、dify、ollama,可自行适配 - XinferenceLLM: - # 定义LLM API类型 - type: xinference - # Xinference服务地址和模型名称 - model_name: qwen2.5:72b-AWQ # 使用的模型名称,需要预先在Xinference启动对应模型 - base_url: http://localhost:9997 # Xinference服务地址 - XinferenceSmallLLM: - # 定义轻量级LLM API类型,用于意图识别 - type: xinference - # Xinference服务地址和模型名称 - model_name: qwen2.5:3b-AWQ # 使用的小模型名称,用于意图识别 - base_url: http://localhost:9997 # Xinference服务地址 AliLLM: # 定义LLM API类型 type: openai @@ -293,6 +283,18 @@ LLM: variables: k: "v" k2: "v2" + XinferenceLLM: + # 定义LLM API类型 + type: xinference + # Xinference服务地址和模型名称 + model_name: qwen2.5:72b-AWQ # 使用的模型名称,需要预先在Xinference启动对应模型 + base_url: http://localhost:9997 # Xinference服务地址 + XinferenceSmallLLM: + # 定义轻量级LLM API类型,用于意图识别 + type: xinference + # Xinference服务地址和模型名称 + model_name: qwen2.5:3b-AWQ # 使用的小模型名称,用于意图识别 + base_url: http://localhost:9997 # Xinference服务地址 TTS: # 当前支持的type为edge、doubao,可自行适配 EdgeTTS: diff --git a/main/xiaozhi-server/config/logger.py b/main/xiaozhi-server/config/logger.py index 2206e52c..89d991e3 100644 --- a/main/xiaozhi-server/config/logger.py +++ b/main/xiaozhi-server/config/logger.py @@ -13,7 +13,7 @@ def setup_logging(): log_format_file = log_config.get("log_format_file", "{time:YYYY-MM-DD HH:mm:ss} - {version_{selected_module}} - {name} - {level} - {extra[tag]} - {message}") selected_module = config.get("selected_module") - selected_module_str = ''.join([key[0] + value[0] for key, value in selected_module.items()]) + selected_module_str = ''.join([value[0] + value[1] for key, value in selected_module.items()]) log_format = log_format.replace("{version}", SERVER_VERSION) log_format = log_format.replace("{selected_module}", selected_module_str) diff --git a/main/xiaozhi-server/core/connection.py b/main/xiaozhi-server/core/connection.py index 07c9c779..10ffc8f6 100644 --- a/main/xiaozhi-server/core/connection.py +++ b/main/xiaozhi-server/core/connection.py @@ -197,12 +197,12 @@ class ConnectionHandler: """为意图识别设置LLM,优先使用专用LLM""" # 检查是否配置了专用的意图识别LLM - intent_llm_name = self.config.get("IntentLLM", "") + intent_llm_name = self.config["Intent"]["intent_llm"]["llm"] # 记录开始初始化意图识别LLM的时间 intent_llm_init_start = time.time() - if intent_llm_name and intent_llm_name in self.config["LLM"]: + if not self.use_function_call_mode and intent_llm_name and intent_llm_name in self.config["LLM"]: # 如果配置了专用LLM,则创建独立的LLM实例 from core.utils import llm as llm_utils intent_llm_config = self.config["LLM"][intent_llm_name] diff --git a/main/xiaozhi-server/core/handle/intentHandler.py b/main/xiaozhi-server/core/handle/intentHandler.py index 900a25cf..c63ca329 100644 --- a/main/xiaozhi-server/core/handle/intentHandler.py +++ b/main/xiaozhi-server/core/handle/intentHandler.py @@ -4,8 +4,7 @@ import uuid from core.handle.sendAudioHandle import send_stt_message from core.handle.helloHandle import checkWakeupWords from core.utils.util import remove_punctuation_and_length -import re -import asyncio +from core.utils.dialogue import Message from loguru import logger TAG = __name__ @@ -65,242 +64,46 @@ async def process_intent_result(conn, intent_result, original_text): try: # 尝试将结果解析为JSON intent_data = json.loads(intent_result) - + # 检查是否有function_call if "function_call" in intent_data: # 直接从意图识别获取了function_call logger.bind(tag=TAG).info(f"检测到function_call格式的意图结果: {intent_data['function_call']['name']}") - function_name = intent_data["function_call"]["name"] - function_args = intent_data["function_call"]["arguments"] - + if function_name == "continue_chat": + return False + function_args = None + if "arguments" in intent_data["function_call"]: + function_args = intent_data["function_call"]["arguments"] # 确保参数是字符串格式的JSON if isinstance(function_args, dict): function_args = json.dumps(function_args) - + function_call_data = { "name": function_name, "id": str(uuid.uuid4().hex), "arguments": function_args } - - # 处理特定类型的函数调用 - if function_name == "get_weather": - logger.bind(tag=TAG).info(f"识别到天气查询意图") - # 先发送消息确认 - await send_stt_message(conn, original_text) - - # 使用executor执行函数调用和结果处理 - def process_weather_query(): - # 直接调用函数 - result = conn.func_handler.handle_llm_function_call(conn, function_call_data) - if result: - # 获取当前最新的文本索引 - text_index = conn.tts_last_text_index + 1 if hasattr(conn, 'tts_last_text_index') else 0 - # 处理函数调用结果 - conn._handle_function_result(result, function_call_data, text_index) - - # 将函数执行放在线程池中 - conn.executor.submit(process_weather_query) - return True - - elif function_name == "play_music": - logger.bind(tag=TAG).info(f"识别到音乐播放意图") - # 先发送消息确认 - await send_stt_message(conn, original_text) - - # 使用executor执行函数调用和结果处理 - def process_music_query(): - # 直接调用函数 - result = conn.func_handler.handle_llm_function_call(conn, function_call_data) - if result: - # 获取当前最新的文本索引 - text_index = conn.tts_last_text_index + 1 if hasattr(conn, 'tts_last_text_index') else 0 - # 处理函数调用结果 - conn._handle_function_result(result, function_call_data, text_index) - - # 将函数执行放在线程池中 - conn.executor.submit(process_music_query) - return True - - elif function_name == "get_news": - logger.bind(tag=TAG).info(f"识别到新闻查询意图") - # 先发送消息确认 - await send_stt_message(conn, original_text) - - # 使用executor执行函数调用和结果处理 - def process_news_query(): - # 直接调用函数 - result = conn.func_handler.handle_llm_function_call(conn, function_call_data) - if result: - # 获取当前最新的文本索引 - text_index = conn.tts_last_text_index + 1 if hasattr(conn, 'tts_last_text_index') else 0 - # 处理函数调用结果 - conn._handle_function_result(result, function_call_data, text_index) - - # 将函数执行放在线程池中 - conn.executor.submit(process_news_query) - return True - - else: - # 其他类型的函数调用,尝试直接执行 - # 先发送消息确认 - await send_stt_message(conn, original_text) - - # 使用executor执行函数调用和结果处理 - def process_function_call(): - result = conn.func_handler.handle_llm_function_call(conn, function_call_data) - if result: - # 获取当前最新的文本索引 - text_index = conn.tts_last_text_index + 1 if hasattr(conn, 'tts_last_text_index') else 0 - # 处理函数调用结果 - conn._handle_function_result(result, function_call_data, text_index) - - # 将函数执行放在线程池中 - conn.executor.submit(process_function_call) - return True - - # 处理传统意图格式 - elif "intent" in intent_data: - intent = intent_data["intent"] - - # 处理退出意图 - if "结束聊天" in intent: - logger.bind(tag=TAG).info(f"识别到退出意图: {intent}") - # 如果是明确的离别意图,发送告别语并关闭连接 - await send_stt_message(conn, original_text) - conn.executor.submit(conn.chat_and_close, original_text) - return True - - # 其他不需要特殊处理的意图,让常规聊天流程处理 - return False - - except json.JSONDecodeError: - # 如果不是有效的JSON,尝试兼容旧格式 - intent = intent_result - - # 处理退出意图 - if "结束聊天" in intent: - logger.bind(tag=TAG).info(f"识别到退出意图: {intent}") - # 如果是明确的离别意图,发送告别语并关闭连接 - await send_stt_message(conn, original_text) - conn.executor.submit(conn.chat_and_close, original_text) - return True - # 处理播放音乐意图 - if "播放音乐" in intent: - logger.bind(tag=TAG).info(f"识别到音乐播放意图: {intent}") - # 获取歌曲名称 - song_name = extract_text_in_brackets(intent) - - # 先发送消息确认 await send_stt_message(conn, original_text) - - # 构造合适的音乐播放函数调用 - function_id = str(uuid.uuid4().hex) - function_name = "play_music" - function_arguments = '{ "song_name": ' + (f'"{song_name}"' if song_name else '"random"') + ' }' - - function_call_data = { - "name": function_name, - "id": function_id, - "arguments": function_arguments - } - + # 使用executor执行函数调用和结果处理 - def process_music_query(): - # 直接调用函数 + def process_function_call(): + conn.dialogue.put(Message(role="user", content=original_text)) result = conn.func_handler.handle_llm_function_call(conn, function_call_data) if result: # 获取当前最新的文本索引 text_index = conn.tts_last_text_index + 1 if hasattr(conn, 'tts_last_text_index') else 0 # 处理函数调用结果 conn._handle_function_result(result, function_call_data, text_index) - + # 将函数执行放在线程池中 - conn.executor.submit(process_music_query) + conn.executor.submit(process_function_call) return True - - # 处理查询天气意图 - if "查询天气" in intent: - logger.bind(tag=TAG).info(f"识别到天气查询意图: {intent}") - # 获取地点 - location = extract_text_in_brackets(intent) - - # 先发送消息确认 - await send_stt_message(conn, original_text) - - # 构造合适的天气查询函数调用 - function_id = str(uuid.uuid4().hex) - function_name = "get_weather" - function_arguments = '{ "location": ' + (f'"{location}"' if location and location != "当前位置" else 'null') + ', "lang": "zh_CN" }' - - function_call_data = { - "name": function_name, - "id": function_id, - "arguments": function_arguments - } - - # 使用executor执行函数调用和结果处理 - def process_weather_query(): - # 直接调用函数 - result = conn.func_handler.handle_llm_function_call(conn, function_call_data) - if result: - # 获取当前最新的文本索引 - text_index = conn.tts_last_text_index + 1 if hasattr(conn, 'tts_last_text_index') else 0 - # 处理函数调用结果 - conn._handle_function_result(result, function_call_data, text_index) - - # 将函数执行放在线程池中 - conn.executor.submit(process_weather_query) - return True - - # 处理查询新闻意图 - if "查询新闻" in intent or "播报新闻" in intent or "看新闻" in intent: - logger.bind(tag=TAG).info(f"识别到新闻查询意图: {intent}") - # 获取新闻类别 - category = extract_text_in_brackets(intent) - - # 先发送消息确认 - await send_stt_message(conn, original_text) - - # 构造合适的新闻查询函数调用 - function_id = str(uuid.uuid4().hex) - function_name = "get_news" - - # 判断是否是查询详情 - detail = "详情" in intent or "详细" in intent - - # 构造参数JSON字符串 - if detail: - function_arguments = '{ "detail": true, "lang": "zh_CN" }' - else: - function_arguments = '{ "category": ' + (f'"{category}"' if category else 'null') + ', "detail": false, "lang": "zh_CN" }' - - function_call_data = { - "name": function_name, - "id": function_id, - "arguments": function_arguments - } - - # 使用executor执行函数调用和结果处理 - def process_news_query(): - # 直接调用函数 - result = conn.func_handler.handle_llm_function_call(conn, function_call_data) - if result: - # 获取当前最新的文本索引 - text_index = conn.tts_last_text_index + 1 if hasattr(conn, 'tts_last_text_index') else 0 - # 处理函数调用结果 - conn._handle_function_result(result, function_call_data, text_index) - - # 将函数执行放在线程池中 - conn.executor.submit(process_news_query) - return True - except Exception as e: + return False + except json.JSONDecodeError as e: logger.bind(tag=TAG).error(f"处理意图结果时出错: {e}") - - # 默认返回False,表示继续常规聊天流程 - return False + return False def extract_text_in_brackets(s): diff --git a/main/xiaozhi-server/core/providers/intent/base.py b/main/xiaozhi-server/core/providers/intent/base.py index 877dfced..a17cde81 100644 --- a/main/xiaozhi-server/core/providers/intent/base.py +++ b/main/xiaozhi-server/core/providers/intent/base.py @@ -10,11 +10,13 @@ class IntentProviderBase(ABC): def __init__(self, config): self.config = config self.intent_options = config.get("intent_options", { + "handle_exit_intent": "结束聊天, 用户发来如再见之类的表示结束的话, 不想再进行对话的时候", + "play_music": "播放音乐, 用户希望你可以播放音乐, 只用于播放音乐的意图", + "get_weather": "查询天气, 用户希望查询某个地点的天气情况", + "get_news": "查询新闻, 用户希望查询最新新闻或特定类型的新闻", + "get_lunar": "用于获取今天的阴历/农历和黄历信息", + "get_time": "获取今天日期或者当前时间信息", "continue_chat": "继续聊天", - "end_chat": "结束聊天", - "play_music": "播放音乐", - "get_weather": "查询天气", - "get_news": "查询新闻" }) def set_llm(self, llm): diff --git a/main/xiaozhi-server/core/providers/intent/function_call/function_call.py b/main/xiaozhi-server/core/providers/intent/function_call/function_call.py new file mode 100644 index 00000000..ff33e58f --- /dev/null +++ b/main/xiaozhi-server/core/providers/intent/function_call/function_call.py @@ -0,0 +1,20 @@ +from ..base import IntentProviderBase +from typing import List, Dict +from config.logger import setup_logging + +TAG = __name__ +logger = setup_logging() + + +class IntentProvider(IntentProviderBase): + async def detect_intent(self, conn, dialogue_history: List[Dict], text: str) -> str: + """ + 默认的意图识别实现,始终返回继续聊天 + Args: + dialogue_history: 对话历史记录列表 + text: 本次对话记录 + Returns: + 固定返回"继续聊天" + """ + logger.bind(tag=TAG).debug("Using functionCallProvider, always returning continue chat") + return self.intent_options["continue_chat"] diff --git a/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py b/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py index 5d0b0830..1afd835e 100644 --- a/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py +++ b/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py @@ -20,19 +20,6 @@ class IntentProvider(IntentProviderBase): self.intent_cache = {} # 缓存意图识别结果 self.cache_expiry = 600 # 缓存有效期10分钟 self.cache_max_size = 100 # 最多缓存100个意图 - self.common_patterns = { - "天气": '{\"function_call\": {\"name\": \"get_weather\", \"arguments\": {\"location\": null, \"lang\": \"zh_CN\"}}}', - "新闻": '{\"function_call\": {\"name\": \"get_news\", \"arguments\": {\"category\": null, \"detail\": false, \"lang\": \"zh_CN\"}}}', - "财经新闻": '{\"function_call\": {\"name\": \"get_news\", \"arguments\": {\"category\": \"财经\", \"detail\": false, \"lang\": \"zh_CN\"}}}', - "国际新闻": '{\"function_call\": {\"name\": \"get_news\", \"arguments\": {\"category\": \"国际\", \"detail\": false, \"lang\": \"zh_CN\"}}}', - "社会新闻": '{\"function_call\": {\"name\": \"get_news\", \"arguments\": {\"category\": \"社会\", \"detail\": false, \"lang\": \"zh_CN\"}}}', - "详细介绍": '{\"function_call\": {\"name\": \"get_news\", \"arguments\": {\"detail\": true, \"lang\": \"zh_CN\"}}}', - "详情": '{\"function_call\": {\"name\": \"get_news\", \"arguments\": {\"detail\": true, \"lang\": \"zh_CN\"}}}', - "再见": '{\"intent\": \"结束聊天\"}', - "结束": '{\"intent\": \"结束聊天\"}', - "拜拜": '{\"intent\": \"结束聊天\"}', - "播放音乐": '{\"function_call\": {\"name\": \"play_music\", \"arguments\": {\"song_name\": \"random\"}}}' - } def get_intent_system_prompt(self) -> str: """ @@ -42,60 +29,50 @@ class IntentProvider(IntentProviderBase): """ intent_list = [] - """ - "continue_chat": "1.继续聊天, 除了播放音乐和结束聊天的时候的选项, 比如日常的聊天和问候, 对话等", - "end_chat": "2.结束聊天, 用户发来如再见之类的表示结束的话, 不想再进行对话的时候", - "play_music": "3.播放音乐, 用户希望你可以播放音乐, 只用于播放音乐的意图", - "get_weather": "4.查询天气, 用户希望查询某个地点的天气情况" - "get_news": "5.查询新闻, 用户希望查询最新新闻或特定类型的新闻" - """ - for key, value in self.intent_options.items(): - if key == "play_music": - intent_list.append("3.播放音乐, 用户希望你可以播放音乐, 只用于播放音乐的意图") - elif key == "end_chat": - intent_list.append("2.结束聊天, 用户发来如再见之类的表示结束的话, 不想再进行对话的时候") - elif key == "continue_chat": - intent_list.append("1.继续聊天, 除了播放音乐和结束聊天的时候的选项, 比如日常的聊天和问候, 对话等") - elif key == "get_weather": - intent_list.append("4.查询天气, 用户希望查询某个地点的天气情况") - elif key == "get_news": - intent_list.append("5.查询新闻, 用户希望查询最新新闻或特定类型的新闻") - else: - intent_list.append(value) - prompt = ( "你是一个意图识别助手。请分析用户的最后一句话,判断用户意图属于以下哪一类:\n" "" f"{', '.join(intent_list)}" "\n" "处理步骤:" - "1. 思考意图类型" - "2. 继续聊天和结束聊天意图: 返回intent格式" - "3. 播放音乐意图: 分析歌名,生成function_call格式" - "4. 查询天气意图: 分析地点,生成function_call格式" - "5. 查询新闻意图: 分析新闻类别,生成function_call格式" + "1. 思考意图类型,生成function_call格式" "\n\n" "返回格式示例:\n" - "1. 继续聊天意图: {\"intent\": \"继续聊天\"}\n" - "2. 结束聊天意图: {\"intent\": \"结束聊天\"}\n" - "3. 播放音乐意图: {\"function_call\": {\"name\": \"play_music\", \"arguments\": {\"song_name\": \"音乐名称\"}}}\n" - "4. 查询天气意图: {\"function_call\": {\"name\": \"get_weather\", \"arguments\": {\"location\": \"地点名称\", \"lang\": \"zh_CN\"}}}\n" - "5. 查询新闻意图: {\"function_call\": {\"name\": \"get_news\", \"arguments\": {\"category\": \"新闻类别\", \"detail\": false, \"lang\": \"zh_CN\"}}}\n" + "1. 播放音乐意图: {\"function_call\": {\"name\": \"play_music\", \"arguments\": {\"song_name\": \"音乐名称\"}}}\n" + "2. 查询天气意图: {\"function_call\": {\"name\": \"get_weather\", \"arguments\": {\"location\": \"地点名称\", \"lang\": \"zh_CN\"}}}\n" + "3. 查询新闻意图: {\"function_call\": {\"name\": \"get_news\", \"arguments\": {\"category\": \"新闻类别\", \"detail\": false, \"lang\": \"zh_CN\"}}}\n" + "4. 结束对话意图: {\"function_call\": {\"name\": \"handle_exit_intent\", \"arguments\": {\"say_goodbye\": \"goodbye\"}}}\n" + "5. 获取当天日期时间: {\"function_call\": {\"name\": \"get_time\"}}\n" + "6. 获取当前黄历意图: {\"function_call\": {\"name\": \"get_lunar\"}}\n" + "7. 继续聊天意图: {\"function_call\": {\"name\": \"continue_chat\"}}\n" "\n" "注意:\n" "- 播放音乐:无歌名时,song_name设为\"random\"\n" "- 查询天气:无地点时,location设为null\n" "- 查询新闻:无类别时,category设为null;查询详情时,detail设为true\n" + "- 如果没有明显的意图,应按照继续聊天意图处理\n" "- 只返回纯JSON,不要任何其他内容\n" "\n" "示例分析:\n" "```\n" + "用户: 你好小智\n" + "返回: {\"function_call\": {\"name\": \"continue_chat\"}}\n" + "```\n" + "```\n" "用户: 你今天怎么样?\n" - "返回: {\"intent\": \"继续聊天\"}\n" + "返回: {\"function_call\": {\"name\": \"continue_chat\"}}\n" + "```\n" + "```\n" + "用户: 现在是几号了?现在几点了?\n" + "返回: {\"function_call\": {\"name\": \"get_time\"}}\n" + "```\n" + "```\n" + "用户: 今天农历是多少?\n" + "返回: {\"function_call\": {\"name\": \"get_lunar\"}}\n" "```\n" "```\n" "用户: 我们明天再聊吧\n" - "返回: {\"intent\": \"结束聊天\"}\n" + "返回: {\"function_call\": {\"name\": \"handle_exit_intent\"}}\n" "```\n" "```\n" "用户: 播放中秋月\n" @@ -140,25 +117,6 @@ class IntentProvider(IntentProviderBase): for key, _ in sorted_items[:len(sorted_items) - self.cache_max_size]: del self.intent_cache[key] - def check_pattern_match(self, text): - """检查文本是否匹配常见模式,并提取关键信息""" - # 城市+天气的特殊模式匹配 - city_weather_pattern = re.search(r'([^\s,,。?!]+)天气', text) - if city_weather_pattern: - city = city_weather_pattern.group(1) - # 排除可能的误匹配,如"今天天气"、"明天天气"、"现在天气"等 - if city not in ["今天", "今日", "明天", "现在", "当前", "未来", "明日", "这两天", "近期"]: - logger.bind(tag=TAG).info(f"提取到城市名: {city}") - # 返回包含城市名的function_call - return f'{{\"function_call\": {{\"name\": \"get_weather\", \"arguments\": {{\"location\": \"{city}\", \"lang\": \"zh_CN\"}}}}}}' - - # 普通模式匹配 - for pattern, intent in self.common_patterns.items(): - if pattern in text: - return intent - - return None - async def detect_intent(self, conn, dialogue_history: List[Dict], text: str) -> str: if not self.llm: raise ValueError("LLM provider not set") @@ -170,13 +128,6 @@ class IntentProvider(IntentProviderBase): model_info = getattr(self.llm, 'model_name', str(self.llm.__class__.__name__)) logger.bind(tag=TAG).info(f"使用意图识别模型: {model_info}") - # 先尝试简单的模式匹配 - pattern_match = self.check_pattern_match(text) - if pattern_match: - pattern_time = time.time() - total_start_time - logger.bind(tag=TAG).info(f"模式匹配成功: {text} -> {pattern_match}, 耗时: {pattern_time:.4f}秒") - return pattern_match - # 计算缓存键 cache_key = hashlib.md5(text.encode()).hexdigest()