本地记忆+意图识别 (#250)

* 增加本地记忆功能,使用llm总结记忆

* update:增加统一非流式输出输出

* 增加意图识别内容,使用llm进行识别

* 初始化记忆模块

* 完善意图识别处理后的流程

* 通过使用function call实现意图识别

* update:优化意图识别的配置

* update:function call最优设置成doubao-pro-32k-functioncall-241028

---------

Co-authored-by: 玄凤科技 <eric230308@gmail.com>
Co-authored-by: hrz <1710360675@qq.com>
This commit is contained in:
欣南科技
2025-03-09 21:33:45 +08:00
committed by GitHub
co-authored by 玄凤科技 hrz
parent 9c2b2a2dcc
commit 63f34e5a82
19 changed files with 858 additions and 108 deletions
@@ -0,0 +1,33 @@
from abc import ABC, abstractmethod
from typing import List, Dict
from config.logger import setup_logging
TAG = __name__
logger = setup_logging()
class IntentProviderBase(ABC):
def __init__(self, config):
self.config = config
self.intent_options = config.get("intent_options", {
"continue_chat": "继续聊天",
"end_chat": "结束聊天",
"play_music": "播放音乐"
})
def set_llm(self, llm):
self.llm = llm
logger.bind(tag=TAG).debug("Set LLM for intent provider")
@abstractmethod
async def detect_intent(self, dialogue_history: List[Dict]) -> str:
"""
检测用户最后一句话的意图
Args:
dialogue_history: 对话历史记录列表,每条记录包含role和content
Returns:
返回识别出的意图,格式为:
- "继续聊天"
- "结束聊天"
- "播放音乐 歌名""随机播放音乐"
"""
pass
@@ -0,0 +1,61 @@
from typing import List, Dict
from ..base import IntentProviderBase
from config.logger import setup_logging
TAG = __name__
logger = setup_logging()
class IntentProvider(IntentProviderBase):
def __init__(self, config):
super().__init__(config)
self.llm = None
self.promot = self.get_intent_system_prompt()
def get_intent_system_prompt(self) -> str:
"""
根据配置的意图选项动态生成系统提示词
Returns:
格式化后的系统提示词
"""
intent_list = []
for key, value in self.intent_options.items():
if key == "play_music":
intent_list.append(f"{value} [歌名]")
else:
intent_list.append(value)
prompt = (
"你是一个意图识别助手。你需要根据和用户的对话记录,重点分析用户的最后一句话,判断用户意图属于以下哪一类:\n"
f"{', '.join(intent_list)}\n"
"如果是唱歌、听歌、播放音乐,请指定歌名,格式为'播放音乐 [识别出的歌名]'\n"
"如果听不出具体歌名,可以返回'随机播放音乐'\n"
"只需要返回意图结果的json,不要解释。"
"返回格式如下:\n"
"{intent: '用户意图'}"
)
return prompt
async def detect_intent(self, dialogue_history: List[Dict]) -> str:
if not self.llm:
raise ValueError("LLM provider not set")
# 构建用户最后一句话的提示
msgStr = ""
for msg in dialogue_history:
if msg.role == "user":
msgStr += f"User: {msg.content}\n"
elif msg.role== "assistant":
msgStr += f"Assistant: {msg.content}\n"
user_prompt = f"请分析用户的意图:\n{msgStr}"
# 使用LLM进行意图识别
intent = self.llm.response_no_stream(
system_prompt=self.promot,
user_prompt=user_prompt
)
logger.bind(tag=TAG).info(f"Detected intent: {intent}")
return intent.strip()
@@ -0,0 +1,18 @@
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, dialogue_history: List[Dict]) -> str:
"""
默认的意图识别实现,始终返回继续聊天
Args:
dialogue_history: 对话历史记录列表
Returns:
固定返回"继续聊天"
"""
logger.bind(tag=TAG).debug("Using NoIntentProvider, always returning continue chat")
return self.intent_options["continue_chat"]