如何让基于LangChain的聊天机器人识别对话中的话题切换?
解决话题切换识别问题的方案
一、优化对话内存管理
你当前使用的ConversationStringBufferMemory会保留全部对话历史,当历史过长时,模型容易被旧话题信息干扰,无法聚焦新话题。可以换成以下两种内存策略:
- 对话窗口内存(ConversationWindowMemory):只保留最近N轮对话,过滤掉早期无关内容。示例代码:
from langchain.memory import ConversationWindowMemory conv_memory = ConversationWindowMemory( input_key="input_text", buffer=user.chat_history, memory_key="chat_history", k=5 # 只保留最近5轮对话 )
- 对话摘要内存(ConversationSummaryMemory):自动将早期对话总结成摘要,减少冗余信息同时保留关键语境。示例代码:
from langchain.memory import ConversationSummaryMemory conv_memory = ConversationSummaryMemory( llm=recommender, input_key="input_text", memory_key="chat_history", buffer=user.chat_history )
二、强化Prompt的话题检测指令
在你的Prompt中明确加入话题切换判断逻辑,引导模型主动识别新话题。比如在Prompt模板里添加:
请先判断用户当前输入是否与之前的对话话题相关:如果无关,完全切换到新话题,无需提及之前的内容;如果相关,继续基于历史对话回应。
示例Prompt结构(假设你用的是PromptTemplate):
from langchain.prompts import PromptTemplate prompt = PromptTemplate( input_variables=["chat_history", "input_text"], template="""请先判断用户当前输入是否与之前的对话话题相关:如果无关,完全切换到新话题,无需提及之前的内容;如果相关,继续基于历史对话回应。 对话历史:{chat_history} 用户输入:{input_text} 你的回应:""" )
三、选择更适配的LLM
当前使用的text-bison@001在长上下文话题切换上表现一般,可以考虑VertexAI上的这些模型:
- text-bison@002:相比001版本,优化了长上下文理解和话题追踪能力
- Gemini 1.5 Flash/Pro:支持超长上下文(最高1M tokens),对话题边界的识别更精准,适合多轮复杂对话场景
四、使用话题路由Agent
如果需要更精准的话题切换控制,可以基于LangChain的RouterChain实现话题路由:
- 先定义多个话题对应的子Chain(比如“技术咨询”“日常闲聊”等)
- 用一个话题分类LLM作为路由判断器,根据用户输入将请求转发到对应子Chain
- 子Chain仅处理对应话题,避免旧话题干扰
示例简化逻辑:
from langchain.chains.router import MultiPromptChain from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser from langchain.prompts import PromptTemplate # 定义不同话题的Prompt tech_prompt = PromptTemplate( input_variables=["input_text"], template="你是技术咨询助手,回答用户的技术问题:{input_text}" ) chat_prompt = PromptTemplate( input_variables=["input_text"], template="你是闲聊助手,和用户轻松聊天:{input_text}" ) # 路由模板 router_template = """根据用户输入判断话题类型,只能选择以下选项: - 技术咨询:用户问技术相关问题 - 日常闲聊:用户聊生活、兴趣等非技术内容 用户输入:{input_text} 请返回格式为`话题类型:[对应类型]`的结果""" router_prompt = PromptTemplate( input_variables=["input_text"], template=router_template, output_parser=RouterOutputParser() ) router_chain = LLMRouterChain.from_llm(recommender, router_prompt) destination_chains = { "技术咨询": ConversationChain(llm=recommender, prompt=tech_prompt), "日常闲聊": ConversationChain(llm=recommender, prompt=chat_prompt) } # 构建多话题路由Chain multi_prompt_chain = MultiPromptChain( router_chain=router_chain, destination_chains=destination_chains, default_chain=ConversationChain(llm=recommender, prompt=prompt), verbose=True ) # 使用路由Chain处理输入 llm_response = multi_prompt_chain.run(input_text=input_text)
内容的提问来源于stack exchange,提问作者khateeb
相关产品推荐
相关产品推荐

